1*3ac0a46fSAndroid Build Coastguard Worker /*
2*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 1988-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 * Directory Read Support Routines.
29*3ac0a46fSAndroid Build Coastguard Worker */
30*3ac0a46fSAndroid Build Coastguard Worker
31*3ac0a46fSAndroid Build Coastguard Worker /* Suggested pending improvements:
32*3ac0a46fSAndroid Build Coastguard Worker * - add a field 'field_info' to the TIFFDirEntry structure, and set that with
33*3ac0a46fSAndroid Build Coastguard Worker * the pointer to the appropriate TIFFField structure early on in
34*3ac0a46fSAndroid Build Coastguard Worker * TIFFReadDirectory, so as to eliminate current possibly repetitive lookup.
35*3ac0a46fSAndroid Build Coastguard Worker */
36*3ac0a46fSAndroid Build Coastguard Worker
37*3ac0a46fSAndroid Build Coastguard Worker #include "tiffconf.h"
38*3ac0a46fSAndroid Build Coastguard Worker #include "tiffiop.h"
39*3ac0a46fSAndroid Build Coastguard Worker #include <float.h>
40*3ac0a46fSAndroid Build Coastguard Worker #include <limits.h>
41*3ac0a46fSAndroid Build Coastguard Worker #include <stdlib.h>
42*3ac0a46fSAndroid Build Coastguard Worker #include <string.h>
43*3ac0a46fSAndroid Build Coastguard Worker
44*3ac0a46fSAndroid Build Coastguard Worker #define FAILED_FII ((uint32_t)-1)
45*3ac0a46fSAndroid Build Coastguard Worker
46*3ac0a46fSAndroid Build Coastguard Worker #ifdef HAVE_IEEEFP
47*3ac0a46fSAndroid Build Coastguard Worker #define TIFFCvtIEEEFloatToNative(tif, n, fp)
48*3ac0a46fSAndroid Build Coastguard Worker #define TIFFCvtIEEEDoubleToNative(tif, n, dp)
49*3ac0a46fSAndroid Build Coastguard Worker #else
50*3ac0a46fSAndroid Build Coastguard Worker extern void TIFFCvtIEEEFloatToNative(TIFF *, uint32_t, float *);
51*3ac0a46fSAndroid Build Coastguard Worker extern void TIFFCvtIEEEDoubleToNative(TIFF *, uint32_t, double *);
52*3ac0a46fSAndroid Build Coastguard Worker #endif
53*3ac0a46fSAndroid Build Coastguard Worker
54*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr
55*3ac0a46fSAndroid Build Coastguard Worker {
56*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryErrOk = 0,
57*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryErrCount = 1,
58*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryErrType = 2,
59*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryErrIo = 3,
60*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryErrRange = 4,
61*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryErrPsdif = 5,
62*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryErrSizesan = 6,
63*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryErrAlloc = 7,
64*3ac0a46fSAndroid Build Coastguard Worker };
65*3ac0a46fSAndroid Build Coastguard Worker
66*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
67*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value);
68*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
69*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value);
70*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
71*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value);
72*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
73*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value);
74*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
75*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value);
76*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
77*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value);
78*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
79*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value);
80*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
81*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value);
82*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
83*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value);
84*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
85*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value);
86*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
87*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value);
88*3ac0a46fSAndroid Build Coastguard Worker
89*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
90*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count,
91*3ac0a46fSAndroid Build Coastguard Worker uint32_t desttypesize, void **value);
92*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
93*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value);
94*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
95*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value);
96*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
97*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value);
98*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
99*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value);
100*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
101*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value);
102*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
103*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value);
104*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
105*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value);
106*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
107*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value);
108*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
109*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value);
110*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
111*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value);
112*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
113*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value);
114*3ac0a46fSAndroid Build Coastguard Worker
115*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
116*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry,
117*3ac0a46fSAndroid Build Coastguard Worker uint16_t *value);
118*3ac0a46fSAndroid Build Coastguard Worker
119*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry,
120*3ac0a46fSAndroid Build Coastguard Worker uint8_t *value);
121*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry,
122*3ac0a46fSAndroid Build Coastguard Worker int8_t *value);
123*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry,
124*3ac0a46fSAndroid Build Coastguard Worker uint16_t *value);
125*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry,
126*3ac0a46fSAndroid Build Coastguard Worker int16_t *value);
127*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry,
128*3ac0a46fSAndroid Build Coastguard Worker uint32_t *value);
129*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry,
130*3ac0a46fSAndroid Build Coastguard Worker int32_t *value);
131*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
132*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry,
133*3ac0a46fSAndroid Build Coastguard Worker uint64_t *value);
134*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
135*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry,
136*3ac0a46fSAndroid Build Coastguard Worker int64_t *value);
137*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
138*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry,
139*3ac0a46fSAndroid Build Coastguard Worker double *value);
140*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
141*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry,
142*3ac0a46fSAndroid Build Coastguard Worker double *value);
143*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry,
144*3ac0a46fSAndroid Build Coastguard Worker float *value);
145*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
146*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value);
147*3ac0a46fSAndroid Build Coastguard Worker #if 0
148*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
149*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedRationalDirect(TIFF *tif, TIFFDirEntry *direntry,
150*3ac0a46fSAndroid Build Coastguard Worker TIFFRational_t *value);
151*3ac0a46fSAndroid Build Coastguard Worker #endif
152*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
153*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteSbyte(int8_t value);
154*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
155*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteShort(uint16_t value);
156*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
157*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteSshort(int16_t value);
158*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
159*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteLong(uint32_t value);
160*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
161*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteSlong(int32_t value);
162*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
163*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteLong8(uint64_t value);
164*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
165*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteSlong8(int64_t value);
166*3ac0a46fSAndroid Build Coastguard Worker
167*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
168*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value);
169*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
170*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value);
171*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
172*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value);
173*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
174*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value);
175*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
176*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value);
177*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
178*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value);
179*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
180*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value);
181*3ac0a46fSAndroid Build Coastguard Worker
182*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
183*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeShortSbyte(int8_t value);
184*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
185*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeShortSshort(int16_t value);
186*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
187*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeShortLong(uint32_t value);
188*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
189*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeShortSlong(int32_t value);
190*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
191*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeShortLong8(uint64_t value);
192*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
193*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeShortSlong8(int64_t value);
194*3ac0a46fSAndroid Build Coastguard Worker
195*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
196*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSshortShort(uint16_t value);
197*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
198*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSshortLong(uint32_t value);
199*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
200*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSshortSlong(int32_t value);
201*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
202*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value);
203*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
204*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value);
205*3ac0a46fSAndroid Build Coastguard Worker
206*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
207*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLongSbyte(int8_t value);
208*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
209*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLongSshort(int16_t value);
210*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
211*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLongSlong(int32_t value);
212*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
213*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLongLong8(uint64_t value);
214*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
215*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLongSlong8(int64_t value);
216*3ac0a46fSAndroid Build Coastguard Worker
217*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
218*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSlongLong(uint32_t value);
219*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
220*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value);
221*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
222*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value);
223*3ac0a46fSAndroid Build Coastguard Worker
224*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
225*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value);
226*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
227*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value);
228*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
229*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLong8Slong(int32_t value);
230*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
231*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value);
232*3ac0a46fSAndroid Build Coastguard Worker
233*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
234*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value);
235*3ac0a46fSAndroid Build Coastguard Worker
236*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset,
237*3ac0a46fSAndroid Build Coastguard Worker tmsize_t size, void *dest);
238*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err,
239*3ac0a46fSAndroid Build Coastguard Worker const char *module, const char *tagname,
240*3ac0a46fSAndroid Build Coastguard Worker int recover);
241*3ac0a46fSAndroid Build Coastguard Worker
242*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir,
243*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount);
244*3ac0a46fSAndroid Build Coastguard Worker static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir,
245*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount,
246*3ac0a46fSAndroid Build Coastguard Worker uint16_t tagid);
247*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid,
248*3ac0a46fSAndroid Build Coastguard Worker uint32_t *fii);
249*3ac0a46fSAndroid Build Coastguard Worker
250*3ac0a46fSAndroid Build Coastguard Worker static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir,
251*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount);
252*3ac0a46fSAndroid Build Coastguard Worker static void MissingRequired(TIFF *, const char *);
253*3ac0a46fSAndroid Build Coastguard Worker static int CheckDirCount(TIFF *, TIFFDirEntry *, uint32_t);
254*3ac0a46fSAndroid Build Coastguard Worker static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
255*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry **pdir, uint64_t *nextdiroff);
256*3ac0a46fSAndroid Build Coastguard Worker static int TIFFFetchNormalTag(TIFF *, TIFFDirEntry *, int recover);
257*3ac0a46fSAndroid Build Coastguard Worker static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips,
258*3ac0a46fSAndroid Build Coastguard Worker uint64_t **lpp);
259*3ac0a46fSAndroid Build Coastguard Worker static int TIFFFetchSubjectDistance(TIFF *, TIFFDirEntry *);
260*3ac0a46fSAndroid Build Coastguard Worker static void ChopUpSingleUncompressedStrip(TIFF *);
261*3ac0a46fSAndroid Build Coastguard Worker static void TryChopUpUncompressedBigTiff(TIFF *);
262*3ac0a46fSAndroid Build Coastguard Worker static uint64_t TIFFReadUInt64(const uint8_t *value);
263*3ac0a46fSAndroid Build Coastguard Worker static int _TIFFGetMaxColorChannels(uint16_t photometric);
264*3ac0a46fSAndroid Build Coastguard Worker
265*3ac0a46fSAndroid Build Coastguard Worker static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount);
266*3ac0a46fSAndroid Build Coastguard Worker
267*3ac0a46fSAndroid Build Coastguard Worker typedef union _UInt64Aligned_t
268*3ac0a46fSAndroid Build Coastguard Worker {
269*3ac0a46fSAndroid Build Coastguard Worker double d;
270*3ac0a46fSAndroid Build Coastguard Worker uint64_t l;
271*3ac0a46fSAndroid Build Coastguard Worker uint32_t i[2];
272*3ac0a46fSAndroid Build Coastguard Worker uint16_t s[4];
273*3ac0a46fSAndroid Build Coastguard Worker uint8_t c[8];
274*3ac0a46fSAndroid Build Coastguard Worker } UInt64Aligned_t;
275*3ac0a46fSAndroid Build Coastguard Worker
276*3ac0a46fSAndroid Build Coastguard Worker /*
277*3ac0a46fSAndroid Build Coastguard Worker Unaligned safe copy of a uint64_t value from an octet array.
278*3ac0a46fSAndroid Build Coastguard Worker */
TIFFReadUInt64(const uint8_t * value)279*3ac0a46fSAndroid Build Coastguard Worker static uint64_t TIFFReadUInt64(const uint8_t *value)
280*3ac0a46fSAndroid Build Coastguard Worker {
281*3ac0a46fSAndroid Build Coastguard Worker UInt64Aligned_t result;
282*3ac0a46fSAndroid Build Coastguard Worker
283*3ac0a46fSAndroid Build Coastguard Worker result.c[0] = value[0];
284*3ac0a46fSAndroid Build Coastguard Worker result.c[1] = value[1];
285*3ac0a46fSAndroid Build Coastguard Worker result.c[2] = value[2];
286*3ac0a46fSAndroid Build Coastguard Worker result.c[3] = value[3];
287*3ac0a46fSAndroid Build Coastguard Worker result.c[4] = value[4];
288*3ac0a46fSAndroid Build Coastguard Worker result.c[5] = value[5];
289*3ac0a46fSAndroid Build Coastguard Worker result.c[6] = value[6];
290*3ac0a46fSAndroid Build Coastguard Worker result.c[7] = value[7];
291*3ac0a46fSAndroid Build Coastguard Worker
292*3ac0a46fSAndroid Build Coastguard Worker return result.l;
293*3ac0a46fSAndroid Build Coastguard Worker }
294*3ac0a46fSAndroid Build Coastguard Worker
295*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryByte(TIFF * tif,TIFFDirEntry * direntry,uint8_t * value)296*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value)
297*3ac0a46fSAndroid Build Coastguard Worker {
298*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
299*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count != 1)
300*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
301*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
302*3ac0a46fSAndroid Build Coastguard Worker {
303*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
304*3ac0a46fSAndroid Build Coastguard Worker case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with
305*3ac0a46fSAndroid Build Coastguard Worker field_readcount==1 */
306*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedByte(tif, direntry, value);
307*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
308*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
309*3ac0a46fSAndroid Build Coastguard Worker {
310*3ac0a46fSAndroid Build Coastguard Worker int8_t m;
311*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
312*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteSbyte(m);
313*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
314*3ac0a46fSAndroid Build Coastguard Worker return (err);
315*3ac0a46fSAndroid Build Coastguard Worker *value = (uint8_t)m;
316*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
317*3ac0a46fSAndroid Build Coastguard Worker }
318*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
319*3ac0a46fSAndroid Build Coastguard Worker {
320*3ac0a46fSAndroid Build Coastguard Worker uint16_t m;
321*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedShort(tif, direntry, &m);
322*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteShort(m);
323*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
324*3ac0a46fSAndroid Build Coastguard Worker return (err);
325*3ac0a46fSAndroid Build Coastguard Worker *value = (uint8_t)m;
326*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
327*3ac0a46fSAndroid Build Coastguard Worker }
328*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
329*3ac0a46fSAndroid Build Coastguard Worker {
330*3ac0a46fSAndroid Build Coastguard Worker int16_t m;
331*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
332*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteSshort(m);
333*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
334*3ac0a46fSAndroid Build Coastguard Worker return (err);
335*3ac0a46fSAndroid Build Coastguard Worker *value = (uint8_t)m;
336*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
337*3ac0a46fSAndroid Build Coastguard Worker }
338*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
339*3ac0a46fSAndroid Build Coastguard Worker {
340*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
341*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong(tif, direntry, &m);
342*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteLong(m);
343*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
344*3ac0a46fSAndroid Build Coastguard Worker return (err);
345*3ac0a46fSAndroid Build Coastguard Worker *value = (uint8_t)m;
346*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
347*3ac0a46fSAndroid Build Coastguard Worker }
348*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
349*3ac0a46fSAndroid Build Coastguard Worker {
350*3ac0a46fSAndroid Build Coastguard Worker int32_t m;
351*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
352*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteSlong(m);
353*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
354*3ac0a46fSAndroid Build Coastguard Worker return (err);
355*3ac0a46fSAndroid Build Coastguard Worker *value = (uint8_t)m;
356*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
357*3ac0a46fSAndroid Build Coastguard Worker }
358*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
359*3ac0a46fSAndroid Build Coastguard Worker {
360*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
361*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
362*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
363*3ac0a46fSAndroid Build Coastguard Worker return (err);
364*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteLong8(m);
365*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
366*3ac0a46fSAndroid Build Coastguard Worker return (err);
367*3ac0a46fSAndroid Build Coastguard Worker *value = (uint8_t)m;
368*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
369*3ac0a46fSAndroid Build Coastguard Worker }
370*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
371*3ac0a46fSAndroid Build Coastguard Worker {
372*3ac0a46fSAndroid Build Coastguard Worker int64_t m;
373*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
374*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
375*3ac0a46fSAndroid Build Coastguard Worker return (err);
376*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteSlong8(m);
377*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
378*3ac0a46fSAndroid Build Coastguard Worker return (err);
379*3ac0a46fSAndroid Build Coastguard Worker *value = (uint8_t)m;
380*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
381*3ac0a46fSAndroid Build Coastguard Worker }
382*3ac0a46fSAndroid Build Coastguard Worker default:
383*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
384*3ac0a46fSAndroid Build Coastguard Worker }
385*3ac0a46fSAndroid Build Coastguard Worker }
386*3ac0a46fSAndroid Build Coastguard Worker
387*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntrySbyte(TIFF * tif,TIFFDirEntry * direntry,int8_t * value)388*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value)
389*3ac0a46fSAndroid Build Coastguard Worker {
390*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
391*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count != 1)
392*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
393*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
394*3ac0a46fSAndroid Build Coastguard Worker {
395*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
396*3ac0a46fSAndroid Build Coastguard Worker case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with
397*3ac0a46fSAndroid Build Coastguard Worker field_readcount==1 */
398*3ac0a46fSAndroid Build Coastguard Worker {
399*3ac0a46fSAndroid Build Coastguard Worker uint8_t m;
400*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedByte(tif, direntry, &m);
401*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteByte(m);
402*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
403*3ac0a46fSAndroid Build Coastguard Worker return (err);
404*3ac0a46fSAndroid Build Coastguard Worker *value = (int8_t)m;
405*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
406*3ac0a46fSAndroid Build Coastguard Worker }
407*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
408*3ac0a46fSAndroid Build Coastguard Worker {
409*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSbyte(tif, direntry, value);
410*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
411*3ac0a46fSAndroid Build Coastguard Worker }
412*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
413*3ac0a46fSAndroid Build Coastguard Worker {
414*3ac0a46fSAndroid Build Coastguard Worker uint16_t m;
415*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedShort(tif, direntry, &m);
416*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteShort(m);
417*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
418*3ac0a46fSAndroid Build Coastguard Worker return (err);
419*3ac0a46fSAndroid Build Coastguard Worker *value = (int8_t)m;
420*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
421*3ac0a46fSAndroid Build Coastguard Worker }
422*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
423*3ac0a46fSAndroid Build Coastguard Worker {
424*3ac0a46fSAndroid Build Coastguard Worker int16_t m;
425*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
426*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteSshort(m);
427*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
428*3ac0a46fSAndroid Build Coastguard Worker return (err);
429*3ac0a46fSAndroid Build Coastguard Worker *value = (int8_t)m;
430*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
431*3ac0a46fSAndroid Build Coastguard Worker }
432*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
433*3ac0a46fSAndroid Build Coastguard Worker {
434*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
435*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong(tif, direntry, &m);
436*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteLong(m);
437*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
438*3ac0a46fSAndroid Build Coastguard Worker return (err);
439*3ac0a46fSAndroid Build Coastguard Worker *value = (int8_t)m;
440*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
441*3ac0a46fSAndroid Build Coastguard Worker }
442*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
443*3ac0a46fSAndroid Build Coastguard Worker {
444*3ac0a46fSAndroid Build Coastguard Worker int32_t m;
445*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
446*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteSlong(m);
447*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
448*3ac0a46fSAndroid Build Coastguard Worker return (err);
449*3ac0a46fSAndroid Build Coastguard Worker *value = (int8_t)m;
450*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
451*3ac0a46fSAndroid Build Coastguard Worker }
452*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
453*3ac0a46fSAndroid Build Coastguard Worker {
454*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
455*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
456*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
457*3ac0a46fSAndroid Build Coastguard Worker return (err);
458*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteLong8(m);
459*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
460*3ac0a46fSAndroid Build Coastguard Worker return (err);
461*3ac0a46fSAndroid Build Coastguard Worker *value = (int8_t)m;
462*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
463*3ac0a46fSAndroid Build Coastguard Worker }
464*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
465*3ac0a46fSAndroid Build Coastguard Worker {
466*3ac0a46fSAndroid Build Coastguard Worker int64_t m;
467*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
468*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
469*3ac0a46fSAndroid Build Coastguard Worker return (err);
470*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteSlong8(m);
471*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
472*3ac0a46fSAndroid Build Coastguard Worker return (err);
473*3ac0a46fSAndroid Build Coastguard Worker *value = (int8_t)m;
474*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
475*3ac0a46fSAndroid Build Coastguard Worker }
476*3ac0a46fSAndroid Build Coastguard Worker default:
477*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
478*3ac0a46fSAndroid Build Coastguard Worker }
479*3ac0a46fSAndroid Build Coastguard Worker } /*-- TIFFReadDirEntrySbyte() --*/
480*3ac0a46fSAndroid Build Coastguard Worker
481*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryShort(TIFF * tif,TIFFDirEntry * direntry,uint16_t * value)482*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value)
483*3ac0a46fSAndroid Build Coastguard Worker {
484*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
485*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count != 1)
486*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
487*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
488*3ac0a46fSAndroid Build Coastguard Worker {
489*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
490*3ac0a46fSAndroid Build Coastguard Worker {
491*3ac0a46fSAndroid Build Coastguard Worker uint8_t m;
492*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedByte(tif, direntry, &m);
493*3ac0a46fSAndroid Build Coastguard Worker *value = (uint16_t)m;
494*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
495*3ac0a46fSAndroid Build Coastguard Worker }
496*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
497*3ac0a46fSAndroid Build Coastguard Worker {
498*3ac0a46fSAndroid Build Coastguard Worker int8_t m;
499*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
500*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeShortSbyte(m);
501*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
502*3ac0a46fSAndroid Build Coastguard Worker return (err);
503*3ac0a46fSAndroid Build Coastguard Worker *value = (uint16_t)m;
504*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
505*3ac0a46fSAndroid Build Coastguard Worker }
506*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
507*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedShort(tif, direntry, value);
508*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
509*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
510*3ac0a46fSAndroid Build Coastguard Worker {
511*3ac0a46fSAndroid Build Coastguard Worker int16_t m;
512*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
513*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeShortSshort(m);
514*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
515*3ac0a46fSAndroid Build Coastguard Worker return (err);
516*3ac0a46fSAndroid Build Coastguard Worker *value = (uint16_t)m;
517*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
518*3ac0a46fSAndroid Build Coastguard Worker }
519*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
520*3ac0a46fSAndroid Build Coastguard Worker {
521*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
522*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong(tif, direntry, &m);
523*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeShortLong(m);
524*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
525*3ac0a46fSAndroid Build Coastguard Worker return (err);
526*3ac0a46fSAndroid Build Coastguard Worker *value = (uint16_t)m;
527*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
528*3ac0a46fSAndroid Build Coastguard Worker }
529*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
530*3ac0a46fSAndroid Build Coastguard Worker {
531*3ac0a46fSAndroid Build Coastguard Worker int32_t m;
532*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
533*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeShortSlong(m);
534*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
535*3ac0a46fSAndroid Build Coastguard Worker return (err);
536*3ac0a46fSAndroid Build Coastguard Worker *value = (uint16_t)m;
537*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
538*3ac0a46fSAndroid Build Coastguard Worker }
539*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
540*3ac0a46fSAndroid Build Coastguard Worker {
541*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
542*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
543*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
544*3ac0a46fSAndroid Build Coastguard Worker return (err);
545*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeShortLong8(m);
546*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
547*3ac0a46fSAndroid Build Coastguard Worker return (err);
548*3ac0a46fSAndroid Build Coastguard Worker *value = (uint16_t)m;
549*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
550*3ac0a46fSAndroid Build Coastguard Worker }
551*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
552*3ac0a46fSAndroid Build Coastguard Worker {
553*3ac0a46fSAndroid Build Coastguard Worker int64_t m;
554*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
555*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
556*3ac0a46fSAndroid Build Coastguard Worker return (err);
557*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeShortSlong8(m);
558*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
559*3ac0a46fSAndroid Build Coastguard Worker return (err);
560*3ac0a46fSAndroid Build Coastguard Worker *value = (uint16_t)m;
561*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
562*3ac0a46fSAndroid Build Coastguard Worker }
563*3ac0a46fSAndroid Build Coastguard Worker default:
564*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
565*3ac0a46fSAndroid Build Coastguard Worker }
566*3ac0a46fSAndroid Build Coastguard Worker } /*-- TIFFReadDirEntryShort() --*/
567*3ac0a46fSAndroid Build Coastguard Worker
568*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntrySshort(TIFF * tif,TIFFDirEntry * direntry,int16_t * value)569*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value)
570*3ac0a46fSAndroid Build Coastguard Worker {
571*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
572*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count != 1)
573*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
574*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
575*3ac0a46fSAndroid Build Coastguard Worker {
576*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
577*3ac0a46fSAndroid Build Coastguard Worker {
578*3ac0a46fSAndroid Build Coastguard Worker uint8_t m;
579*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedByte(tif, direntry, &m);
580*3ac0a46fSAndroid Build Coastguard Worker *value = (int16_t)m;
581*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
582*3ac0a46fSAndroid Build Coastguard Worker }
583*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
584*3ac0a46fSAndroid Build Coastguard Worker {
585*3ac0a46fSAndroid Build Coastguard Worker int8_t m;
586*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
587*3ac0a46fSAndroid Build Coastguard Worker *value = (int16_t)m;
588*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
589*3ac0a46fSAndroid Build Coastguard Worker }
590*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
591*3ac0a46fSAndroid Build Coastguard Worker {
592*3ac0a46fSAndroid Build Coastguard Worker uint16_t m;
593*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedShort(tif, direntry, &m);
594*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSshortShort(m);
595*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
596*3ac0a46fSAndroid Build Coastguard Worker return (err);
597*3ac0a46fSAndroid Build Coastguard Worker *value = (uint16_t)m;
598*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
599*3ac0a46fSAndroid Build Coastguard Worker }
600*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
601*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSshort(tif, direntry, value);
602*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
603*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
604*3ac0a46fSAndroid Build Coastguard Worker {
605*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
606*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong(tif, direntry, &m);
607*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSshortLong(m);
608*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
609*3ac0a46fSAndroid Build Coastguard Worker return (err);
610*3ac0a46fSAndroid Build Coastguard Worker *value = (int16_t)m;
611*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
612*3ac0a46fSAndroid Build Coastguard Worker }
613*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
614*3ac0a46fSAndroid Build Coastguard Worker {
615*3ac0a46fSAndroid Build Coastguard Worker int32_t m;
616*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
617*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSshortSlong(m);
618*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
619*3ac0a46fSAndroid Build Coastguard Worker return (err);
620*3ac0a46fSAndroid Build Coastguard Worker *value = (int16_t)m;
621*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
622*3ac0a46fSAndroid Build Coastguard Worker }
623*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
624*3ac0a46fSAndroid Build Coastguard Worker {
625*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
626*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
627*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
628*3ac0a46fSAndroid Build Coastguard Worker return (err);
629*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSshortLong8(m);
630*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
631*3ac0a46fSAndroid Build Coastguard Worker return (err);
632*3ac0a46fSAndroid Build Coastguard Worker *value = (int16_t)m;
633*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
634*3ac0a46fSAndroid Build Coastguard Worker }
635*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
636*3ac0a46fSAndroid Build Coastguard Worker {
637*3ac0a46fSAndroid Build Coastguard Worker int64_t m;
638*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
639*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
640*3ac0a46fSAndroid Build Coastguard Worker return (err);
641*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSshortSlong8(m);
642*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
643*3ac0a46fSAndroid Build Coastguard Worker return (err);
644*3ac0a46fSAndroid Build Coastguard Worker *value = (int16_t)m;
645*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
646*3ac0a46fSAndroid Build Coastguard Worker }
647*3ac0a46fSAndroid Build Coastguard Worker default:
648*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
649*3ac0a46fSAndroid Build Coastguard Worker }
650*3ac0a46fSAndroid Build Coastguard Worker } /*-- TIFFReadDirEntrySshort() --*/
651*3ac0a46fSAndroid Build Coastguard Worker
652*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryLong(TIFF * tif,TIFFDirEntry * direntry,uint32_t * value)653*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value)
654*3ac0a46fSAndroid Build Coastguard Worker {
655*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
656*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count != 1)
657*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
658*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
659*3ac0a46fSAndroid Build Coastguard Worker {
660*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
661*3ac0a46fSAndroid Build Coastguard Worker {
662*3ac0a46fSAndroid Build Coastguard Worker uint8_t m;
663*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedByte(tif, direntry, &m);
664*3ac0a46fSAndroid Build Coastguard Worker *value = (uint32_t)m;
665*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
666*3ac0a46fSAndroid Build Coastguard Worker }
667*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
668*3ac0a46fSAndroid Build Coastguard Worker {
669*3ac0a46fSAndroid Build Coastguard Worker int8_t m;
670*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
671*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLongSbyte(m);
672*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
673*3ac0a46fSAndroid Build Coastguard Worker return (err);
674*3ac0a46fSAndroid Build Coastguard Worker *value = (uint32_t)m;
675*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
676*3ac0a46fSAndroid Build Coastguard Worker }
677*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
678*3ac0a46fSAndroid Build Coastguard Worker {
679*3ac0a46fSAndroid Build Coastguard Worker uint16_t m;
680*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedShort(tif, direntry, &m);
681*3ac0a46fSAndroid Build Coastguard Worker *value = (uint32_t)m;
682*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
683*3ac0a46fSAndroid Build Coastguard Worker }
684*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
685*3ac0a46fSAndroid Build Coastguard Worker {
686*3ac0a46fSAndroid Build Coastguard Worker int16_t m;
687*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
688*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLongSshort(m);
689*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
690*3ac0a46fSAndroid Build Coastguard Worker return (err);
691*3ac0a46fSAndroid Build Coastguard Worker *value = (uint32_t)m;
692*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
693*3ac0a46fSAndroid Build Coastguard Worker }
694*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
695*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong(tif, direntry, value);
696*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
697*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
698*3ac0a46fSAndroid Build Coastguard Worker {
699*3ac0a46fSAndroid Build Coastguard Worker int32_t m;
700*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
701*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLongSlong(m);
702*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
703*3ac0a46fSAndroid Build Coastguard Worker return (err);
704*3ac0a46fSAndroid Build Coastguard Worker *value = (uint32_t)m;
705*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
706*3ac0a46fSAndroid Build Coastguard Worker }
707*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
708*3ac0a46fSAndroid Build Coastguard Worker {
709*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
710*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
711*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
712*3ac0a46fSAndroid Build Coastguard Worker return (err);
713*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLongLong8(m);
714*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
715*3ac0a46fSAndroid Build Coastguard Worker return (err);
716*3ac0a46fSAndroid Build Coastguard Worker *value = (uint32_t)m;
717*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
718*3ac0a46fSAndroid Build Coastguard Worker }
719*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
720*3ac0a46fSAndroid Build Coastguard Worker {
721*3ac0a46fSAndroid Build Coastguard Worker int64_t m;
722*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
723*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
724*3ac0a46fSAndroid Build Coastguard Worker return (err);
725*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLongSlong8(m);
726*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
727*3ac0a46fSAndroid Build Coastguard Worker return (err);
728*3ac0a46fSAndroid Build Coastguard Worker *value = (uint32_t)m;
729*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
730*3ac0a46fSAndroid Build Coastguard Worker }
731*3ac0a46fSAndroid Build Coastguard Worker default:
732*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
733*3ac0a46fSAndroid Build Coastguard Worker }
734*3ac0a46fSAndroid Build Coastguard Worker } /*-- TIFFReadDirEntryLong() --*/
735*3ac0a46fSAndroid Build Coastguard Worker
736*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntrySlong(TIFF * tif,TIFFDirEntry * direntry,int32_t * value)737*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value)
738*3ac0a46fSAndroid Build Coastguard Worker {
739*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
740*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count != 1)
741*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
742*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
743*3ac0a46fSAndroid Build Coastguard Worker {
744*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
745*3ac0a46fSAndroid Build Coastguard Worker {
746*3ac0a46fSAndroid Build Coastguard Worker uint8_t m;
747*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedByte(tif, direntry, &m);
748*3ac0a46fSAndroid Build Coastguard Worker *value = (int32_t)m;
749*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
750*3ac0a46fSAndroid Build Coastguard Worker }
751*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
752*3ac0a46fSAndroid Build Coastguard Worker {
753*3ac0a46fSAndroid Build Coastguard Worker int8_t m;
754*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
755*3ac0a46fSAndroid Build Coastguard Worker *value = (int32_t)m;
756*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
757*3ac0a46fSAndroid Build Coastguard Worker }
758*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
759*3ac0a46fSAndroid Build Coastguard Worker {
760*3ac0a46fSAndroid Build Coastguard Worker uint16_t m;
761*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedShort(tif, direntry, &m);
762*3ac0a46fSAndroid Build Coastguard Worker *value = (int32_t)m;
763*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
764*3ac0a46fSAndroid Build Coastguard Worker }
765*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
766*3ac0a46fSAndroid Build Coastguard Worker {
767*3ac0a46fSAndroid Build Coastguard Worker int16_t m;
768*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
769*3ac0a46fSAndroid Build Coastguard Worker *value = (int32_t)m;
770*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
771*3ac0a46fSAndroid Build Coastguard Worker }
772*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
773*3ac0a46fSAndroid Build Coastguard Worker {
774*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
775*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong(tif, direntry, &m);
776*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSlongLong(m);
777*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
778*3ac0a46fSAndroid Build Coastguard Worker return (err);
779*3ac0a46fSAndroid Build Coastguard Worker *value = (int32_t)m;
780*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
781*3ac0a46fSAndroid Build Coastguard Worker }
782*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
783*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSlong(tif, direntry, value);
784*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
785*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
786*3ac0a46fSAndroid Build Coastguard Worker {
787*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
788*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
789*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
790*3ac0a46fSAndroid Build Coastguard Worker return (err);
791*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSlongLong8(m);
792*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
793*3ac0a46fSAndroid Build Coastguard Worker return (err);
794*3ac0a46fSAndroid Build Coastguard Worker *value = (int32_t)m;
795*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
796*3ac0a46fSAndroid Build Coastguard Worker }
797*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
798*3ac0a46fSAndroid Build Coastguard Worker {
799*3ac0a46fSAndroid Build Coastguard Worker int64_t m;
800*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
801*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
802*3ac0a46fSAndroid Build Coastguard Worker return (err);
803*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSlongSlong8(m);
804*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
805*3ac0a46fSAndroid Build Coastguard Worker return (err);
806*3ac0a46fSAndroid Build Coastguard Worker *value = (int32_t)m;
807*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
808*3ac0a46fSAndroid Build Coastguard Worker }
809*3ac0a46fSAndroid Build Coastguard Worker default:
810*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
811*3ac0a46fSAndroid Build Coastguard Worker }
812*3ac0a46fSAndroid Build Coastguard Worker } /*-- TIFFReadDirEntrySlong() --*/
813*3ac0a46fSAndroid Build Coastguard Worker
814*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryLong8(TIFF * tif,TIFFDirEntry * direntry,uint64_t * value)815*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
816*3ac0a46fSAndroid Build Coastguard Worker {
817*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
818*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count != 1)
819*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
820*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
821*3ac0a46fSAndroid Build Coastguard Worker {
822*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
823*3ac0a46fSAndroid Build Coastguard Worker {
824*3ac0a46fSAndroid Build Coastguard Worker uint8_t m;
825*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedByte(tif, direntry, &m);
826*3ac0a46fSAndroid Build Coastguard Worker *value = (uint64_t)m;
827*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
828*3ac0a46fSAndroid Build Coastguard Worker }
829*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
830*3ac0a46fSAndroid Build Coastguard Worker {
831*3ac0a46fSAndroid Build Coastguard Worker int8_t m;
832*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
833*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLong8Sbyte(m);
834*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
835*3ac0a46fSAndroid Build Coastguard Worker return (err);
836*3ac0a46fSAndroid Build Coastguard Worker *value = (uint64_t)m;
837*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
838*3ac0a46fSAndroid Build Coastguard Worker }
839*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
840*3ac0a46fSAndroid Build Coastguard Worker {
841*3ac0a46fSAndroid Build Coastguard Worker uint16_t m;
842*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedShort(tif, direntry, &m);
843*3ac0a46fSAndroid Build Coastguard Worker *value = (uint64_t)m;
844*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
845*3ac0a46fSAndroid Build Coastguard Worker }
846*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
847*3ac0a46fSAndroid Build Coastguard Worker {
848*3ac0a46fSAndroid Build Coastguard Worker int16_t m;
849*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
850*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLong8Sshort(m);
851*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
852*3ac0a46fSAndroid Build Coastguard Worker return (err);
853*3ac0a46fSAndroid Build Coastguard Worker *value = (uint64_t)m;
854*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
855*3ac0a46fSAndroid Build Coastguard Worker }
856*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
857*3ac0a46fSAndroid Build Coastguard Worker {
858*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
859*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong(tif, direntry, &m);
860*3ac0a46fSAndroid Build Coastguard Worker *value = (uint64_t)m;
861*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
862*3ac0a46fSAndroid Build Coastguard Worker }
863*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
864*3ac0a46fSAndroid Build Coastguard Worker {
865*3ac0a46fSAndroid Build Coastguard Worker int32_t m;
866*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
867*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLong8Slong(m);
868*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
869*3ac0a46fSAndroid Build Coastguard Worker return (err);
870*3ac0a46fSAndroid Build Coastguard Worker *value = (uint64_t)m;
871*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
872*3ac0a46fSAndroid Build Coastguard Worker }
873*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
874*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedLong8(tif, direntry, value);
875*3ac0a46fSAndroid Build Coastguard Worker return (err);
876*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
877*3ac0a46fSAndroid Build Coastguard Worker {
878*3ac0a46fSAndroid Build Coastguard Worker int64_t m;
879*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
880*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
881*3ac0a46fSAndroid Build Coastguard Worker return (err);
882*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLong8Slong8(m);
883*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
884*3ac0a46fSAndroid Build Coastguard Worker return (err);
885*3ac0a46fSAndroid Build Coastguard Worker *value = (uint64_t)m;
886*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
887*3ac0a46fSAndroid Build Coastguard Worker }
888*3ac0a46fSAndroid Build Coastguard Worker default:
889*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
890*3ac0a46fSAndroid Build Coastguard Worker }
891*3ac0a46fSAndroid Build Coastguard Worker } /*-- TIFFReadDirEntryLong8() --*/
892*3ac0a46fSAndroid Build Coastguard Worker
893*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntrySlong8(TIFF * tif,TIFFDirEntry * direntry,int64_t * value)894*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value)
895*3ac0a46fSAndroid Build Coastguard Worker {
896*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
897*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count != 1)
898*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
899*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
900*3ac0a46fSAndroid Build Coastguard Worker {
901*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
902*3ac0a46fSAndroid Build Coastguard Worker {
903*3ac0a46fSAndroid Build Coastguard Worker uint8_t m;
904*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedByte(tif, direntry, &m);
905*3ac0a46fSAndroid Build Coastguard Worker *value = (int64_t)m;
906*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
907*3ac0a46fSAndroid Build Coastguard Worker }
908*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
909*3ac0a46fSAndroid Build Coastguard Worker {
910*3ac0a46fSAndroid Build Coastguard Worker int8_t m;
911*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
912*3ac0a46fSAndroid Build Coastguard Worker *value = (int64_t)m;
913*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
914*3ac0a46fSAndroid Build Coastguard Worker }
915*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
916*3ac0a46fSAndroid Build Coastguard Worker {
917*3ac0a46fSAndroid Build Coastguard Worker uint16_t m;
918*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedShort(tif, direntry, &m);
919*3ac0a46fSAndroid Build Coastguard Worker *value = (int64_t)m;
920*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
921*3ac0a46fSAndroid Build Coastguard Worker }
922*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
923*3ac0a46fSAndroid Build Coastguard Worker {
924*3ac0a46fSAndroid Build Coastguard Worker int16_t m;
925*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
926*3ac0a46fSAndroid Build Coastguard Worker *value = (int64_t)m;
927*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
928*3ac0a46fSAndroid Build Coastguard Worker }
929*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
930*3ac0a46fSAndroid Build Coastguard Worker {
931*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
932*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong(tif, direntry, &m);
933*3ac0a46fSAndroid Build Coastguard Worker *value = (int64_t)m;
934*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
935*3ac0a46fSAndroid Build Coastguard Worker }
936*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
937*3ac0a46fSAndroid Build Coastguard Worker {
938*3ac0a46fSAndroid Build Coastguard Worker int32_t m;
939*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
940*3ac0a46fSAndroid Build Coastguard Worker *value = (int64_t)m;
941*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
942*3ac0a46fSAndroid Build Coastguard Worker }
943*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
944*3ac0a46fSAndroid Build Coastguard Worker {
945*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
946*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
947*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
948*3ac0a46fSAndroid Build Coastguard Worker return (err);
949*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSlong8Long8(m);
950*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
951*3ac0a46fSAndroid Build Coastguard Worker return (err);
952*3ac0a46fSAndroid Build Coastguard Worker *value = (int64_t)m;
953*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
954*3ac0a46fSAndroid Build Coastguard Worker }
955*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
956*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedSlong8(tif, direntry, value);
957*3ac0a46fSAndroid Build Coastguard Worker return (err);
958*3ac0a46fSAndroid Build Coastguard Worker default:
959*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
960*3ac0a46fSAndroid Build Coastguard Worker }
961*3ac0a46fSAndroid Build Coastguard Worker } /*-- TIFFReadDirEntrySlong8() --*/
962*3ac0a46fSAndroid Build Coastguard Worker
963*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryFloat(TIFF * tif,TIFFDirEntry * direntry,float * value)964*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value)
965*3ac0a46fSAndroid Build Coastguard Worker {
966*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
967*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count != 1)
968*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
969*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
970*3ac0a46fSAndroid Build Coastguard Worker {
971*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
972*3ac0a46fSAndroid Build Coastguard Worker {
973*3ac0a46fSAndroid Build Coastguard Worker uint8_t m;
974*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedByte(tif, direntry, &m);
975*3ac0a46fSAndroid Build Coastguard Worker *value = (float)m;
976*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
977*3ac0a46fSAndroid Build Coastguard Worker }
978*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
979*3ac0a46fSAndroid Build Coastguard Worker {
980*3ac0a46fSAndroid Build Coastguard Worker int8_t m;
981*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
982*3ac0a46fSAndroid Build Coastguard Worker *value = (float)m;
983*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
984*3ac0a46fSAndroid Build Coastguard Worker }
985*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
986*3ac0a46fSAndroid Build Coastguard Worker {
987*3ac0a46fSAndroid Build Coastguard Worker uint16_t m;
988*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedShort(tif, direntry, &m);
989*3ac0a46fSAndroid Build Coastguard Worker *value = (float)m;
990*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
991*3ac0a46fSAndroid Build Coastguard Worker }
992*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
993*3ac0a46fSAndroid Build Coastguard Worker {
994*3ac0a46fSAndroid Build Coastguard Worker int16_t m;
995*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
996*3ac0a46fSAndroid Build Coastguard Worker *value = (float)m;
997*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
998*3ac0a46fSAndroid Build Coastguard Worker }
999*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
1000*3ac0a46fSAndroid Build Coastguard Worker {
1001*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
1002*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong(tif, direntry, &m);
1003*3ac0a46fSAndroid Build Coastguard Worker *value = (float)m;
1004*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1005*3ac0a46fSAndroid Build Coastguard Worker }
1006*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
1007*3ac0a46fSAndroid Build Coastguard Worker {
1008*3ac0a46fSAndroid Build Coastguard Worker int32_t m;
1009*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
1010*3ac0a46fSAndroid Build Coastguard Worker *value = (float)m;
1011*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1012*3ac0a46fSAndroid Build Coastguard Worker }
1013*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
1014*3ac0a46fSAndroid Build Coastguard Worker {
1015*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
1016*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
1017*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1018*3ac0a46fSAndroid Build Coastguard Worker return (err);
1019*3ac0a46fSAndroid Build Coastguard Worker #if defined(__WIN32__) && (_MSC_VER < 1500)
1020*3ac0a46fSAndroid Build Coastguard Worker /*
1021*3ac0a46fSAndroid Build Coastguard Worker * XXX: MSVC 6.0 does not support conversion
1022*3ac0a46fSAndroid Build Coastguard Worker * of 64-bit integers into floating point
1023*3ac0a46fSAndroid Build Coastguard Worker * values.
1024*3ac0a46fSAndroid Build Coastguard Worker */
1025*3ac0a46fSAndroid Build Coastguard Worker *value = _TIFFUInt64ToFloat(m);
1026*3ac0a46fSAndroid Build Coastguard Worker #else
1027*3ac0a46fSAndroid Build Coastguard Worker *value = (float)m;
1028*3ac0a46fSAndroid Build Coastguard Worker #endif
1029*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1030*3ac0a46fSAndroid Build Coastguard Worker }
1031*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
1032*3ac0a46fSAndroid Build Coastguard Worker {
1033*3ac0a46fSAndroid Build Coastguard Worker int64_t m;
1034*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
1035*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1036*3ac0a46fSAndroid Build Coastguard Worker return (err);
1037*3ac0a46fSAndroid Build Coastguard Worker *value = (float)m;
1038*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1039*3ac0a46fSAndroid Build Coastguard Worker }
1040*3ac0a46fSAndroid Build Coastguard Worker case TIFF_RATIONAL:
1041*3ac0a46fSAndroid Build Coastguard Worker {
1042*3ac0a46fSAndroid Build Coastguard Worker double m;
1043*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedRational(tif, direntry, &m);
1044*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1045*3ac0a46fSAndroid Build Coastguard Worker return (err);
1046*3ac0a46fSAndroid Build Coastguard Worker *value = (float)m;
1047*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1048*3ac0a46fSAndroid Build Coastguard Worker }
1049*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SRATIONAL:
1050*3ac0a46fSAndroid Build Coastguard Worker {
1051*3ac0a46fSAndroid Build Coastguard Worker double m;
1052*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedSrational(tif, direntry, &m);
1053*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1054*3ac0a46fSAndroid Build Coastguard Worker return (err);
1055*3ac0a46fSAndroid Build Coastguard Worker *value = (float)m;
1056*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1057*3ac0a46fSAndroid Build Coastguard Worker }
1058*3ac0a46fSAndroid Build Coastguard Worker case TIFF_FLOAT:
1059*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedFloat(tif, direntry, value);
1060*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1061*3ac0a46fSAndroid Build Coastguard Worker case TIFF_DOUBLE:
1062*3ac0a46fSAndroid Build Coastguard Worker {
1063*3ac0a46fSAndroid Build Coastguard Worker double m;
1064*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedDouble(tif, direntry, &m);
1065*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1066*3ac0a46fSAndroid Build Coastguard Worker return (err);
1067*3ac0a46fSAndroid Build Coastguard Worker if ((m > FLT_MAX) || (m < -FLT_MAX))
1068*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
1069*3ac0a46fSAndroid Build Coastguard Worker *value = (float)m;
1070*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1071*3ac0a46fSAndroid Build Coastguard Worker }
1072*3ac0a46fSAndroid Build Coastguard Worker default:
1073*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
1074*3ac0a46fSAndroid Build Coastguard Worker }
1075*3ac0a46fSAndroid Build Coastguard Worker }
1076*3ac0a46fSAndroid Build Coastguard Worker
1077*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryDouble(TIFF * tif,TIFFDirEntry * direntry,double * value)1078*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value)
1079*3ac0a46fSAndroid Build Coastguard Worker {
1080*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
1081*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count != 1)
1082*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
1083*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1084*3ac0a46fSAndroid Build Coastguard Worker {
1085*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
1086*3ac0a46fSAndroid Build Coastguard Worker {
1087*3ac0a46fSAndroid Build Coastguard Worker uint8_t m;
1088*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedByte(tif, direntry, &m);
1089*3ac0a46fSAndroid Build Coastguard Worker *value = (double)m;
1090*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1091*3ac0a46fSAndroid Build Coastguard Worker }
1092*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
1093*3ac0a46fSAndroid Build Coastguard Worker {
1094*3ac0a46fSAndroid Build Coastguard Worker int8_t m;
1095*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
1096*3ac0a46fSAndroid Build Coastguard Worker *value = (double)m;
1097*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1098*3ac0a46fSAndroid Build Coastguard Worker }
1099*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
1100*3ac0a46fSAndroid Build Coastguard Worker {
1101*3ac0a46fSAndroid Build Coastguard Worker uint16_t m;
1102*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedShort(tif, direntry, &m);
1103*3ac0a46fSAndroid Build Coastguard Worker *value = (double)m;
1104*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1105*3ac0a46fSAndroid Build Coastguard Worker }
1106*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
1107*3ac0a46fSAndroid Build Coastguard Worker {
1108*3ac0a46fSAndroid Build Coastguard Worker int16_t m;
1109*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
1110*3ac0a46fSAndroid Build Coastguard Worker *value = (double)m;
1111*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1112*3ac0a46fSAndroid Build Coastguard Worker }
1113*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
1114*3ac0a46fSAndroid Build Coastguard Worker {
1115*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
1116*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong(tif, direntry, &m);
1117*3ac0a46fSAndroid Build Coastguard Worker *value = (double)m;
1118*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1119*3ac0a46fSAndroid Build Coastguard Worker }
1120*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
1121*3ac0a46fSAndroid Build Coastguard Worker {
1122*3ac0a46fSAndroid Build Coastguard Worker int32_t m;
1123*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
1124*3ac0a46fSAndroid Build Coastguard Worker *value = (double)m;
1125*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1126*3ac0a46fSAndroid Build Coastguard Worker }
1127*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
1128*3ac0a46fSAndroid Build Coastguard Worker {
1129*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
1130*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
1131*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1132*3ac0a46fSAndroid Build Coastguard Worker return (err);
1133*3ac0a46fSAndroid Build Coastguard Worker #if defined(__WIN32__) && (_MSC_VER < 1500)
1134*3ac0a46fSAndroid Build Coastguard Worker /*
1135*3ac0a46fSAndroid Build Coastguard Worker * XXX: MSVC 6.0 does not support conversion
1136*3ac0a46fSAndroid Build Coastguard Worker * of 64-bit integers into floating point
1137*3ac0a46fSAndroid Build Coastguard Worker * values.
1138*3ac0a46fSAndroid Build Coastguard Worker */
1139*3ac0a46fSAndroid Build Coastguard Worker *value = _TIFFUInt64ToDouble(m);
1140*3ac0a46fSAndroid Build Coastguard Worker #else
1141*3ac0a46fSAndroid Build Coastguard Worker *value = (double)m;
1142*3ac0a46fSAndroid Build Coastguard Worker #endif
1143*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1144*3ac0a46fSAndroid Build Coastguard Worker }
1145*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
1146*3ac0a46fSAndroid Build Coastguard Worker {
1147*3ac0a46fSAndroid Build Coastguard Worker int64_t m;
1148*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
1149*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1150*3ac0a46fSAndroid Build Coastguard Worker return (err);
1151*3ac0a46fSAndroid Build Coastguard Worker *value = (double)m;
1152*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1153*3ac0a46fSAndroid Build Coastguard Worker }
1154*3ac0a46fSAndroid Build Coastguard Worker case TIFF_RATIONAL:
1155*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedRational(tif, direntry, value);
1156*3ac0a46fSAndroid Build Coastguard Worker return (err);
1157*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SRATIONAL:
1158*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedSrational(tif, direntry, value);
1159*3ac0a46fSAndroid Build Coastguard Worker return (err);
1160*3ac0a46fSAndroid Build Coastguard Worker case TIFF_FLOAT:
1161*3ac0a46fSAndroid Build Coastguard Worker {
1162*3ac0a46fSAndroid Build Coastguard Worker float m;
1163*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedFloat(tif, direntry, &m);
1164*3ac0a46fSAndroid Build Coastguard Worker *value = (double)m;
1165*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1166*3ac0a46fSAndroid Build Coastguard Worker }
1167*3ac0a46fSAndroid Build Coastguard Worker case TIFF_DOUBLE:
1168*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedDouble(tif, direntry, value);
1169*3ac0a46fSAndroid Build Coastguard Worker return (err);
1170*3ac0a46fSAndroid Build Coastguard Worker default:
1171*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
1172*3ac0a46fSAndroid Build Coastguard Worker }
1173*3ac0a46fSAndroid Build Coastguard Worker }
1174*3ac0a46fSAndroid Build Coastguard Worker
1175*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryIfd8(TIFF * tif,TIFFDirEntry * direntry,uint64_t * value)1176*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
1177*3ac0a46fSAndroid Build Coastguard Worker {
1178*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
1179*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count != 1)
1180*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
1181*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1182*3ac0a46fSAndroid Build Coastguard Worker {
1183*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
1184*3ac0a46fSAndroid Build Coastguard Worker case TIFF_IFD:
1185*3ac0a46fSAndroid Build Coastguard Worker {
1186*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
1187*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong(tif, direntry, &m);
1188*3ac0a46fSAndroid Build Coastguard Worker *value = (uint64_t)m;
1189*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1190*3ac0a46fSAndroid Build Coastguard Worker }
1191*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
1192*3ac0a46fSAndroid Build Coastguard Worker case TIFF_IFD8:
1193*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedLong8(tif, direntry, value);
1194*3ac0a46fSAndroid Build Coastguard Worker return (err);
1195*3ac0a46fSAndroid Build Coastguard Worker default:
1196*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
1197*3ac0a46fSAndroid Build Coastguard Worker }
1198*3ac0a46fSAndroid Build Coastguard Worker }
1199*3ac0a46fSAndroid Build Coastguard Worker
1200*3ac0a46fSAndroid Build Coastguard Worker #define INITIAL_THRESHOLD (1024 * 1024)
1201*3ac0a46fSAndroid Build Coastguard Worker #define THRESHOLD_MULTIPLIER 10
1202*3ac0a46fSAndroid Build Coastguard Worker #define MAX_THRESHOLD \
1203*3ac0a46fSAndroid Build Coastguard Worker (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * \
1204*3ac0a46fSAndroid Build Coastguard Worker INITIAL_THRESHOLD)
1205*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirEntryDataAndRealloc(TIFF * tif,uint64_t offset,tmsize_t size,void ** pdest)1206*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(TIFF *tif,
1207*3ac0a46fSAndroid Build Coastguard Worker uint64_t offset,
1208*3ac0a46fSAndroid Build Coastguard Worker tmsize_t size,
1209*3ac0a46fSAndroid Build Coastguard Worker void **pdest)
1210*3ac0a46fSAndroid Build Coastguard Worker {
1211*3ac0a46fSAndroid Build Coastguard Worker #if SIZEOF_SIZE_T == 8
1212*3ac0a46fSAndroid Build Coastguard Worker tmsize_t threshold = INITIAL_THRESHOLD;
1213*3ac0a46fSAndroid Build Coastguard Worker #endif
1214*3ac0a46fSAndroid Build Coastguard Worker tmsize_t already_read = 0;
1215*3ac0a46fSAndroid Build Coastguard Worker
1216*3ac0a46fSAndroid Build Coastguard Worker assert(!isMapped(tif));
1217*3ac0a46fSAndroid Build Coastguard Worker
1218*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, offset))
1219*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrIo);
1220*3ac0a46fSAndroid Build Coastguard Worker
1221*3ac0a46fSAndroid Build Coastguard Worker /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
1222*3ac0a46fSAndroid Build Coastguard Worker /* so as to avoid allocating too much memory in case the file is too */
1223*3ac0a46fSAndroid Build Coastguard Worker /* short. We could ask for the file size, but this might be */
1224*3ac0a46fSAndroid Build Coastguard Worker /* expensive with some I/O layers (think of reading a gzipped file) */
1225*3ac0a46fSAndroid Build Coastguard Worker /* Restrict to 64 bit processes, so as to avoid reallocs() */
1226*3ac0a46fSAndroid Build Coastguard Worker /* on 32 bit processes where virtual memory is scarce. */
1227*3ac0a46fSAndroid Build Coastguard Worker while (already_read < size)
1228*3ac0a46fSAndroid Build Coastguard Worker {
1229*3ac0a46fSAndroid Build Coastguard Worker void *new_dest;
1230*3ac0a46fSAndroid Build Coastguard Worker tmsize_t bytes_read;
1231*3ac0a46fSAndroid Build Coastguard Worker tmsize_t to_read = size - already_read;
1232*3ac0a46fSAndroid Build Coastguard Worker #if SIZEOF_SIZE_T == 8
1233*3ac0a46fSAndroid Build Coastguard Worker if (to_read >= threshold && threshold < MAX_THRESHOLD)
1234*3ac0a46fSAndroid Build Coastguard Worker {
1235*3ac0a46fSAndroid Build Coastguard Worker to_read = threshold;
1236*3ac0a46fSAndroid Build Coastguard Worker threshold *= THRESHOLD_MULTIPLIER;
1237*3ac0a46fSAndroid Build Coastguard Worker }
1238*3ac0a46fSAndroid Build Coastguard Worker #endif
1239*3ac0a46fSAndroid Build Coastguard Worker
1240*3ac0a46fSAndroid Build Coastguard Worker new_dest =
1241*3ac0a46fSAndroid Build Coastguard Worker (uint8_t *)_TIFFreallocExt(tif, *pdest, already_read + to_read);
1242*3ac0a46fSAndroid Build Coastguard Worker if (new_dest == NULL)
1243*3ac0a46fSAndroid Build Coastguard Worker {
1244*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, tif->tif_name,
1245*3ac0a46fSAndroid Build Coastguard Worker "Failed to allocate memory for %s "
1246*3ac0a46fSAndroid Build Coastguard Worker "(%" TIFF_SSIZE_FORMAT
1247*3ac0a46fSAndroid Build Coastguard Worker " elements of %" TIFF_SSIZE_FORMAT " bytes each)",
1248*3ac0a46fSAndroid Build Coastguard Worker "TIFFReadDirEntryArray", (tmsize_t)1,
1249*3ac0a46fSAndroid Build Coastguard Worker already_read + to_read);
1250*3ac0a46fSAndroid Build Coastguard Worker return TIFFReadDirEntryErrAlloc;
1251*3ac0a46fSAndroid Build Coastguard Worker }
1252*3ac0a46fSAndroid Build Coastguard Worker *pdest = new_dest;
1253*3ac0a46fSAndroid Build Coastguard Worker
1254*3ac0a46fSAndroid Build Coastguard Worker bytes_read = TIFFReadFile(tif, (char *)*pdest + already_read, to_read);
1255*3ac0a46fSAndroid Build Coastguard Worker already_read += bytes_read;
1256*3ac0a46fSAndroid Build Coastguard Worker if (bytes_read != to_read)
1257*3ac0a46fSAndroid Build Coastguard Worker {
1258*3ac0a46fSAndroid Build Coastguard Worker return TIFFReadDirEntryErrIo;
1259*3ac0a46fSAndroid Build Coastguard Worker }
1260*3ac0a46fSAndroid Build Coastguard Worker }
1261*3ac0a46fSAndroid Build Coastguard Worker return TIFFReadDirEntryErrOk;
1262*3ac0a46fSAndroid Build Coastguard Worker }
1263*3ac0a46fSAndroid Build Coastguard Worker
1264*3ac0a46fSAndroid Build Coastguard Worker /* Caution: if raising that value, make sure int32 / uint32 overflows can't
1265*3ac0a46fSAndroid Build Coastguard Worker * occur elsewhere */
1266*3ac0a46fSAndroid Build Coastguard Worker #define MAX_SIZE_TAG_DATA 2147483647U
1267*3ac0a46fSAndroid Build Coastguard Worker
1268*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryArrayWithLimit(TIFF * tif,TIFFDirEntry * direntry,uint32_t * count,uint32_t desttypesize,void ** value,uint64_t maxcount)1269*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
1270*3ac0a46fSAndroid Build Coastguard Worker uint32_t *count, uint32_t desttypesize,
1271*3ac0a46fSAndroid Build Coastguard Worker void **value, uint64_t maxcount)
1272*3ac0a46fSAndroid Build Coastguard Worker {
1273*3ac0a46fSAndroid Build Coastguard Worker int typesize;
1274*3ac0a46fSAndroid Build Coastguard Worker uint32_t datasize;
1275*3ac0a46fSAndroid Build Coastguard Worker void *data;
1276*3ac0a46fSAndroid Build Coastguard Worker uint64_t target_count64;
1277*3ac0a46fSAndroid Build Coastguard Worker int original_datasize_clamped;
1278*3ac0a46fSAndroid Build Coastguard Worker typesize = TIFFDataWidth(direntry->tdir_type);
1279*3ac0a46fSAndroid Build Coastguard Worker
1280*3ac0a46fSAndroid Build Coastguard Worker target_count64 =
1281*3ac0a46fSAndroid Build Coastguard Worker (direntry->tdir_count > maxcount) ? maxcount : direntry->tdir_count;
1282*3ac0a46fSAndroid Build Coastguard Worker
1283*3ac0a46fSAndroid Build Coastguard Worker if ((target_count64 == 0) || (typesize == 0))
1284*3ac0a46fSAndroid Build Coastguard Worker {
1285*3ac0a46fSAndroid Build Coastguard Worker *value = 0;
1286*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1287*3ac0a46fSAndroid Build Coastguard Worker }
1288*3ac0a46fSAndroid Build Coastguard Worker (void)desttypesize;
1289*3ac0a46fSAndroid Build Coastguard Worker
1290*3ac0a46fSAndroid Build Coastguard Worker /* We just want to know if the original tag size is more than 4 bytes
1291*3ac0a46fSAndroid Build Coastguard Worker * (classic TIFF) or 8 bytes (BigTIFF)
1292*3ac0a46fSAndroid Build Coastguard Worker */
1293*3ac0a46fSAndroid Build Coastguard Worker original_datasize_clamped =
1294*3ac0a46fSAndroid Build Coastguard Worker ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) *
1295*3ac0a46fSAndroid Build Coastguard Worker typesize;
1296*3ac0a46fSAndroid Build Coastguard Worker
1297*3ac0a46fSAndroid Build Coastguard Worker /*
1298*3ac0a46fSAndroid Build Coastguard Worker * As a sanity check, make sure we have no more than a 2GB tag array
1299*3ac0a46fSAndroid Build Coastguard Worker * in either the current data type or the dest data type. This also
1300*3ac0a46fSAndroid Build Coastguard Worker * avoids problems with overflow of tmsize_t on 32bit systems.
1301*3ac0a46fSAndroid Build Coastguard Worker */
1302*3ac0a46fSAndroid Build Coastguard Worker if ((uint64_t)(MAX_SIZE_TAG_DATA / typesize) < target_count64)
1303*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrSizesan);
1304*3ac0a46fSAndroid Build Coastguard Worker if ((uint64_t)(MAX_SIZE_TAG_DATA / desttypesize) < target_count64)
1305*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrSizesan);
1306*3ac0a46fSAndroid Build Coastguard Worker
1307*3ac0a46fSAndroid Build Coastguard Worker *count = (uint32_t)target_count64;
1308*3ac0a46fSAndroid Build Coastguard Worker datasize = (*count) * typesize;
1309*3ac0a46fSAndroid Build Coastguard Worker assert((tmsize_t)datasize > 0);
1310*3ac0a46fSAndroid Build Coastguard Worker
1311*3ac0a46fSAndroid Build Coastguard Worker if (isMapped(tif) && datasize > (uint64_t)tif->tif_size)
1312*3ac0a46fSAndroid Build Coastguard Worker return TIFFReadDirEntryErrIo;
1313*3ac0a46fSAndroid Build Coastguard Worker
1314*3ac0a46fSAndroid Build Coastguard Worker if (!isMapped(tif) && (((tif->tif_flags & TIFF_BIGTIFF) && datasize > 8) ||
1315*3ac0a46fSAndroid Build Coastguard Worker (!(tif->tif_flags & TIFF_BIGTIFF) && datasize > 4)))
1316*3ac0a46fSAndroid Build Coastguard Worker {
1317*3ac0a46fSAndroid Build Coastguard Worker data = NULL;
1318*3ac0a46fSAndroid Build Coastguard Worker }
1319*3ac0a46fSAndroid Build Coastguard Worker else
1320*3ac0a46fSAndroid Build Coastguard Worker {
1321*3ac0a46fSAndroid Build Coastguard Worker data = _TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
1322*3ac0a46fSAndroid Build Coastguard Worker if (data == 0)
1323*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrAlloc);
1324*3ac0a46fSAndroid Build Coastguard Worker }
1325*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
1326*3ac0a46fSAndroid Build Coastguard Worker {
1327*3ac0a46fSAndroid Build Coastguard Worker /* Only the condition on original_datasize_clamped. The second
1328*3ac0a46fSAndroid Build Coastguard Worker * one is implied, but Coverity Scan cannot see it. */
1329*3ac0a46fSAndroid Build Coastguard Worker if (original_datasize_clamped <= 4 && datasize <= 4)
1330*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(data, &direntry->tdir_offset, datasize);
1331*3ac0a46fSAndroid Build Coastguard Worker else
1332*3ac0a46fSAndroid Build Coastguard Worker {
1333*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
1334*3ac0a46fSAndroid Build Coastguard Worker uint32_t offset = direntry->tdir_offset.toff_long;
1335*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1336*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&offset);
1337*3ac0a46fSAndroid Build Coastguard Worker if (isMapped(tif))
1338*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryData(tif, (uint64_t)offset,
1339*3ac0a46fSAndroid Build Coastguard Worker (tmsize_t)datasize, data);
1340*3ac0a46fSAndroid Build Coastguard Worker else
1341*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset,
1342*3ac0a46fSAndroid Build Coastguard Worker (tmsize_t)datasize, &data);
1343*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1344*3ac0a46fSAndroid Build Coastguard Worker {
1345*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
1346*3ac0a46fSAndroid Build Coastguard Worker return (err);
1347*3ac0a46fSAndroid Build Coastguard Worker }
1348*3ac0a46fSAndroid Build Coastguard Worker }
1349*3ac0a46fSAndroid Build Coastguard Worker }
1350*3ac0a46fSAndroid Build Coastguard Worker else
1351*3ac0a46fSAndroid Build Coastguard Worker {
1352*3ac0a46fSAndroid Build Coastguard Worker /* See above comment for the Classic TIFF case */
1353*3ac0a46fSAndroid Build Coastguard Worker if (original_datasize_clamped <= 8 && datasize <= 8)
1354*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(data, &direntry->tdir_offset, datasize);
1355*3ac0a46fSAndroid Build Coastguard Worker else
1356*3ac0a46fSAndroid Build Coastguard Worker {
1357*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
1358*3ac0a46fSAndroid Build Coastguard Worker uint64_t offset = direntry->tdir_offset.toff_long8;
1359*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1360*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&offset);
1361*3ac0a46fSAndroid Build Coastguard Worker if (isMapped(tif))
1362*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryData(tif, (uint64_t)offset,
1363*3ac0a46fSAndroid Build Coastguard Worker (tmsize_t)datasize, data);
1364*3ac0a46fSAndroid Build Coastguard Worker else
1365*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset,
1366*3ac0a46fSAndroid Build Coastguard Worker (tmsize_t)datasize, &data);
1367*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1368*3ac0a46fSAndroid Build Coastguard Worker {
1369*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
1370*3ac0a46fSAndroid Build Coastguard Worker return (err);
1371*3ac0a46fSAndroid Build Coastguard Worker }
1372*3ac0a46fSAndroid Build Coastguard Worker }
1373*3ac0a46fSAndroid Build Coastguard Worker }
1374*3ac0a46fSAndroid Build Coastguard Worker *value = data;
1375*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1376*3ac0a46fSAndroid Build Coastguard Worker }
1377*3ac0a46fSAndroid Build Coastguard Worker
1378*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryArray(TIFF * tif,TIFFDirEntry * direntry,uint32_t * count,uint32_t desttypesize,void ** value)1379*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count,
1380*3ac0a46fSAndroid Build Coastguard Worker uint32_t desttypesize, void **value)
1381*3ac0a46fSAndroid Build Coastguard Worker {
1382*3ac0a46fSAndroid Build Coastguard Worker return TIFFReadDirEntryArrayWithLimit(tif, direntry, count, desttypesize,
1383*3ac0a46fSAndroid Build Coastguard Worker value, ~((uint64_t)0));
1384*3ac0a46fSAndroid Build Coastguard Worker }
1385*3ac0a46fSAndroid Build Coastguard Worker
1386*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryByteArray(TIFF * tif,TIFFDirEntry * direntry,uint8_t ** value)1387*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value)
1388*3ac0a46fSAndroid Build Coastguard Worker {
1389*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
1390*3ac0a46fSAndroid Build Coastguard Worker uint32_t count;
1391*3ac0a46fSAndroid Build Coastguard Worker void *origdata;
1392*3ac0a46fSAndroid Build Coastguard Worker uint8_t *data;
1393*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1394*3ac0a46fSAndroid Build Coastguard Worker {
1395*3ac0a46fSAndroid Build Coastguard Worker case TIFF_ASCII:
1396*3ac0a46fSAndroid Build Coastguard Worker case TIFF_UNDEFINED:
1397*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
1398*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
1399*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
1400*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
1401*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
1402*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
1403*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
1404*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
1405*3ac0a46fSAndroid Build Coastguard Worker break;
1406*3ac0a46fSAndroid Build Coastguard Worker default:
1407*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
1408*3ac0a46fSAndroid Build Coastguard Worker }
1409*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata);
1410*3ac0a46fSAndroid Build Coastguard Worker if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
1411*3ac0a46fSAndroid Build Coastguard Worker {
1412*3ac0a46fSAndroid Build Coastguard Worker *value = 0;
1413*3ac0a46fSAndroid Build Coastguard Worker return (err);
1414*3ac0a46fSAndroid Build Coastguard Worker }
1415*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1416*3ac0a46fSAndroid Build Coastguard Worker {
1417*3ac0a46fSAndroid Build Coastguard Worker case TIFF_ASCII:
1418*3ac0a46fSAndroid Build Coastguard Worker case TIFF_UNDEFINED:
1419*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
1420*3ac0a46fSAndroid Build Coastguard Worker *value = (uint8_t *)origdata;
1421*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1422*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
1423*3ac0a46fSAndroid Build Coastguard Worker {
1424*3ac0a46fSAndroid Build Coastguard Worker int8_t *m;
1425*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1426*3ac0a46fSAndroid Build Coastguard Worker m = (int8_t *)origdata;
1427*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1428*3ac0a46fSAndroid Build Coastguard Worker {
1429*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteSbyte(*m);
1430*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1431*3ac0a46fSAndroid Build Coastguard Worker {
1432*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
1433*3ac0a46fSAndroid Build Coastguard Worker return (err);
1434*3ac0a46fSAndroid Build Coastguard Worker }
1435*3ac0a46fSAndroid Build Coastguard Worker m++;
1436*3ac0a46fSAndroid Build Coastguard Worker }
1437*3ac0a46fSAndroid Build Coastguard Worker *value = (uint8_t *)origdata;
1438*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1439*3ac0a46fSAndroid Build Coastguard Worker }
1440*3ac0a46fSAndroid Build Coastguard Worker }
1441*3ac0a46fSAndroid Build Coastguard Worker data = (uint8_t *)_TIFFmallocExt(tif, count);
1442*3ac0a46fSAndroid Build Coastguard Worker if (data == 0)
1443*3ac0a46fSAndroid Build Coastguard Worker {
1444*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
1445*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrAlloc);
1446*3ac0a46fSAndroid Build Coastguard Worker }
1447*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1448*3ac0a46fSAndroid Build Coastguard Worker {
1449*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
1450*3ac0a46fSAndroid Build Coastguard Worker {
1451*3ac0a46fSAndroid Build Coastguard Worker uint16_t *ma;
1452*3ac0a46fSAndroid Build Coastguard Worker uint8_t *mb;
1453*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1454*3ac0a46fSAndroid Build Coastguard Worker ma = (uint16_t *)origdata;
1455*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1456*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1457*3ac0a46fSAndroid Build Coastguard Worker {
1458*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1459*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(ma);
1460*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteShort(*ma);
1461*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1462*3ac0a46fSAndroid Build Coastguard Worker break;
1463*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint8_t)(*ma++);
1464*3ac0a46fSAndroid Build Coastguard Worker }
1465*3ac0a46fSAndroid Build Coastguard Worker }
1466*3ac0a46fSAndroid Build Coastguard Worker break;
1467*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
1468*3ac0a46fSAndroid Build Coastguard Worker {
1469*3ac0a46fSAndroid Build Coastguard Worker int16_t *ma;
1470*3ac0a46fSAndroid Build Coastguard Worker uint8_t *mb;
1471*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1472*3ac0a46fSAndroid Build Coastguard Worker ma = (int16_t *)origdata;
1473*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1474*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1475*3ac0a46fSAndroid Build Coastguard Worker {
1476*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1477*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)ma);
1478*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteSshort(*ma);
1479*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1480*3ac0a46fSAndroid Build Coastguard Worker break;
1481*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint8_t)(*ma++);
1482*3ac0a46fSAndroid Build Coastguard Worker }
1483*3ac0a46fSAndroid Build Coastguard Worker }
1484*3ac0a46fSAndroid Build Coastguard Worker break;
1485*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
1486*3ac0a46fSAndroid Build Coastguard Worker {
1487*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
1488*3ac0a46fSAndroid Build Coastguard Worker uint8_t *mb;
1489*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1490*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
1491*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1492*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1493*3ac0a46fSAndroid Build Coastguard Worker {
1494*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1495*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
1496*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteLong(*ma);
1497*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1498*3ac0a46fSAndroid Build Coastguard Worker break;
1499*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint8_t)(*ma++);
1500*3ac0a46fSAndroid Build Coastguard Worker }
1501*3ac0a46fSAndroid Build Coastguard Worker }
1502*3ac0a46fSAndroid Build Coastguard Worker break;
1503*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
1504*3ac0a46fSAndroid Build Coastguard Worker {
1505*3ac0a46fSAndroid Build Coastguard Worker int32_t *ma;
1506*3ac0a46fSAndroid Build Coastguard Worker uint8_t *mb;
1507*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1508*3ac0a46fSAndroid Build Coastguard Worker ma = (int32_t *)origdata;
1509*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1510*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1511*3ac0a46fSAndroid Build Coastguard Worker {
1512*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1513*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)ma);
1514*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteSlong(*ma);
1515*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1516*3ac0a46fSAndroid Build Coastguard Worker break;
1517*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint8_t)(*ma++);
1518*3ac0a46fSAndroid Build Coastguard Worker }
1519*3ac0a46fSAndroid Build Coastguard Worker }
1520*3ac0a46fSAndroid Build Coastguard Worker break;
1521*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
1522*3ac0a46fSAndroid Build Coastguard Worker {
1523*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ma;
1524*3ac0a46fSAndroid Build Coastguard Worker uint8_t *mb;
1525*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1526*3ac0a46fSAndroid Build Coastguard Worker ma = (uint64_t *)origdata;
1527*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1528*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1529*3ac0a46fSAndroid Build Coastguard Worker {
1530*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1531*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(ma);
1532*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteLong8(*ma);
1533*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1534*3ac0a46fSAndroid Build Coastguard Worker break;
1535*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint8_t)(*ma++);
1536*3ac0a46fSAndroid Build Coastguard Worker }
1537*3ac0a46fSAndroid Build Coastguard Worker }
1538*3ac0a46fSAndroid Build Coastguard Worker break;
1539*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
1540*3ac0a46fSAndroid Build Coastguard Worker {
1541*3ac0a46fSAndroid Build Coastguard Worker int64_t *ma;
1542*3ac0a46fSAndroid Build Coastguard Worker uint8_t *mb;
1543*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1544*3ac0a46fSAndroid Build Coastguard Worker ma = (int64_t *)origdata;
1545*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1546*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1547*3ac0a46fSAndroid Build Coastguard Worker {
1548*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1549*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)ma);
1550*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeByteSlong8(*ma);
1551*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1552*3ac0a46fSAndroid Build Coastguard Worker break;
1553*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint8_t)(*ma++);
1554*3ac0a46fSAndroid Build Coastguard Worker }
1555*3ac0a46fSAndroid Build Coastguard Worker }
1556*3ac0a46fSAndroid Build Coastguard Worker break;
1557*3ac0a46fSAndroid Build Coastguard Worker }
1558*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
1559*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1560*3ac0a46fSAndroid Build Coastguard Worker {
1561*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
1562*3ac0a46fSAndroid Build Coastguard Worker return (err);
1563*3ac0a46fSAndroid Build Coastguard Worker }
1564*3ac0a46fSAndroid Build Coastguard Worker *value = data;
1565*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1566*3ac0a46fSAndroid Build Coastguard Worker }
1567*3ac0a46fSAndroid Build Coastguard Worker
1568*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntrySbyteArray(TIFF * tif,TIFFDirEntry * direntry,int8_t ** value)1569*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value)
1570*3ac0a46fSAndroid Build Coastguard Worker {
1571*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
1572*3ac0a46fSAndroid Build Coastguard Worker uint32_t count;
1573*3ac0a46fSAndroid Build Coastguard Worker void *origdata;
1574*3ac0a46fSAndroid Build Coastguard Worker int8_t *data;
1575*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1576*3ac0a46fSAndroid Build Coastguard Worker {
1577*3ac0a46fSAndroid Build Coastguard Worker case TIFF_UNDEFINED:
1578*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
1579*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
1580*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
1581*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
1582*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
1583*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
1584*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
1585*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
1586*3ac0a46fSAndroid Build Coastguard Worker break;
1587*3ac0a46fSAndroid Build Coastguard Worker default:
1588*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
1589*3ac0a46fSAndroid Build Coastguard Worker }
1590*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata);
1591*3ac0a46fSAndroid Build Coastguard Worker if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
1592*3ac0a46fSAndroid Build Coastguard Worker {
1593*3ac0a46fSAndroid Build Coastguard Worker *value = 0;
1594*3ac0a46fSAndroid Build Coastguard Worker return (err);
1595*3ac0a46fSAndroid Build Coastguard Worker }
1596*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1597*3ac0a46fSAndroid Build Coastguard Worker {
1598*3ac0a46fSAndroid Build Coastguard Worker case TIFF_UNDEFINED:
1599*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
1600*3ac0a46fSAndroid Build Coastguard Worker {
1601*3ac0a46fSAndroid Build Coastguard Worker uint8_t *m;
1602*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1603*3ac0a46fSAndroid Build Coastguard Worker m = (uint8_t *)origdata;
1604*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1605*3ac0a46fSAndroid Build Coastguard Worker {
1606*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteByte(*m);
1607*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1608*3ac0a46fSAndroid Build Coastguard Worker {
1609*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
1610*3ac0a46fSAndroid Build Coastguard Worker return (err);
1611*3ac0a46fSAndroid Build Coastguard Worker }
1612*3ac0a46fSAndroid Build Coastguard Worker m++;
1613*3ac0a46fSAndroid Build Coastguard Worker }
1614*3ac0a46fSAndroid Build Coastguard Worker *value = (int8_t *)origdata;
1615*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1616*3ac0a46fSAndroid Build Coastguard Worker }
1617*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
1618*3ac0a46fSAndroid Build Coastguard Worker *value = (int8_t *)origdata;
1619*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1620*3ac0a46fSAndroid Build Coastguard Worker }
1621*3ac0a46fSAndroid Build Coastguard Worker data = (int8_t *)_TIFFmallocExt(tif, count);
1622*3ac0a46fSAndroid Build Coastguard Worker if (data == 0)
1623*3ac0a46fSAndroid Build Coastguard Worker {
1624*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
1625*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrAlloc);
1626*3ac0a46fSAndroid Build Coastguard Worker }
1627*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1628*3ac0a46fSAndroid Build Coastguard Worker {
1629*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
1630*3ac0a46fSAndroid Build Coastguard Worker {
1631*3ac0a46fSAndroid Build Coastguard Worker uint16_t *ma;
1632*3ac0a46fSAndroid Build Coastguard Worker int8_t *mb;
1633*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1634*3ac0a46fSAndroid Build Coastguard Worker ma = (uint16_t *)origdata;
1635*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1636*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1637*3ac0a46fSAndroid Build Coastguard Worker {
1638*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1639*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(ma);
1640*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteShort(*ma);
1641*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1642*3ac0a46fSAndroid Build Coastguard Worker break;
1643*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int8_t)(*ma++);
1644*3ac0a46fSAndroid Build Coastguard Worker }
1645*3ac0a46fSAndroid Build Coastguard Worker }
1646*3ac0a46fSAndroid Build Coastguard Worker break;
1647*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
1648*3ac0a46fSAndroid Build Coastguard Worker {
1649*3ac0a46fSAndroid Build Coastguard Worker int16_t *ma;
1650*3ac0a46fSAndroid Build Coastguard Worker int8_t *mb;
1651*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1652*3ac0a46fSAndroid Build Coastguard Worker ma = (int16_t *)origdata;
1653*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1654*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1655*3ac0a46fSAndroid Build Coastguard Worker {
1656*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1657*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)ma);
1658*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteSshort(*ma);
1659*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1660*3ac0a46fSAndroid Build Coastguard Worker break;
1661*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int8_t)(*ma++);
1662*3ac0a46fSAndroid Build Coastguard Worker }
1663*3ac0a46fSAndroid Build Coastguard Worker }
1664*3ac0a46fSAndroid Build Coastguard Worker break;
1665*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
1666*3ac0a46fSAndroid Build Coastguard Worker {
1667*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
1668*3ac0a46fSAndroid Build Coastguard Worker int8_t *mb;
1669*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1670*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
1671*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1672*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1673*3ac0a46fSAndroid Build Coastguard Worker {
1674*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1675*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
1676*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteLong(*ma);
1677*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1678*3ac0a46fSAndroid Build Coastguard Worker break;
1679*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int8_t)(*ma++);
1680*3ac0a46fSAndroid Build Coastguard Worker }
1681*3ac0a46fSAndroid Build Coastguard Worker }
1682*3ac0a46fSAndroid Build Coastguard Worker break;
1683*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
1684*3ac0a46fSAndroid Build Coastguard Worker {
1685*3ac0a46fSAndroid Build Coastguard Worker int32_t *ma;
1686*3ac0a46fSAndroid Build Coastguard Worker int8_t *mb;
1687*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1688*3ac0a46fSAndroid Build Coastguard Worker ma = (int32_t *)origdata;
1689*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1690*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1691*3ac0a46fSAndroid Build Coastguard Worker {
1692*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1693*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)ma);
1694*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteSlong(*ma);
1695*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1696*3ac0a46fSAndroid Build Coastguard Worker break;
1697*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int8_t)(*ma++);
1698*3ac0a46fSAndroid Build Coastguard Worker }
1699*3ac0a46fSAndroid Build Coastguard Worker }
1700*3ac0a46fSAndroid Build Coastguard Worker break;
1701*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
1702*3ac0a46fSAndroid Build Coastguard Worker {
1703*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ma;
1704*3ac0a46fSAndroid Build Coastguard Worker int8_t *mb;
1705*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1706*3ac0a46fSAndroid Build Coastguard Worker ma = (uint64_t *)origdata;
1707*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1708*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1709*3ac0a46fSAndroid Build Coastguard Worker {
1710*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1711*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(ma);
1712*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteLong8(*ma);
1713*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1714*3ac0a46fSAndroid Build Coastguard Worker break;
1715*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int8_t)(*ma++);
1716*3ac0a46fSAndroid Build Coastguard Worker }
1717*3ac0a46fSAndroid Build Coastguard Worker }
1718*3ac0a46fSAndroid Build Coastguard Worker break;
1719*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
1720*3ac0a46fSAndroid Build Coastguard Worker {
1721*3ac0a46fSAndroid Build Coastguard Worker int64_t *ma;
1722*3ac0a46fSAndroid Build Coastguard Worker int8_t *mb;
1723*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1724*3ac0a46fSAndroid Build Coastguard Worker ma = (int64_t *)origdata;
1725*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1726*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1727*3ac0a46fSAndroid Build Coastguard Worker {
1728*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1729*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)ma);
1730*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSbyteSlong8(*ma);
1731*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1732*3ac0a46fSAndroid Build Coastguard Worker break;
1733*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int8_t)(*ma++);
1734*3ac0a46fSAndroid Build Coastguard Worker }
1735*3ac0a46fSAndroid Build Coastguard Worker }
1736*3ac0a46fSAndroid Build Coastguard Worker break;
1737*3ac0a46fSAndroid Build Coastguard Worker }
1738*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
1739*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1740*3ac0a46fSAndroid Build Coastguard Worker {
1741*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
1742*3ac0a46fSAndroid Build Coastguard Worker return (err);
1743*3ac0a46fSAndroid Build Coastguard Worker }
1744*3ac0a46fSAndroid Build Coastguard Worker *value = data;
1745*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1746*3ac0a46fSAndroid Build Coastguard Worker }
1747*3ac0a46fSAndroid Build Coastguard Worker
1748*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryShortArray(TIFF * tif,TIFFDirEntry * direntry,uint16_t ** value)1749*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value)
1750*3ac0a46fSAndroid Build Coastguard Worker {
1751*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
1752*3ac0a46fSAndroid Build Coastguard Worker uint32_t count;
1753*3ac0a46fSAndroid Build Coastguard Worker void *origdata;
1754*3ac0a46fSAndroid Build Coastguard Worker uint16_t *data;
1755*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1756*3ac0a46fSAndroid Build Coastguard Worker {
1757*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
1758*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
1759*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
1760*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
1761*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
1762*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
1763*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
1764*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
1765*3ac0a46fSAndroid Build Coastguard Worker break;
1766*3ac0a46fSAndroid Build Coastguard Worker default:
1767*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
1768*3ac0a46fSAndroid Build Coastguard Worker }
1769*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata);
1770*3ac0a46fSAndroid Build Coastguard Worker if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
1771*3ac0a46fSAndroid Build Coastguard Worker {
1772*3ac0a46fSAndroid Build Coastguard Worker *value = 0;
1773*3ac0a46fSAndroid Build Coastguard Worker return (err);
1774*3ac0a46fSAndroid Build Coastguard Worker }
1775*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1776*3ac0a46fSAndroid Build Coastguard Worker {
1777*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
1778*3ac0a46fSAndroid Build Coastguard Worker *value = (uint16_t *)origdata;
1779*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1780*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfShort(*value, count);
1781*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1782*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
1783*3ac0a46fSAndroid Build Coastguard Worker {
1784*3ac0a46fSAndroid Build Coastguard Worker int16_t *m;
1785*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1786*3ac0a46fSAndroid Build Coastguard Worker m = (int16_t *)origdata;
1787*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1788*3ac0a46fSAndroid Build Coastguard Worker {
1789*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1790*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)m);
1791*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeShortSshort(*m);
1792*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1793*3ac0a46fSAndroid Build Coastguard Worker {
1794*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
1795*3ac0a46fSAndroid Build Coastguard Worker return (err);
1796*3ac0a46fSAndroid Build Coastguard Worker }
1797*3ac0a46fSAndroid Build Coastguard Worker m++;
1798*3ac0a46fSAndroid Build Coastguard Worker }
1799*3ac0a46fSAndroid Build Coastguard Worker *value = (uint16_t *)origdata;
1800*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1801*3ac0a46fSAndroid Build Coastguard Worker }
1802*3ac0a46fSAndroid Build Coastguard Worker }
1803*3ac0a46fSAndroid Build Coastguard Worker data = (uint16_t *)_TIFFmallocExt(tif, count * 2);
1804*3ac0a46fSAndroid Build Coastguard Worker if (data == 0)
1805*3ac0a46fSAndroid Build Coastguard Worker {
1806*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
1807*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrAlloc);
1808*3ac0a46fSAndroid Build Coastguard Worker }
1809*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1810*3ac0a46fSAndroid Build Coastguard Worker {
1811*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
1812*3ac0a46fSAndroid Build Coastguard Worker {
1813*3ac0a46fSAndroid Build Coastguard Worker uint8_t *ma;
1814*3ac0a46fSAndroid Build Coastguard Worker uint16_t *mb;
1815*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1816*3ac0a46fSAndroid Build Coastguard Worker ma = (uint8_t *)origdata;
1817*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1818*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1819*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint16_t)(*ma++);
1820*3ac0a46fSAndroid Build Coastguard Worker }
1821*3ac0a46fSAndroid Build Coastguard Worker break;
1822*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
1823*3ac0a46fSAndroid Build Coastguard Worker {
1824*3ac0a46fSAndroid Build Coastguard Worker int8_t *ma;
1825*3ac0a46fSAndroid Build Coastguard Worker uint16_t *mb;
1826*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1827*3ac0a46fSAndroid Build Coastguard Worker ma = (int8_t *)origdata;
1828*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1829*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1830*3ac0a46fSAndroid Build Coastguard Worker {
1831*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeShortSbyte(*ma);
1832*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1833*3ac0a46fSAndroid Build Coastguard Worker break;
1834*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint16_t)(*ma++);
1835*3ac0a46fSAndroid Build Coastguard Worker }
1836*3ac0a46fSAndroid Build Coastguard Worker }
1837*3ac0a46fSAndroid Build Coastguard Worker break;
1838*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
1839*3ac0a46fSAndroid Build Coastguard Worker {
1840*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
1841*3ac0a46fSAndroid Build Coastguard Worker uint16_t *mb;
1842*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1843*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
1844*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1845*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1846*3ac0a46fSAndroid Build Coastguard Worker {
1847*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1848*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
1849*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeShortLong(*ma);
1850*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1851*3ac0a46fSAndroid Build Coastguard Worker break;
1852*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint16_t)(*ma++);
1853*3ac0a46fSAndroid Build Coastguard Worker }
1854*3ac0a46fSAndroid Build Coastguard Worker }
1855*3ac0a46fSAndroid Build Coastguard Worker break;
1856*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
1857*3ac0a46fSAndroid Build Coastguard Worker {
1858*3ac0a46fSAndroid Build Coastguard Worker int32_t *ma;
1859*3ac0a46fSAndroid Build Coastguard Worker uint16_t *mb;
1860*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1861*3ac0a46fSAndroid Build Coastguard Worker ma = (int32_t *)origdata;
1862*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1863*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1864*3ac0a46fSAndroid Build Coastguard Worker {
1865*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1866*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)ma);
1867*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeShortSlong(*ma);
1868*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1869*3ac0a46fSAndroid Build Coastguard Worker break;
1870*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint16_t)(*ma++);
1871*3ac0a46fSAndroid Build Coastguard Worker }
1872*3ac0a46fSAndroid Build Coastguard Worker }
1873*3ac0a46fSAndroid Build Coastguard Worker break;
1874*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
1875*3ac0a46fSAndroid Build Coastguard Worker {
1876*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ma;
1877*3ac0a46fSAndroid Build Coastguard Worker uint16_t *mb;
1878*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1879*3ac0a46fSAndroid Build Coastguard Worker ma = (uint64_t *)origdata;
1880*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1881*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1882*3ac0a46fSAndroid Build Coastguard Worker {
1883*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1884*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(ma);
1885*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeShortLong8(*ma);
1886*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1887*3ac0a46fSAndroid Build Coastguard Worker break;
1888*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint16_t)(*ma++);
1889*3ac0a46fSAndroid Build Coastguard Worker }
1890*3ac0a46fSAndroid Build Coastguard Worker }
1891*3ac0a46fSAndroid Build Coastguard Worker break;
1892*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
1893*3ac0a46fSAndroid Build Coastguard Worker {
1894*3ac0a46fSAndroid Build Coastguard Worker int64_t *ma;
1895*3ac0a46fSAndroid Build Coastguard Worker uint16_t *mb;
1896*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1897*3ac0a46fSAndroid Build Coastguard Worker ma = (int64_t *)origdata;
1898*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1899*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1900*3ac0a46fSAndroid Build Coastguard Worker {
1901*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1902*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)ma);
1903*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeShortSlong8(*ma);
1904*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1905*3ac0a46fSAndroid Build Coastguard Worker break;
1906*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint16_t)(*ma++);
1907*3ac0a46fSAndroid Build Coastguard Worker }
1908*3ac0a46fSAndroid Build Coastguard Worker }
1909*3ac0a46fSAndroid Build Coastguard Worker break;
1910*3ac0a46fSAndroid Build Coastguard Worker }
1911*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
1912*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1913*3ac0a46fSAndroid Build Coastguard Worker {
1914*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
1915*3ac0a46fSAndroid Build Coastguard Worker return (err);
1916*3ac0a46fSAndroid Build Coastguard Worker }
1917*3ac0a46fSAndroid Build Coastguard Worker *value = data;
1918*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1919*3ac0a46fSAndroid Build Coastguard Worker }
1920*3ac0a46fSAndroid Build Coastguard Worker
1921*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntrySshortArray(TIFF * tif,TIFFDirEntry * direntry,int16_t ** value)1922*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value)
1923*3ac0a46fSAndroid Build Coastguard Worker {
1924*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
1925*3ac0a46fSAndroid Build Coastguard Worker uint32_t count;
1926*3ac0a46fSAndroid Build Coastguard Worker void *origdata;
1927*3ac0a46fSAndroid Build Coastguard Worker int16_t *data;
1928*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1929*3ac0a46fSAndroid Build Coastguard Worker {
1930*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
1931*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
1932*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
1933*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
1934*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
1935*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
1936*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
1937*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
1938*3ac0a46fSAndroid Build Coastguard Worker break;
1939*3ac0a46fSAndroid Build Coastguard Worker default:
1940*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
1941*3ac0a46fSAndroid Build Coastguard Worker }
1942*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata);
1943*3ac0a46fSAndroid Build Coastguard Worker if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
1944*3ac0a46fSAndroid Build Coastguard Worker {
1945*3ac0a46fSAndroid Build Coastguard Worker *value = 0;
1946*3ac0a46fSAndroid Build Coastguard Worker return (err);
1947*3ac0a46fSAndroid Build Coastguard Worker }
1948*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1949*3ac0a46fSAndroid Build Coastguard Worker {
1950*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
1951*3ac0a46fSAndroid Build Coastguard Worker {
1952*3ac0a46fSAndroid Build Coastguard Worker uint16_t *m;
1953*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1954*3ac0a46fSAndroid Build Coastguard Worker m = (uint16_t *)origdata;
1955*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1956*3ac0a46fSAndroid Build Coastguard Worker {
1957*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1958*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(m);
1959*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSshortShort(*m);
1960*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
1961*3ac0a46fSAndroid Build Coastguard Worker {
1962*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
1963*3ac0a46fSAndroid Build Coastguard Worker return (err);
1964*3ac0a46fSAndroid Build Coastguard Worker }
1965*3ac0a46fSAndroid Build Coastguard Worker m++;
1966*3ac0a46fSAndroid Build Coastguard Worker }
1967*3ac0a46fSAndroid Build Coastguard Worker *value = (int16_t *)origdata;
1968*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1969*3ac0a46fSAndroid Build Coastguard Worker }
1970*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
1971*3ac0a46fSAndroid Build Coastguard Worker *value = (int16_t *)origdata;
1972*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1973*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfShort((uint16_t *)(*value), count);
1974*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
1975*3ac0a46fSAndroid Build Coastguard Worker }
1976*3ac0a46fSAndroid Build Coastguard Worker data = (int16_t *)_TIFFmallocExt(tif, count * 2);
1977*3ac0a46fSAndroid Build Coastguard Worker if (data == 0)
1978*3ac0a46fSAndroid Build Coastguard Worker {
1979*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
1980*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrAlloc);
1981*3ac0a46fSAndroid Build Coastguard Worker }
1982*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
1983*3ac0a46fSAndroid Build Coastguard Worker {
1984*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
1985*3ac0a46fSAndroid Build Coastguard Worker {
1986*3ac0a46fSAndroid Build Coastguard Worker uint8_t *ma;
1987*3ac0a46fSAndroid Build Coastguard Worker int16_t *mb;
1988*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
1989*3ac0a46fSAndroid Build Coastguard Worker ma = (uint8_t *)origdata;
1990*3ac0a46fSAndroid Build Coastguard Worker mb = data;
1991*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
1992*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int16_t)(*ma++);
1993*3ac0a46fSAndroid Build Coastguard Worker }
1994*3ac0a46fSAndroid Build Coastguard Worker break;
1995*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
1996*3ac0a46fSAndroid Build Coastguard Worker {
1997*3ac0a46fSAndroid Build Coastguard Worker int8_t *ma;
1998*3ac0a46fSAndroid Build Coastguard Worker int16_t *mb;
1999*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2000*3ac0a46fSAndroid Build Coastguard Worker ma = (int8_t *)origdata;
2001*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2002*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2003*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int16_t)(*ma++);
2004*3ac0a46fSAndroid Build Coastguard Worker }
2005*3ac0a46fSAndroid Build Coastguard Worker break;
2006*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
2007*3ac0a46fSAndroid Build Coastguard Worker {
2008*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
2009*3ac0a46fSAndroid Build Coastguard Worker int16_t *mb;
2010*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2011*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
2012*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2013*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2014*3ac0a46fSAndroid Build Coastguard Worker {
2015*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2016*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
2017*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSshortLong(*ma);
2018*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2019*3ac0a46fSAndroid Build Coastguard Worker break;
2020*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int16_t)(*ma++);
2021*3ac0a46fSAndroid Build Coastguard Worker }
2022*3ac0a46fSAndroid Build Coastguard Worker }
2023*3ac0a46fSAndroid Build Coastguard Worker break;
2024*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
2025*3ac0a46fSAndroid Build Coastguard Worker {
2026*3ac0a46fSAndroid Build Coastguard Worker int32_t *ma;
2027*3ac0a46fSAndroid Build Coastguard Worker int16_t *mb;
2028*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2029*3ac0a46fSAndroid Build Coastguard Worker ma = (int32_t *)origdata;
2030*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2031*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2032*3ac0a46fSAndroid Build Coastguard Worker {
2033*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2034*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)ma);
2035*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSshortSlong(*ma);
2036*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2037*3ac0a46fSAndroid Build Coastguard Worker break;
2038*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int16_t)(*ma++);
2039*3ac0a46fSAndroid Build Coastguard Worker }
2040*3ac0a46fSAndroid Build Coastguard Worker }
2041*3ac0a46fSAndroid Build Coastguard Worker break;
2042*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
2043*3ac0a46fSAndroid Build Coastguard Worker {
2044*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ma;
2045*3ac0a46fSAndroid Build Coastguard Worker int16_t *mb;
2046*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2047*3ac0a46fSAndroid Build Coastguard Worker ma = (uint64_t *)origdata;
2048*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2049*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2050*3ac0a46fSAndroid Build Coastguard Worker {
2051*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2052*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(ma);
2053*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSshortLong8(*ma);
2054*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2055*3ac0a46fSAndroid Build Coastguard Worker break;
2056*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int16_t)(*ma++);
2057*3ac0a46fSAndroid Build Coastguard Worker }
2058*3ac0a46fSAndroid Build Coastguard Worker }
2059*3ac0a46fSAndroid Build Coastguard Worker break;
2060*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
2061*3ac0a46fSAndroid Build Coastguard Worker {
2062*3ac0a46fSAndroid Build Coastguard Worker int64_t *ma;
2063*3ac0a46fSAndroid Build Coastguard Worker int16_t *mb;
2064*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2065*3ac0a46fSAndroid Build Coastguard Worker ma = (int64_t *)origdata;
2066*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2067*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2068*3ac0a46fSAndroid Build Coastguard Worker {
2069*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2070*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)ma);
2071*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSshortSlong8(*ma);
2072*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2073*3ac0a46fSAndroid Build Coastguard Worker break;
2074*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int16_t)(*ma++);
2075*3ac0a46fSAndroid Build Coastguard Worker }
2076*3ac0a46fSAndroid Build Coastguard Worker }
2077*3ac0a46fSAndroid Build Coastguard Worker break;
2078*3ac0a46fSAndroid Build Coastguard Worker }
2079*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2080*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2081*3ac0a46fSAndroid Build Coastguard Worker {
2082*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
2083*3ac0a46fSAndroid Build Coastguard Worker return (err);
2084*3ac0a46fSAndroid Build Coastguard Worker }
2085*3ac0a46fSAndroid Build Coastguard Worker *value = data;
2086*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2087*3ac0a46fSAndroid Build Coastguard Worker }
2088*3ac0a46fSAndroid Build Coastguard Worker
2089*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryLongArray(TIFF * tif,TIFFDirEntry * direntry,uint32_t ** value)2090*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
2091*3ac0a46fSAndroid Build Coastguard Worker {
2092*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
2093*3ac0a46fSAndroid Build Coastguard Worker uint32_t count;
2094*3ac0a46fSAndroid Build Coastguard Worker void *origdata;
2095*3ac0a46fSAndroid Build Coastguard Worker uint32_t *data;
2096*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2097*3ac0a46fSAndroid Build Coastguard Worker {
2098*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
2099*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
2100*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
2101*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
2102*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
2103*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
2104*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
2105*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
2106*3ac0a46fSAndroid Build Coastguard Worker break;
2107*3ac0a46fSAndroid Build Coastguard Worker default:
2108*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
2109*3ac0a46fSAndroid Build Coastguard Worker }
2110*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata);
2111*3ac0a46fSAndroid Build Coastguard Worker if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
2112*3ac0a46fSAndroid Build Coastguard Worker {
2113*3ac0a46fSAndroid Build Coastguard Worker *value = 0;
2114*3ac0a46fSAndroid Build Coastguard Worker return (err);
2115*3ac0a46fSAndroid Build Coastguard Worker }
2116*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2117*3ac0a46fSAndroid Build Coastguard Worker {
2118*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
2119*3ac0a46fSAndroid Build Coastguard Worker *value = (uint32_t *)origdata;
2120*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2121*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong(*value, count);
2122*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2123*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
2124*3ac0a46fSAndroid Build Coastguard Worker {
2125*3ac0a46fSAndroid Build Coastguard Worker int32_t *m;
2126*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2127*3ac0a46fSAndroid Build Coastguard Worker m = (int32_t *)origdata;
2128*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2129*3ac0a46fSAndroid Build Coastguard Worker {
2130*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2131*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)m);
2132*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLongSlong(*m);
2133*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2134*3ac0a46fSAndroid Build Coastguard Worker {
2135*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2136*3ac0a46fSAndroid Build Coastguard Worker return (err);
2137*3ac0a46fSAndroid Build Coastguard Worker }
2138*3ac0a46fSAndroid Build Coastguard Worker m++;
2139*3ac0a46fSAndroid Build Coastguard Worker }
2140*3ac0a46fSAndroid Build Coastguard Worker *value = (uint32_t *)origdata;
2141*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2142*3ac0a46fSAndroid Build Coastguard Worker }
2143*3ac0a46fSAndroid Build Coastguard Worker }
2144*3ac0a46fSAndroid Build Coastguard Worker data = (uint32_t *)_TIFFmallocExt(tif, count * 4);
2145*3ac0a46fSAndroid Build Coastguard Worker if (data == 0)
2146*3ac0a46fSAndroid Build Coastguard Worker {
2147*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2148*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrAlloc);
2149*3ac0a46fSAndroid Build Coastguard Worker }
2150*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2151*3ac0a46fSAndroid Build Coastguard Worker {
2152*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
2153*3ac0a46fSAndroid Build Coastguard Worker {
2154*3ac0a46fSAndroid Build Coastguard Worker uint8_t *ma;
2155*3ac0a46fSAndroid Build Coastguard Worker uint32_t *mb;
2156*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2157*3ac0a46fSAndroid Build Coastguard Worker ma = (uint8_t *)origdata;
2158*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2159*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2160*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint32_t)(*ma++);
2161*3ac0a46fSAndroid Build Coastguard Worker }
2162*3ac0a46fSAndroid Build Coastguard Worker break;
2163*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
2164*3ac0a46fSAndroid Build Coastguard Worker {
2165*3ac0a46fSAndroid Build Coastguard Worker int8_t *ma;
2166*3ac0a46fSAndroid Build Coastguard Worker uint32_t *mb;
2167*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2168*3ac0a46fSAndroid Build Coastguard Worker ma = (int8_t *)origdata;
2169*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2170*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2171*3ac0a46fSAndroid Build Coastguard Worker {
2172*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLongSbyte(*ma);
2173*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2174*3ac0a46fSAndroid Build Coastguard Worker break;
2175*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint32_t)(*ma++);
2176*3ac0a46fSAndroid Build Coastguard Worker }
2177*3ac0a46fSAndroid Build Coastguard Worker }
2178*3ac0a46fSAndroid Build Coastguard Worker break;
2179*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
2180*3ac0a46fSAndroid Build Coastguard Worker {
2181*3ac0a46fSAndroid Build Coastguard Worker uint16_t *ma;
2182*3ac0a46fSAndroid Build Coastguard Worker uint32_t *mb;
2183*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2184*3ac0a46fSAndroid Build Coastguard Worker ma = (uint16_t *)origdata;
2185*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2186*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2187*3ac0a46fSAndroid Build Coastguard Worker {
2188*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2189*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(ma);
2190*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint32_t)(*ma++);
2191*3ac0a46fSAndroid Build Coastguard Worker }
2192*3ac0a46fSAndroid Build Coastguard Worker }
2193*3ac0a46fSAndroid Build Coastguard Worker break;
2194*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
2195*3ac0a46fSAndroid Build Coastguard Worker {
2196*3ac0a46fSAndroid Build Coastguard Worker int16_t *ma;
2197*3ac0a46fSAndroid Build Coastguard Worker uint32_t *mb;
2198*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2199*3ac0a46fSAndroid Build Coastguard Worker ma = (int16_t *)origdata;
2200*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2201*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2202*3ac0a46fSAndroid Build Coastguard Worker {
2203*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2204*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)ma);
2205*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLongSshort(*ma);
2206*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2207*3ac0a46fSAndroid Build Coastguard Worker break;
2208*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint32_t)(*ma++);
2209*3ac0a46fSAndroid Build Coastguard Worker }
2210*3ac0a46fSAndroid Build Coastguard Worker }
2211*3ac0a46fSAndroid Build Coastguard Worker break;
2212*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
2213*3ac0a46fSAndroid Build Coastguard Worker {
2214*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ma;
2215*3ac0a46fSAndroid Build Coastguard Worker uint32_t *mb;
2216*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2217*3ac0a46fSAndroid Build Coastguard Worker ma = (uint64_t *)origdata;
2218*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2219*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2220*3ac0a46fSAndroid Build Coastguard Worker {
2221*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2222*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(ma);
2223*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLongLong8(*ma);
2224*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2225*3ac0a46fSAndroid Build Coastguard Worker break;
2226*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint32_t)(*ma++);
2227*3ac0a46fSAndroid Build Coastguard Worker }
2228*3ac0a46fSAndroid Build Coastguard Worker }
2229*3ac0a46fSAndroid Build Coastguard Worker break;
2230*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
2231*3ac0a46fSAndroid Build Coastguard Worker {
2232*3ac0a46fSAndroid Build Coastguard Worker int64_t *ma;
2233*3ac0a46fSAndroid Build Coastguard Worker uint32_t *mb;
2234*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2235*3ac0a46fSAndroid Build Coastguard Worker ma = (int64_t *)origdata;
2236*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2237*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2238*3ac0a46fSAndroid Build Coastguard Worker {
2239*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2240*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)ma);
2241*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLongSlong8(*ma);
2242*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2243*3ac0a46fSAndroid Build Coastguard Worker break;
2244*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint32_t)(*ma++);
2245*3ac0a46fSAndroid Build Coastguard Worker }
2246*3ac0a46fSAndroid Build Coastguard Worker }
2247*3ac0a46fSAndroid Build Coastguard Worker break;
2248*3ac0a46fSAndroid Build Coastguard Worker }
2249*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2250*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2251*3ac0a46fSAndroid Build Coastguard Worker {
2252*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
2253*3ac0a46fSAndroid Build Coastguard Worker return (err);
2254*3ac0a46fSAndroid Build Coastguard Worker }
2255*3ac0a46fSAndroid Build Coastguard Worker *value = data;
2256*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2257*3ac0a46fSAndroid Build Coastguard Worker }
2258*3ac0a46fSAndroid Build Coastguard Worker
2259*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntrySlongArray(TIFF * tif,TIFFDirEntry * direntry,int32_t ** value)2260*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value)
2261*3ac0a46fSAndroid Build Coastguard Worker {
2262*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
2263*3ac0a46fSAndroid Build Coastguard Worker uint32_t count;
2264*3ac0a46fSAndroid Build Coastguard Worker void *origdata;
2265*3ac0a46fSAndroid Build Coastguard Worker int32_t *data;
2266*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2267*3ac0a46fSAndroid Build Coastguard Worker {
2268*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
2269*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
2270*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
2271*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
2272*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
2273*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
2274*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
2275*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
2276*3ac0a46fSAndroid Build Coastguard Worker break;
2277*3ac0a46fSAndroid Build Coastguard Worker default:
2278*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
2279*3ac0a46fSAndroid Build Coastguard Worker }
2280*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata);
2281*3ac0a46fSAndroid Build Coastguard Worker if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
2282*3ac0a46fSAndroid Build Coastguard Worker {
2283*3ac0a46fSAndroid Build Coastguard Worker *value = 0;
2284*3ac0a46fSAndroid Build Coastguard Worker return (err);
2285*3ac0a46fSAndroid Build Coastguard Worker }
2286*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2287*3ac0a46fSAndroid Build Coastguard Worker {
2288*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
2289*3ac0a46fSAndroid Build Coastguard Worker {
2290*3ac0a46fSAndroid Build Coastguard Worker uint32_t *m;
2291*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2292*3ac0a46fSAndroid Build Coastguard Worker m = (uint32_t *)origdata;
2293*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2294*3ac0a46fSAndroid Build Coastguard Worker {
2295*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2296*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)m);
2297*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSlongLong(*m);
2298*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2299*3ac0a46fSAndroid Build Coastguard Worker {
2300*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2301*3ac0a46fSAndroid Build Coastguard Worker return (err);
2302*3ac0a46fSAndroid Build Coastguard Worker }
2303*3ac0a46fSAndroid Build Coastguard Worker m++;
2304*3ac0a46fSAndroid Build Coastguard Worker }
2305*3ac0a46fSAndroid Build Coastguard Worker *value = (int32_t *)origdata;
2306*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2307*3ac0a46fSAndroid Build Coastguard Worker }
2308*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
2309*3ac0a46fSAndroid Build Coastguard Worker *value = (int32_t *)origdata;
2310*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2311*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong((uint32_t *)(*value), count);
2312*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2313*3ac0a46fSAndroid Build Coastguard Worker }
2314*3ac0a46fSAndroid Build Coastguard Worker data = (int32_t *)_TIFFmallocExt(tif, count * 4);
2315*3ac0a46fSAndroid Build Coastguard Worker if (data == 0)
2316*3ac0a46fSAndroid Build Coastguard Worker {
2317*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2318*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrAlloc);
2319*3ac0a46fSAndroid Build Coastguard Worker }
2320*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2321*3ac0a46fSAndroid Build Coastguard Worker {
2322*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
2323*3ac0a46fSAndroid Build Coastguard Worker {
2324*3ac0a46fSAndroid Build Coastguard Worker uint8_t *ma;
2325*3ac0a46fSAndroid Build Coastguard Worker int32_t *mb;
2326*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2327*3ac0a46fSAndroid Build Coastguard Worker ma = (uint8_t *)origdata;
2328*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2329*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2330*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int32_t)(*ma++);
2331*3ac0a46fSAndroid Build Coastguard Worker }
2332*3ac0a46fSAndroid Build Coastguard Worker break;
2333*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
2334*3ac0a46fSAndroid Build Coastguard Worker {
2335*3ac0a46fSAndroid Build Coastguard Worker int8_t *ma;
2336*3ac0a46fSAndroid Build Coastguard Worker int32_t *mb;
2337*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2338*3ac0a46fSAndroid Build Coastguard Worker ma = (int8_t *)origdata;
2339*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2340*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2341*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int32_t)(*ma++);
2342*3ac0a46fSAndroid Build Coastguard Worker }
2343*3ac0a46fSAndroid Build Coastguard Worker break;
2344*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
2345*3ac0a46fSAndroid Build Coastguard Worker {
2346*3ac0a46fSAndroid Build Coastguard Worker uint16_t *ma;
2347*3ac0a46fSAndroid Build Coastguard Worker int32_t *mb;
2348*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2349*3ac0a46fSAndroid Build Coastguard Worker ma = (uint16_t *)origdata;
2350*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2351*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2352*3ac0a46fSAndroid Build Coastguard Worker {
2353*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2354*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(ma);
2355*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int32_t)(*ma++);
2356*3ac0a46fSAndroid Build Coastguard Worker }
2357*3ac0a46fSAndroid Build Coastguard Worker }
2358*3ac0a46fSAndroid Build Coastguard Worker break;
2359*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
2360*3ac0a46fSAndroid Build Coastguard Worker {
2361*3ac0a46fSAndroid Build Coastguard Worker int16_t *ma;
2362*3ac0a46fSAndroid Build Coastguard Worker int32_t *mb;
2363*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2364*3ac0a46fSAndroid Build Coastguard Worker ma = (int16_t *)origdata;
2365*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2366*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2367*3ac0a46fSAndroid Build Coastguard Worker {
2368*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2369*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)ma);
2370*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int32_t)(*ma++);
2371*3ac0a46fSAndroid Build Coastguard Worker }
2372*3ac0a46fSAndroid Build Coastguard Worker }
2373*3ac0a46fSAndroid Build Coastguard Worker break;
2374*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
2375*3ac0a46fSAndroid Build Coastguard Worker {
2376*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ma;
2377*3ac0a46fSAndroid Build Coastguard Worker int32_t *mb;
2378*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2379*3ac0a46fSAndroid Build Coastguard Worker ma = (uint64_t *)origdata;
2380*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2381*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2382*3ac0a46fSAndroid Build Coastguard Worker {
2383*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2384*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(ma);
2385*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSlongLong8(*ma);
2386*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2387*3ac0a46fSAndroid Build Coastguard Worker break;
2388*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int32_t)(*ma++);
2389*3ac0a46fSAndroid Build Coastguard Worker }
2390*3ac0a46fSAndroid Build Coastguard Worker }
2391*3ac0a46fSAndroid Build Coastguard Worker break;
2392*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
2393*3ac0a46fSAndroid Build Coastguard Worker {
2394*3ac0a46fSAndroid Build Coastguard Worker int64_t *ma;
2395*3ac0a46fSAndroid Build Coastguard Worker int32_t *mb;
2396*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2397*3ac0a46fSAndroid Build Coastguard Worker ma = (int64_t *)origdata;
2398*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2399*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2400*3ac0a46fSAndroid Build Coastguard Worker {
2401*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2402*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)ma);
2403*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSlongSlong8(*ma);
2404*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2405*3ac0a46fSAndroid Build Coastguard Worker break;
2406*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int32_t)(*ma++);
2407*3ac0a46fSAndroid Build Coastguard Worker }
2408*3ac0a46fSAndroid Build Coastguard Worker }
2409*3ac0a46fSAndroid Build Coastguard Worker break;
2410*3ac0a46fSAndroid Build Coastguard Worker }
2411*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2412*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2413*3ac0a46fSAndroid Build Coastguard Worker {
2414*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
2415*3ac0a46fSAndroid Build Coastguard Worker return (err);
2416*3ac0a46fSAndroid Build Coastguard Worker }
2417*3ac0a46fSAndroid Build Coastguard Worker *value = data;
2418*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2419*3ac0a46fSAndroid Build Coastguard Worker }
2420*3ac0a46fSAndroid Build Coastguard Worker
2421*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryLong8ArrayWithLimit(TIFF * tif,TIFFDirEntry * direntry,uint64_t ** value,uint64_t maxcount)2422*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
2423*3ac0a46fSAndroid Build Coastguard Worker uint64_t **value, uint64_t maxcount)
2424*3ac0a46fSAndroid Build Coastguard Worker {
2425*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
2426*3ac0a46fSAndroid Build Coastguard Worker uint32_t count;
2427*3ac0a46fSAndroid Build Coastguard Worker void *origdata;
2428*3ac0a46fSAndroid Build Coastguard Worker uint64_t *data;
2429*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2430*3ac0a46fSAndroid Build Coastguard Worker {
2431*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
2432*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
2433*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
2434*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
2435*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
2436*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
2437*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
2438*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
2439*3ac0a46fSAndroid Build Coastguard Worker break;
2440*3ac0a46fSAndroid Build Coastguard Worker default:
2441*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
2442*3ac0a46fSAndroid Build Coastguard Worker }
2443*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryArrayWithLimit(tif, direntry, &count, 8, &origdata,
2444*3ac0a46fSAndroid Build Coastguard Worker maxcount);
2445*3ac0a46fSAndroid Build Coastguard Worker if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
2446*3ac0a46fSAndroid Build Coastguard Worker {
2447*3ac0a46fSAndroid Build Coastguard Worker *value = 0;
2448*3ac0a46fSAndroid Build Coastguard Worker return (err);
2449*3ac0a46fSAndroid Build Coastguard Worker }
2450*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2451*3ac0a46fSAndroid Build Coastguard Worker {
2452*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
2453*3ac0a46fSAndroid Build Coastguard Worker *value = (uint64_t *)origdata;
2454*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2455*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong8(*value, count);
2456*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2457*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
2458*3ac0a46fSAndroid Build Coastguard Worker {
2459*3ac0a46fSAndroid Build Coastguard Worker int64_t *m;
2460*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2461*3ac0a46fSAndroid Build Coastguard Worker m = (int64_t *)origdata;
2462*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2463*3ac0a46fSAndroid Build Coastguard Worker {
2464*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2465*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)m);
2466*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLong8Slong8(*m);
2467*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2468*3ac0a46fSAndroid Build Coastguard Worker {
2469*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2470*3ac0a46fSAndroid Build Coastguard Worker return (err);
2471*3ac0a46fSAndroid Build Coastguard Worker }
2472*3ac0a46fSAndroid Build Coastguard Worker m++;
2473*3ac0a46fSAndroid Build Coastguard Worker }
2474*3ac0a46fSAndroid Build Coastguard Worker *value = (uint64_t *)origdata;
2475*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2476*3ac0a46fSAndroid Build Coastguard Worker }
2477*3ac0a46fSAndroid Build Coastguard Worker }
2478*3ac0a46fSAndroid Build Coastguard Worker data = (uint64_t *)_TIFFmallocExt(tif, count * 8);
2479*3ac0a46fSAndroid Build Coastguard Worker if (data == 0)
2480*3ac0a46fSAndroid Build Coastguard Worker {
2481*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2482*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrAlloc);
2483*3ac0a46fSAndroid Build Coastguard Worker }
2484*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2485*3ac0a46fSAndroid Build Coastguard Worker {
2486*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
2487*3ac0a46fSAndroid Build Coastguard Worker {
2488*3ac0a46fSAndroid Build Coastguard Worker uint8_t *ma;
2489*3ac0a46fSAndroid Build Coastguard Worker uint64_t *mb;
2490*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2491*3ac0a46fSAndroid Build Coastguard Worker ma = (uint8_t *)origdata;
2492*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2493*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2494*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint64_t)(*ma++);
2495*3ac0a46fSAndroid Build Coastguard Worker }
2496*3ac0a46fSAndroid Build Coastguard Worker break;
2497*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
2498*3ac0a46fSAndroid Build Coastguard Worker {
2499*3ac0a46fSAndroid Build Coastguard Worker int8_t *ma;
2500*3ac0a46fSAndroid Build Coastguard Worker uint64_t *mb;
2501*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2502*3ac0a46fSAndroid Build Coastguard Worker ma = (int8_t *)origdata;
2503*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2504*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2505*3ac0a46fSAndroid Build Coastguard Worker {
2506*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLong8Sbyte(*ma);
2507*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2508*3ac0a46fSAndroid Build Coastguard Worker break;
2509*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint64_t)(*ma++);
2510*3ac0a46fSAndroid Build Coastguard Worker }
2511*3ac0a46fSAndroid Build Coastguard Worker }
2512*3ac0a46fSAndroid Build Coastguard Worker break;
2513*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
2514*3ac0a46fSAndroid Build Coastguard Worker {
2515*3ac0a46fSAndroid Build Coastguard Worker uint16_t *ma;
2516*3ac0a46fSAndroid Build Coastguard Worker uint64_t *mb;
2517*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2518*3ac0a46fSAndroid Build Coastguard Worker ma = (uint16_t *)origdata;
2519*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2520*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2521*3ac0a46fSAndroid Build Coastguard Worker {
2522*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2523*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(ma);
2524*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint64_t)(*ma++);
2525*3ac0a46fSAndroid Build Coastguard Worker }
2526*3ac0a46fSAndroid Build Coastguard Worker }
2527*3ac0a46fSAndroid Build Coastguard Worker break;
2528*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
2529*3ac0a46fSAndroid Build Coastguard Worker {
2530*3ac0a46fSAndroid Build Coastguard Worker int16_t *ma;
2531*3ac0a46fSAndroid Build Coastguard Worker uint64_t *mb;
2532*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2533*3ac0a46fSAndroid Build Coastguard Worker ma = (int16_t *)origdata;
2534*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2535*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2536*3ac0a46fSAndroid Build Coastguard Worker {
2537*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2538*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)ma);
2539*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLong8Sshort(*ma);
2540*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2541*3ac0a46fSAndroid Build Coastguard Worker break;
2542*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint64_t)(*ma++);
2543*3ac0a46fSAndroid Build Coastguard Worker }
2544*3ac0a46fSAndroid Build Coastguard Worker }
2545*3ac0a46fSAndroid Build Coastguard Worker break;
2546*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
2547*3ac0a46fSAndroid Build Coastguard Worker {
2548*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
2549*3ac0a46fSAndroid Build Coastguard Worker uint64_t *mb;
2550*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2551*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
2552*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2553*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2554*3ac0a46fSAndroid Build Coastguard Worker {
2555*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2556*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
2557*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint64_t)(*ma++);
2558*3ac0a46fSAndroid Build Coastguard Worker }
2559*3ac0a46fSAndroid Build Coastguard Worker }
2560*3ac0a46fSAndroid Build Coastguard Worker break;
2561*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
2562*3ac0a46fSAndroid Build Coastguard Worker {
2563*3ac0a46fSAndroid Build Coastguard Worker int32_t *ma;
2564*3ac0a46fSAndroid Build Coastguard Worker uint64_t *mb;
2565*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2566*3ac0a46fSAndroid Build Coastguard Worker ma = (int32_t *)origdata;
2567*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2568*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2569*3ac0a46fSAndroid Build Coastguard Worker {
2570*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2571*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)ma);
2572*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeLong8Slong(*ma);
2573*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2574*3ac0a46fSAndroid Build Coastguard Worker break;
2575*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint64_t)(*ma++);
2576*3ac0a46fSAndroid Build Coastguard Worker }
2577*3ac0a46fSAndroid Build Coastguard Worker }
2578*3ac0a46fSAndroid Build Coastguard Worker break;
2579*3ac0a46fSAndroid Build Coastguard Worker }
2580*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2581*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2582*3ac0a46fSAndroid Build Coastguard Worker {
2583*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
2584*3ac0a46fSAndroid Build Coastguard Worker return (err);
2585*3ac0a46fSAndroid Build Coastguard Worker }
2586*3ac0a46fSAndroid Build Coastguard Worker *value = data;
2587*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2588*3ac0a46fSAndroid Build Coastguard Worker }
2589*3ac0a46fSAndroid Build Coastguard Worker
2590*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryLong8Array(TIFF * tif,TIFFDirEntry * direntry,uint64_t ** value)2591*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value)
2592*3ac0a46fSAndroid Build Coastguard Worker {
2593*3ac0a46fSAndroid Build Coastguard Worker return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value,
2594*3ac0a46fSAndroid Build Coastguard Worker ~((uint64_t)0));
2595*3ac0a46fSAndroid Build Coastguard Worker }
2596*3ac0a46fSAndroid Build Coastguard Worker
2597*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntrySlong8Array(TIFF * tif,TIFFDirEntry * direntry,int64_t ** value)2598*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value)
2599*3ac0a46fSAndroid Build Coastguard Worker {
2600*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
2601*3ac0a46fSAndroid Build Coastguard Worker uint32_t count;
2602*3ac0a46fSAndroid Build Coastguard Worker void *origdata;
2603*3ac0a46fSAndroid Build Coastguard Worker int64_t *data;
2604*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2605*3ac0a46fSAndroid Build Coastguard Worker {
2606*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
2607*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
2608*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
2609*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
2610*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
2611*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
2612*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
2613*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
2614*3ac0a46fSAndroid Build Coastguard Worker break;
2615*3ac0a46fSAndroid Build Coastguard Worker default:
2616*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
2617*3ac0a46fSAndroid Build Coastguard Worker }
2618*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata);
2619*3ac0a46fSAndroid Build Coastguard Worker if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
2620*3ac0a46fSAndroid Build Coastguard Worker {
2621*3ac0a46fSAndroid Build Coastguard Worker *value = 0;
2622*3ac0a46fSAndroid Build Coastguard Worker return (err);
2623*3ac0a46fSAndroid Build Coastguard Worker }
2624*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2625*3ac0a46fSAndroid Build Coastguard Worker {
2626*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
2627*3ac0a46fSAndroid Build Coastguard Worker {
2628*3ac0a46fSAndroid Build Coastguard Worker uint64_t *m;
2629*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2630*3ac0a46fSAndroid Build Coastguard Worker m = (uint64_t *)origdata;
2631*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2632*3ac0a46fSAndroid Build Coastguard Worker {
2633*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2634*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(m);
2635*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckRangeSlong8Long8(*m);
2636*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
2637*3ac0a46fSAndroid Build Coastguard Worker {
2638*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2639*3ac0a46fSAndroid Build Coastguard Worker return (err);
2640*3ac0a46fSAndroid Build Coastguard Worker }
2641*3ac0a46fSAndroid Build Coastguard Worker m++;
2642*3ac0a46fSAndroid Build Coastguard Worker }
2643*3ac0a46fSAndroid Build Coastguard Worker *value = (int64_t *)origdata;
2644*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2645*3ac0a46fSAndroid Build Coastguard Worker }
2646*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
2647*3ac0a46fSAndroid Build Coastguard Worker *value = (int64_t *)origdata;
2648*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2649*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong8((uint64_t *)(*value), count);
2650*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2651*3ac0a46fSAndroid Build Coastguard Worker }
2652*3ac0a46fSAndroid Build Coastguard Worker data = (int64_t *)_TIFFmallocExt(tif, count * 8);
2653*3ac0a46fSAndroid Build Coastguard Worker if (data == 0)
2654*3ac0a46fSAndroid Build Coastguard Worker {
2655*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2656*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrAlloc);
2657*3ac0a46fSAndroid Build Coastguard Worker }
2658*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2659*3ac0a46fSAndroid Build Coastguard Worker {
2660*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
2661*3ac0a46fSAndroid Build Coastguard Worker {
2662*3ac0a46fSAndroid Build Coastguard Worker uint8_t *ma;
2663*3ac0a46fSAndroid Build Coastguard Worker int64_t *mb;
2664*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2665*3ac0a46fSAndroid Build Coastguard Worker ma = (uint8_t *)origdata;
2666*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2667*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2668*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int64_t)(*ma++);
2669*3ac0a46fSAndroid Build Coastguard Worker }
2670*3ac0a46fSAndroid Build Coastguard Worker break;
2671*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
2672*3ac0a46fSAndroid Build Coastguard Worker {
2673*3ac0a46fSAndroid Build Coastguard Worker int8_t *ma;
2674*3ac0a46fSAndroid Build Coastguard Worker int64_t *mb;
2675*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2676*3ac0a46fSAndroid Build Coastguard Worker ma = (int8_t *)origdata;
2677*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2678*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2679*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int64_t)(*ma++);
2680*3ac0a46fSAndroid Build Coastguard Worker }
2681*3ac0a46fSAndroid Build Coastguard Worker break;
2682*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
2683*3ac0a46fSAndroid Build Coastguard Worker {
2684*3ac0a46fSAndroid Build Coastguard Worker uint16_t *ma;
2685*3ac0a46fSAndroid Build Coastguard Worker int64_t *mb;
2686*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2687*3ac0a46fSAndroid Build Coastguard Worker ma = (uint16_t *)origdata;
2688*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2689*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2690*3ac0a46fSAndroid Build Coastguard Worker {
2691*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2692*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(ma);
2693*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int64_t)(*ma++);
2694*3ac0a46fSAndroid Build Coastguard Worker }
2695*3ac0a46fSAndroid Build Coastguard Worker }
2696*3ac0a46fSAndroid Build Coastguard Worker break;
2697*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
2698*3ac0a46fSAndroid Build Coastguard Worker {
2699*3ac0a46fSAndroid Build Coastguard Worker int16_t *ma;
2700*3ac0a46fSAndroid Build Coastguard Worker int64_t *mb;
2701*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2702*3ac0a46fSAndroid Build Coastguard Worker ma = (int16_t *)origdata;
2703*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2704*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2705*3ac0a46fSAndroid Build Coastguard Worker {
2706*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2707*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)ma);
2708*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int64_t)(*ma++);
2709*3ac0a46fSAndroid Build Coastguard Worker }
2710*3ac0a46fSAndroid Build Coastguard Worker }
2711*3ac0a46fSAndroid Build Coastguard Worker break;
2712*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
2713*3ac0a46fSAndroid Build Coastguard Worker {
2714*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
2715*3ac0a46fSAndroid Build Coastguard Worker int64_t *mb;
2716*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2717*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
2718*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2719*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2720*3ac0a46fSAndroid Build Coastguard Worker {
2721*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2722*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
2723*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int64_t)(*ma++);
2724*3ac0a46fSAndroid Build Coastguard Worker }
2725*3ac0a46fSAndroid Build Coastguard Worker }
2726*3ac0a46fSAndroid Build Coastguard Worker break;
2727*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
2728*3ac0a46fSAndroid Build Coastguard Worker {
2729*3ac0a46fSAndroid Build Coastguard Worker int32_t *ma;
2730*3ac0a46fSAndroid Build Coastguard Worker int64_t *mb;
2731*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2732*3ac0a46fSAndroid Build Coastguard Worker ma = (int32_t *)origdata;
2733*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2734*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2735*3ac0a46fSAndroid Build Coastguard Worker {
2736*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2737*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)ma);
2738*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (int64_t)(*ma++);
2739*3ac0a46fSAndroid Build Coastguard Worker }
2740*3ac0a46fSAndroid Build Coastguard Worker }
2741*3ac0a46fSAndroid Build Coastguard Worker break;
2742*3ac0a46fSAndroid Build Coastguard Worker }
2743*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2744*3ac0a46fSAndroid Build Coastguard Worker *value = data;
2745*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2746*3ac0a46fSAndroid Build Coastguard Worker }
2747*3ac0a46fSAndroid Build Coastguard Worker
2748*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryFloatArray(TIFF * tif,TIFFDirEntry * direntry,float ** value)2749*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value)
2750*3ac0a46fSAndroid Build Coastguard Worker {
2751*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
2752*3ac0a46fSAndroid Build Coastguard Worker uint32_t count;
2753*3ac0a46fSAndroid Build Coastguard Worker void *origdata;
2754*3ac0a46fSAndroid Build Coastguard Worker float *data;
2755*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2756*3ac0a46fSAndroid Build Coastguard Worker {
2757*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
2758*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
2759*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
2760*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
2761*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
2762*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
2763*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
2764*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
2765*3ac0a46fSAndroid Build Coastguard Worker case TIFF_RATIONAL:
2766*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SRATIONAL:
2767*3ac0a46fSAndroid Build Coastguard Worker case TIFF_FLOAT:
2768*3ac0a46fSAndroid Build Coastguard Worker case TIFF_DOUBLE:
2769*3ac0a46fSAndroid Build Coastguard Worker break;
2770*3ac0a46fSAndroid Build Coastguard Worker default:
2771*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
2772*3ac0a46fSAndroid Build Coastguard Worker }
2773*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata);
2774*3ac0a46fSAndroid Build Coastguard Worker if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
2775*3ac0a46fSAndroid Build Coastguard Worker {
2776*3ac0a46fSAndroid Build Coastguard Worker *value = 0;
2777*3ac0a46fSAndroid Build Coastguard Worker return (err);
2778*3ac0a46fSAndroid Build Coastguard Worker }
2779*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2780*3ac0a46fSAndroid Build Coastguard Worker {
2781*3ac0a46fSAndroid Build Coastguard Worker case TIFF_FLOAT:
2782*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2783*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong((uint32_t *)origdata, count);
2784*3ac0a46fSAndroid Build Coastguard Worker TIFFCvtIEEEDoubleToNative(tif, count, (float *)origdata);
2785*3ac0a46fSAndroid Build Coastguard Worker *value = (float *)origdata;
2786*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2787*3ac0a46fSAndroid Build Coastguard Worker }
2788*3ac0a46fSAndroid Build Coastguard Worker data = (float *)_TIFFmallocExt(tif, count * sizeof(float));
2789*3ac0a46fSAndroid Build Coastguard Worker if (data == 0)
2790*3ac0a46fSAndroid Build Coastguard Worker {
2791*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2792*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrAlloc);
2793*3ac0a46fSAndroid Build Coastguard Worker }
2794*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
2795*3ac0a46fSAndroid Build Coastguard Worker {
2796*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
2797*3ac0a46fSAndroid Build Coastguard Worker {
2798*3ac0a46fSAndroid Build Coastguard Worker uint8_t *ma;
2799*3ac0a46fSAndroid Build Coastguard Worker float *mb;
2800*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2801*3ac0a46fSAndroid Build Coastguard Worker ma = (uint8_t *)origdata;
2802*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2803*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2804*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (float)(*ma++);
2805*3ac0a46fSAndroid Build Coastguard Worker }
2806*3ac0a46fSAndroid Build Coastguard Worker break;
2807*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
2808*3ac0a46fSAndroid Build Coastguard Worker {
2809*3ac0a46fSAndroid Build Coastguard Worker int8_t *ma;
2810*3ac0a46fSAndroid Build Coastguard Worker float *mb;
2811*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2812*3ac0a46fSAndroid Build Coastguard Worker ma = (int8_t *)origdata;
2813*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2814*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2815*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (float)(*ma++);
2816*3ac0a46fSAndroid Build Coastguard Worker }
2817*3ac0a46fSAndroid Build Coastguard Worker break;
2818*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
2819*3ac0a46fSAndroid Build Coastguard Worker {
2820*3ac0a46fSAndroid Build Coastguard Worker uint16_t *ma;
2821*3ac0a46fSAndroid Build Coastguard Worker float *mb;
2822*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2823*3ac0a46fSAndroid Build Coastguard Worker ma = (uint16_t *)origdata;
2824*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2825*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2826*3ac0a46fSAndroid Build Coastguard Worker {
2827*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2828*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(ma);
2829*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (float)(*ma++);
2830*3ac0a46fSAndroid Build Coastguard Worker }
2831*3ac0a46fSAndroid Build Coastguard Worker }
2832*3ac0a46fSAndroid Build Coastguard Worker break;
2833*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
2834*3ac0a46fSAndroid Build Coastguard Worker {
2835*3ac0a46fSAndroid Build Coastguard Worker int16_t *ma;
2836*3ac0a46fSAndroid Build Coastguard Worker float *mb;
2837*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2838*3ac0a46fSAndroid Build Coastguard Worker ma = (int16_t *)origdata;
2839*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2840*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2841*3ac0a46fSAndroid Build Coastguard Worker {
2842*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2843*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)ma);
2844*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (float)(*ma++);
2845*3ac0a46fSAndroid Build Coastguard Worker }
2846*3ac0a46fSAndroid Build Coastguard Worker }
2847*3ac0a46fSAndroid Build Coastguard Worker break;
2848*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
2849*3ac0a46fSAndroid Build Coastguard Worker {
2850*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
2851*3ac0a46fSAndroid Build Coastguard Worker float *mb;
2852*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2853*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
2854*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2855*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2856*3ac0a46fSAndroid Build Coastguard Worker {
2857*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2858*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
2859*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (float)(*ma++);
2860*3ac0a46fSAndroid Build Coastguard Worker }
2861*3ac0a46fSAndroid Build Coastguard Worker }
2862*3ac0a46fSAndroid Build Coastguard Worker break;
2863*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
2864*3ac0a46fSAndroid Build Coastguard Worker {
2865*3ac0a46fSAndroid Build Coastguard Worker int32_t *ma;
2866*3ac0a46fSAndroid Build Coastguard Worker float *mb;
2867*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2868*3ac0a46fSAndroid Build Coastguard Worker ma = (int32_t *)origdata;
2869*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2870*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2871*3ac0a46fSAndroid Build Coastguard Worker {
2872*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2873*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)ma);
2874*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (float)(*ma++);
2875*3ac0a46fSAndroid Build Coastguard Worker }
2876*3ac0a46fSAndroid Build Coastguard Worker }
2877*3ac0a46fSAndroid Build Coastguard Worker break;
2878*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
2879*3ac0a46fSAndroid Build Coastguard Worker {
2880*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ma;
2881*3ac0a46fSAndroid Build Coastguard Worker float *mb;
2882*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2883*3ac0a46fSAndroid Build Coastguard Worker ma = (uint64_t *)origdata;
2884*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2885*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2886*3ac0a46fSAndroid Build Coastguard Worker {
2887*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2888*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(ma);
2889*3ac0a46fSAndroid Build Coastguard Worker #if defined(__WIN32__) && (_MSC_VER < 1500)
2890*3ac0a46fSAndroid Build Coastguard Worker /*
2891*3ac0a46fSAndroid Build Coastguard Worker * XXX: MSVC 6.0 does not support
2892*3ac0a46fSAndroid Build Coastguard Worker * conversion of 64-bit integers into
2893*3ac0a46fSAndroid Build Coastguard Worker * floating point values.
2894*3ac0a46fSAndroid Build Coastguard Worker */
2895*3ac0a46fSAndroid Build Coastguard Worker *mb++ = _TIFFUInt64ToFloat(*ma++);
2896*3ac0a46fSAndroid Build Coastguard Worker #else
2897*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (float)(*ma++);
2898*3ac0a46fSAndroid Build Coastguard Worker #endif
2899*3ac0a46fSAndroid Build Coastguard Worker }
2900*3ac0a46fSAndroid Build Coastguard Worker }
2901*3ac0a46fSAndroid Build Coastguard Worker break;
2902*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
2903*3ac0a46fSAndroid Build Coastguard Worker {
2904*3ac0a46fSAndroid Build Coastguard Worker int64_t *ma;
2905*3ac0a46fSAndroid Build Coastguard Worker float *mb;
2906*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2907*3ac0a46fSAndroid Build Coastguard Worker ma = (int64_t *)origdata;
2908*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2909*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2910*3ac0a46fSAndroid Build Coastguard Worker {
2911*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2912*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)ma);
2913*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (float)(*ma++);
2914*3ac0a46fSAndroid Build Coastguard Worker }
2915*3ac0a46fSAndroid Build Coastguard Worker }
2916*3ac0a46fSAndroid Build Coastguard Worker break;
2917*3ac0a46fSAndroid Build Coastguard Worker case TIFF_RATIONAL:
2918*3ac0a46fSAndroid Build Coastguard Worker {
2919*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
2920*3ac0a46fSAndroid Build Coastguard Worker uint32_t maa;
2921*3ac0a46fSAndroid Build Coastguard Worker uint32_t mab;
2922*3ac0a46fSAndroid Build Coastguard Worker float *mb;
2923*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2924*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
2925*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2926*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2927*3ac0a46fSAndroid Build Coastguard Worker {
2928*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2929*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
2930*3ac0a46fSAndroid Build Coastguard Worker maa = *ma++;
2931*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2932*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
2933*3ac0a46fSAndroid Build Coastguard Worker mab = *ma++;
2934*3ac0a46fSAndroid Build Coastguard Worker if (mab == 0)
2935*3ac0a46fSAndroid Build Coastguard Worker *mb++ = 0.0;
2936*3ac0a46fSAndroid Build Coastguard Worker else
2937*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (float)maa / (float)mab;
2938*3ac0a46fSAndroid Build Coastguard Worker }
2939*3ac0a46fSAndroid Build Coastguard Worker }
2940*3ac0a46fSAndroid Build Coastguard Worker break;
2941*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SRATIONAL:
2942*3ac0a46fSAndroid Build Coastguard Worker {
2943*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
2944*3ac0a46fSAndroid Build Coastguard Worker int32_t maa;
2945*3ac0a46fSAndroid Build Coastguard Worker uint32_t mab;
2946*3ac0a46fSAndroid Build Coastguard Worker float *mb;
2947*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2948*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
2949*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2950*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2951*3ac0a46fSAndroid Build Coastguard Worker {
2952*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2953*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
2954*3ac0a46fSAndroid Build Coastguard Worker maa = *(int32_t *)ma;
2955*3ac0a46fSAndroid Build Coastguard Worker ma++;
2956*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2957*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
2958*3ac0a46fSAndroid Build Coastguard Worker mab = *ma++;
2959*3ac0a46fSAndroid Build Coastguard Worker if (mab == 0)
2960*3ac0a46fSAndroid Build Coastguard Worker *mb++ = 0.0;
2961*3ac0a46fSAndroid Build Coastguard Worker else
2962*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (float)maa / (float)mab;
2963*3ac0a46fSAndroid Build Coastguard Worker }
2964*3ac0a46fSAndroid Build Coastguard Worker }
2965*3ac0a46fSAndroid Build Coastguard Worker break;
2966*3ac0a46fSAndroid Build Coastguard Worker case TIFF_DOUBLE:
2967*3ac0a46fSAndroid Build Coastguard Worker {
2968*3ac0a46fSAndroid Build Coastguard Worker double *ma;
2969*3ac0a46fSAndroid Build Coastguard Worker float *mb;
2970*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2971*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2972*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong8((uint64_t *)origdata, count);
2973*3ac0a46fSAndroid Build Coastguard Worker TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata);
2974*3ac0a46fSAndroid Build Coastguard Worker ma = (double *)origdata;
2975*3ac0a46fSAndroid Build Coastguard Worker mb = data;
2976*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
2977*3ac0a46fSAndroid Build Coastguard Worker {
2978*3ac0a46fSAndroid Build Coastguard Worker double val = *ma++;
2979*3ac0a46fSAndroid Build Coastguard Worker if (val > FLT_MAX)
2980*3ac0a46fSAndroid Build Coastguard Worker val = FLT_MAX;
2981*3ac0a46fSAndroid Build Coastguard Worker else if (val < -FLT_MAX)
2982*3ac0a46fSAndroid Build Coastguard Worker val = -FLT_MAX;
2983*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (float)val;
2984*3ac0a46fSAndroid Build Coastguard Worker }
2985*3ac0a46fSAndroid Build Coastguard Worker }
2986*3ac0a46fSAndroid Build Coastguard Worker break;
2987*3ac0a46fSAndroid Build Coastguard Worker }
2988*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
2989*3ac0a46fSAndroid Build Coastguard Worker *value = data;
2990*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
2991*3ac0a46fSAndroid Build Coastguard Worker }
2992*3ac0a46fSAndroid Build Coastguard Worker
2993*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryDoubleArray(TIFF * tif,TIFFDirEntry * direntry,double ** value)2994*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value)
2995*3ac0a46fSAndroid Build Coastguard Worker {
2996*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
2997*3ac0a46fSAndroid Build Coastguard Worker uint32_t count;
2998*3ac0a46fSAndroid Build Coastguard Worker void *origdata;
2999*3ac0a46fSAndroid Build Coastguard Worker double *data;
3000*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
3001*3ac0a46fSAndroid Build Coastguard Worker {
3002*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
3003*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
3004*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
3005*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
3006*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
3007*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
3008*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
3009*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
3010*3ac0a46fSAndroid Build Coastguard Worker case TIFF_RATIONAL:
3011*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SRATIONAL:
3012*3ac0a46fSAndroid Build Coastguard Worker case TIFF_FLOAT:
3013*3ac0a46fSAndroid Build Coastguard Worker case TIFF_DOUBLE:
3014*3ac0a46fSAndroid Build Coastguard Worker break;
3015*3ac0a46fSAndroid Build Coastguard Worker default:
3016*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
3017*3ac0a46fSAndroid Build Coastguard Worker }
3018*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata);
3019*3ac0a46fSAndroid Build Coastguard Worker if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
3020*3ac0a46fSAndroid Build Coastguard Worker {
3021*3ac0a46fSAndroid Build Coastguard Worker *value = 0;
3022*3ac0a46fSAndroid Build Coastguard Worker return (err);
3023*3ac0a46fSAndroid Build Coastguard Worker }
3024*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
3025*3ac0a46fSAndroid Build Coastguard Worker {
3026*3ac0a46fSAndroid Build Coastguard Worker case TIFF_DOUBLE:
3027*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3028*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong8((uint64_t *)origdata, count);
3029*3ac0a46fSAndroid Build Coastguard Worker TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata);
3030*3ac0a46fSAndroid Build Coastguard Worker *value = (double *)origdata;
3031*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3032*3ac0a46fSAndroid Build Coastguard Worker }
3033*3ac0a46fSAndroid Build Coastguard Worker data = (double *)_TIFFmallocExt(tif, count * sizeof(double));
3034*3ac0a46fSAndroid Build Coastguard Worker if (data == 0)
3035*3ac0a46fSAndroid Build Coastguard Worker {
3036*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
3037*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrAlloc);
3038*3ac0a46fSAndroid Build Coastguard Worker }
3039*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
3040*3ac0a46fSAndroid Build Coastguard Worker {
3041*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
3042*3ac0a46fSAndroid Build Coastguard Worker {
3043*3ac0a46fSAndroid Build Coastguard Worker uint8_t *ma;
3044*3ac0a46fSAndroid Build Coastguard Worker double *mb;
3045*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
3046*3ac0a46fSAndroid Build Coastguard Worker ma = (uint8_t *)origdata;
3047*3ac0a46fSAndroid Build Coastguard Worker mb = data;
3048*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
3049*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (double)(*ma++);
3050*3ac0a46fSAndroid Build Coastguard Worker }
3051*3ac0a46fSAndroid Build Coastguard Worker break;
3052*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
3053*3ac0a46fSAndroid Build Coastguard Worker {
3054*3ac0a46fSAndroid Build Coastguard Worker int8_t *ma;
3055*3ac0a46fSAndroid Build Coastguard Worker double *mb;
3056*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
3057*3ac0a46fSAndroid Build Coastguard Worker ma = (int8_t *)origdata;
3058*3ac0a46fSAndroid Build Coastguard Worker mb = data;
3059*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
3060*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (double)(*ma++);
3061*3ac0a46fSAndroid Build Coastguard Worker }
3062*3ac0a46fSAndroid Build Coastguard Worker break;
3063*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
3064*3ac0a46fSAndroid Build Coastguard Worker {
3065*3ac0a46fSAndroid Build Coastguard Worker uint16_t *ma;
3066*3ac0a46fSAndroid Build Coastguard Worker double *mb;
3067*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
3068*3ac0a46fSAndroid Build Coastguard Worker ma = (uint16_t *)origdata;
3069*3ac0a46fSAndroid Build Coastguard Worker mb = data;
3070*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
3071*3ac0a46fSAndroid Build Coastguard Worker {
3072*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3073*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(ma);
3074*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (double)(*ma++);
3075*3ac0a46fSAndroid Build Coastguard Worker }
3076*3ac0a46fSAndroid Build Coastguard Worker }
3077*3ac0a46fSAndroid Build Coastguard Worker break;
3078*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
3079*3ac0a46fSAndroid Build Coastguard Worker {
3080*3ac0a46fSAndroid Build Coastguard Worker int16_t *ma;
3081*3ac0a46fSAndroid Build Coastguard Worker double *mb;
3082*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
3083*3ac0a46fSAndroid Build Coastguard Worker ma = (int16_t *)origdata;
3084*3ac0a46fSAndroid Build Coastguard Worker mb = data;
3085*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
3086*3ac0a46fSAndroid Build Coastguard Worker {
3087*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3088*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)ma);
3089*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (double)(*ma++);
3090*3ac0a46fSAndroid Build Coastguard Worker }
3091*3ac0a46fSAndroid Build Coastguard Worker }
3092*3ac0a46fSAndroid Build Coastguard Worker break;
3093*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
3094*3ac0a46fSAndroid Build Coastguard Worker {
3095*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
3096*3ac0a46fSAndroid Build Coastguard Worker double *mb;
3097*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
3098*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
3099*3ac0a46fSAndroid Build Coastguard Worker mb = data;
3100*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
3101*3ac0a46fSAndroid Build Coastguard Worker {
3102*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3103*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
3104*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (double)(*ma++);
3105*3ac0a46fSAndroid Build Coastguard Worker }
3106*3ac0a46fSAndroid Build Coastguard Worker }
3107*3ac0a46fSAndroid Build Coastguard Worker break;
3108*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
3109*3ac0a46fSAndroid Build Coastguard Worker {
3110*3ac0a46fSAndroid Build Coastguard Worker int32_t *ma;
3111*3ac0a46fSAndroid Build Coastguard Worker double *mb;
3112*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
3113*3ac0a46fSAndroid Build Coastguard Worker ma = (int32_t *)origdata;
3114*3ac0a46fSAndroid Build Coastguard Worker mb = data;
3115*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
3116*3ac0a46fSAndroid Build Coastguard Worker {
3117*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3118*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)ma);
3119*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (double)(*ma++);
3120*3ac0a46fSAndroid Build Coastguard Worker }
3121*3ac0a46fSAndroid Build Coastguard Worker }
3122*3ac0a46fSAndroid Build Coastguard Worker break;
3123*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
3124*3ac0a46fSAndroid Build Coastguard Worker {
3125*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ma;
3126*3ac0a46fSAndroid Build Coastguard Worker double *mb;
3127*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
3128*3ac0a46fSAndroid Build Coastguard Worker ma = (uint64_t *)origdata;
3129*3ac0a46fSAndroid Build Coastguard Worker mb = data;
3130*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
3131*3ac0a46fSAndroid Build Coastguard Worker {
3132*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3133*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(ma);
3134*3ac0a46fSAndroid Build Coastguard Worker #if defined(__WIN32__) && (_MSC_VER < 1500)
3135*3ac0a46fSAndroid Build Coastguard Worker /*
3136*3ac0a46fSAndroid Build Coastguard Worker * XXX: MSVC 6.0 does not support
3137*3ac0a46fSAndroid Build Coastguard Worker * conversion of 64-bit integers into
3138*3ac0a46fSAndroid Build Coastguard Worker * floating point values.
3139*3ac0a46fSAndroid Build Coastguard Worker */
3140*3ac0a46fSAndroid Build Coastguard Worker *mb++ = _TIFFUInt64ToDouble(*ma++);
3141*3ac0a46fSAndroid Build Coastguard Worker #else
3142*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (double)(*ma++);
3143*3ac0a46fSAndroid Build Coastguard Worker #endif
3144*3ac0a46fSAndroid Build Coastguard Worker }
3145*3ac0a46fSAndroid Build Coastguard Worker }
3146*3ac0a46fSAndroid Build Coastguard Worker break;
3147*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
3148*3ac0a46fSAndroid Build Coastguard Worker {
3149*3ac0a46fSAndroid Build Coastguard Worker int64_t *ma;
3150*3ac0a46fSAndroid Build Coastguard Worker double *mb;
3151*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
3152*3ac0a46fSAndroid Build Coastguard Worker ma = (int64_t *)origdata;
3153*3ac0a46fSAndroid Build Coastguard Worker mb = data;
3154*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
3155*3ac0a46fSAndroid Build Coastguard Worker {
3156*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3157*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)ma);
3158*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (double)(*ma++);
3159*3ac0a46fSAndroid Build Coastguard Worker }
3160*3ac0a46fSAndroid Build Coastguard Worker }
3161*3ac0a46fSAndroid Build Coastguard Worker break;
3162*3ac0a46fSAndroid Build Coastguard Worker case TIFF_RATIONAL:
3163*3ac0a46fSAndroid Build Coastguard Worker {
3164*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
3165*3ac0a46fSAndroid Build Coastguard Worker uint32_t maa;
3166*3ac0a46fSAndroid Build Coastguard Worker uint32_t mab;
3167*3ac0a46fSAndroid Build Coastguard Worker double *mb;
3168*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
3169*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
3170*3ac0a46fSAndroid Build Coastguard Worker mb = data;
3171*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
3172*3ac0a46fSAndroid Build Coastguard Worker {
3173*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3174*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
3175*3ac0a46fSAndroid Build Coastguard Worker maa = *ma++;
3176*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3177*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
3178*3ac0a46fSAndroid Build Coastguard Worker mab = *ma++;
3179*3ac0a46fSAndroid Build Coastguard Worker if (mab == 0)
3180*3ac0a46fSAndroid Build Coastguard Worker *mb++ = 0.0;
3181*3ac0a46fSAndroid Build Coastguard Worker else
3182*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (double)maa / (double)mab;
3183*3ac0a46fSAndroid Build Coastguard Worker }
3184*3ac0a46fSAndroid Build Coastguard Worker }
3185*3ac0a46fSAndroid Build Coastguard Worker break;
3186*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SRATIONAL:
3187*3ac0a46fSAndroid Build Coastguard Worker {
3188*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
3189*3ac0a46fSAndroid Build Coastguard Worker int32_t maa;
3190*3ac0a46fSAndroid Build Coastguard Worker uint32_t mab;
3191*3ac0a46fSAndroid Build Coastguard Worker double *mb;
3192*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
3193*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
3194*3ac0a46fSAndroid Build Coastguard Worker mb = data;
3195*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
3196*3ac0a46fSAndroid Build Coastguard Worker {
3197*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3198*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
3199*3ac0a46fSAndroid Build Coastguard Worker maa = *(int32_t *)ma;
3200*3ac0a46fSAndroid Build Coastguard Worker ma++;
3201*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3202*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
3203*3ac0a46fSAndroid Build Coastguard Worker mab = *ma++;
3204*3ac0a46fSAndroid Build Coastguard Worker if (mab == 0)
3205*3ac0a46fSAndroid Build Coastguard Worker *mb++ = 0.0;
3206*3ac0a46fSAndroid Build Coastguard Worker else
3207*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (double)maa / (double)mab;
3208*3ac0a46fSAndroid Build Coastguard Worker }
3209*3ac0a46fSAndroid Build Coastguard Worker }
3210*3ac0a46fSAndroid Build Coastguard Worker break;
3211*3ac0a46fSAndroid Build Coastguard Worker case TIFF_FLOAT:
3212*3ac0a46fSAndroid Build Coastguard Worker {
3213*3ac0a46fSAndroid Build Coastguard Worker float *ma;
3214*3ac0a46fSAndroid Build Coastguard Worker double *mb;
3215*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
3216*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3217*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong((uint32_t *)origdata, count);
3218*3ac0a46fSAndroid Build Coastguard Worker TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata);
3219*3ac0a46fSAndroid Build Coastguard Worker ma = (float *)origdata;
3220*3ac0a46fSAndroid Build Coastguard Worker mb = data;
3221*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
3222*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (double)(*ma++);
3223*3ac0a46fSAndroid Build Coastguard Worker }
3224*3ac0a46fSAndroid Build Coastguard Worker break;
3225*3ac0a46fSAndroid Build Coastguard Worker }
3226*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
3227*3ac0a46fSAndroid Build Coastguard Worker *value = data;
3228*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3229*3ac0a46fSAndroid Build Coastguard Worker }
3230*3ac0a46fSAndroid Build Coastguard Worker
3231*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryIfd8Array(TIFF * tif,TIFFDirEntry * direntry,uint64_t ** value)3232*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value)
3233*3ac0a46fSAndroid Build Coastguard Worker {
3234*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
3235*3ac0a46fSAndroid Build Coastguard Worker uint32_t count;
3236*3ac0a46fSAndroid Build Coastguard Worker void *origdata;
3237*3ac0a46fSAndroid Build Coastguard Worker uint64_t *data;
3238*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
3239*3ac0a46fSAndroid Build Coastguard Worker {
3240*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
3241*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
3242*3ac0a46fSAndroid Build Coastguard Worker case TIFF_IFD:
3243*3ac0a46fSAndroid Build Coastguard Worker case TIFF_IFD8:
3244*3ac0a46fSAndroid Build Coastguard Worker break;
3245*3ac0a46fSAndroid Build Coastguard Worker default:
3246*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
3247*3ac0a46fSAndroid Build Coastguard Worker }
3248*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata);
3249*3ac0a46fSAndroid Build Coastguard Worker if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
3250*3ac0a46fSAndroid Build Coastguard Worker {
3251*3ac0a46fSAndroid Build Coastguard Worker *value = 0;
3252*3ac0a46fSAndroid Build Coastguard Worker return (err);
3253*3ac0a46fSAndroid Build Coastguard Worker }
3254*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
3255*3ac0a46fSAndroid Build Coastguard Worker {
3256*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
3257*3ac0a46fSAndroid Build Coastguard Worker case TIFF_IFD8:
3258*3ac0a46fSAndroid Build Coastguard Worker *value = (uint64_t *)origdata;
3259*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3260*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong8(*value, count);
3261*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3262*3ac0a46fSAndroid Build Coastguard Worker }
3263*3ac0a46fSAndroid Build Coastguard Worker data = (uint64_t *)_TIFFmallocExt(tif, count * 8);
3264*3ac0a46fSAndroid Build Coastguard Worker if (data == 0)
3265*3ac0a46fSAndroid Build Coastguard Worker {
3266*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
3267*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrAlloc);
3268*3ac0a46fSAndroid Build Coastguard Worker }
3269*3ac0a46fSAndroid Build Coastguard Worker switch (direntry->tdir_type)
3270*3ac0a46fSAndroid Build Coastguard Worker {
3271*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
3272*3ac0a46fSAndroid Build Coastguard Worker case TIFF_IFD:
3273*3ac0a46fSAndroid Build Coastguard Worker {
3274*3ac0a46fSAndroid Build Coastguard Worker uint32_t *ma;
3275*3ac0a46fSAndroid Build Coastguard Worker uint64_t *mb;
3276*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
3277*3ac0a46fSAndroid Build Coastguard Worker ma = (uint32_t *)origdata;
3278*3ac0a46fSAndroid Build Coastguard Worker mb = data;
3279*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < count; n++)
3280*3ac0a46fSAndroid Build Coastguard Worker {
3281*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3282*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(ma);
3283*3ac0a46fSAndroid Build Coastguard Worker *mb++ = (uint64_t)(*ma++);
3284*3ac0a46fSAndroid Build Coastguard Worker }
3285*3ac0a46fSAndroid Build Coastguard Worker }
3286*3ac0a46fSAndroid Build Coastguard Worker break;
3287*3ac0a46fSAndroid Build Coastguard Worker }
3288*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdata);
3289*3ac0a46fSAndroid Build Coastguard Worker *value = data;
3290*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3291*3ac0a46fSAndroid Build Coastguard Worker }
3292*3ac0a46fSAndroid Build Coastguard Worker
3293*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryPersampleShort(TIFF * tif,TIFFDirEntry * direntry,uint16_t * value)3294*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry,
3295*3ac0a46fSAndroid Build Coastguard Worker uint16_t *value)
3296*3ac0a46fSAndroid Build Coastguard Worker {
3297*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
3298*3ac0a46fSAndroid Build Coastguard Worker uint16_t *m;
3299*3ac0a46fSAndroid Build Coastguard Worker uint16_t *na;
3300*3ac0a46fSAndroid Build Coastguard Worker uint16_t nb;
3301*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count < (uint64_t)tif->tif_dir.td_samplesperpixel)
3302*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
3303*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryShortArray(tif, direntry, &m);
3304*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk || m == NULL)
3305*3ac0a46fSAndroid Build Coastguard Worker return (err);
3306*3ac0a46fSAndroid Build Coastguard Worker na = m;
3307*3ac0a46fSAndroid Build Coastguard Worker nb = tif->tif_dir.td_samplesperpixel;
3308*3ac0a46fSAndroid Build Coastguard Worker *value = *na++;
3309*3ac0a46fSAndroid Build Coastguard Worker nb--;
3310*3ac0a46fSAndroid Build Coastguard Worker while (nb > 0)
3311*3ac0a46fSAndroid Build Coastguard Worker {
3312*3ac0a46fSAndroid Build Coastguard Worker if (*na++ != *value)
3313*3ac0a46fSAndroid Build Coastguard Worker {
3314*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrPsdif;
3315*3ac0a46fSAndroid Build Coastguard Worker break;
3316*3ac0a46fSAndroid Build Coastguard Worker }
3317*3ac0a46fSAndroid Build Coastguard Worker nb--;
3318*3ac0a46fSAndroid Build Coastguard Worker }
3319*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, m);
3320*3ac0a46fSAndroid Build Coastguard Worker return (err);
3321*3ac0a46fSAndroid Build Coastguard Worker }
3322*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirEntryCheckedByte(TIFF * tif,TIFFDirEntry * direntry,uint8_t * value)3323*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry,
3324*3ac0a46fSAndroid Build Coastguard Worker uint8_t *value)
3325*3ac0a46fSAndroid Build Coastguard Worker {
3326*3ac0a46fSAndroid Build Coastguard Worker (void)tif;
3327*3ac0a46fSAndroid Build Coastguard Worker *value = *(uint8_t *)(&direntry->tdir_offset);
3328*3ac0a46fSAndroid Build Coastguard Worker }
3329*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirEntryCheckedSbyte(TIFF * tif,TIFFDirEntry * direntry,int8_t * value)3330*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry,
3331*3ac0a46fSAndroid Build Coastguard Worker int8_t *value)
3332*3ac0a46fSAndroid Build Coastguard Worker {
3333*3ac0a46fSAndroid Build Coastguard Worker (void)tif;
3334*3ac0a46fSAndroid Build Coastguard Worker *value = *(int8_t *)(&direntry->tdir_offset);
3335*3ac0a46fSAndroid Build Coastguard Worker }
3336*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirEntryCheckedShort(TIFF * tif,TIFFDirEntry * direntry,uint16_t * value)3337*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry,
3338*3ac0a46fSAndroid Build Coastguard Worker uint16_t *value)
3339*3ac0a46fSAndroid Build Coastguard Worker {
3340*3ac0a46fSAndroid Build Coastguard Worker *value = direntry->tdir_offset.toff_short;
3341*3ac0a46fSAndroid Build Coastguard Worker /* *value=*(uint16_t*)(&direntry->tdir_offset); */
3342*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3343*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(value);
3344*3ac0a46fSAndroid Build Coastguard Worker }
3345*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirEntryCheckedSshort(TIFF * tif,TIFFDirEntry * direntry,int16_t * value)3346*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry,
3347*3ac0a46fSAndroid Build Coastguard Worker int16_t *value)
3348*3ac0a46fSAndroid Build Coastguard Worker {
3349*3ac0a46fSAndroid Build Coastguard Worker *value = *(int16_t *)(&direntry->tdir_offset);
3350*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3351*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)value);
3352*3ac0a46fSAndroid Build Coastguard Worker }
3353*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirEntryCheckedLong(TIFF * tif,TIFFDirEntry * direntry,uint32_t * value)3354*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry,
3355*3ac0a46fSAndroid Build Coastguard Worker uint32_t *value)
3356*3ac0a46fSAndroid Build Coastguard Worker {
3357*3ac0a46fSAndroid Build Coastguard Worker *value = *(uint32_t *)(&direntry->tdir_offset);
3358*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3359*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(value);
3360*3ac0a46fSAndroid Build Coastguard Worker }
3361*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirEntryCheckedSlong(TIFF * tif,TIFFDirEntry * direntry,int32_t * value)3362*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry,
3363*3ac0a46fSAndroid Build Coastguard Worker int32_t *value)
3364*3ac0a46fSAndroid Build Coastguard Worker {
3365*3ac0a46fSAndroid Build Coastguard Worker *value = *(int32_t *)(&direntry->tdir_offset);
3366*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3367*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)value);
3368*3ac0a46fSAndroid Build Coastguard Worker }
3369*3ac0a46fSAndroid Build Coastguard Worker
3370*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckedLong8(TIFF * tif,TIFFDirEntry * direntry,uint64_t * value)3371*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
3372*3ac0a46fSAndroid Build Coastguard Worker {
3373*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
3374*3ac0a46fSAndroid Build Coastguard Worker {
3375*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
3376*3ac0a46fSAndroid Build Coastguard Worker uint32_t offset = direntry->tdir_offset.toff_long;
3377*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3378*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&offset);
3379*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryData(tif, offset, 8, value);
3380*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
3381*3ac0a46fSAndroid Build Coastguard Worker return (err);
3382*3ac0a46fSAndroid Build Coastguard Worker }
3383*3ac0a46fSAndroid Build Coastguard Worker else
3384*3ac0a46fSAndroid Build Coastguard Worker *value = direntry->tdir_offset.toff_long8;
3385*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3386*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(value);
3387*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3388*3ac0a46fSAndroid Build Coastguard Worker }
3389*3ac0a46fSAndroid Build Coastguard Worker
3390*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckedSlong8(TIFF * tif,TIFFDirEntry * direntry,int64_t * value)3391*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value)
3392*3ac0a46fSAndroid Build Coastguard Worker {
3393*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
3394*3ac0a46fSAndroid Build Coastguard Worker {
3395*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
3396*3ac0a46fSAndroid Build Coastguard Worker uint32_t offset = direntry->tdir_offset.toff_long;
3397*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3398*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&offset);
3399*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryData(tif, offset, 8, value);
3400*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
3401*3ac0a46fSAndroid Build Coastguard Worker return (err);
3402*3ac0a46fSAndroid Build Coastguard Worker }
3403*3ac0a46fSAndroid Build Coastguard Worker else
3404*3ac0a46fSAndroid Build Coastguard Worker *value = *(int64_t *)(&direntry->tdir_offset);
3405*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3406*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)value);
3407*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3408*3ac0a46fSAndroid Build Coastguard Worker }
3409*3ac0a46fSAndroid Build Coastguard Worker
3410*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckedRational(TIFF * tif,TIFFDirEntry * direntry,double * value)3411*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry,
3412*3ac0a46fSAndroid Build Coastguard Worker double *value)
3413*3ac0a46fSAndroid Build Coastguard Worker {
3414*3ac0a46fSAndroid Build Coastguard Worker UInt64Aligned_t m;
3415*3ac0a46fSAndroid Build Coastguard Worker
3416*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(double) == 8);
3417*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint64_t) == 8);
3418*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint32_t) == 4);
3419*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
3420*3ac0a46fSAndroid Build Coastguard Worker {
3421*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
3422*3ac0a46fSAndroid Build Coastguard Worker uint32_t offset = direntry->tdir_offset.toff_long;
3423*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3424*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&offset);
3425*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryData(tif, offset, 8, m.i);
3426*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
3427*3ac0a46fSAndroid Build Coastguard Worker return (err);
3428*3ac0a46fSAndroid Build Coastguard Worker }
3429*3ac0a46fSAndroid Build Coastguard Worker else
3430*3ac0a46fSAndroid Build Coastguard Worker m.l = direntry->tdir_offset.toff_long8;
3431*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3432*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong(m.i, 2);
3433*3ac0a46fSAndroid Build Coastguard Worker /* Not completely sure what we should do when m.i[1]==0, but some */
3434*3ac0a46fSAndroid Build Coastguard Worker /* sanitizers do not like division by 0.0: */
3435*3ac0a46fSAndroid Build Coastguard Worker /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
3436*3ac0a46fSAndroid Build Coastguard Worker if (m.i[0] == 0 || m.i[1] == 0)
3437*3ac0a46fSAndroid Build Coastguard Worker *value = 0.0;
3438*3ac0a46fSAndroid Build Coastguard Worker else
3439*3ac0a46fSAndroid Build Coastguard Worker *value = (double)m.i[0] / (double)m.i[1];
3440*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3441*3ac0a46fSAndroid Build Coastguard Worker }
3442*3ac0a46fSAndroid Build Coastguard Worker
3443*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckedSrational(TIFF * tif,TIFFDirEntry * direntry,double * value)3444*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry,
3445*3ac0a46fSAndroid Build Coastguard Worker double *value)
3446*3ac0a46fSAndroid Build Coastguard Worker {
3447*3ac0a46fSAndroid Build Coastguard Worker UInt64Aligned_t m;
3448*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(double) == 8);
3449*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint64_t) == 8);
3450*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(int32_t) == 4);
3451*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint32_t) == 4);
3452*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
3453*3ac0a46fSAndroid Build Coastguard Worker {
3454*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
3455*3ac0a46fSAndroid Build Coastguard Worker uint32_t offset = direntry->tdir_offset.toff_long;
3456*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3457*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&offset);
3458*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryData(tif, offset, 8, m.i);
3459*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
3460*3ac0a46fSAndroid Build Coastguard Worker return (err);
3461*3ac0a46fSAndroid Build Coastguard Worker }
3462*3ac0a46fSAndroid Build Coastguard Worker else
3463*3ac0a46fSAndroid Build Coastguard Worker m.l = direntry->tdir_offset.toff_long8;
3464*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3465*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong(m.i, 2);
3466*3ac0a46fSAndroid Build Coastguard Worker /* Not completely sure what we should do when m.i[1]==0, but some */
3467*3ac0a46fSAndroid Build Coastguard Worker /* sanitizers do not like division by 0.0: */
3468*3ac0a46fSAndroid Build Coastguard Worker /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
3469*3ac0a46fSAndroid Build Coastguard Worker if ((int32_t)m.i[0] == 0 || m.i[1] == 0)
3470*3ac0a46fSAndroid Build Coastguard Worker *value = 0.0;
3471*3ac0a46fSAndroid Build Coastguard Worker else
3472*3ac0a46fSAndroid Build Coastguard Worker *value = (double)((int32_t)m.i[0]) / (double)m.i[1];
3473*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3474*3ac0a46fSAndroid Build Coastguard Worker }
3475*3ac0a46fSAndroid Build Coastguard Worker
3476*3ac0a46fSAndroid Build Coastguard Worker #if 0
3477*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
3478*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedRationalDirect(TIFF *tif, TIFFDirEntry *direntry,
3479*3ac0a46fSAndroid Build Coastguard Worker TIFFRational_t *value)
3480*3ac0a46fSAndroid Build Coastguard Worker { /*--: SetGetRATIONAL_directly:_CustomTag: Read rational (and signed rationals)
3481*3ac0a46fSAndroid Build Coastguard Worker directly --*/
3482*3ac0a46fSAndroid Build Coastguard Worker UInt64Aligned_t m;
3483*3ac0a46fSAndroid Build Coastguard Worker
3484*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(double) == 8);
3485*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint64_t) == 8);
3486*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint32_t) == 4);
3487*3ac0a46fSAndroid Build Coastguard Worker
3488*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_count != 1)
3489*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrCount);
3490*3ac0a46fSAndroid Build Coastguard Worker
3491*3ac0a46fSAndroid Build Coastguard Worker if (direntry->tdir_type != TIFF_RATIONAL &&
3492*3ac0a46fSAndroid Build Coastguard Worker direntry->tdir_type != TIFF_SRATIONAL)
3493*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrType);
3494*3ac0a46fSAndroid Build Coastguard Worker
3495*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
3496*3ac0a46fSAndroid Build Coastguard Worker {
3497*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
3498*3ac0a46fSAndroid Build Coastguard Worker uint32_t offset = direntry->tdir_offset.toff_long;
3499*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3500*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&offset);
3501*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryData(tif, offset, 8, m.i);
3502*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
3503*3ac0a46fSAndroid Build Coastguard Worker return (err);
3504*3ac0a46fSAndroid Build Coastguard Worker }
3505*3ac0a46fSAndroid Build Coastguard Worker else
3506*3ac0a46fSAndroid Build Coastguard Worker {
3507*3ac0a46fSAndroid Build Coastguard Worker m.l = direntry->tdir_offset.toff_long8;
3508*3ac0a46fSAndroid Build Coastguard Worker }
3509*3ac0a46fSAndroid Build Coastguard Worker
3510*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3511*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong(m.i, 2);
3512*3ac0a46fSAndroid Build Coastguard Worker
3513*3ac0a46fSAndroid Build Coastguard Worker value->uNum = m.i[0];
3514*3ac0a46fSAndroid Build Coastguard Worker value->uDenom = m.i[1];
3515*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3516*3ac0a46fSAndroid Build Coastguard Worker } /*-- TIFFReadDirEntryCheckedRationalDirect() --*/
3517*3ac0a46fSAndroid Build Coastguard Worker #endif
3518*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirEntryCheckedFloat(TIFF * tif,TIFFDirEntry * direntry,float * value)3519*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry,
3520*3ac0a46fSAndroid Build Coastguard Worker float *value)
3521*3ac0a46fSAndroid Build Coastguard Worker {
3522*3ac0a46fSAndroid Build Coastguard Worker union
3523*3ac0a46fSAndroid Build Coastguard Worker {
3524*3ac0a46fSAndroid Build Coastguard Worker float f;
3525*3ac0a46fSAndroid Build Coastguard Worker uint32_t i;
3526*3ac0a46fSAndroid Build Coastguard Worker } float_union;
3527*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(float) == 4);
3528*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint32_t) == 4);
3529*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(float_union) == 4);
3530*3ac0a46fSAndroid Build Coastguard Worker float_union.i = *(uint32_t *)(&direntry->tdir_offset);
3531*3ac0a46fSAndroid Build Coastguard Worker *value = float_union.f;
3532*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3533*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)value);
3534*3ac0a46fSAndroid Build Coastguard Worker }
3535*3ac0a46fSAndroid Build Coastguard Worker
3536*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckedDouble(TIFF * tif,TIFFDirEntry * direntry,double * value)3537*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value)
3538*3ac0a46fSAndroid Build Coastguard Worker {
3539*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(double) == 8);
3540*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint64_t) == 8);
3541*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(UInt64Aligned_t) == 8);
3542*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
3543*3ac0a46fSAndroid Build Coastguard Worker {
3544*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
3545*3ac0a46fSAndroid Build Coastguard Worker uint32_t offset = direntry->tdir_offset.toff_long;
3546*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3547*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&offset);
3548*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryData(tif, offset, 8, value);
3549*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
3550*3ac0a46fSAndroid Build Coastguard Worker return (err);
3551*3ac0a46fSAndroid Build Coastguard Worker }
3552*3ac0a46fSAndroid Build Coastguard Worker else
3553*3ac0a46fSAndroid Build Coastguard Worker {
3554*3ac0a46fSAndroid Build Coastguard Worker UInt64Aligned_t uint64_union;
3555*3ac0a46fSAndroid Build Coastguard Worker uint64_union.l = direntry->tdir_offset.toff_long8;
3556*3ac0a46fSAndroid Build Coastguard Worker *value = uint64_union.d;
3557*3ac0a46fSAndroid Build Coastguard Worker }
3558*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3559*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)value);
3560*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3561*3ac0a46fSAndroid Build Coastguard Worker }
3562*3ac0a46fSAndroid Build Coastguard Worker
3563*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteSbyte(int8_t value)3564*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteSbyte(int8_t value)
3565*3ac0a46fSAndroid Build Coastguard Worker {
3566*3ac0a46fSAndroid Build Coastguard Worker if (value < 0)
3567*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3568*3ac0a46fSAndroid Build Coastguard Worker else
3569*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3570*3ac0a46fSAndroid Build Coastguard Worker }
3571*3ac0a46fSAndroid Build Coastguard Worker
3572*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteShort(uint16_t value)3573*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteShort(uint16_t value)
3574*3ac0a46fSAndroid Build Coastguard Worker {
3575*3ac0a46fSAndroid Build Coastguard Worker if (value > 0xFF)
3576*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3577*3ac0a46fSAndroid Build Coastguard Worker else
3578*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3579*3ac0a46fSAndroid Build Coastguard Worker }
3580*3ac0a46fSAndroid Build Coastguard Worker
3581*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteSshort(int16_t value)3582*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteSshort(int16_t value)
3583*3ac0a46fSAndroid Build Coastguard Worker {
3584*3ac0a46fSAndroid Build Coastguard Worker if ((value < 0) || (value > 0xFF))
3585*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3586*3ac0a46fSAndroid Build Coastguard Worker else
3587*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3588*3ac0a46fSAndroid Build Coastguard Worker }
3589*3ac0a46fSAndroid Build Coastguard Worker
3590*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteLong(uint32_t value)3591*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteLong(uint32_t value)
3592*3ac0a46fSAndroid Build Coastguard Worker {
3593*3ac0a46fSAndroid Build Coastguard Worker if (value > 0xFF)
3594*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3595*3ac0a46fSAndroid Build Coastguard Worker else
3596*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3597*3ac0a46fSAndroid Build Coastguard Worker }
3598*3ac0a46fSAndroid Build Coastguard Worker
3599*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteSlong(int32_t value)3600*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteSlong(int32_t value)
3601*3ac0a46fSAndroid Build Coastguard Worker {
3602*3ac0a46fSAndroid Build Coastguard Worker if ((value < 0) || (value > 0xFF))
3603*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3604*3ac0a46fSAndroid Build Coastguard Worker else
3605*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3606*3ac0a46fSAndroid Build Coastguard Worker }
3607*3ac0a46fSAndroid Build Coastguard Worker
3608*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteLong8(uint64_t value)3609*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteLong8(uint64_t value)
3610*3ac0a46fSAndroid Build Coastguard Worker {
3611*3ac0a46fSAndroid Build Coastguard Worker if (value > 0xFF)
3612*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3613*3ac0a46fSAndroid Build Coastguard Worker else
3614*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3615*3ac0a46fSAndroid Build Coastguard Worker }
3616*3ac0a46fSAndroid Build Coastguard Worker
3617*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteSlong8(int64_t value)3618*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeByteSlong8(int64_t value)
3619*3ac0a46fSAndroid Build Coastguard Worker {
3620*3ac0a46fSAndroid Build Coastguard Worker if ((value < 0) || (value > 0xFF))
3621*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3622*3ac0a46fSAndroid Build Coastguard Worker else
3623*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3624*3ac0a46fSAndroid Build Coastguard Worker }
3625*3ac0a46fSAndroid Build Coastguard Worker
3626*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value)3627*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value)
3628*3ac0a46fSAndroid Build Coastguard Worker {
3629*3ac0a46fSAndroid Build Coastguard Worker if (value > 0x7F)
3630*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3631*3ac0a46fSAndroid Build Coastguard Worker else
3632*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3633*3ac0a46fSAndroid Build Coastguard Worker }
3634*3ac0a46fSAndroid Build Coastguard Worker
3635*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value)3636*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value)
3637*3ac0a46fSAndroid Build Coastguard Worker {
3638*3ac0a46fSAndroid Build Coastguard Worker if (value > 0x7F)
3639*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3640*3ac0a46fSAndroid Build Coastguard Worker else
3641*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3642*3ac0a46fSAndroid Build Coastguard Worker }
3643*3ac0a46fSAndroid Build Coastguard Worker
3644*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value)3645*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value)
3646*3ac0a46fSAndroid Build Coastguard Worker {
3647*3ac0a46fSAndroid Build Coastguard Worker if ((value < -0x80) || (value > 0x7F))
3648*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3649*3ac0a46fSAndroid Build Coastguard Worker else
3650*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3651*3ac0a46fSAndroid Build Coastguard Worker }
3652*3ac0a46fSAndroid Build Coastguard Worker
3653*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value)3654*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value)
3655*3ac0a46fSAndroid Build Coastguard Worker {
3656*3ac0a46fSAndroid Build Coastguard Worker if (value > 0x7F)
3657*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3658*3ac0a46fSAndroid Build Coastguard Worker else
3659*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3660*3ac0a46fSAndroid Build Coastguard Worker }
3661*3ac0a46fSAndroid Build Coastguard Worker
3662*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value)3663*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value)
3664*3ac0a46fSAndroid Build Coastguard Worker {
3665*3ac0a46fSAndroid Build Coastguard Worker if ((value < -0x80) || (value > 0x7F))
3666*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3667*3ac0a46fSAndroid Build Coastguard Worker else
3668*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3669*3ac0a46fSAndroid Build Coastguard Worker }
3670*3ac0a46fSAndroid Build Coastguard Worker
3671*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value)3672*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value)
3673*3ac0a46fSAndroid Build Coastguard Worker {
3674*3ac0a46fSAndroid Build Coastguard Worker if (value > 0x7F)
3675*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3676*3ac0a46fSAndroid Build Coastguard Worker else
3677*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3678*3ac0a46fSAndroid Build Coastguard Worker }
3679*3ac0a46fSAndroid Build Coastguard Worker
3680*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value)3681*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value)
3682*3ac0a46fSAndroid Build Coastguard Worker {
3683*3ac0a46fSAndroid Build Coastguard Worker if ((value < -0x80) || (value > 0x7F))
3684*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3685*3ac0a46fSAndroid Build Coastguard Worker else
3686*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3687*3ac0a46fSAndroid Build Coastguard Worker }
3688*3ac0a46fSAndroid Build Coastguard Worker
3689*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeShortSbyte(int8_t value)3690*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeShortSbyte(int8_t value)
3691*3ac0a46fSAndroid Build Coastguard Worker {
3692*3ac0a46fSAndroid Build Coastguard Worker if (value < 0)
3693*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3694*3ac0a46fSAndroid Build Coastguard Worker else
3695*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3696*3ac0a46fSAndroid Build Coastguard Worker }
3697*3ac0a46fSAndroid Build Coastguard Worker
3698*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeShortSshort(int16_t value)3699*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeShortSshort(int16_t value)
3700*3ac0a46fSAndroid Build Coastguard Worker {
3701*3ac0a46fSAndroid Build Coastguard Worker if (value < 0)
3702*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3703*3ac0a46fSAndroid Build Coastguard Worker else
3704*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3705*3ac0a46fSAndroid Build Coastguard Worker }
3706*3ac0a46fSAndroid Build Coastguard Worker
3707*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeShortLong(uint32_t value)3708*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeShortLong(uint32_t value)
3709*3ac0a46fSAndroid Build Coastguard Worker {
3710*3ac0a46fSAndroid Build Coastguard Worker if (value > 0xFFFF)
3711*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3712*3ac0a46fSAndroid Build Coastguard Worker else
3713*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3714*3ac0a46fSAndroid Build Coastguard Worker }
3715*3ac0a46fSAndroid Build Coastguard Worker
3716*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeShortSlong(int32_t value)3717*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeShortSlong(int32_t value)
3718*3ac0a46fSAndroid Build Coastguard Worker {
3719*3ac0a46fSAndroid Build Coastguard Worker if ((value < 0) || (value > 0xFFFF))
3720*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3721*3ac0a46fSAndroid Build Coastguard Worker else
3722*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3723*3ac0a46fSAndroid Build Coastguard Worker }
3724*3ac0a46fSAndroid Build Coastguard Worker
3725*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeShortLong8(uint64_t value)3726*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeShortLong8(uint64_t value)
3727*3ac0a46fSAndroid Build Coastguard Worker {
3728*3ac0a46fSAndroid Build Coastguard Worker if (value > 0xFFFF)
3729*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3730*3ac0a46fSAndroid Build Coastguard Worker else
3731*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3732*3ac0a46fSAndroid Build Coastguard Worker }
3733*3ac0a46fSAndroid Build Coastguard Worker
3734*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeShortSlong8(int64_t value)3735*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeShortSlong8(int64_t value)
3736*3ac0a46fSAndroid Build Coastguard Worker {
3737*3ac0a46fSAndroid Build Coastguard Worker if ((value < 0) || (value > 0xFFFF))
3738*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3739*3ac0a46fSAndroid Build Coastguard Worker else
3740*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3741*3ac0a46fSAndroid Build Coastguard Worker }
3742*3ac0a46fSAndroid Build Coastguard Worker
3743*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSshortShort(uint16_t value)3744*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSshortShort(uint16_t value)
3745*3ac0a46fSAndroid Build Coastguard Worker {
3746*3ac0a46fSAndroid Build Coastguard Worker if (value > 0x7FFF)
3747*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3748*3ac0a46fSAndroid Build Coastguard Worker else
3749*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3750*3ac0a46fSAndroid Build Coastguard Worker }
3751*3ac0a46fSAndroid Build Coastguard Worker
3752*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSshortLong(uint32_t value)3753*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSshortLong(uint32_t value)
3754*3ac0a46fSAndroid Build Coastguard Worker {
3755*3ac0a46fSAndroid Build Coastguard Worker if (value > 0x7FFF)
3756*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3757*3ac0a46fSAndroid Build Coastguard Worker else
3758*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3759*3ac0a46fSAndroid Build Coastguard Worker }
3760*3ac0a46fSAndroid Build Coastguard Worker
3761*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSshortSlong(int32_t value)3762*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSshortSlong(int32_t value)
3763*3ac0a46fSAndroid Build Coastguard Worker {
3764*3ac0a46fSAndroid Build Coastguard Worker if ((value < -0x8000) || (value > 0x7FFF))
3765*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3766*3ac0a46fSAndroid Build Coastguard Worker else
3767*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3768*3ac0a46fSAndroid Build Coastguard Worker }
3769*3ac0a46fSAndroid Build Coastguard Worker
3770*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value)3771*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value)
3772*3ac0a46fSAndroid Build Coastguard Worker {
3773*3ac0a46fSAndroid Build Coastguard Worker if (value > 0x7FFF)
3774*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3775*3ac0a46fSAndroid Build Coastguard Worker else
3776*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3777*3ac0a46fSAndroid Build Coastguard Worker }
3778*3ac0a46fSAndroid Build Coastguard Worker
3779*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value)3780*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value)
3781*3ac0a46fSAndroid Build Coastguard Worker {
3782*3ac0a46fSAndroid Build Coastguard Worker if ((value < -0x8000) || (value > 0x7FFF))
3783*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3784*3ac0a46fSAndroid Build Coastguard Worker else
3785*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3786*3ac0a46fSAndroid Build Coastguard Worker }
3787*3ac0a46fSAndroid Build Coastguard Worker
3788*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongSbyte(int8_t value)3789*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLongSbyte(int8_t value)
3790*3ac0a46fSAndroid Build Coastguard Worker {
3791*3ac0a46fSAndroid Build Coastguard Worker if (value < 0)
3792*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3793*3ac0a46fSAndroid Build Coastguard Worker else
3794*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3795*3ac0a46fSAndroid Build Coastguard Worker }
3796*3ac0a46fSAndroid Build Coastguard Worker
3797*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongSshort(int16_t value)3798*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLongSshort(int16_t value)
3799*3ac0a46fSAndroid Build Coastguard Worker {
3800*3ac0a46fSAndroid Build Coastguard Worker if (value < 0)
3801*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3802*3ac0a46fSAndroid Build Coastguard Worker else
3803*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3804*3ac0a46fSAndroid Build Coastguard Worker }
3805*3ac0a46fSAndroid Build Coastguard Worker
3806*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongSlong(int32_t value)3807*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLongSlong(int32_t value)
3808*3ac0a46fSAndroid Build Coastguard Worker {
3809*3ac0a46fSAndroid Build Coastguard Worker if (value < 0)
3810*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3811*3ac0a46fSAndroid Build Coastguard Worker else
3812*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3813*3ac0a46fSAndroid Build Coastguard Worker }
3814*3ac0a46fSAndroid Build Coastguard Worker
3815*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongLong8(uint64_t value)3816*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLongLong8(uint64_t value)
3817*3ac0a46fSAndroid Build Coastguard Worker {
3818*3ac0a46fSAndroid Build Coastguard Worker if (value > UINT32_MAX)
3819*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3820*3ac0a46fSAndroid Build Coastguard Worker else
3821*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3822*3ac0a46fSAndroid Build Coastguard Worker }
3823*3ac0a46fSAndroid Build Coastguard Worker
3824*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongSlong8(int64_t value)3825*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLongSlong8(int64_t value)
3826*3ac0a46fSAndroid Build Coastguard Worker {
3827*3ac0a46fSAndroid Build Coastguard Worker if ((value < 0) || (value > (int64_t)UINT32_MAX))
3828*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3829*3ac0a46fSAndroid Build Coastguard Worker else
3830*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3831*3ac0a46fSAndroid Build Coastguard Worker }
3832*3ac0a46fSAndroid Build Coastguard Worker
3833*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlongLong(uint32_t value)3834*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSlongLong(uint32_t value)
3835*3ac0a46fSAndroid Build Coastguard Worker {
3836*3ac0a46fSAndroid Build Coastguard Worker if (value > 0x7FFFFFFFUL)
3837*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3838*3ac0a46fSAndroid Build Coastguard Worker else
3839*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3840*3ac0a46fSAndroid Build Coastguard Worker }
3841*3ac0a46fSAndroid Build Coastguard Worker
3842*3ac0a46fSAndroid Build Coastguard Worker /* Check that the 8-byte unsigned value can fit in a 4-byte unsigned range */
3843*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value)3844*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value)
3845*3ac0a46fSAndroid Build Coastguard Worker {
3846*3ac0a46fSAndroid Build Coastguard Worker if (value > 0x7FFFFFFF)
3847*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3848*3ac0a46fSAndroid Build Coastguard Worker else
3849*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3850*3ac0a46fSAndroid Build Coastguard Worker }
3851*3ac0a46fSAndroid Build Coastguard Worker
3852*3ac0a46fSAndroid Build Coastguard Worker /* Check that the 8-byte signed value can fit in a 4-byte signed range */
3853*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value)3854*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value)
3855*3ac0a46fSAndroid Build Coastguard Worker {
3856*3ac0a46fSAndroid Build Coastguard Worker if ((value < 0 - ((int64_t)0x7FFFFFFF + 1)) || (value > 0x7FFFFFFF))
3857*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3858*3ac0a46fSAndroid Build Coastguard Worker else
3859*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3860*3ac0a46fSAndroid Build Coastguard Worker }
3861*3ac0a46fSAndroid Build Coastguard Worker
3862*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value)3863*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value)
3864*3ac0a46fSAndroid Build Coastguard Worker {
3865*3ac0a46fSAndroid Build Coastguard Worker if (value < 0)
3866*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3867*3ac0a46fSAndroid Build Coastguard Worker else
3868*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3869*3ac0a46fSAndroid Build Coastguard Worker }
3870*3ac0a46fSAndroid Build Coastguard Worker
3871*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value)3872*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value)
3873*3ac0a46fSAndroid Build Coastguard Worker {
3874*3ac0a46fSAndroid Build Coastguard Worker if (value < 0)
3875*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3876*3ac0a46fSAndroid Build Coastguard Worker else
3877*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3878*3ac0a46fSAndroid Build Coastguard Worker }
3879*3ac0a46fSAndroid Build Coastguard Worker
3880*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLong8Slong(int32_t value)3881*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLong8Slong(int32_t value)
3882*3ac0a46fSAndroid Build Coastguard Worker {
3883*3ac0a46fSAndroid Build Coastguard Worker if (value < 0)
3884*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3885*3ac0a46fSAndroid Build Coastguard Worker else
3886*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3887*3ac0a46fSAndroid Build Coastguard Worker }
3888*3ac0a46fSAndroid Build Coastguard Worker
3889*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value)3890*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value)
3891*3ac0a46fSAndroid Build Coastguard Worker {
3892*3ac0a46fSAndroid Build Coastguard Worker if (value < 0)
3893*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3894*3ac0a46fSAndroid Build Coastguard Worker else
3895*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3896*3ac0a46fSAndroid Build Coastguard Worker }
3897*3ac0a46fSAndroid Build Coastguard Worker
3898*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value)3899*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value)
3900*3ac0a46fSAndroid Build Coastguard Worker {
3901*3ac0a46fSAndroid Build Coastguard Worker if (value > INT64_MAX)
3902*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrRange);
3903*3ac0a46fSAndroid Build Coastguard Worker else
3904*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3905*3ac0a46fSAndroid Build Coastguard Worker }
3906*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirEntryData(TIFF * tif,uint64_t offset,tmsize_t size,void * dest)3907*3ac0a46fSAndroid Build Coastguard Worker static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset,
3908*3ac0a46fSAndroid Build Coastguard Worker tmsize_t size, void *dest)
3909*3ac0a46fSAndroid Build Coastguard Worker {
3910*3ac0a46fSAndroid Build Coastguard Worker assert(size > 0);
3911*3ac0a46fSAndroid Build Coastguard Worker if (!isMapped(tif))
3912*3ac0a46fSAndroid Build Coastguard Worker {
3913*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, offset))
3914*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrIo);
3915*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, dest, size))
3916*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrIo);
3917*3ac0a46fSAndroid Build Coastguard Worker }
3918*3ac0a46fSAndroid Build Coastguard Worker else
3919*3ac0a46fSAndroid Build Coastguard Worker {
3920*3ac0a46fSAndroid Build Coastguard Worker size_t ma, mb;
3921*3ac0a46fSAndroid Build Coastguard Worker ma = (size_t)offset;
3922*3ac0a46fSAndroid Build Coastguard Worker if ((uint64_t)ma != offset || ma > (~(size_t)0) - (size_t)size)
3923*3ac0a46fSAndroid Build Coastguard Worker {
3924*3ac0a46fSAndroid Build Coastguard Worker return TIFFReadDirEntryErrIo;
3925*3ac0a46fSAndroid Build Coastguard Worker }
3926*3ac0a46fSAndroid Build Coastguard Worker mb = ma + size;
3927*3ac0a46fSAndroid Build Coastguard Worker if (mb > (uint64_t)tif->tif_size)
3928*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrIo);
3929*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(dest, tif->tif_base + ma, size);
3930*3ac0a46fSAndroid Build Coastguard Worker }
3931*3ac0a46fSAndroid Build Coastguard Worker return (TIFFReadDirEntryErrOk);
3932*3ac0a46fSAndroid Build Coastguard Worker }
3933*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirEntryOutputErr(TIFF * tif,enum TIFFReadDirEntryErr err,const char * module,const char * tagname,int recover)3934*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err,
3935*3ac0a46fSAndroid Build Coastguard Worker const char *module, const char *tagname,
3936*3ac0a46fSAndroid Build Coastguard Worker int recover)
3937*3ac0a46fSAndroid Build Coastguard Worker {
3938*3ac0a46fSAndroid Build Coastguard Worker if (!recover)
3939*3ac0a46fSAndroid Build Coastguard Worker {
3940*3ac0a46fSAndroid Build Coastguard Worker switch (err)
3941*3ac0a46fSAndroid Build Coastguard Worker {
3942*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrCount:
3943*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Incorrect count for \"%s\"",
3944*3ac0a46fSAndroid Build Coastguard Worker tagname);
3945*3ac0a46fSAndroid Build Coastguard Worker break;
3946*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrType:
3947*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Incompatible type for \"%s\"",
3948*3ac0a46fSAndroid Build Coastguard Worker tagname);
3949*3ac0a46fSAndroid Build Coastguard Worker break;
3950*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrIo:
3951*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "IO error during reading of \"%s\"",
3952*3ac0a46fSAndroid Build Coastguard Worker tagname);
3953*3ac0a46fSAndroid Build Coastguard Worker break;
3954*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrRange:
3955*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Incorrect value for \"%s\"",
3956*3ac0a46fSAndroid Build Coastguard Worker tagname);
3957*3ac0a46fSAndroid Build Coastguard Worker break;
3958*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrPsdif:
3959*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(
3960*3ac0a46fSAndroid Build Coastguard Worker tif, module,
3961*3ac0a46fSAndroid Build Coastguard Worker "Cannot handle different values per sample for \"%s\"",
3962*3ac0a46fSAndroid Build Coastguard Worker tagname);
3963*3ac0a46fSAndroid Build Coastguard Worker break;
3964*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrSizesan:
3965*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
3966*3ac0a46fSAndroid Build Coastguard Worker "Sanity check on size of \"%s\" value failed",
3967*3ac0a46fSAndroid Build Coastguard Worker tagname);
3968*3ac0a46fSAndroid Build Coastguard Worker break;
3969*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrAlloc:
3970*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory reading of \"%s\"",
3971*3ac0a46fSAndroid Build Coastguard Worker tagname);
3972*3ac0a46fSAndroid Build Coastguard Worker break;
3973*3ac0a46fSAndroid Build Coastguard Worker default:
3974*3ac0a46fSAndroid Build Coastguard Worker assert(0); /* we should never get here */
3975*3ac0a46fSAndroid Build Coastguard Worker break;
3976*3ac0a46fSAndroid Build Coastguard Worker }
3977*3ac0a46fSAndroid Build Coastguard Worker }
3978*3ac0a46fSAndroid Build Coastguard Worker else
3979*3ac0a46fSAndroid Build Coastguard Worker {
3980*3ac0a46fSAndroid Build Coastguard Worker switch (err)
3981*3ac0a46fSAndroid Build Coastguard Worker {
3982*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrCount:
3983*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
3984*3ac0a46fSAndroid Build Coastguard Worker "Incorrect count for \"%s\"; tag ignored",
3985*3ac0a46fSAndroid Build Coastguard Worker tagname);
3986*3ac0a46fSAndroid Build Coastguard Worker break;
3987*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrType:
3988*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
3989*3ac0a46fSAndroid Build Coastguard Worker "Incompatible type for \"%s\"; tag ignored",
3990*3ac0a46fSAndroid Build Coastguard Worker tagname);
3991*3ac0a46fSAndroid Build Coastguard Worker break;
3992*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrIo:
3993*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
3994*3ac0a46fSAndroid Build Coastguard Worker tif, module,
3995*3ac0a46fSAndroid Build Coastguard Worker "IO error during reading of \"%s\"; tag ignored", tagname);
3996*3ac0a46fSAndroid Build Coastguard Worker break;
3997*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrRange:
3998*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
3999*3ac0a46fSAndroid Build Coastguard Worker "Incorrect value for \"%s\"; tag ignored",
4000*3ac0a46fSAndroid Build Coastguard Worker tagname);
4001*3ac0a46fSAndroid Build Coastguard Worker break;
4002*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrPsdif:
4003*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
4004*3ac0a46fSAndroid Build Coastguard Worker "Cannot handle different values per sample for "
4005*3ac0a46fSAndroid Build Coastguard Worker "\"%s\"; tag ignored",
4006*3ac0a46fSAndroid Build Coastguard Worker tagname);
4007*3ac0a46fSAndroid Build Coastguard Worker break;
4008*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrSizesan:
4009*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
4010*3ac0a46fSAndroid Build Coastguard Worker tif, module,
4011*3ac0a46fSAndroid Build Coastguard Worker "Sanity check on size of \"%s\" value failed; tag ignored",
4012*3ac0a46fSAndroid Build Coastguard Worker tagname);
4013*3ac0a46fSAndroid Build Coastguard Worker break;
4014*3ac0a46fSAndroid Build Coastguard Worker case TIFFReadDirEntryErrAlloc:
4015*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
4016*3ac0a46fSAndroid Build Coastguard Worker "Out of memory reading of \"%s\"; tag ignored",
4017*3ac0a46fSAndroid Build Coastguard Worker tagname);
4018*3ac0a46fSAndroid Build Coastguard Worker break;
4019*3ac0a46fSAndroid Build Coastguard Worker default:
4020*3ac0a46fSAndroid Build Coastguard Worker assert(0); /* we should never get here */
4021*3ac0a46fSAndroid Build Coastguard Worker break;
4022*3ac0a46fSAndroid Build Coastguard Worker }
4023*3ac0a46fSAndroid Build Coastguard Worker }
4024*3ac0a46fSAndroid Build Coastguard Worker }
4025*3ac0a46fSAndroid Build Coastguard Worker
4026*3ac0a46fSAndroid Build Coastguard Worker /*
4027*3ac0a46fSAndroid Build Coastguard Worker * Return the maximum number of color channels specified for a given photometric
4028*3ac0a46fSAndroid Build Coastguard Worker * type. 0 is returned if photometric type isn't supported or no default value
4029*3ac0a46fSAndroid Build Coastguard Worker * is defined by the specification.
4030*3ac0a46fSAndroid Build Coastguard Worker */
_TIFFGetMaxColorChannels(uint16_t photometric)4031*3ac0a46fSAndroid Build Coastguard Worker static int _TIFFGetMaxColorChannels(uint16_t photometric)
4032*3ac0a46fSAndroid Build Coastguard Worker {
4033*3ac0a46fSAndroid Build Coastguard Worker switch (photometric)
4034*3ac0a46fSAndroid Build Coastguard Worker {
4035*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_PALETTE:
4036*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_MINISWHITE:
4037*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_MINISBLACK:
4038*3ac0a46fSAndroid Build Coastguard Worker return 1;
4039*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_YCBCR:
4040*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_RGB:
4041*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_CIELAB:
4042*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_LOGLUV:
4043*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_ITULAB:
4044*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_ICCLAB:
4045*3ac0a46fSAndroid Build Coastguard Worker return 3;
4046*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_SEPARATED:
4047*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_MASK:
4048*3ac0a46fSAndroid Build Coastguard Worker return 4;
4049*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_LOGL:
4050*3ac0a46fSAndroid Build Coastguard Worker case PHOTOMETRIC_CFA:
4051*3ac0a46fSAndroid Build Coastguard Worker default:
4052*3ac0a46fSAndroid Build Coastguard Worker return 0;
4053*3ac0a46fSAndroid Build Coastguard Worker }
4054*3ac0a46fSAndroid Build Coastguard Worker }
4055*3ac0a46fSAndroid Build Coastguard Worker
ByteCountLooksBad(TIFF * tif)4056*3ac0a46fSAndroid Build Coastguard Worker static int ByteCountLooksBad(TIFF *tif)
4057*3ac0a46fSAndroid Build Coastguard Worker {
4058*3ac0a46fSAndroid Build Coastguard Worker /*
4059*3ac0a46fSAndroid Build Coastguard Worker * Assume we have wrong StripByteCount value (in case
4060*3ac0a46fSAndroid Build Coastguard Worker * of single strip) in following cases:
4061*3ac0a46fSAndroid Build Coastguard Worker * - it is equal to zero along with StripOffset;
4062*3ac0a46fSAndroid Build Coastguard Worker * - it is larger than file itself (in case of uncompressed
4063*3ac0a46fSAndroid Build Coastguard Worker * image);
4064*3ac0a46fSAndroid Build Coastguard Worker * - it is smaller than the size of the bytes per row
4065*3ac0a46fSAndroid Build Coastguard Worker * multiplied on the number of rows. The last case should
4066*3ac0a46fSAndroid Build Coastguard Worker * not be checked in the case of writing new image,
4067*3ac0a46fSAndroid Build Coastguard Worker * because we may do not know the exact strip size
4068*3ac0a46fSAndroid Build Coastguard Worker * until the whole image will be written and directory
4069*3ac0a46fSAndroid Build Coastguard Worker * dumped out.
4070*3ac0a46fSAndroid Build Coastguard Worker */
4071*3ac0a46fSAndroid Build Coastguard Worker uint64_t bytecount = TIFFGetStrileByteCount(tif, 0);
4072*3ac0a46fSAndroid Build Coastguard Worker uint64_t offset = TIFFGetStrileOffset(tif, 0);
4073*3ac0a46fSAndroid Build Coastguard Worker uint64_t filesize;
4074*3ac0a46fSAndroid Build Coastguard Worker
4075*3ac0a46fSAndroid Build Coastguard Worker if (offset == 0)
4076*3ac0a46fSAndroid Build Coastguard Worker return 0;
4077*3ac0a46fSAndroid Build Coastguard Worker if (bytecount == 0)
4078*3ac0a46fSAndroid Build Coastguard Worker return 1;
4079*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_compression != COMPRESSION_NONE)
4080*3ac0a46fSAndroid Build Coastguard Worker return 0;
4081*3ac0a46fSAndroid Build Coastguard Worker filesize = TIFFGetFileSize(tif);
4082*3ac0a46fSAndroid Build Coastguard Worker if (offset <= filesize && bytecount > filesize - offset)
4083*3ac0a46fSAndroid Build Coastguard Worker return 1;
4084*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_mode == O_RDONLY)
4085*3ac0a46fSAndroid Build Coastguard Worker {
4086*3ac0a46fSAndroid Build Coastguard Worker uint64_t scanlinesize = TIFFScanlineSize64(tif);
4087*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_imagelength > 0 &&
4088*3ac0a46fSAndroid Build Coastguard Worker scanlinesize > UINT64_MAX / tif->tif_dir.td_imagelength)
4089*3ac0a46fSAndroid Build Coastguard Worker {
4090*3ac0a46fSAndroid Build Coastguard Worker return 1;
4091*3ac0a46fSAndroid Build Coastguard Worker }
4092*3ac0a46fSAndroid Build Coastguard Worker if (bytecount < scanlinesize * tif->tif_dir.td_imagelength)
4093*3ac0a46fSAndroid Build Coastguard Worker return 1;
4094*3ac0a46fSAndroid Build Coastguard Worker }
4095*3ac0a46fSAndroid Build Coastguard Worker return 0;
4096*3ac0a46fSAndroid Build Coastguard Worker }
4097*3ac0a46fSAndroid Build Coastguard Worker
4098*3ac0a46fSAndroid Build Coastguard Worker /*
4099*3ac0a46fSAndroid Build Coastguard Worker * Read the next TIFF directory from a file and convert it to the internal
4100*3ac0a46fSAndroid Build Coastguard Worker * format. We read directories sequentially.
4101*3ac0a46fSAndroid Build Coastguard Worker */
TIFFReadDirectory(TIFF * tif)4102*3ac0a46fSAndroid Build Coastguard Worker int TIFFReadDirectory(TIFF *tif)
4103*3ac0a46fSAndroid Build Coastguard Worker {
4104*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFReadDirectory";
4105*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir;
4106*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount;
4107*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dp;
4108*3ac0a46fSAndroid Build Coastguard Worker uint16_t di;
4109*3ac0a46fSAndroid Build Coastguard Worker const TIFFField *fip;
4110*3ac0a46fSAndroid Build Coastguard Worker uint32_t fii = FAILED_FII;
4111*3ac0a46fSAndroid Build Coastguard Worker toff_t nextdiroff;
4112*3ac0a46fSAndroid Build Coastguard Worker int bitspersample_read = FALSE;
4113*3ac0a46fSAndroid Build Coastguard Worker int color_channels;
4114*3ac0a46fSAndroid Build Coastguard Worker
4115*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_nextdiroff == 0)
4116*3ac0a46fSAndroid Build Coastguard Worker {
4117*3ac0a46fSAndroid Build Coastguard Worker /* In this special case, tif_diroff needs also to be set to 0.
4118*3ac0a46fSAndroid Build Coastguard Worker * This is behind the last IFD, thus no checking or reading necessary.
4119*3ac0a46fSAndroid Build Coastguard Worker */
4120*3ac0a46fSAndroid Build Coastguard Worker tif->tif_diroff = tif->tif_nextdiroff;
4121*3ac0a46fSAndroid Build Coastguard Worker return 0;
4122*3ac0a46fSAndroid Build Coastguard Worker }
4123*3ac0a46fSAndroid Build Coastguard Worker
4124*3ac0a46fSAndroid Build Coastguard Worker nextdiroff = tif->tif_nextdiroff;
4125*3ac0a46fSAndroid Build Coastguard Worker /* tif_curdir++ and tif_nextdiroff should only be updated after SUCCESSFUL
4126*3ac0a46fSAndroid Build Coastguard Worker * reading of the directory. Otherwise, invalid IFD offsets could corrupt
4127*3ac0a46fSAndroid Build Coastguard Worker * the IFD list. */
4128*3ac0a46fSAndroid Build Coastguard Worker if (!_TIFFCheckDirNumberAndOffset(tif,
4129*3ac0a46fSAndroid Build Coastguard Worker tif->tif_curdir ==
4130*3ac0a46fSAndroid Build Coastguard Worker TIFF_NON_EXISTENT_DIR_NUMBER
4131*3ac0a46fSAndroid Build Coastguard Worker ? 0
4132*3ac0a46fSAndroid Build Coastguard Worker : tif->tif_curdir + 1,
4133*3ac0a46fSAndroid Build Coastguard Worker nextdiroff))
4134*3ac0a46fSAndroid Build Coastguard Worker {
4135*3ac0a46fSAndroid Build Coastguard Worker return 0; /* bad offset (IFD looping or more than TIFF_MAX_DIR_COUNT
4136*3ac0a46fSAndroid Build Coastguard Worker IFDs) */
4137*3ac0a46fSAndroid Build Coastguard Worker }
4138*3ac0a46fSAndroid Build Coastguard Worker dircount = TIFFFetchDirectory(tif, nextdiroff, &dir, &tif->tif_nextdiroff);
4139*3ac0a46fSAndroid Build Coastguard Worker if (!dircount)
4140*3ac0a46fSAndroid Build Coastguard Worker {
4141*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
4142*3ac0a46fSAndroid Build Coastguard Worker "Failed to read directory at offset %" PRIu64,
4143*3ac0a46fSAndroid Build Coastguard Worker nextdiroff);
4144*3ac0a46fSAndroid Build Coastguard Worker return 0;
4145*3ac0a46fSAndroid Build Coastguard Worker }
4146*3ac0a46fSAndroid Build Coastguard Worker /* Set global values after a valid directory has been fetched.
4147*3ac0a46fSAndroid Build Coastguard Worker * tif_diroff is already set to nextdiroff in TIFFFetchDirectory() in the
4148*3ac0a46fSAndroid Build Coastguard Worker * beginning. */
4149*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
4150*3ac0a46fSAndroid Build Coastguard Worker tif->tif_curdir = 0;
4151*3ac0a46fSAndroid Build Coastguard Worker else
4152*3ac0a46fSAndroid Build Coastguard Worker tif->tif_curdir++;
4153*3ac0a46fSAndroid Build Coastguard Worker (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
4154*3ac0a46fSAndroid Build Coastguard Worker
4155*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirectoryCheckOrder(tif, dir, dircount);
4156*3ac0a46fSAndroid Build Coastguard Worker
4157*3ac0a46fSAndroid Build Coastguard Worker /*
4158*3ac0a46fSAndroid Build Coastguard Worker * Mark duplicates of any tag to be ignored (bugzilla 1994)
4159*3ac0a46fSAndroid Build Coastguard Worker * to avoid certain pathological problems.
4160*3ac0a46fSAndroid Build Coastguard Worker */
4161*3ac0a46fSAndroid Build Coastguard Worker {
4162*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *ma;
4163*3ac0a46fSAndroid Build Coastguard Worker uint16_t mb;
4164*3ac0a46fSAndroid Build Coastguard Worker for (ma = dir, mb = 0; mb < dircount; ma++, mb++)
4165*3ac0a46fSAndroid Build Coastguard Worker {
4166*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *na;
4167*3ac0a46fSAndroid Build Coastguard Worker uint16_t nb;
4168*3ac0a46fSAndroid Build Coastguard Worker for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++)
4169*3ac0a46fSAndroid Build Coastguard Worker {
4170*3ac0a46fSAndroid Build Coastguard Worker if (ma->tdir_tag == na->tdir_tag)
4171*3ac0a46fSAndroid Build Coastguard Worker {
4172*3ac0a46fSAndroid Build Coastguard Worker na->tdir_ignore = TRUE;
4173*3ac0a46fSAndroid Build Coastguard Worker }
4174*3ac0a46fSAndroid Build Coastguard Worker }
4175*3ac0a46fSAndroid Build Coastguard Worker }
4176*3ac0a46fSAndroid Build Coastguard Worker }
4177*3ac0a46fSAndroid Build Coastguard Worker
4178*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */
4179*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */
4180*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS;
4181*3ac0a46fSAndroid Build Coastguard Worker
4182*3ac0a46fSAndroid Build Coastguard Worker /* free any old stuff and reinit */
4183*3ac0a46fSAndroid Build Coastguard Worker TIFFFreeDirectory(tif);
4184*3ac0a46fSAndroid Build Coastguard Worker TIFFDefaultDirectory(tif);
4185*3ac0a46fSAndroid Build Coastguard Worker /*
4186*3ac0a46fSAndroid Build Coastguard Worker * Electronic Arts writes gray-scale TIFF files
4187*3ac0a46fSAndroid Build Coastguard Worker * without a PlanarConfiguration directory entry.
4188*3ac0a46fSAndroid Build Coastguard Worker * Thus we setup a default value here, even though
4189*3ac0a46fSAndroid Build Coastguard Worker * the TIFF spec says there is no default value.
4190*3ac0a46fSAndroid Build Coastguard Worker * After PlanarConfiguration is preset in TIFFDefaultDirectory()
4191*3ac0a46fSAndroid Build Coastguard Worker * the following setting is not needed, but does not harm either.
4192*3ac0a46fSAndroid Build Coastguard Worker */
4193*3ac0a46fSAndroid Build Coastguard Worker TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
4194*3ac0a46fSAndroid Build Coastguard Worker /*
4195*3ac0a46fSAndroid Build Coastguard Worker * Setup default value and then make a pass over
4196*3ac0a46fSAndroid Build Coastguard Worker * the fields to check type and tag information,
4197*3ac0a46fSAndroid Build Coastguard Worker * and to extract info required to size data
4198*3ac0a46fSAndroid Build Coastguard Worker * structures. A second pass is made afterwards
4199*3ac0a46fSAndroid Build Coastguard Worker * to read in everything not taken in the first pass.
4200*3ac0a46fSAndroid Build Coastguard Worker * But we must process the Compression tag first
4201*3ac0a46fSAndroid Build Coastguard Worker * in order to merge in codec-private tag definitions (otherwise
4202*3ac0a46fSAndroid Build Coastguard Worker * we may get complaints about unknown tags). However, the
4203*3ac0a46fSAndroid Build Coastguard Worker * Compression tag may be dependent on the SamplesPerPixel
4204*3ac0a46fSAndroid Build Coastguard Worker * tag value because older TIFF specs permitted Compression
4205*3ac0a46fSAndroid Build Coastguard Worker * to be written as a SamplesPerPixel-count tag entry.
4206*3ac0a46fSAndroid Build Coastguard Worker * Thus if we don't first figure out the correct SamplesPerPixel
4207*3ac0a46fSAndroid Build Coastguard Worker * tag value then we may end up ignoring the Compression tag
4208*3ac0a46fSAndroid Build Coastguard Worker * value because it has an incorrect count value (if the
4209*3ac0a46fSAndroid Build Coastguard Worker * true value of SamplesPerPixel is not 1).
4210*3ac0a46fSAndroid Build Coastguard Worker */
4211*3ac0a46fSAndroid Build Coastguard Worker dp =
4212*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_SAMPLESPERPIXEL);
4213*3ac0a46fSAndroid Build Coastguard Worker if (dp)
4214*3ac0a46fSAndroid Build Coastguard Worker {
4215*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFetchNormalTag(tif, dp, 0))
4216*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4217*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_ignore = TRUE;
4218*3ac0a46fSAndroid Build Coastguard Worker }
4219*3ac0a46fSAndroid Build Coastguard Worker dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_COMPRESSION);
4220*3ac0a46fSAndroid Build Coastguard Worker if (dp)
4221*3ac0a46fSAndroid Build Coastguard Worker {
4222*3ac0a46fSAndroid Build Coastguard Worker /*
4223*3ac0a46fSAndroid Build Coastguard Worker * The 5.0 spec says the Compression tag has one value, while
4224*3ac0a46fSAndroid Build Coastguard Worker * earlier specs say it has one value per sample. Because of
4225*3ac0a46fSAndroid Build Coastguard Worker * this, we accept the tag if one value is supplied with either
4226*3ac0a46fSAndroid Build Coastguard Worker * count.
4227*3ac0a46fSAndroid Build Coastguard Worker */
4228*3ac0a46fSAndroid Build Coastguard Worker uint16_t value;
4229*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
4230*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryShort(tif, dp, &value);
4231*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrCount)
4232*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryPersampleShort(tif, dp, &value);
4233*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
4234*3ac0a46fSAndroid Build Coastguard Worker {
4235*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryOutputErr(tif, err, module, "Compression", 0);
4236*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4237*3ac0a46fSAndroid Build Coastguard Worker }
4238*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, value))
4239*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4240*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_ignore = TRUE;
4241*3ac0a46fSAndroid Build Coastguard Worker }
4242*3ac0a46fSAndroid Build Coastguard Worker else
4243*3ac0a46fSAndroid Build Coastguard Worker {
4244*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE))
4245*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4246*3ac0a46fSAndroid Build Coastguard Worker }
4247*3ac0a46fSAndroid Build Coastguard Worker /*
4248*3ac0a46fSAndroid Build Coastguard Worker * First real pass over the directory.
4249*3ac0a46fSAndroid Build Coastguard Worker */
4250*3ac0a46fSAndroid Build Coastguard Worker for (di = 0, dp = dir; di < dircount; di++, dp++)
4251*3ac0a46fSAndroid Build Coastguard Worker {
4252*3ac0a46fSAndroid Build Coastguard Worker if (!dp->tdir_ignore)
4253*3ac0a46fSAndroid Build Coastguard Worker {
4254*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
4255*3ac0a46fSAndroid Build Coastguard Worker if (fii == FAILED_FII)
4256*3ac0a46fSAndroid Build Coastguard Worker {
4257*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
4258*3ac0a46fSAndroid Build Coastguard Worker "Unknown field with tag %" PRIu16 " (0x%" PRIx16
4259*3ac0a46fSAndroid Build Coastguard Worker ") encountered",
4260*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_tag, dp->tdir_tag);
4261*3ac0a46fSAndroid Build Coastguard Worker /* the following knowingly leaks the
4262*3ac0a46fSAndroid Build Coastguard Worker anonymous field structure */
4263*3ac0a46fSAndroid Build Coastguard Worker if (!_TIFFMergeFields(
4264*3ac0a46fSAndroid Build Coastguard Worker tif,
4265*3ac0a46fSAndroid Build Coastguard Worker _TIFFCreateAnonField(tif, dp->tdir_tag,
4266*3ac0a46fSAndroid Build Coastguard Worker (TIFFDataType)dp->tdir_type),
4267*3ac0a46fSAndroid Build Coastguard Worker 1))
4268*3ac0a46fSAndroid Build Coastguard Worker {
4269*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
4270*3ac0a46fSAndroid Build Coastguard Worker tif, module,
4271*3ac0a46fSAndroid Build Coastguard Worker "Registering anonymous field with tag %" PRIu16
4272*3ac0a46fSAndroid Build Coastguard Worker " (0x%" PRIx16 ") failed",
4273*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_tag, dp->tdir_tag);
4274*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_ignore = TRUE;
4275*3ac0a46fSAndroid Build Coastguard Worker }
4276*3ac0a46fSAndroid Build Coastguard Worker else
4277*3ac0a46fSAndroid Build Coastguard Worker {
4278*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
4279*3ac0a46fSAndroid Build Coastguard Worker assert(fii != FAILED_FII);
4280*3ac0a46fSAndroid Build Coastguard Worker }
4281*3ac0a46fSAndroid Build Coastguard Worker }
4282*3ac0a46fSAndroid Build Coastguard Worker }
4283*3ac0a46fSAndroid Build Coastguard Worker if (!dp->tdir_ignore)
4284*3ac0a46fSAndroid Build Coastguard Worker {
4285*3ac0a46fSAndroid Build Coastguard Worker fip = tif->tif_fields[fii];
4286*3ac0a46fSAndroid Build Coastguard Worker if (fip->field_bit == FIELD_IGNORE)
4287*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_ignore = TRUE;
4288*3ac0a46fSAndroid Build Coastguard Worker else
4289*3ac0a46fSAndroid Build Coastguard Worker {
4290*3ac0a46fSAndroid Build Coastguard Worker switch (dp->tdir_tag)
4291*3ac0a46fSAndroid Build Coastguard Worker {
4292*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_STRIPOFFSETS:
4293*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_STRIPBYTECOUNTS:
4294*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_TILEOFFSETS:
4295*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_TILEBYTECOUNTS:
4296*3ac0a46fSAndroid Build Coastguard Worker TIFFSetFieldBit(tif, fip->field_bit);
4297*3ac0a46fSAndroid Build Coastguard Worker break;
4298*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_IMAGEWIDTH:
4299*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_IMAGELENGTH:
4300*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_IMAGEDEPTH:
4301*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_TILELENGTH:
4302*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_TILEWIDTH:
4303*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_TILEDEPTH:
4304*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_PLANARCONFIG:
4305*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_ROWSPERSTRIP:
4306*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_EXTRASAMPLES:
4307*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFetchNormalTag(tif, dp, 0))
4308*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4309*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_ignore = TRUE;
4310*3ac0a46fSAndroid Build Coastguard Worker break;
4311*3ac0a46fSAndroid Build Coastguard Worker default:
4312*3ac0a46fSAndroid Build Coastguard Worker if (!_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag))
4313*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_ignore = TRUE;
4314*3ac0a46fSAndroid Build Coastguard Worker break;
4315*3ac0a46fSAndroid Build Coastguard Worker }
4316*3ac0a46fSAndroid Build Coastguard Worker }
4317*3ac0a46fSAndroid Build Coastguard Worker }
4318*3ac0a46fSAndroid Build Coastguard Worker }
4319*3ac0a46fSAndroid Build Coastguard Worker /*
4320*3ac0a46fSAndroid Build Coastguard Worker * XXX: OJPEG hack.
4321*3ac0a46fSAndroid Build Coastguard Worker * If a) compression is OJPEG, b) planarconfig tag says it's separate,
4322*3ac0a46fSAndroid Build Coastguard Worker * c) strip offsets/bytecounts tag are both present and
4323*3ac0a46fSAndroid Build Coastguard Worker * d) both contain exactly one value, then we consistently find
4324*3ac0a46fSAndroid Build Coastguard Worker * that the buggy implementation of the buggy compression scheme
4325*3ac0a46fSAndroid Build Coastguard Worker * matches contig planarconfig best. So we 'fix-up' the tag here
4326*3ac0a46fSAndroid Build Coastguard Worker */
4327*3ac0a46fSAndroid Build Coastguard Worker if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) &&
4328*3ac0a46fSAndroid Build Coastguard Worker (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE))
4329*3ac0a46fSAndroid Build Coastguard Worker {
4330*3ac0a46fSAndroid Build Coastguard Worker if (!_TIFFFillStriles(tif))
4331*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4332*3ac0a46fSAndroid Build Coastguard Worker dp = TIFFReadDirectoryFindEntry(tif, dir, dircount,
4333*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_STRIPOFFSETS);
4334*3ac0a46fSAndroid Build Coastguard Worker if ((dp != 0) && (dp->tdir_count == 1))
4335*3ac0a46fSAndroid Build Coastguard Worker {
4336*3ac0a46fSAndroid Build Coastguard Worker dp = TIFFReadDirectoryFindEntry(tif, dir, dircount,
4337*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_STRIPBYTECOUNTS);
4338*3ac0a46fSAndroid Build Coastguard Worker if ((dp != 0) && (dp->tdir_count == 1))
4339*3ac0a46fSAndroid Build Coastguard Worker {
4340*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
4341*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
4342*3ac0a46fSAndroid Build Coastguard Worker "Planarconfig tag value assumed incorrect, "
4343*3ac0a46fSAndroid Build Coastguard Worker "assuming data is contig instead of chunky");
4344*3ac0a46fSAndroid Build Coastguard Worker }
4345*3ac0a46fSAndroid Build Coastguard Worker }
4346*3ac0a46fSAndroid Build Coastguard Worker }
4347*3ac0a46fSAndroid Build Coastguard Worker /*
4348*3ac0a46fSAndroid Build Coastguard Worker * Allocate directory structure and setup defaults.
4349*3ac0a46fSAndroid Build Coastguard Worker */
4350*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
4351*3ac0a46fSAndroid Build Coastguard Worker {
4352*3ac0a46fSAndroid Build Coastguard Worker MissingRequired(tif, "ImageLength");
4353*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4354*3ac0a46fSAndroid Build Coastguard Worker }
4355*3ac0a46fSAndroid Build Coastguard Worker
4356*3ac0a46fSAndroid Build Coastguard Worker /*
4357*3ac0a46fSAndroid Build Coastguard Worker * Second pass: extract other information.
4358*3ac0a46fSAndroid Build Coastguard Worker */
4359*3ac0a46fSAndroid Build Coastguard Worker for (di = 0, dp = dir; di < dircount; di++, dp++)
4360*3ac0a46fSAndroid Build Coastguard Worker {
4361*3ac0a46fSAndroid Build Coastguard Worker if (!dp->tdir_ignore)
4362*3ac0a46fSAndroid Build Coastguard Worker {
4363*3ac0a46fSAndroid Build Coastguard Worker switch (dp->tdir_tag)
4364*3ac0a46fSAndroid Build Coastguard Worker {
4365*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_MINSAMPLEVALUE:
4366*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_MAXSAMPLEVALUE:
4367*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_BITSPERSAMPLE:
4368*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_DATATYPE:
4369*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_SAMPLEFORMAT:
4370*3ac0a46fSAndroid Build Coastguard Worker /*
4371*3ac0a46fSAndroid Build Coastguard Worker * The MinSampleValue, MaxSampleValue, BitsPerSample
4372*3ac0a46fSAndroid Build Coastguard Worker * DataType and SampleFormat tags are supposed to be
4373*3ac0a46fSAndroid Build Coastguard Worker * written as one value/sample, but some vendors
4374*3ac0a46fSAndroid Build Coastguard Worker * incorrectly write one value only -- so we accept
4375*3ac0a46fSAndroid Build Coastguard Worker * that as well (yuck). Other vendors write correct
4376*3ac0a46fSAndroid Build Coastguard Worker * value for NumberOfSamples, but incorrect one for
4377*3ac0a46fSAndroid Build Coastguard Worker * BitsPerSample and friends, and we will read this
4378*3ac0a46fSAndroid Build Coastguard Worker * too.
4379*3ac0a46fSAndroid Build Coastguard Worker */
4380*3ac0a46fSAndroid Build Coastguard Worker {
4381*3ac0a46fSAndroid Build Coastguard Worker uint16_t value;
4382*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
4383*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryShort(tif, dp, &value);
4384*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrCount)
4385*3ac0a46fSAndroid Build Coastguard Worker err =
4386*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryPersampleShort(tif, dp, &value);
4387*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
4388*3ac0a46fSAndroid Build Coastguard Worker {
4389*3ac0a46fSAndroid Build Coastguard Worker fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4390*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryOutputErr(
4391*3ac0a46fSAndroid Build Coastguard Worker tif, err, module,
4392*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name : "unknown tagname", 0);
4393*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4394*3ac0a46fSAndroid Build Coastguard Worker }
4395*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, dp->tdir_tag, value))
4396*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4397*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_tag == TIFFTAG_BITSPERSAMPLE)
4398*3ac0a46fSAndroid Build Coastguard Worker bitspersample_read = TRUE;
4399*3ac0a46fSAndroid Build Coastguard Worker }
4400*3ac0a46fSAndroid Build Coastguard Worker break;
4401*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_SMINSAMPLEVALUE:
4402*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_SMAXSAMPLEVALUE:
4403*3ac0a46fSAndroid Build Coastguard Worker {
4404*3ac0a46fSAndroid Build Coastguard Worker
4405*3ac0a46fSAndroid Build Coastguard Worker double *data = NULL;
4406*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
4407*3ac0a46fSAndroid Build Coastguard Worker uint32_t saved_flags;
4408*3ac0a46fSAndroid Build Coastguard Worker int m;
4409*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count !=
4410*3ac0a46fSAndroid Build Coastguard Worker (uint64_t)tif->tif_dir.td_samplesperpixel)
4411*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
4412*3ac0a46fSAndroid Build Coastguard Worker else
4413*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
4414*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
4415*3ac0a46fSAndroid Build Coastguard Worker {
4416*3ac0a46fSAndroid Build Coastguard Worker fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4417*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryOutputErr(
4418*3ac0a46fSAndroid Build Coastguard Worker tif, err, module,
4419*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name : "unknown tagname", 0);
4420*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4421*3ac0a46fSAndroid Build Coastguard Worker }
4422*3ac0a46fSAndroid Build Coastguard Worker saved_flags = tif->tif_flags;
4423*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags |= TIFF_PERSAMPLE;
4424*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, data);
4425*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags = saved_flags;
4426*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
4427*3ac0a46fSAndroid Build Coastguard Worker if (!m)
4428*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4429*3ac0a46fSAndroid Build Coastguard Worker }
4430*3ac0a46fSAndroid Build Coastguard Worker break;
4431*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_STRIPOFFSETS:
4432*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_TILEOFFSETS:
4433*3ac0a46fSAndroid Build Coastguard Worker switch (dp->tdir_type)
4434*3ac0a46fSAndroid Build Coastguard Worker {
4435*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
4436*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
4437*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
4438*3ac0a46fSAndroid Build Coastguard Worker break;
4439*3ac0a46fSAndroid Build Coastguard Worker default:
4440*3ac0a46fSAndroid Build Coastguard Worker /* Warn except if directory typically created with
4441*3ac0a46fSAndroid Build Coastguard Worker * TIFFDeferStrileArrayWriting() */
4442*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_mode == O_RDWR &&
4443*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_count == 0 && dp->tdir_type == 0 &&
4444*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_offset.toff_long8 == 0))
4445*3ac0a46fSAndroid Build Coastguard Worker {
4446*3ac0a46fSAndroid Build Coastguard Worker fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4447*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
4448*3ac0a46fSAndroid Build Coastguard Worker tif, module, "Invalid data type for tag %s",
4449*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name : "unknown tagname");
4450*3ac0a46fSAndroid Build Coastguard Worker }
4451*3ac0a46fSAndroid Build Coastguard Worker break;
4452*3ac0a46fSAndroid Build Coastguard Worker }
4453*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&(tif->tif_dir.td_stripoffset_entry), dp,
4454*3ac0a46fSAndroid Build Coastguard Worker sizeof(TIFFDirEntry));
4455*3ac0a46fSAndroid Build Coastguard Worker break;
4456*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_STRIPBYTECOUNTS:
4457*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_TILEBYTECOUNTS:
4458*3ac0a46fSAndroid Build Coastguard Worker switch (dp->tdir_type)
4459*3ac0a46fSAndroid Build Coastguard Worker {
4460*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
4461*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
4462*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
4463*3ac0a46fSAndroid Build Coastguard Worker break;
4464*3ac0a46fSAndroid Build Coastguard Worker default:
4465*3ac0a46fSAndroid Build Coastguard Worker /* Warn except if directory typically created with
4466*3ac0a46fSAndroid Build Coastguard Worker * TIFFDeferStrileArrayWriting() */
4467*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_mode == O_RDWR &&
4468*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_count == 0 && dp->tdir_type == 0 &&
4469*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_offset.toff_long8 == 0))
4470*3ac0a46fSAndroid Build Coastguard Worker {
4471*3ac0a46fSAndroid Build Coastguard Worker fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4472*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
4473*3ac0a46fSAndroid Build Coastguard Worker tif, module, "Invalid data type for tag %s",
4474*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name : "unknown tagname");
4475*3ac0a46fSAndroid Build Coastguard Worker }
4476*3ac0a46fSAndroid Build Coastguard Worker break;
4477*3ac0a46fSAndroid Build Coastguard Worker }
4478*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&(tif->tif_dir.td_stripbytecount_entry), dp,
4479*3ac0a46fSAndroid Build Coastguard Worker sizeof(TIFFDirEntry));
4480*3ac0a46fSAndroid Build Coastguard Worker break;
4481*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_COLORMAP:
4482*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_TRANSFERFUNCTION:
4483*3ac0a46fSAndroid Build Coastguard Worker {
4484*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
4485*3ac0a46fSAndroid Build Coastguard Worker uint32_t countpersample;
4486*3ac0a46fSAndroid Build Coastguard Worker uint32_t countrequired;
4487*3ac0a46fSAndroid Build Coastguard Worker uint32_t incrementpersample;
4488*3ac0a46fSAndroid Build Coastguard Worker uint16_t *value = NULL;
4489*3ac0a46fSAndroid Build Coastguard Worker /* It would be dangerous to instantiate those tag values */
4490*3ac0a46fSAndroid Build Coastguard Worker /* since if td_bitspersample has not yet been read (due to
4491*3ac0a46fSAndroid Build Coastguard Worker */
4492*3ac0a46fSAndroid Build Coastguard Worker /* unordered tags), it could be read afterwards with a */
4493*3ac0a46fSAndroid Build Coastguard Worker /* values greater than the default one (1), which may cause
4494*3ac0a46fSAndroid Build Coastguard Worker */
4495*3ac0a46fSAndroid Build Coastguard Worker /* crashes in user code */
4496*3ac0a46fSAndroid Build Coastguard Worker if (!bitspersample_read)
4497*3ac0a46fSAndroid Build Coastguard Worker {
4498*3ac0a46fSAndroid Build Coastguard Worker fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4499*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
4500*3ac0a46fSAndroid Build Coastguard Worker tif, module,
4501*3ac0a46fSAndroid Build Coastguard Worker "Ignoring %s since BitsPerSample tag not found",
4502*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name : "unknown tagname");
4503*3ac0a46fSAndroid Build Coastguard Worker continue;
4504*3ac0a46fSAndroid Build Coastguard Worker }
4505*3ac0a46fSAndroid Build Coastguard Worker /* ColorMap or TransferFunction for high bit */
4506*3ac0a46fSAndroid Build Coastguard Worker /* depths do not make much sense and could be */
4507*3ac0a46fSAndroid Build Coastguard Worker /* used as a denial of service vector */
4508*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_bitspersample > 24)
4509*3ac0a46fSAndroid Build Coastguard Worker {
4510*3ac0a46fSAndroid Build Coastguard Worker fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4511*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
4512*3ac0a46fSAndroid Build Coastguard Worker tif, module,
4513*3ac0a46fSAndroid Build Coastguard Worker "Ignoring %s because BitsPerSample=%" PRIu16 ">24",
4514*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name : "unknown tagname",
4515*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_bitspersample);
4516*3ac0a46fSAndroid Build Coastguard Worker continue;
4517*3ac0a46fSAndroid Build Coastguard Worker }
4518*3ac0a46fSAndroid Build Coastguard Worker countpersample = (1U << tif->tif_dir.td_bitspersample);
4519*3ac0a46fSAndroid Build Coastguard Worker if ((dp->tdir_tag == TIFFTAG_TRANSFERFUNCTION) &&
4520*3ac0a46fSAndroid Build Coastguard Worker (dp->tdir_count == (uint64_t)countpersample))
4521*3ac0a46fSAndroid Build Coastguard Worker {
4522*3ac0a46fSAndroid Build Coastguard Worker countrequired = countpersample;
4523*3ac0a46fSAndroid Build Coastguard Worker incrementpersample = 0;
4524*3ac0a46fSAndroid Build Coastguard Worker }
4525*3ac0a46fSAndroid Build Coastguard Worker else
4526*3ac0a46fSAndroid Build Coastguard Worker {
4527*3ac0a46fSAndroid Build Coastguard Worker countrequired = 3 * countpersample;
4528*3ac0a46fSAndroid Build Coastguard Worker incrementpersample = countpersample;
4529*3ac0a46fSAndroid Build Coastguard Worker }
4530*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count != (uint64_t)countrequired)
4531*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
4532*3ac0a46fSAndroid Build Coastguard Worker else
4533*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryShortArray(tif, dp, &value);
4534*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
4535*3ac0a46fSAndroid Build Coastguard Worker {
4536*3ac0a46fSAndroid Build Coastguard Worker fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4537*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryOutputErr(
4538*3ac0a46fSAndroid Build Coastguard Worker tif, err, module,
4539*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name : "unknown tagname", 1);
4540*3ac0a46fSAndroid Build Coastguard Worker }
4541*3ac0a46fSAndroid Build Coastguard Worker else
4542*3ac0a46fSAndroid Build Coastguard Worker {
4543*3ac0a46fSAndroid Build Coastguard Worker TIFFSetField(tif, dp->tdir_tag, value,
4544*3ac0a46fSAndroid Build Coastguard Worker value + incrementpersample,
4545*3ac0a46fSAndroid Build Coastguard Worker value + 2 * incrementpersample);
4546*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, value);
4547*3ac0a46fSAndroid Build Coastguard Worker }
4548*3ac0a46fSAndroid Build Coastguard Worker }
4549*3ac0a46fSAndroid Build Coastguard Worker break;
4550*3ac0a46fSAndroid Build Coastguard Worker /* BEGIN REV 4.0 COMPATIBILITY */
4551*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_OSUBFILETYPE:
4552*3ac0a46fSAndroid Build Coastguard Worker {
4553*3ac0a46fSAndroid Build Coastguard Worker uint16_t valueo;
4554*3ac0a46fSAndroid Build Coastguard Worker uint32_t value;
4555*3ac0a46fSAndroid Build Coastguard Worker if (TIFFReadDirEntryShort(tif, dp, &valueo) ==
4556*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryErrOk)
4557*3ac0a46fSAndroid Build Coastguard Worker {
4558*3ac0a46fSAndroid Build Coastguard Worker switch (valueo)
4559*3ac0a46fSAndroid Build Coastguard Worker {
4560*3ac0a46fSAndroid Build Coastguard Worker case OFILETYPE_REDUCEDIMAGE:
4561*3ac0a46fSAndroid Build Coastguard Worker value = FILETYPE_REDUCEDIMAGE;
4562*3ac0a46fSAndroid Build Coastguard Worker break;
4563*3ac0a46fSAndroid Build Coastguard Worker case OFILETYPE_PAGE:
4564*3ac0a46fSAndroid Build Coastguard Worker value = FILETYPE_PAGE;
4565*3ac0a46fSAndroid Build Coastguard Worker break;
4566*3ac0a46fSAndroid Build Coastguard Worker default:
4567*3ac0a46fSAndroid Build Coastguard Worker value = 0;
4568*3ac0a46fSAndroid Build Coastguard Worker break;
4569*3ac0a46fSAndroid Build Coastguard Worker }
4570*3ac0a46fSAndroid Build Coastguard Worker if (value != 0)
4571*3ac0a46fSAndroid Build Coastguard Worker TIFFSetField(tif, TIFFTAG_SUBFILETYPE, value);
4572*3ac0a46fSAndroid Build Coastguard Worker }
4573*3ac0a46fSAndroid Build Coastguard Worker }
4574*3ac0a46fSAndroid Build Coastguard Worker break;
4575*3ac0a46fSAndroid Build Coastguard Worker /* END REV 4.0 COMPATIBILITY */
4576*3ac0a46fSAndroid Build Coastguard Worker #if 0
4577*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_EP_BATTERYLEVEL:
4578*3ac0a46fSAndroid Build Coastguard Worker /* TIFFTAG_EP_BATTERYLEVEL can be RATIONAL or ASCII.
4579*3ac0a46fSAndroid Build Coastguard Worker * LibTiff defines it as ASCII and converts RATIONAL to an
4580*3ac0a46fSAndroid Build Coastguard Worker * ASCII string. */
4581*3ac0a46fSAndroid Build Coastguard Worker switch (dp->tdir_type)
4582*3ac0a46fSAndroid Build Coastguard Worker {
4583*3ac0a46fSAndroid Build Coastguard Worker case TIFF_RATIONAL:
4584*3ac0a46fSAndroid Build Coastguard Worker {
4585*3ac0a46fSAndroid Build Coastguard Worker /* Read rational and convert to ASCII*/
4586*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
4587*3ac0a46fSAndroid Build Coastguard Worker TIFFRational_t rValue;
4588*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryCheckedRationalDirect(
4589*3ac0a46fSAndroid Build Coastguard Worker tif, dp, &rValue);
4590*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
4591*3ac0a46fSAndroid Build Coastguard Worker {
4592*3ac0a46fSAndroid Build Coastguard Worker fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4593*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryOutputErr(
4594*3ac0a46fSAndroid Build Coastguard Worker tif, err, module,
4595*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name : "unknown tagname",
4596*3ac0a46fSAndroid Build Coastguard Worker 1);
4597*3ac0a46fSAndroid Build Coastguard Worker }
4598*3ac0a46fSAndroid Build Coastguard Worker else
4599*3ac0a46fSAndroid Build Coastguard Worker {
4600*3ac0a46fSAndroid Build Coastguard Worker char szAux[32];
4601*3ac0a46fSAndroid Build Coastguard Worker snprintf(szAux, sizeof(szAux) - 1, "%d/%d",
4602*3ac0a46fSAndroid Build Coastguard Worker rValue.uNum, rValue.uDenom);
4603*3ac0a46fSAndroid Build Coastguard Worker TIFFSetField(tif, dp->tdir_tag, szAux);
4604*3ac0a46fSAndroid Build Coastguard Worker }
4605*3ac0a46fSAndroid Build Coastguard Worker }
4606*3ac0a46fSAndroid Build Coastguard Worker break;
4607*3ac0a46fSAndroid Build Coastguard Worker case TIFF_ASCII:
4608*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFFetchNormalTag(tif, dp, TRUE);
4609*3ac0a46fSAndroid Build Coastguard Worker break;
4610*3ac0a46fSAndroid Build Coastguard Worker default:
4611*3ac0a46fSAndroid Build Coastguard Worker fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4612*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
4613*3ac0a46fSAndroid Build Coastguard Worker "Invalid data type for tag %s. "
4614*3ac0a46fSAndroid Build Coastguard Worker "ASCII or RATIONAL expected",
4615*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name
4616*3ac0a46fSAndroid Build Coastguard Worker : "unknown tagname");
4617*3ac0a46fSAndroid Build Coastguard Worker break;
4618*3ac0a46fSAndroid Build Coastguard Worker }
4619*3ac0a46fSAndroid Build Coastguard Worker break;
4620*3ac0a46fSAndroid Build Coastguard Worker #endif
4621*3ac0a46fSAndroid Build Coastguard Worker default:
4622*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFFetchNormalTag(tif, dp, TRUE);
4623*3ac0a46fSAndroid Build Coastguard Worker break;
4624*3ac0a46fSAndroid Build Coastguard Worker }
4625*3ac0a46fSAndroid Build Coastguard Worker } /* -- if (!dp->tdir_ignore) */
4626*3ac0a46fSAndroid Build Coastguard Worker } /* -- for-loop -- */
4627*3ac0a46fSAndroid Build Coastguard Worker
4628*3ac0a46fSAndroid Build Coastguard Worker /*
4629*3ac0a46fSAndroid Build Coastguard Worker * OJPEG hack:
4630*3ac0a46fSAndroid Build Coastguard Worker * - If a) compression is OJPEG, and b) photometric tag is missing,
4631*3ac0a46fSAndroid Build Coastguard Worker * then we consistently find that photometric should be YCbCr
4632*3ac0a46fSAndroid Build Coastguard Worker * - If a) compression is OJPEG, and b) photometric tag says it's RGB,
4633*3ac0a46fSAndroid Build Coastguard Worker * then we consistently find that the buggy implementation of the
4634*3ac0a46fSAndroid Build Coastguard Worker * buggy compression scheme matches photometric YCbCr instead.
4635*3ac0a46fSAndroid Build Coastguard Worker * - If a) compression is OJPEG, and b) bitspersample tag is missing,
4636*3ac0a46fSAndroid Build Coastguard Worker * then we consistently find bitspersample should be 8.
4637*3ac0a46fSAndroid Build Coastguard Worker * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
4638*3ac0a46fSAndroid Build Coastguard Worker * and c) photometric is RGB or YCbCr, then we consistently find
4639*3ac0a46fSAndroid Build Coastguard Worker * samplesperpixel should be 3
4640*3ac0a46fSAndroid Build Coastguard Worker * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
4641*3ac0a46fSAndroid Build Coastguard Worker * and c) photometric is MINISWHITE or MINISBLACK, then we consistently
4642*3ac0a46fSAndroid Build Coastguard Worker * find samplesperpixel should be 3
4643*3ac0a46fSAndroid Build Coastguard Worker */
4644*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_compression == COMPRESSION_OJPEG)
4645*3ac0a46fSAndroid Build Coastguard Worker {
4646*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFieldSet(tif, FIELD_PHOTOMETRIC))
4647*3ac0a46fSAndroid Build Coastguard Worker {
4648*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
4649*3ac0a46fSAndroid Build Coastguard Worker tif, module,
4650*3ac0a46fSAndroid Build Coastguard Worker "Photometric tag is missing, assuming data is YCbCr");
4651*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR))
4652*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4653*3ac0a46fSAndroid Build Coastguard Worker }
4654*3ac0a46fSAndroid Build Coastguard Worker else if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB)
4655*3ac0a46fSAndroid Build Coastguard Worker {
4656*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_photometric = PHOTOMETRIC_YCBCR;
4657*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
4658*3ac0a46fSAndroid Build Coastguard Worker "Photometric tag value assumed incorrect, "
4659*3ac0a46fSAndroid Build Coastguard Worker "assuming data is YCbCr instead of RGB");
4660*3ac0a46fSAndroid Build Coastguard Worker }
4661*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
4662*3ac0a46fSAndroid Build Coastguard Worker {
4663*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
4664*3ac0a46fSAndroid Build Coastguard Worker tif, module,
4665*3ac0a46fSAndroid Build Coastguard Worker "BitsPerSample tag is missing, assuming 8 bits per sample");
4666*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8))
4667*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4668*3ac0a46fSAndroid Build Coastguard Worker }
4669*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
4670*3ac0a46fSAndroid Build Coastguard Worker {
4671*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB)
4672*3ac0a46fSAndroid Build Coastguard Worker {
4673*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
4674*3ac0a46fSAndroid Build Coastguard Worker "SamplesPerPixel tag is missing, "
4675*3ac0a46fSAndroid Build Coastguard Worker "assuming correct SamplesPerPixel value is 3");
4676*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3))
4677*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4678*3ac0a46fSAndroid Build Coastguard Worker }
4679*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR)
4680*3ac0a46fSAndroid Build Coastguard Worker {
4681*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
4682*3ac0a46fSAndroid Build Coastguard Worker "SamplesPerPixel tag is missing, "
4683*3ac0a46fSAndroid Build Coastguard Worker "applying correct SamplesPerPixel value of 3");
4684*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3))
4685*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4686*3ac0a46fSAndroid Build Coastguard Worker }
4687*3ac0a46fSAndroid Build Coastguard Worker else if ((tif->tif_dir.td_photometric == PHOTOMETRIC_MINISWHITE) ||
4688*3ac0a46fSAndroid Build Coastguard Worker (tif->tif_dir.td_photometric == PHOTOMETRIC_MINISBLACK))
4689*3ac0a46fSAndroid Build Coastguard Worker {
4690*3ac0a46fSAndroid Build Coastguard Worker /*
4691*3ac0a46fSAndroid Build Coastguard Worker * SamplesPerPixel tag is missing, but is not required
4692*3ac0a46fSAndroid Build Coastguard Worker * by spec. Assume correct SamplesPerPixel value of 1.
4693*3ac0a46fSAndroid Build Coastguard Worker */
4694*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1))
4695*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4696*3ac0a46fSAndroid Build Coastguard Worker }
4697*3ac0a46fSAndroid Build Coastguard Worker }
4698*3ac0a46fSAndroid Build Coastguard Worker }
4699*3ac0a46fSAndroid Build Coastguard Worker
4700*3ac0a46fSAndroid Build Coastguard Worker /*
4701*3ac0a46fSAndroid Build Coastguard Worker * Setup appropriate structures (by strip or by tile)
4702*3ac0a46fSAndroid Build Coastguard Worker * We do that only after the above OJPEG hack which alters SamplesPerPixel
4703*3ac0a46fSAndroid Build Coastguard Worker * and thus influences the number of strips in the separate planarconfig.
4704*3ac0a46fSAndroid Build Coastguard Worker */
4705*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
4706*3ac0a46fSAndroid Build Coastguard Worker {
4707*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);
4708*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
4709*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
4710*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
4711*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_ISTILED;
4712*3ac0a46fSAndroid Build Coastguard Worker }
4713*3ac0a46fSAndroid Build Coastguard Worker else
4714*3ac0a46fSAndroid Build Coastguard Worker {
4715*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
4716*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags |= TIFF_ISTILED;
4717*3ac0a46fSAndroid Build Coastguard Worker }
4718*3ac0a46fSAndroid Build Coastguard Worker if (!tif->tif_dir.td_nstrips)
4719*3ac0a46fSAndroid Build Coastguard Worker {
4720*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Cannot handle zero number of %s",
4721*3ac0a46fSAndroid Build Coastguard Worker isTiled(tif) ? "tiles" : "strips");
4722*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4723*3ac0a46fSAndroid Build Coastguard Worker }
4724*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_nstrips > INT_MAX)
4725*3ac0a46fSAndroid Build Coastguard Worker {
4726*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExt(tif->tif_clientdata, module,
4727*3ac0a46fSAndroid Build Coastguard Worker "Cannot handle %u number of %s",
4728*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nstrips,
4729*3ac0a46fSAndroid Build Coastguard Worker isTiled(tif) ? "tiles" : "strips");
4730*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4731*3ac0a46fSAndroid Build Coastguard Worker }
4732*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
4733*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
4734*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
4735*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
4736*3ac0a46fSAndroid Build Coastguard Worker {
4737*3ac0a46fSAndroid Build Coastguard Worker #ifdef OJPEG_SUPPORT
4738*3ac0a46fSAndroid Build Coastguard Worker if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) &&
4739*3ac0a46fSAndroid Build Coastguard Worker (isTiled(tif) == 0) && (tif->tif_dir.td_nstrips == 1))
4740*3ac0a46fSAndroid Build Coastguard Worker {
4741*3ac0a46fSAndroid Build Coastguard Worker /*
4742*3ac0a46fSAndroid Build Coastguard Worker * XXX: OJPEG hack.
4743*3ac0a46fSAndroid Build Coastguard Worker * If a) compression is OJPEG, b) it's not a tiled TIFF,
4744*3ac0a46fSAndroid Build Coastguard Worker * and c) the number of strips is 1,
4745*3ac0a46fSAndroid Build Coastguard Worker * then we tolerate the absence of stripoffsets tag,
4746*3ac0a46fSAndroid Build Coastguard Worker * because, presumably, all required data is in the
4747*3ac0a46fSAndroid Build Coastguard Worker * JpegInterchangeFormat stream.
4748*3ac0a46fSAndroid Build Coastguard Worker */
4749*3ac0a46fSAndroid Build Coastguard Worker TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
4750*3ac0a46fSAndroid Build Coastguard Worker }
4751*3ac0a46fSAndroid Build Coastguard Worker else
4752*3ac0a46fSAndroid Build Coastguard Worker #endif
4753*3ac0a46fSAndroid Build Coastguard Worker {
4754*3ac0a46fSAndroid Build Coastguard Worker MissingRequired(tif, isTiled(tif) ? "TileOffsets" : "StripOffsets");
4755*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4756*3ac0a46fSAndroid Build Coastguard Worker }
4757*3ac0a46fSAndroid Build Coastguard Worker }
4758*3ac0a46fSAndroid Build Coastguard Worker
4759*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_mode == O_RDWR &&
4760*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
4761*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
4762*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
4763*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
4764*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
4765*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
4766*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
4767*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)
4768*3ac0a46fSAndroid Build Coastguard Worker {
4769*3ac0a46fSAndroid Build Coastguard Worker /* Directory typically created with TIFFDeferStrileArrayWriting() */
4770*3ac0a46fSAndroid Build Coastguard Worker TIFFSetupStrips(tif);
4771*3ac0a46fSAndroid Build Coastguard Worker }
4772*3ac0a46fSAndroid Build Coastguard Worker else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD))
4773*3ac0a46fSAndroid Build Coastguard Worker {
4774*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0)
4775*3ac0a46fSAndroid Build Coastguard Worker {
4776*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFetchStripThing(tif, &(tif->tif_dir.td_stripoffset_entry),
4777*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nstrips,
4778*3ac0a46fSAndroid Build Coastguard Worker &tif->tif_dir.td_stripoffset_p))
4779*3ac0a46fSAndroid Build Coastguard Worker {
4780*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4781*3ac0a46fSAndroid Build Coastguard Worker }
4782*3ac0a46fSAndroid Build Coastguard Worker }
4783*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0)
4784*3ac0a46fSAndroid Build Coastguard Worker {
4785*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFetchStripThing(
4786*3ac0a46fSAndroid Build Coastguard Worker tif, &(tif->tif_dir.td_stripbytecount_entry),
4787*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nstrips, &tif->tif_dir.td_stripbytecount_p))
4788*3ac0a46fSAndroid Build Coastguard Worker {
4789*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4790*3ac0a46fSAndroid Build Coastguard Worker }
4791*3ac0a46fSAndroid Build Coastguard Worker }
4792*3ac0a46fSAndroid Build Coastguard Worker }
4793*3ac0a46fSAndroid Build Coastguard Worker
4794*3ac0a46fSAndroid Build Coastguard Worker /*
4795*3ac0a46fSAndroid Build Coastguard Worker * Make sure all non-color channels are extrasamples.
4796*3ac0a46fSAndroid Build Coastguard Worker * If it's not the case, define them as such.
4797*3ac0a46fSAndroid Build Coastguard Worker */
4798*3ac0a46fSAndroid Build Coastguard Worker color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric);
4799*3ac0a46fSAndroid Build Coastguard Worker if (color_channels &&
4800*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples >
4801*3ac0a46fSAndroid Build Coastguard Worker color_channels)
4802*3ac0a46fSAndroid Build Coastguard Worker {
4803*3ac0a46fSAndroid Build Coastguard Worker uint16_t old_extrasamples;
4804*3ac0a46fSAndroid Build Coastguard Worker uint16_t *new_sampleinfo;
4805*3ac0a46fSAndroid Build Coastguard Worker
4806*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
4807*3ac0a46fSAndroid Build Coastguard Worker tif, module,
4808*3ac0a46fSAndroid Build Coastguard Worker "Sum of Photometric type-related "
4809*3ac0a46fSAndroid Build Coastguard Worker "color channels and ExtraSamples doesn't match SamplesPerPixel. "
4810*3ac0a46fSAndroid Build Coastguard Worker "Defining non-color channels as ExtraSamples.");
4811*3ac0a46fSAndroid Build Coastguard Worker
4812*3ac0a46fSAndroid Build Coastguard Worker old_extrasamples = tif->tif_dir.td_extrasamples;
4813*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_extrasamples =
4814*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(tif->tif_dir.td_samplesperpixel - color_channels);
4815*3ac0a46fSAndroid Build Coastguard Worker
4816*3ac0a46fSAndroid Build Coastguard Worker // sampleinfo should contain information relative to these new extra
4817*3ac0a46fSAndroid Build Coastguard Worker // samples
4818*3ac0a46fSAndroid Build Coastguard Worker new_sampleinfo = (uint16_t *)_TIFFcallocExt(
4819*3ac0a46fSAndroid Build Coastguard Worker tif, tif->tif_dir.td_extrasamples, sizeof(uint16_t));
4820*3ac0a46fSAndroid Build Coastguard Worker if (!new_sampleinfo)
4821*3ac0a46fSAndroid Build Coastguard Worker {
4822*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
4823*3ac0a46fSAndroid Build Coastguard Worker "Failed to allocate memory for "
4824*3ac0a46fSAndroid Build Coastguard Worker "temporary new sampleinfo array "
4825*3ac0a46fSAndroid Build Coastguard Worker "(%" PRIu16 " 16 bit elements)",
4826*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_extrasamples);
4827*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4828*3ac0a46fSAndroid Build Coastguard Worker }
4829*3ac0a46fSAndroid Build Coastguard Worker
4830*3ac0a46fSAndroid Build Coastguard Worker if (old_extrasamples > 0)
4831*3ac0a46fSAndroid Build Coastguard Worker memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo,
4832*3ac0a46fSAndroid Build Coastguard Worker old_extrasamples * sizeof(uint16_t));
4833*3ac0a46fSAndroid Build Coastguard Worker _TIFFsetShortArrayExt(tif, &tif->tif_dir.td_sampleinfo, new_sampleinfo,
4834*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_extrasamples);
4835*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, new_sampleinfo);
4836*3ac0a46fSAndroid Build Coastguard Worker }
4837*3ac0a46fSAndroid Build Coastguard Worker
4838*3ac0a46fSAndroid Build Coastguard Worker /*
4839*3ac0a46fSAndroid Build Coastguard Worker * Verify Palette image has a Colormap.
4840*3ac0a46fSAndroid Build Coastguard Worker */
4841*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE &&
4842*3ac0a46fSAndroid Build Coastguard Worker !TIFFFieldSet(tif, FIELD_COLORMAP))
4843*3ac0a46fSAndroid Build Coastguard Worker {
4844*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_bitspersample >= 8 &&
4845*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_samplesperpixel == 3)
4846*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_photometric = PHOTOMETRIC_RGB;
4847*3ac0a46fSAndroid Build Coastguard Worker else if (tif->tif_dir.td_bitspersample >= 8)
4848*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK;
4849*3ac0a46fSAndroid Build Coastguard Worker else
4850*3ac0a46fSAndroid Build Coastguard Worker {
4851*3ac0a46fSAndroid Build Coastguard Worker MissingRequired(tif, "Colormap");
4852*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4853*3ac0a46fSAndroid Build Coastguard Worker }
4854*3ac0a46fSAndroid Build Coastguard Worker }
4855*3ac0a46fSAndroid Build Coastguard Worker /*
4856*3ac0a46fSAndroid Build Coastguard Worker * OJPEG hack:
4857*3ac0a46fSAndroid Build Coastguard Worker * We do no further messing with strip/tile offsets/bytecounts in OJPEG
4858*3ac0a46fSAndroid Build Coastguard Worker * TIFFs
4859*3ac0a46fSAndroid Build Coastguard Worker */
4860*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_compression != COMPRESSION_OJPEG)
4861*3ac0a46fSAndroid Build Coastguard Worker {
4862*3ac0a46fSAndroid Build Coastguard Worker /*
4863*3ac0a46fSAndroid Build Coastguard Worker * Attempt to deal with a missing StripByteCounts tag.
4864*3ac0a46fSAndroid Build Coastguard Worker */
4865*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS))
4866*3ac0a46fSAndroid Build Coastguard Worker {
4867*3ac0a46fSAndroid Build Coastguard Worker /*
4868*3ac0a46fSAndroid Build Coastguard Worker * Some manufacturers violate the spec by not giving
4869*3ac0a46fSAndroid Build Coastguard Worker * the size of the strips. In this case, assume there
4870*3ac0a46fSAndroid Build Coastguard Worker * is one uncompressed strip of data.
4871*3ac0a46fSAndroid Build Coastguard Worker */
4872*3ac0a46fSAndroid Build Coastguard Worker if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
4873*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nstrips > 1) ||
4874*3ac0a46fSAndroid Build Coastguard Worker (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE &&
4875*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nstrips !=
4876*3ac0a46fSAndroid Build Coastguard Worker (uint32_t)tif->tif_dir.td_samplesperpixel))
4877*3ac0a46fSAndroid Build Coastguard Worker {
4878*3ac0a46fSAndroid Build Coastguard Worker MissingRequired(tif, "StripByteCounts");
4879*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4880*3ac0a46fSAndroid Build Coastguard Worker }
4881*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
4882*3ac0a46fSAndroid Build Coastguard Worker tif, module,
4883*3ac0a46fSAndroid Build Coastguard Worker "TIFF directory is missing required "
4884*3ac0a46fSAndroid Build Coastguard Worker "\"StripByteCounts\" field, calculating from imagelength");
4885*3ac0a46fSAndroid Build Coastguard Worker if (EstimateStripByteCounts(tif, dir, dircount) < 0)
4886*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4887*3ac0a46fSAndroid Build Coastguard Worker }
4888*3ac0a46fSAndroid Build Coastguard Worker else if (tif->tif_dir.td_nstrips == 1 &&
4889*3ac0a46fSAndroid Build Coastguard Worker !(tif->tif_flags & TIFF_ISTILED) && ByteCountLooksBad(tif))
4890*3ac0a46fSAndroid Build Coastguard Worker {
4891*3ac0a46fSAndroid Build Coastguard Worker /*
4892*3ac0a46fSAndroid Build Coastguard Worker * XXX: Plexus (and others) sometimes give a value of
4893*3ac0a46fSAndroid Build Coastguard Worker * zero for a tag when they don't know what the
4894*3ac0a46fSAndroid Build Coastguard Worker * correct value is! Try and handle the simple case
4895*3ac0a46fSAndroid Build Coastguard Worker * of estimating the size of a one strip image.
4896*3ac0a46fSAndroid Build Coastguard Worker */
4897*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
4898*3ac0a46fSAndroid Build Coastguard Worker "Bogus \"StripByteCounts\" field, ignoring and "
4899*3ac0a46fSAndroid Build Coastguard Worker "calculating from imagelength");
4900*3ac0a46fSAndroid Build Coastguard Worker if (EstimateStripByteCounts(tif, dir, dircount) < 0)
4901*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4902*3ac0a46fSAndroid Build Coastguard Worker }
4903*3ac0a46fSAndroid Build Coastguard Worker else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) &&
4904*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
4905*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nstrips > 2 &&
4906*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_compression == COMPRESSION_NONE &&
4907*3ac0a46fSAndroid Build Coastguard Worker TIFFGetStrileByteCount(tif, 0) !=
4908*3ac0a46fSAndroid Build Coastguard Worker TIFFGetStrileByteCount(tif, 1) &&
4909*3ac0a46fSAndroid Build Coastguard Worker TIFFGetStrileByteCount(tif, 0) != 0 &&
4910*3ac0a46fSAndroid Build Coastguard Worker TIFFGetStrileByteCount(tif, 1) != 0)
4911*3ac0a46fSAndroid Build Coastguard Worker {
4912*3ac0a46fSAndroid Build Coastguard Worker /*
4913*3ac0a46fSAndroid Build Coastguard Worker * XXX: Some vendors fill StripByteCount array with
4914*3ac0a46fSAndroid Build Coastguard Worker * absolutely wrong values (it can be equal to
4915*3ac0a46fSAndroid Build Coastguard Worker * StripOffset array, for example). Catch this case
4916*3ac0a46fSAndroid Build Coastguard Worker * here.
4917*3ac0a46fSAndroid Build Coastguard Worker *
4918*3ac0a46fSAndroid Build Coastguard Worker * We avoid this check if deferring strile loading
4919*3ac0a46fSAndroid Build Coastguard Worker * as it would always force us to load the strip/tile
4920*3ac0a46fSAndroid Build Coastguard Worker * information.
4921*3ac0a46fSAndroid Build Coastguard Worker */
4922*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
4923*3ac0a46fSAndroid Build Coastguard Worker "Wrong \"StripByteCounts\" field, ignoring and "
4924*3ac0a46fSAndroid Build Coastguard Worker "calculating from imagelength");
4925*3ac0a46fSAndroid Build Coastguard Worker if (EstimateStripByteCounts(tif, dir, dircount) < 0)
4926*3ac0a46fSAndroid Build Coastguard Worker goto bad;
4927*3ac0a46fSAndroid Build Coastguard Worker }
4928*3ac0a46fSAndroid Build Coastguard Worker }
4929*3ac0a46fSAndroid Build Coastguard Worker if (dir)
4930*3ac0a46fSAndroid Build Coastguard Worker {
4931*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, dir);
4932*3ac0a46fSAndroid Build Coastguard Worker dir = NULL;
4933*3ac0a46fSAndroid Build Coastguard Worker }
4934*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
4935*3ac0a46fSAndroid Build Coastguard Worker {
4936*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_bitspersample >= 16)
4937*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_maxsamplevalue = 0xFFFF;
4938*3ac0a46fSAndroid Build Coastguard Worker else
4939*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_maxsamplevalue =
4940*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)((1L << tif->tif_dir.td_bitspersample) - 1);
4941*3ac0a46fSAndroid Build Coastguard Worker }
4942*3ac0a46fSAndroid Build Coastguard Worker
4943*3ac0a46fSAndroid Build Coastguard Worker #ifdef STRIPBYTECOUNTSORTED_UNUSED
4944*3ac0a46fSAndroid Build Coastguard Worker /*
4945*3ac0a46fSAndroid Build Coastguard Worker * XXX: We can optimize checking for the strip bounds using the sorted
4946*3ac0a46fSAndroid Build Coastguard Worker * bytecounts array. See also comments for TIFFAppendToStrip()
4947*3ac0a46fSAndroid Build Coastguard Worker * function in tif_write.c.
4948*3ac0a46fSAndroid Build Coastguard Worker */
4949*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips > 1)
4950*3ac0a46fSAndroid Build Coastguard Worker {
4951*3ac0a46fSAndroid Build Coastguard Worker uint32_t strip;
4952*3ac0a46fSAndroid Build Coastguard Worker
4953*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecountsorted = 1;
4954*3ac0a46fSAndroid Build Coastguard Worker for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++)
4955*3ac0a46fSAndroid Build Coastguard Worker {
4956*3ac0a46fSAndroid Build Coastguard Worker if (TIFFGetStrileOffset(tif, strip - 1) >
4957*3ac0a46fSAndroid Build Coastguard Worker TIFFGetStrileOffset(tif, strip))
4958*3ac0a46fSAndroid Build Coastguard Worker {
4959*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecountsorted = 0;
4960*3ac0a46fSAndroid Build Coastguard Worker break;
4961*3ac0a46fSAndroid Build Coastguard Worker }
4962*3ac0a46fSAndroid Build Coastguard Worker }
4963*3ac0a46fSAndroid Build Coastguard Worker }
4964*3ac0a46fSAndroid Build Coastguard Worker #endif
4965*3ac0a46fSAndroid Build Coastguard Worker
4966*3ac0a46fSAndroid Build Coastguard Worker /*
4967*3ac0a46fSAndroid Build Coastguard Worker * An opportunity for compression mode dependent tag fixup
4968*3ac0a46fSAndroid Build Coastguard Worker */
4969*3ac0a46fSAndroid Build Coastguard Worker (*tif->tif_fixuptags)(tif);
4970*3ac0a46fSAndroid Build Coastguard Worker
4971*3ac0a46fSAndroid Build Coastguard Worker /*
4972*3ac0a46fSAndroid Build Coastguard Worker * Some manufacturers make life difficult by writing
4973*3ac0a46fSAndroid Build Coastguard Worker * large amounts of uncompressed data as a single strip.
4974*3ac0a46fSAndroid Build Coastguard Worker * This is contrary to the recommendations of the spec.
4975*3ac0a46fSAndroid Build Coastguard Worker * The following makes an attempt at breaking such images
4976*3ac0a46fSAndroid Build Coastguard Worker * into strips closer to the recommended 8k bytes. A
4977*3ac0a46fSAndroid Build Coastguard Worker * side effect, however, is that the RowsPerStrip tag
4978*3ac0a46fSAndroid Build Coastguard Worker * value may be changed.
4979*3ac0a46fSAndroid Build Coastguard Worker */
4980*3ac0a46fSAndroid Build Coastguard Worker if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) &&
4981*3ac0a46fSAndroid Build Coastguard Worker (tif->tif_dir.td_nstrips == 1) &&
4982*3ac0a46fSAndroid Build Coastguard Worker (tif->tif_dir.td_compression == COMPRESSION_NONE) &&
4983*3ac0a46fSAndroid Build Coastguard Worker ((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP))
4984*3ac0a46fSAndroid Build Coastguard Worker {
4985*3ac0a46fSAndroid Build Coastguard Worker ChopUpSingleUncompressedStrip(tif);
4986*3ac0a46fSAndroid Build Coastguard Worker }
4987*3ac0a46fSAndroid Build Coastguard Worker
4988*3ac0a46fSAndroid Build Coastguard Worker /* There are also uncompressed striped files with strips larger than */
4989*3ac0a46fSAndroid Build Coastguard Worker /* 2 GB, which make them unfriendly with a lot of code. If possible, */
4990*3ac0a46fSAndroid Build Coastguard Worker /* try to expose smaller "virtual" strips. */
4991*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
4992*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_compression == COMPRESSION_NONE &&
4993*3ac0a46fSAndroid Build Coastguard Worker (tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP &&
4994*3ac0a46fSAndroid Build Coastguard Worker TIFFStripSize64(tif) > 0x7FFFFFFFUL)
4995*3ac0a46fSAndroid Build Coastguard Worker {
4996*3ac0a46fSAndroid Build Coastguard Worker TryChopUpUncompressedBigTiff(tif);
4997*3ac0a46fSAndroid Build Coastguard Worker }
4998*3ac0a46fSAndroid Build Coastguard Worker
4999*3ac0a46fSAndroid Build Coastguard Worker /*
5000*3ac0a46fSAndroid Build Coastguard Worker * Clear the dirty directory flag.
5001*3ac0a46fSAndroid Build Coastguard Worker */
5002*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_DIRTYDIRECT;
5003*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_DIRTYSTRIP;
5004*3ac0a46fSAndroid Build Coastguard Worker
5005*3ac0a46fSAndroid Build Coastguard Worker /*
5006*3ac0a46fSAndroid Build Coastguard Worker * Reinitialize i/o since we are starting on a new directory.
5007*3ac0a46fSAndroid Build Coastguard Worker */
5008*3ac0a46fSAndroid Build Coastguard Worker tif->tif_row = (uint32_t)-1;
5009*3ac0a46fSAndroid Build Coastguard Worker tif->tif_curstrip = (uint32_t)-1;
5010*3ac0a46fSAndroid Build Coastguard Worker tif->tif_col = (uint32_t)-1;
5011*3ac0a46fSAndroid Build Coastguard Worker tif->tif_curtile = (uint32_t)-1;
5012*3ac0a46fSAndroid Build Coastguard Worker tif->tif_tilesize = (tmsize_t)-1;
5013*3ac0a46fSAndroid Build Coastguard Worker
5014*3ac0a46fSAndroid Build Coastguard Worker tif->tif_scanlinesize = TIFFScanlineSize(tif);
5015*3ac0a46fSAndroid Build Coastguard Worker if (!tif->tif_scanlinesize)
5016*3ac0a46fSAndroid Build Coastguard Worker {
5017*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Cannot handle zero scanline size");
5018*3ac0a46fSAndroid Build Coastguard Worker return (0);
5019*3ac0a46fSAndroid Build Coastguard Worker }
5020*3ac0a46fSAndroid Build Coastguard Worker
5021*3ac0a46fSAndroid Build Coastguard Worker if (isTiled(tif))
5022*3ac0a46fSAndroid Build Coastguard Worker {
5023*3ac0a46fSAndroid Build Coastguard Worker tif->tif_tilesize = TIFFTileSize(tif);
5024*3ac0a46fSAndroid Build Coastguard Worker if (!tif->tif_tilesize)
5025*3ac0a46fSAndroid Build Coastguard Worker {
5026*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Cannot handle zero tile size");
5027*3ac0a46fSAndroid Build Coastguard Worker return (0);
5028*3ac0a46fSAndroid Build Coastguard Worker }
5029*3ac0a46fSAndroid Build Coastguard Worker }
5030*3ac0a46fSAndroid Build Coastguard Worker else
5031*3ac0a46fSAndroid Build Coastguard Worker {
5032*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFStripSize(tif))
5033*3ac0a46fSAndroid Build Coastguard Worker {
5034*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Cannot handle zero strip size");
5035*3ac0a46fSAndroid Build Coastguard Worker return (0);
5036*3ac0a46fSAndroid Build Coastguard Worker }
5037*3ac0a46fSAndroid Build Coastguard Worker }
5038*3ac0a46fSAndroid Build Coastguard Worker return (1);
5039*3ac0a46fSAndroid Build Coastguard Worker bad:
5040*3ac0a46fSAndroid Build Coastguard Worker if (dir)
5041*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, dir);
5042*3ac0a46fSAndroid Build Coastguard Worker return (0);
5043*3ac0a46fSAndroid Build Coastguard Worker }
5044*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirectoryCheckOrder(TIFF * tif,TIFFDirEntry * dir,uint16_t dircount)5045*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir,
5046*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount)
5047*3ac0a46fSAndroid Build Coastguard Worker {
5048*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFReadDirectoryCheckOrder";
5049*3ac0a46fSAndroid Build Coastguard Worker uint16_t m;
5050*3ac0a46fSAndroid Build Coastguard Worker uint16_t n;
5051*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *o;
5052*3ac0a46fSAndroid Build Coastguard Worker m = 0;
5053*3ac0a46fSAndroid Build Coastguard Worker for (n = 0, o = dir; n < dircount; n++, o++)
5054*3ac0a46fSAndroid Build Coastguard Worker {
5055*3ac0a46fSAndroid Build Coastguard Worker if (o->tdir_tag < m)
5056*3ac0a46fSAndroid Build Coastguard Worker {
5057*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
5058*3ac0a46fSAndroid Build Coastguard Worker "Invalid TIFF directory; tags are not sorted in "
5059*3ac0a46fSAndroid Build Coastguard Worker "ascending order");
5060*3ac0a46fSAndroid Build Coastguard Worker break;
5061*3ac0a46fSAndroid Build Coastguard Worker }
5062*3ac0a46fSAndroid Build Coastguard Worker m = o->tdir_tag + 1;
5063*3ac0a46fSAndroid Build Coastguard Worker }
5064*3ac0a46fSAndroid Build Coastguard Worker }
5065*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirectoryFindEntry(TIFF * tif,TIFFDirEntry * dir,uint16_t dircount,uint16_t tagid)5066*3ac0a46fSAndroid Build Coastguard Worker static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir,
5067*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount,
5068*3ac0a46fSAndroid Build Coastguard Worker uint16_t tagid)
5069*3ac0a46fSAndroid Build Coastguard Worker {
5070*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *m;
5071*3ac0a46fSAndroid Build Coastguard Worker uint16_t n;
5072*3ac0a46fSAndroid Build Coastguard Worker (void)tif;
5073*3ac0a46fSAndroid Build Coastguard Worker for (m = dir, n = 0; n < dircount; m++, n++)
5074*3ac0a46fSAndroid Build Coastguard Worker {
5075*3ac0a46fSAndroid Build Coastguard Worker if (m->tdir_tag == tagid)
5076*3ac0a46fSAndroid Build Coastguard Worker return (m);
5077*3ac0a46fSAndroid Build Coastguard Worker }
5078*3ac0a46fSAndroid Build Coastguard Worker return (0);
5079*3ac0a46fSAndroid Build Coastguard Worker }
5080*3ac0a46fSAndroid Build Coastguard Worker
TIFFReadDirectoryFindFieldInfo(TIFF * tif,uint16_t tagid,uint32_t * fii)5081*3ac0a46fSAndroid Build Coastguard Worker static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid,
5082*3ac0a46fSAndroid Build Coastguard Worker uint32_t *fii)
5083*3ac0a46fSAndroid Build Coastguard Worker {
5084*3ac0a46fSAndroid Build Coastguard Worker int32_t ma, mb, mc;
5085*3ac0a46fSAndroid Build Coastguard Worker ma = -1;
5086*3ac0a46fSAndroid Build Coastguard Worker mc = (int32_t)tif->tif_nfields;
5087*3ac0a46fSAndroid Build Coastguard Worker while (1)
5088*3ac0a46fSAndroid Build Coastguard Worker {
5089*3ac0a46fSAndroid Build Coastguard Worker if (ma + 1 == mc)
5090*3ac0a46fSAndroid Build Coastguard Worker {
5091*3ac0a46fSAndroid Build Coastguard Worker *fii = FAILED_FII;
5092*3ac0a46fSAndroid Build Coastguard Worker return;
5093*3ac0a46fSAndroid Build Coastguard Worker }
5094*3ac0a46fSAndroid Build Coastguard Worker mb = (ma + mc) / 2;
5095*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_fields[mb]->field_tag == (uint32_t)tagid)
5096*3ac0a46fSAndroid Build Coastguard Worker break;
5097*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_fields[mb]->field_tag < (uint32_t)tagid)
5098*3ac0a46fSAndroid Build Coastguard Worker ma = mb;
5099*3ac0a46fSAndroid Build Coastguard Worker else
5100*3ac0a46fSAndroid Build Coastguard Worker mc = mb;
5101*3ac0a46fSAndroid Build Coastguard Worker }
5102*3ac0a46fSAndroid Build Coastguard Worker while (1)
5103*3ac0a46fSAndroid Build Coastguard Worker {
5104*3ac0a46fSAndroid Build Coastguard Worker if (mb == 0)
5105*3ac0a46fSAndroid Build Coastguard Worker break;
5106*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_fields[mb - 1]->field_tag != (uint32_t)tagid)
5107*3ac0a46fSAndroid Build Coastguard Worker break;
5108*3ac0a46fSAndroid Build Coastguard Worker mb--;
5109*3ac0a46fSAndroid Build Coastguard Worker }
5110*3ac0a46fSAndroid Build Coastguard Worker *fii = mb;
5111*3ac0a46fSAndroid Build Coastguard Worker }
5112*3ac0a46fSAndroid Build Coastguard Worker
5113*3ac0a46fSAndroid Build Coastguard Worker /*
5114*3ac0a46fSAndroid Build Coastguard Worker * Read custom directory from the arbitrary offset.
5115*3ac0a46fSAndroid Build Coastguard Worker * The code is very similar to TIFFReadDirectory().
5116*3ac0a46fSAndroid Build Coastguard Worker */
TIFFReadCustomDirectory(TIFF * tif,toff_t diroff,const TIFFFieldArray * infoarray)5117*3ac0a46fSAndroid Build Coastguard Worker int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff,
5118*3ac0a46fSAndroid Build Coastguard Worker const TIFFFieldArray *infoarray)
5119*3ac0a46fSAndroid Build Coastguard Worker {
5120*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFReadCustomDirectory";
5121*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir;
5122*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount;
5123*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dp;
5124*3ac0a46fSAndroid Build Coastguard Worker uint16_t di;
5125*3ac0a46fSAndroid Build Coastguard Worker const TIFFField *fip;
5126*3ac0a46fSAndroid Build Coastguard Worker uint32_t fii;
5127*3ac0a46fSAndroid Build Coastguard Worker (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
5128*3ac0a46fSAndroid Build Coastguard Worker _TIFFSetupFields(tif, infoarray);
5129*3ac0a46fSAndroid Build Coastguard Worker dircount = TIFFFetchDirectory(tif, diroff, &dir, NULL);
5130*3ac0a46fSAndroid Build Coastguard Worker if (!dircount)
5131*3ac0a46fSAndroid Build Coastguard Worker {
5132*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
5133*3ac0a46fSAndroid Build Coastguard Worker "Failed to read custom directory at offset %" PRIu64,
5134*3ac0a46fSAndroid Build Coastguard Worker diroff);
5135*3ac0a46fSAndroid Build Coastguard Worker return 0;
5136*3ac0a46fSAndroid Build Coastguard Worker }
5137*3ac0a46fSAndroid Build Coastguard Worker TIFFFreeDirectory(tif);
5138*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory));
5139*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirectoryCheckOrder(tif, dir, dircount);
5140*3ac0a46fSAndroid Build Coastguard Worker for (di = 0, dp = dir; di < dircount; di++, dp++)
5141*3ac0a46fSAndroid Build Coastguard Worker {
5142*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
5143*3ac0a46fSAndroid Build Coastguard Worker if (fii == FAILED_FII)
5144*3ac0a46fSAndroid Build Coastguard Worker {
5145*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
5146*3ac0a46fSAndroid Build Coastguard Worker "Unknown field with tag %" PRIu16 " (0x%" PRIx16
5147*3ac0a46fSAndroid Build Coastguard Worker ") encountered",
5148*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_tag, dp->tdir_tag);
5149*3ac0a46fSAndroid Build Coastguard Worker if (!_TIFFMergeFields(
5150*3ac0a46fSAndroid Build Coastguard Worker tif,
5151*3ac0a46fSAndroid Build Coastguard Worker _TIFFCreateAnonField(tif, dp->tdir_tag,
5152*3ac0a46fSAndroid Build Coastguard Worker (TIFFDataType)dp->tdir_type),
5153*3ac0a46fSAndroid Build Coastguard Worker 1))
5154*3ac0a46fSAndroid Build Coastguard Worker {
5155*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
5156*3ac0a46fSAndroid Build Coastguard Worker "Registering anonymous field with tag %" PRIu16
5157*3ac0a46fSAndroid Build Coastguard Worker " (0x%" PRIx16 ") failed",
5158*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_tag, dp->tdir_tag);
5159*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_ignore = TRUE;
5160*3ac0a46fSAndroid Build Coastguard Worker }
5161*3ac0a46fSAndroid Build Coastguard Worker else
5162*3ac0a46fSAndroid Build Coastguard Worker {
5163*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
5164*3ac0a46fSAndroid Build Coastguard Worker assert(fii != FAILED_FII);
5165*3ac0a46fSAndroid Build Coastguard Worker }
5166*3ac0a46fSAndroid Build Coastguard Worker }
5167*3ac0a46fSAndroid Build Coastguard Worker if (!dp->tdir_ignore)
5168*3ac0a46fSAndroid Build Coastguard Worker {
5169*3ac0a46fSAndroid Build Coastguard Worker fip = tif->tif_fields[fii];
5170*3ac0a46fSAndroid Build Coastguard Worker if (fip->field_bit == FIELD_IGNORE)
5171*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_ignore = TRUE;
5172*3ac0a46fSAndroid Build Coastguard Worker else
5173*3ac0a46fSAndroid Build Coastguard Worker {
5174*3ac0a46fSAndroid Build Coastguard Worker /* check data type */
5175*3ac0a46fSAndroid Build Coastguard Worker while ((fip->field_type != TIFF_ANY) &&
5176*3ac0a46fSAndroid Build Coastguard Worker (fip->field_type != dp->tdir_type))
5177*3ac0a46fSAndroid Build Coastguard Worker {
5178*3ac0a46fSAndroid Build Coastguard Worker fii++;
5179*3ac0a46fSAndroid Build Coastguard Worker if ((fii == tif->tif_nfields) ||
5180*3ac0a46fSAndroid Build Coastguard Worker (tif->tif_fields[fii]->field_tag !=
5181*3ac0a46fSAndroid Build Coastguard Worker (uint32_t)dp->tdir_tag))
5182*3ac0a46fSAndroid Build Coastguard Worker {
5183*3ac0a46fSAndroid Build Coastguard Worker fii = 0xFFFF;
5184*3ac0a46fSAndroid Build Coastguard Worker break;
5185*3ac0a46fSAndroid Build Coastguard Worker }
5186*3ac0a46fSAndroid Build Coastguard Worker fip = tif->tif_fields[fii];
5187*3ac0a46fSAndroid Build Coastguard Worker }
5188*3ac0a46fSAndroid Build Coastguard Worker if (fii == 0xFFFF)
5189*3ac0a46fSAndroid Build Coastguard Worker {
5190*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
5191*3ac0a46fSAndroid Build Coastguard Worker "Wrong data type %" PRIu16
5192*3ac0a46fSAndroid Build Coastguard Worker " for \"%s\"; tag ignored",
5193*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_type, fip->field_name);
5194*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_ignore = TRUE;
5195*3ac0a46fSAndroid Build Coastguard Worker }
5196*3ac0a46fSAndroid Build Coastguard Worker else
5197*3ac0a46fSAndroid Build Coastguard Worker {
5198*3ac0a46fSAndroid Build Coastguard Worker /* check count if known in advance */
5199*3ac0a46fSAndroid Build Coastguard Worker if ((fip->field_readcount != TIFF_VARIABLE) &&
5200*3ac0a46fSAndroid Build Coastguard Worker (fip->field_readcount != TIFF_VARIABLE2))
5201*3ac0a46fSAndroid Build Coastguard Worker {
5202*3ac0a46fSAndroid Build Coastguard Worker uint32_t expected;
5203*3ac0a46fSAndroid Build Coastguard Worker if (fip->field_readcount == TIFF_SPP)
5204*3ac0a46fSAndroid Build Coastguard Worker expected =
5205*3ac0a46fSAndroid Build Coastguard Worker (uint32_t)tif->tif_dir.td_samplesperpixel;
5206*3ac0a46fSAndroid Build Coastguard Worker else
5207*3ac0a46fSAndroid Build Coastguard Worker expected = (uint32_t)fip->field_readcount;
5208*3ac0a46fSAndroid Build Coastguard Worker if (!CheckDirCount(tif, dp, expected))
5209*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_ignore = TRUE;
5210*3ac0a46fSAndroid Build Coastguard Worker }
5211*3ac0a46fSAndroid Build Coastguard Worker }
5212*3ac0a46fSAndroid Build Coastguard Worker }
5213*3ac0a46fSAndroid Build Coastguard Worker if (!dp->tdir_ignore)
5214*3ac0a46fSAndroid Build Coastguard Worker {
5215*3ac0a46fSAndroid Build Coastguard Worker switch (dp->tdir_tag)
5216*3ac0a46fSAndroid Build Coastguard Worker {
5217*3ac0a46fSAndroid Build Coastguard Worker case EXIFTAG_SUBJECTDISTANCE:
5218*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFieldIsAnonymous(fip))
5219*3ac0a46fSAndroid Build Coastguard Worker {
5220*3ac0a46fSAndroid Build Coastguard Worker /* should only be called on a Exif directory */
5221*3ac0a46fSAndroid Build Coastguard Worker /* when exifFields[] is active */
5222*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFFetchSubjectDistance(tif, dp);
5223*3ac0a46fSAndroid Build Coastguard Worker }
5224*3ac0a46fSAndroid Build Coastguard Worker else
5225*3ac0a46fSAndroid Build Coastguard Worker {
5226*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFFetchNormalTag(tif, dp, TRUE);
5227*3ac0a46fSAndroid Build Coastguard Worker }
5228*3ac0a46fSAndroid Build Coastguard Worker break;
5229*3ac0a46fSAndroid Build Coastguard Worker default:
5230*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFFetchNormalTag(tif, dp, TRUE);
5231*3ac0a46fSAndroid Build Coastguard Worker break;
5232*3ac0a46fSAndroid Build Coastguard Worker }
5233*3ac0a46fSAndroid Build Coastguard Worker } /*-- if (!dp->tdir_ignore) */
5234*3ac0a46fSAndroid Build Coastguard Worker }
5235*3ac0a46fSAndroid Build Coastguard Worker }
5236*3ac0a46fSAndroid Build Coastguard Worker /* To be able to return from SubIFD or custom-IFD to main-IFD */
5237*3ac0a46fSAndroid Build Coastguard Worker tif->tif_setdirectory_force_absolute = TRUE;
5238*3ac0a46fSAndroid Build Coastguard Worker if (dir)
5239*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, dir);
5240*3ac0a46fSAndroid Build Coastguard Worker return 1;
5241*3ac0a46fSAndroid Build Coastguard Worker }
5242*3ac0a46fSAndroid Build Coastguard Worker
5243*3ac0a46fSAndroid Build Coastguard Worker /*
5244*3ac0a46fSAndroid Build Coastguard Worker * EXIF is important special case of custom IFD, so we have a special
5245*3ac0a46fSAndroid Build Coastguard Worker * function to read it.
5246*3ac0a46fSAndroid Build Coastguard Worker */
TIFFReadEXIFDirectory(TIFF * tif,toff_t diroff)5247*3ac0a46fSAndroid Build Coastguard Worker int TIFFReadEXIFDirectory(TIFF *tif, toff_t diroff)
5248*3ac0a46fSAndroid Build Coastguard Worker {
5249*3ac0a46fSAndroid Build Coastguard Worker const TIFFFieldArray *exifFieldArray;
5250*3ac0a46fSAndroid Build Coastguard Worker exifFieldArray = _TIFFGetExifFields();
5251*3ac0a46fSAndroid Build Coastguard Worker return TIFFReadCustomDirectory(tif, diroff, exifFieldArray);
5252*3ac0a46fSAndroid Build Coastguard Worker }
5253*3ac0a46fSAndroid Build Coastguard Worker
5254*3ac0a46fSAndroid Build Coastguard Worker /*
5255*3ac0a46fSAndroid Build Coastguard Worker *--: EXIF-GPS custom directory reading as another special case of custom IFD.
5256*3ac0a46fSAndroid Build Coastguard Worker */
TIFFReadGPSDirectory(TIFF * tif,toff_t diroff)5257*3ac0a46fSAndroid Build Coastguard Worker int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff)
5258*3ac0a46fSAndroid Build Coastguard Worker {
5259*3ac0a46fSAndroid Build Coastguard Worker const TIFFFieldArray *gpsFieldArray;
5260*3ac0a46fSAndroid Build Coastguard Worker gpsFieldArray = _TIFFGetGpsFields();
5261*3ac0a46fSAndroid Build Coastguard Worker return TIFFReadCustomDirectory(tif, diroff, gpsFieldArray);
5262*3ac0a46fSAndroid Build Coastguard Worker }
5263*3ac0a46fSAndroid Build Coastguard Worker
EstimateStripByteCounts(TIFF * tif,TIFFDirEntry * dir,uint16_t dircount)5264*3ac0a46fSAndroid Build Coastguard Worker static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir,
5265*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount)
5266*3ac0a46fSAndroid Build Coastguard Worker {
5267*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "EstimateStripByteCounts";
5268*3ac0a46fSAndroid Build Coastguard Worker
5269*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dp;
5270*3ac0a46fSAndroid Build Coastguard Worker TIFFDirectory *td = &tif->tif_dir;
5271*3ac0a46fSAndroid Build Coastguard Worker uint32_t strip;
5272*3ac0a46fSAndroid Build Coastguard Worker
5273*3ac0a46fSAndroid Build Coastguard Worker /* Do not try to load stripbytecount as we will compute it */
5274*3ac0a46fSAndroid Build Coastguard Worker if (!_TIFFFillStrilesInternal(tif, 0))
5275*3ac0a46fSAndroid Build Coastguard Worker return -1;
5276*3ac0a46fSAndroid Build Coastguard Worker
5277*3ac0a46fSAndroid Build Coastguard Worker if (td->td_stripbytecount_p)
5278*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, td->td_stripbytecount_p);
5279*3ac0a46fSAndroid Build Coastguard Worker td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc(
5280*3ac0a46fSAndroid Build Coastguard Worker tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array");
5281*3ac0a46fSAndroid Build Coastguard Worker if (td->td_stripbytecount_p == NULL)
5282*3ac0a46fSAndroid Build Coastguard Worker return -1;
5283*3ac0a46fSAndroid Build Coastguard Worker
5284*3ac0a46fSAndroid Build Coastguard Worker if (td->td_compression != COMPRESSION_NONE)
5285*3ac0a46fSAndroid Build Coastguard Worker {
5286*3ac0a46fSAndroid Build Coastguard Worker uint64_t space;
5287*3ac0a46fSAndroid Build Coastguard Worker uint64_t filesize;
5288*3ac0a46fSAndroid Build Coastguard Worker uint16_t n;
5289*3ac0a46fSAndroid Build Coastguard Worker filesize = TIFFGetFileSize(tif);
5290*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
5291*3ac0a46fSAndroid Build Coastguard Worker space = sizeof(TIFFHeaderClassic) + 2 + dircount * 12 + 4;
5292*3ac0a46fSAndroid Build Coastguard Worker else
5293*3ac0a46fSAndroid Build Coastguard Worker space = sizeof(TIFFHeaderBig) + 8 + dircount * 20 + 8;
5294*3ac0a46fSAndroid Build Coastguard Worker /* calculate amount of space used by indirect values */
5295*3ac0a46fSAndroid Build Coastguard Worker for (dp = dir, n = dircount; n > 0; n--, dp++)
5296*3ac0a46fSAndroid Build Coastguard Worker {
5297*3ac0a46fSAndroid Build Coastguard Worker uint32_t typewidth;
5298*3ac0a46fSAndroid Build Coastguard Worker uint64_t datasize;
5299*3ac0a46fSAndroid Build Coastguard Worker typewidth = TIFFDataWidth((TIFFDataType)dp->tdir_type);
5300*3ac0a46fSAndroid Build Coastguard Worker if (typewidth == 0)
5301*3ac0a46fSAndroid Build Coastguard Worker {
5302*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(
5303*3ac0a46fSAndroid Build Coastguard Worker tif, module,
5304*3ac0a46fSAndroid Build Coastguard Worker "Cannot determine size of unknown tag type %" PRIu16,
5305*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_type);
5306*3ac0a46fSAndroid Build Coastguard Worker return -1;
5307*3ac0a46fSAndroid Build Coastguard Worker }
5308*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > UINT64_MAX / typewidth)
5309*3ac0a46fSAndroid Build Coastguard Worker return -1;
5310*3ac0a46fSAndroid Build Coastguard Worker datasize = (uint64_t)typewidth * dp->tdir_count;
5311*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
5312*3ac0a46fSAndroid Build Coastguard Worker {
5313*3ac0a46fSAndroid Build Coastguard Worker if (datasize <= 4)
5314*3ac0a46fSAndroid Build Coastguard Worker datasize = 0;
5315*3ac0a46fSAndroid Build Coastguard Worker }
5316*3ac0a46fSAndroid Build Coastguard Worker else
5317*3ac0a46fSAndroid Build Coastguard Worker {
5318*3ac0a46fSAndroid Build Coastguard Worker if (datasize <= 8)
5319*3ac0a46fSAndroid Build Coastguard Worker datasize = 0;
5320*3ac0a46fSAndroid Build Coastguard Worker }
5321*3ac0a46fSAndroid Build Coastguard Worker if (space > UINT64_MAX - datasize)
5322*3ac0a46fSAndroid Build Coastguard Worker return -1;
5323*3ac0a46fSAndroid Build Coastguard Worker space += datasize;
5324*3ac0a46fSAndroid Build Coastguard Worker }
5325*3ac0a46fSAndroid Build Coastguard Worker if (filesize < space)
5326*3ac0a46fSAndroid Build Coastguard Worker /* we should perhaps return in error ? */
5327*3ac0a46fSAndroid Build Coastguard Worker space = filesize;
5328*3ac0a46fSAndroid Build Coastguard Worker else
5329*3ac0a46fSAndroid Build Coastguard Worker space = filesize - space;
5330*3ac0a46fSAndroid Build Coastguard Worker if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
5331*3ac0a46fSAndroid Build Coastguard Worker space /= td->td_samplesperpixel;
5332*3ac0a46fSAndroid Build Coastguard Worker for (strip = 0; strip < td->td_nstrips; strip++)
5333*3ac0a46fSAndroid Build Coastguard Worker td->td_stripbytecount_p[strip] = space;
5334*3ac0a46fSAndroid Build Coastguard Worker /*
5335*3ac0a46fSAndroid Build Coastguard Worker * This gross hack handles the case were the offset to
5336*3ac0a46fSAndroid Build Coastguard Worker * the last strip is past the place where we think the strip
5337*3ac0a46fSAndroid Build Coastguard Worker * should begin. Since a strip of data must be contiguous,
5338*3ac0a46fSAndroid Build Coastguard Worker * it's safe to assume that we've overestimated the amount
5339*3ac0a46fSAndroid Build Coastguard Worker * of data in the strip and trim this number back accordingly.
5340*3ac0a46fSAndroid Build Coastguard Worker */
5341*3ac0a46fSAndroid Build Coastguard Worker strip--;
5342*3ac0a46fSAndroid Build Coastguard Worker if (td->td_stripoffset_p[strip] >
5343*3ac0a46fSAndroid Build Coastguard Worker UINT64_MAX - td->td_stripbytecount_p[strip])
5344*3ac0a46fSAndroid Build Coastguard Worker return -1;
5345*3ac0a46fSAndroid Build Coastguard Worker if (td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip] >
5346*3ac0a46fSAndroid Build Coastguard Worker filesize)
5347*3ac0a46fSAndroid Build Coastguard Worker {
5348*3ac0a46fSAndroid Build Coastguard Worker if (td->td_stripoffset_p[strip] >= filesize)
5349*3ac0a46fSAndroid Build Coastguard Worker {
5350*3ac0a46fSAndroid Build Coastguard Worker /* Not sure what we should in that case... */
5351*3ac0a46fSAndroid Build Coastguard Worker td->td_stripbytecount_p[strip] = 0;
5352*3ac0a46fSAndroid Build Coastguard Worker }
5353*3ac0a46fSAndroid Build Coastguard Worker else
5354*3ac0a46fSAndroid Build Coastguard Worker {
5355*3ac0a46fSAndroid Build Coastguard Worker td->td_stripbytecount_p[strip] =
5356*3ac0a46fSAndroid Build Coastguard Worker filesize - td->td_stripoffset_p[strip];
5357*3ac0a46fSAndroid Build Coastguard Worker }
5358*3ac0a46fSAndroid Build Coastguard Worker }
5359*3ac0a46fSAndroid Build Coastguard Worker }
5360*3ac0a46fSAndroid Build Coastguard Worker else if (isTiled(tif))
5361*3ac0a46fSAndroid Build Coastguard Worker {
5362*3ac0a46fSAndroid Build Coastguard Worker uint64_t bytespertile = TIFFTileSize64(tif);
5363*3ac0a46fSAndroid Build Coastguard Worker
5364*3ac0a46fSAndroid Build Coastguard Worker for (strip = 0; strip < td->td_nstrips; strip++)
5365*3ac0a46fSAndroid Build Coastguard Worker td->td_stripbytecount_p[strip] = bytespertile;
5366*3ac0a46fSAndroid Build Coastguard Worker }
5367*3ac0a46fSAndroid Build Coastguard Worker else
5368*3ac0a46fSAndroid Build Coastguard Worker {
5369*3ac0a46fSAndroid Build Coastguard Worker uint64_t rowbytes = TIFFScanlineSize64(tif);
5370*3ac0a46fSAndroid Build Coastguard Worker uint32_t rowsperstrip = td->td_imagelength / td->td_stripsperimage;
5371*3ac0a46fSAndroid Build Coastguard Worker for (strip = 0; strip < td->td_nstrips; strip++)
5372*3ac0a46fSAndroid Build Coastguard Worker {
5373*3ac0a46fSAndroid Build Coastguard Worker if (rowbytes > 0 && rowsperstrip > UINT64_MAX / rowbytes)
5374*3ac0a46fSAndroid Build Coastguard Worker return -1;
5375*3ac0a46fSAndroid Build Coastguard Worker td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip;
5376*3ac0a46fSAndroid Build Coastguard Worker }
5377*3ac0a46fSAndroid Build Coastguard Worker }
5378*3ac0a46fSAndroid Build Coastguard Worker TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
5379*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
5380*3ac0a46fSAndroid Build Coastguard Worker td->td_rowsperstrip = td->td_imagelength;
5381*3ac0a46fSAndroid Build Coastguard Worker return 1;
5382*3ac0a46fSAndroid Build Coastguard Worker }
5383*3ac0a46fSAndroid Build Coastguard Worker
MissingRequired(TIFF * tif,const char * tagname)5384*3ac0a46fSAndroid Build Coastguard Worker static void MissingRequired(TIFF *tif, const char *tagname)
5385*3ac0a46fSAndroid Build Coastguard Worker {
5386*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "MissingRequired";
5387*3ac0a46fSAndroid Build Coastguard Worker
5388*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
5389*3ac0a46fSAndroid Build Coastguard Worker "TIFF directory is missing required \"%s\" field", tagname);
5390*3ac0a46fSAndroid Build Coastguard Worker }
5391*3ac0a46fSAndroid Build Coastguard Worker
hashFuncOffsetToNumber(const void * elt)5392*3ac0a46fSAndroid Build Coastguard Worker static unsigned long hashFuncOffsetToNumber(const void *elt)
5393*3ac0a46fSAndroid Build Coastguard Worker {
5394*3ac0a46fSAndroid Build Coastguard Worker const TIFFOffsetAndDirNumber *offsetAndDirNumber =
5395*3ac0a46fSAndroid Build Coastguard Worker (const TIFFOffsetAndDirNumber *)elt;
5396*3ac0a46fSAndroid Build Coastguard Worker const uint32_t hash = (uint32_t)(offsetAndDirNumber->offset >> 32) ^
5397*3ac0a46fSAndroid Build Coastguard Worker ((uint32_t)offsetAndDirNumber->offset & 0xFFFFFFFFU);
5398*3ac0a46fSAndroid Build Coastguard Worker return hash;
5399*3ac0a46fSAndroid Build Coastguard Worker }
5400*3ac0a46fSAndroid Build Coastguard Worker
equalFuncOffsetToNumber(const void * elt1,const void * elt2)5401*3ac0a46fSAndroid Build Coastguard Worker static bool equalFuncOffsetToNumber(const void *elt1, const void *elt2)
5402*3ac0a46fSAndroid Build Coastguard Worker {
5403*3ac0a46fSAndroid Build Coastguard Worker const TIFFOffsetAndDirNumber *offsetAndDirNumber1 =
5404*3ac0a46fSAndroid Build Coastguard Worker (const TIFFOffsetAndDirNumber *)elt1;
5405*3ac0a46fSAndroid Build Coastguard Worker const TIFFOffsetAndDirNumber *offsetAndDirNumber2 =
5406*3ac0a46fSAndroid Build Coastguard Worker (const TIFFOffsetAndDirNumber *)elt2;
5407*3ac0a46fSAndroid Build Coastguard Worker return offsetAndDirNumber1->offset == offsetAndDirNumber2->offset;
5408*3ac0a46fSAndroid Build Coastguard Worker }
5409*3ac0a46fSAndroid Build Coastguard Worker
hashFuncNumberToOffset(const void * elt)5410*3ac0a46fSAndroid Build Coastguard Worker static unsigned long hashFuncNumberToOffset(const void *elt)
5411*3ac0a46fSAndroid Build Coastguard Worker {
5412*3ac0a46fSAndroid Build Coastguard Worker const TIFFOffsetAndDirNumber *offsetAndDirNumber =
5413*3ac0a46fSAndroid Build Coastguard Worker (const TIFFOffsetAndDirNumber *)elt;
5414*3ac0a46fSAndroid Build Coastguard Worker return offsetAndDirNumber->dirNumber;
5415*3ac0a46fSAndroid Build Coastguard Worker }
5416*3ac0a46fSAndroid Build Coastguard Worker
equalFuncNumberToOffset(const void * elt1,const void * elt2)5417*3ac0a46fSAndroid Build Coastguard Worker static bool equalFuncNumberToOffset(const void *elt1, const void *elt2)
5418*3ac0a46fSAndroid Build Coastguard Worker {
5419*3ac0a46fSAndroid Build Coastguard Worker const TIFFOffsetAndDirNumber *offsetAndDirNumber1 =
5420*3ac0a46fSAndroid Build Coastguard Worker (const TIFFOffsetAndDirNumber *)elt1;
5421*3ac0a46fSAndroid Build Coastguard Worker const TIFFOffsetAndDirNumber *offsetAndDirNumber2 =
5422*3ac0a46fSAndroid Build Coastguard Worker (const TIFFOffsetAndDirNumber *)elt2;
5423*3ac0a46fSAndroid Build Coastguard Worker return offsetAndDirNumber1->dirNumber == offsetAndDirNumber2->dirNumber;
5424*3ac0a46fSAndroid Build Coastguard Worker }
5425*3ac0a46fSAndroid Build Coastguard Worker
5426*3ac0a46fSAndroid Build Coastguard Worker /*
5427*3ac0a46fSAndroid Build Coastguard Worker * Check the directory number and offset against the list of already seen
5428*3ac0a46fSAndroid Build Coastguard Worker * directory numbers and offsets. This is a trick to prevent IFD looping.
5429*3ac0a46fSAndroid Build Coastguard Worker * The one can create TIFF file with looped directory pointers. We will
5430*3ac0a46fSAndroid Build Coastguard Worker * maintain a list of already seen directories and check every IFD offset
5431*3ac0a46fSAndroid Build Coastguard Worker * and its IFD number against that list. However, the offset of an IFD number
5432*3ac0a46fSAndroid Build Coastguard Worker * can change - e.g. when writing updates to file.
5433*3ac0a46fSAndroid Build Coastguard Worker * Returns 1 if all is ok; 0 if last directory or IFD loop is encountered,
5434*3ac0a46fSAndroid Build Coastguard Worker * or an error has occurred.
5435*3ac0a46fSAndroid Build Coastguard Worker */
_TIFFCheckDirNumberAndOffset(TIFF * tif,tdir_t dirn,uint64_t diroff)5436*3ac0a46fSAndroid Build Coastguard Worker int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff)
5437*3ac0a46fSAndroid Build Coastguard Worker {
5438*3ac0a46fSAndroid Build Coastguard Worker if (diroff == 0) /* no more directories */
5439*3ac0a46fSAndroid Build Coastguard Worker return 0;
5440*3ac0a46fSAndroid Build Coastguard Worker
5441*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_map_dir_offset_to_number == NULL)
5442*3ac0a46fSAndroid Build Coastguard Worker {
5443*3ac0a46fSAndroid Build Coastguard Worker tif->tif_map_dir_offset_to_number = TIFFHashSetNew(
5444*3ac0a46fSAndroid Build Coastguard Worker hashFuncOffsetToNumber, equalFuncOffsetToNumber, free);
5445*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_map_dir_offset_to_number == NULL)
5446*3ac0a46fSAndroid Build Coastguard Worker {
5447*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
5448*3ac0a46fSAndroid Build Coastguard Worker "Not enough memory");
5449*3ac0a46fSAndroid Build Coastguard Worker return 1;
5450*3ac0a46fSAndroid Build Coastguard Worker }
5451*3ac0a46fSAndroid Build Coastguard Worker }
5452*3ac0a46fSAndroid Build Coastguard Worker
5453*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_map_dir_number_to_offset == NULL)
5454*3ac0a46fSAndroid Build Coastguard Worker {
5455*3ac0a46fSAndroid Build Coastguard Worker /* No free callback for this map, as it shares the same items as
5456*3ac0a46fSAndroid Build Coastguard Worker * tif->tif_map_dir_offset_to_number. */
5457*3ac0a46fSAndroid Build Coastguard Worker tif->tif_map_dir_number_to_offset = TIFFHashSetNew(
5458*3ac0a46fSAndroid Build Coastguard Worker hashFuncNumberToOffset, equalFuncNumberToOffset, NULL);
5459*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_map_dir_number_to_offset == NULL)
5460*3ac0a46fSAndroid Build Coastguard Worker {
5461*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
5462*3ac0a46fSAndroid Build Coastguard Worker "Not enough memory");
5463*3ac0a46fSAndroid Build Coastguard Worker return 1;
5464*3ac0a46fSAndroid Build Coastguard Worker }
5465*3ac0a46fSAndroid Build Coastguard Worker }
5466*3ac0a46fSAndroid Build Coastguard Worker
5467*3ac0a46fSAndroid Build Coastguard Worker /* Check if offset is already in the list:
5468*3ac0a46fSAndroid Build Coastguard Worker * - yes: check, if offset is at the same IFD number - if not, it is an IFD
5469*3ac0a46fSAndroid Build Coastguard Worker * loop
5470*3ac0a46fSAndroid Build Coastguard Worker * - no: add to list or update offset at that IFD number
5471*3ac0a46fSAndroid Build Coastguard Worker */
5472*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber entry;
5473*3ac0a46fSAndroid Build Coastguard Worker entry.offset = diroff;
5474*3ac0a46fSAndroid Build Coastguard Worker entry.dirNumber = dirn;
5475*3ac0a46fSAndroid Build Coastguard Worker
5476*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber *foundEntry =
5477*3ac0a46fSAndroid Build Coastguard Worker (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5478*3ac0a46fSAndroid Build Coastguard Worker tif->tif_map_dir_offset_to_number, &entry);
5479*3ac0a46fSAndroid Build Coastguard Worker if (foundEntry)
5480*3ac0a46fSAndroid Build Coastguard Worker {
5481*3ac0a46fSAndroid Build Coastguard Worker if (foundEntry->dirNumber == dirn)
5482*3ac0a46fSAndroid Build Coastguard Worker {
5483*3ac0a46fSAndroid Build Coastguard Worker return 1;
5484*3ac0a46fSAndroid Build Coastguard Worker }
5485*3ac0a46fSAndroid Build Coastguard Worker else
5486*3ac0a46fSAndroid Build Coastguard Worker {
5487*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, "_TIFFCheckDirNumberAndOffset",
5488*3ac0a46fSAndroid Build Coastguard Worker "TIFF directory %d has IFD looping to directory %u "
5489*3ac0a46fSAndroid Build Coastguard Worker "at offset 0x%" PRIx64 " (%" PRIu64 ")",
5490*3ac0a46fSAndroid Build Coastguard Worker (int)dirn - 1, foundEntry->dirNumber, diroff,
5491*3ac0a46fSAndroid Build Coastguard Worker diroff);
5492*3ac0a46fSAndroid Build Coastguard Worker return 0;
5493*3ac0a46fSAndroid Build Coastguard Worker }
5494*3ac0a46fSAndroid Build Coastguard Worker }
5495*3ac0a46fSAndroid Build Coastguard Worker
5496*3ac0a46fSAndroid Build Coastguard Worker /* Check if offset of an IFD has been changed and update offset of that IFD
5497*3ac0a46fSAndroid Build Coastguard Worker * number. */
5498*3ac0a46fSAndroid Build Coastguard Worker foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5499*3ac0a46fSAndroid Build Coastguard Worker tif->tif_map_dir_number_to_offset, &entry);
5500*3ac0a46fSAndroid Build Coastguard Worker if (foundEntry)
5501*3ac0a46fSAndroid Build Coastguard Worker {
5502*3ac0a46fSAndroid Build Coastguard Worker if (foundEntry->offset != diroff)
5503*3ac0a46fSAndroid Build Coastguard Worker {
5504*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber entryOld;
5505*3ac0a46fSAndroid Build Coastguard Worker entryOld.offset = foundEntry->offset;
5506*3ac0a46fSAndroid Build Coastguard Worker entryOld.dirNumber = dirn;
5507*3ac0a46fSAndroid Build Coastguard Worker /* We must remove first from tif_map_dir_number_to_offset as the */
5508*3ac0a46fSAndroid Build Coastguard Worker /* entry is owned (and thus freed) by */
5509*3ac0a46fSAndroid Build Coastguard Worker /* tif_map_dir_offset_to_number */
5510*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber *foundEntryOld =
5511*3ac0a46fSAndroid Build Coastguard Worker (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5512*3ac0a46fSAndroid Build Coastguard Worker tif->tif_map_dir_number_to_offset, &entryOld);
5513*3ac0a46fSAndroid Build Coastguard Worker if (foundEntryOld)
5514*3ac0a46fSAndroid Build Coastguard Worker {
5515*3ac0a46fSAndroid Build Coastguard Worker TIFFHashSetRemove(tif->tif_map_dir_number_to_offset,
5516*3ac0a46fSAndroid Build Coastguard Worker foundEntryOld);
5517*3ac0a46fSAndroid Build Coastguard Worker }
5518*3ac0a46fSAndroid Build Coastguard Worker foundEntryOld = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5519*3ac0a46fSAndroid Build Coastguard Worker tif->tif_map_dir_offset_to_number, &entryOld);
5520*3ac0a46fSAndroid Build Coastguard Worker if (foundEntryOld)
5521*3ac0a46fSAndroid Build Coastguard Worker {
5522*3ac0a46fSAndroid Build Coastguard Worker TIFFHashSetRemove(tif->tif_map_dir_offset_to_number,
5523*3ac0a46fSAndroid Build Coastguard Worker foundEntryOld);
5524*3ac0a46fSAndroid Build Coastguard Worker }
5525*3ac0a46fSAndroid Build Coastguard Worker
5526*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber *entryPtr = (TIFFOffsetAndDirNumber *)malloc(
5527*3ac0a46fSAndroid Build Coastguard Worker sizeof(TIFFOffsetAndDirNumber));
5528*3ac0a46fSAndroid Build Coastguard Worker if (entryPtr == NULL)
5529*3ac0a46fSAndroid Build Coastguard Worker {
5530*3ac0a46fSAndroid Build Coastguard Worker return 0;
5531*3ac0a46fSAndroid Build Coastguard Worker }
5532*3ac0a46fSAndroid Build Coastguard Worker
5533*3ac0a46fSAndroid Build Coastguard Worker /* Add IFD offset and dirn to IFD directory list */
5534*3ac0a46fSAndroid Build Coastguard Worker *entryPtr = entry;
5535*3ac0a46fSAndroid Build Coastguard Worker
5536*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr))
5537*3ac0a46fSAndroid Build Coastguard Worker {
5538*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(
5539*3ac0a46fSAndroid Build Coastguard Worker tif, "_TIFFCheckDirNumberAndOffset",
5540*3ac0a46fSAndroid Build Coastguard Worker "Insertion in tif_map_dir_offset_to_number failed");
5541*3ac0a46fSAndroid Build Coastguard Worker return 0;
5542*3ac0a46fSAndroid Build Coastguard Worker }
5543*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr))
5544*3ac0a46fSAndroid Build Coastguard Worker {
5545*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(
5546*3ac0a46fSAndroid Build Coastguard Worker tif, "_TIFFCheckDirNumberAndOffset",
5547*3ac0a46fSAndroid Build Coastguard Worker "Insertion in tif_map_dir_number_to_offset failed");
5548*3ac0a46fSAndroid Build Coastguard Worker return 0;
5549*3ac0a46fSAndroid Build Coastguard Worker }
5550*3ac0a46fSAndroid Build Coastguard Worker }
5551*3ac0a46fSAndroid Build Coastguard Worker return 1;
5552*3ac0a46fSAndroid Build Coastguard Worker }
5553*3ac0a46fSAndroid Build Coastguard Worker
5554*3ac0a46fSAndroid Build Coastguard Worker /* Arbitrary (hopefully big enough) limit */
5555*3ac0a46fSAndroid Build Coastguard Worker if (TIFFHashSetSize(tif->tif_map_dir_offset_to_number) >=
5556*3ac0a46fSAndroid Build Coastguard Worker TIFF_MAX_DIR_COUNT)
5557*3ac0a46fSAndroid Build Coastguard Worker {
5558*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
5559*3ac0a46fSAndroid Build Coastguard Worker "Cannot handle more than %u TIFF directories",
5560*3ac0a46fSAndroid Build Coastguard Worker TIFF_MAX_DIR_COUNT);
5561*3ac0a46fSAndroid Build Coastguard Worker return 0;
5562*3ac0a46fSAndroid Build Coastguard Worker }
5563*3ac0a46fSAndroid Build Coastguard Worker
5564*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber *entryPtr =
5565*3ac0a46fSAndroid Build Coastguard Worker (TIFFOffsetAndDirNumber *)malloc(sizeof(TIFFOffsetAndDirNumber));
5566*3ac0a46fSAndroid Build Coastguard Worker if (entryPtr == NULL)
5567*3ac0a46fSAndroid Build Coastguard Worker {
5568*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
5569*3ac0a46fSAndroid Build Coastguard Worker "malloc(sizeof(TIFFOffsetAndDirNumber)) failed");
5570*3ac0a46fSAndroid Build Coastguard Worker return 0;
5571*3ac0a46fSAndroid Build Coastguard Worker }
5572*3ac0a46fSAndroid Build Coastguard Worker
5573*3ac0a46fSAndroid Build Coastguard Worker /* Add IFD offset and dirn to IFD directory list */
5574*3ac0a46fSAndroid Build Coastguard Worker *entryPtr = entry;
5575*3ac0a46fSAndroid Build Coastguard Worker
5576*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr))
5577*3ac0a46fSAndroid Build Coastguard Worker {
5578*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
5579*3ac0a46fSAndroid Build Coastguard Worker "Insertion in tif_map_dir_offset_to_number failed");
5580*3ac0a46fSAndroid Build Coastguard Worker return 0;
5581*3ac0a46fSAndroid Build Coastguard Worker }
5582*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr))
5583*3ac0a46fSAndroid Build Coastguard Worker {
5584*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
5585*3ac0a46fSAndroid Build Coastguard Worker "Insertion in tif_map_dir_number_to_offset failed");
5586*3ac0a46fSAndroid Build Coastguard Worker return 0;
5587*3ac0a46fSAndroid Build Coastguard Worker }
5588*3ac0a46fSAndroid Build Coastguard Worker
5589*3ac0a46fSAndroid Build Coastguard Worker return 1;
5590*3ac0a46fSAndroid Build Coastguard Worker } /* --- _TIFFCheckDirNumberAndOffset() ---*/
5591*3ac0a46fSAndroid Build Coastguard Worker
5592*3ac0a46fSAndroid Build Coastguard Worker /*
5593*3ac0a46fSAndroid Build Coastguard Worker * Retrieve the matching IFD directory number of a given IFD offset
5594*3ac0a46fSAndroid Build Coastguard Worker * from the list of directories already seen.
5595*3ac0a46fSAndroid Build Coastguard Worker * Returns 1 if the offset was in the list and the directory number
5596*3ac0a46fSAndroid Build Coastguard Worker * can be returned.
5597*3ac0a46fSAndroid Build Coastguard Worker * Otherwise returns 0 or if an error occurred.
5598*3ac0a46fSAndroid Build Coastguard Worker */
_TIFFGetDirNumberFromOffset(TIFF * tif,uint64_t diroff,tdir_t * dirn)5599*3ac0a46fSAndroid Build Coastguard Worker int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, tdir_t *dirn)
5600*3ac0a46fSAndroid Build Coastguard Worker {
5601*3ac0a46fSAndroid Build Coastguard Worker if (diroff == 0) /* no more directories */
5602*3ac0a46fSAndroid Build Coastguard Worker return 0;
5603*3ac0a46fSAndroid Build Coastguard Worker
5604*3ac0a46fSAndroid Build Coastguard Worker /* Check if offset is already in the list and return matching directory
5605*3ac0a46fSAndroid Build Coastguard Worker * number. Otherwise update IFD list using TIFFNumberOfDirectories() and
5606*3ac0a46fSAndroid Build Coastguard Worker * search again in IFD list.
5607*3ac0a46fSAndroid Build Coastguard Worker */
5608*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_map_dir_offset_to_number == NULL)
5609*3ac0a46fSAndroid Build Coastguard Worker return 0;
5610*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber entry;
5611*3ac0a46fSAndroid Build Coastguard Worker entry.offset = diroff;
5612*3ac0a46fSAndroid Build Coastguard Worker entry.dirNumber = 0; /* not used */
5613*3ac0a46fSAndroid Build Coastguard Worker
5614*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber *foundEntry =
5615*3ac0a46fSAndroid Build Coastguard Worker (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5616*3ac0a46fSAndroid Build Coastguard Worker tif->tif_map_dir_offset_to_number, &entry);
5617*3ac0a46fSAndroid Build Coastguard Worker if (foundEntry)
5618*3ac0a46fSAndroid Build Coastguard Worker {
5619*3ac0a46fSAndroid Build Coastguard Worker *dirn = foundEntry->dirNumber;
5620*3ac0a46fSAndroid Build Coastguard Worker return 1;
5621*3ac0a46fSAndroid Build Coastguard Worker }
5622*3ac0a46fSAndroid Build Coastguard Worker
5623*3ac0a46fSAndroid Build Coastguard Worker /* This updates the directory list for all main-IFDs in the file. */
5624*3ac0a46fSAndroid Build Coastguard Worker TIFFNumberOfDirectories(tif);
5625*3ac0a46fSAndroid Build Coastguard Worker
5626*3ac0a46fSAndroid Build Coastguard Worker foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5627*3ac0a46fSAndroid Build Coastguard Worker tif->tif_map_dir_offset_to_number, &entry);
5628*3ac0a46fSAndroid Build Coastguard Worker if (foundEntry)
5629*3ac0a46fSAndroid Build Coastguard Worker {
5630*3ac0a46fSAndroid Build Coastguard Worker *dirn = foundEntry->dirNumber;
5631*3ac0a46fSAndroid Build Coastguard Worker return 1;
5632*3ac0a46fSAndroid Build Coastguard Worker }
5633*3ac0a46fSAndroid Build Coastguard Worker
5634*3ac0a46fSAndroid Build Coastguard Worker return 0;
5635*3ac0a46fSAndroid Build Coastguard Worker } /*--- _TIFFGetDirNumberFromOffset() ---*/
5636*3ac0a46fSAndroid Build Coastguard Worker
5637*3ac0a46fSAndroid Build Coastguard Worker /*
5638*3ac0a46fSAndroid Build Coastguard Worker * Retrieve the matching IFD directory offset of a given IFD number
5639*3ac0a46fSAndroid Build Coastguard Worker * from the list of directories already seen.
5640*3ac0a46fSAndroid Build Coastguard Worker * Returns 1 if the offset was in the list of already seen IFDs and the
5641*3ac0a46fSAndroid Build Coastguard Worker * directory offset can be returned. The directory list is not updated.
5642*3ac0a46fSAndroid Build Coastguard Worker * Otherwise returns 0 or if an error occurred.
5643*3ac0a46fSAndroid Build Coastguard Worker */
_TIFFGetOffsetFromDirNumber(TIFF * tif,tdir_t dirn,uint64_t * diroff)5644*3ac0a46fSAndroid Build Coastguard Worker int _TIFFGetOffsetFromDirNumber(TIFF *tif, tdir_t dirn, uint64_t *diroff)
5645*3ac0a46fSAndroid Build Coastguard Worker {
5646*3ac0a46fSAndroid Build Coastguard Worker
5647*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_map_dir_number_to_offset == NULL)
5648*3ac0a46fSAndroid Build Coastguard Worker return 0;
5649*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber entry;
5650*3ac0a46fSAndroid Build Coastguard Worker entry.offset = 0; /* not used */
5651*3ac0a46fSAndroid Build Coastguard Worker entry.dirNumber = dirn;
5652*3ac0a46fSAndroid Build Coastguard Worker
5653*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber *foundEntry =
5654*3ac0a46fSAndroid Build Coastguard Worker (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5655*3ac0a46fSAndroid Build Coastguard Worker tif->tif_map_dir_number_to_offset, &entry);
5656*3ac0a46fSAndroid Build Coastguard Worker if (foundEntry)
5657*3ac0a46fSAndroid Build Coastguard Worker {
5658*3ac0a46fSAndroid Build Coastguard Worker *diroff = foundEntry->offset;
5659*3ac0a46fSAndroid Build Coastguard Worker return 1;
5660*3ac0a46fSAndroid Build Coastguard Worker }
5661*3ac0a46fSAndroid Build Coastguard Worker
5662*3ac0a46fSAndroid Build Coastguard Worker return 0;
5663*3ac0a46fSAndroid Build Coastguard Worker } /*--- _TIFFGetOffsetFromDirNumber() ---*/
5664*3ac0a46fSAndroid Build Coastguard Worker
5665*3ac0a46fSAndroid Build Coastguard Worker /*
5666*3ac0a46fSAndroid Build Coastguard Worker * Remove an entry from the directory list of already seen directories
5667*3ac0a46fSAndroid Build Coastguard Worker * by directory offset.
5668*3ac0a46fSAndroid Build Coastguard Worker * If an entry is to be removed from the list, it is also okay if the entry
5669*3ac0a46fSAndroid Build Coastguard Worker * is not in the list or the list does not exist.
5670*3ac0a46fSAndroid Build Coastguard Worker */
_TIFFRemoveEntryFromDirectoryListByOffset(TIFF * tif,uint64_t diroff)5671*3ac0a46fSAndroid Build Coastguard Worker int _TIFFRemoveEntryFromDirectoryListByOffset(TIFF *tif, uint64_t diroff)
5672*3ac0a46fSAndroid Build Coastguard Worker {
5673*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_map_dir_offset_to_number == NULL)
5674*3ac0a46fSAndroid Build Coastguard Worker return 1;
5675*3ac0a46fSAndroid Build Coastguard Worker
5676*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber entryOld;
5677*3ac0a46fSAndroid Build Coastguard Worker entryOld.offset = diroff;
5678*3ac0a46fSAndroid Build Coastguard Worker entryOld.dirNumber = 0;
5679*3ac0a46fSAndroid Build Coastguard Worker /* We must remove first from tif_map_dir_number_to_offset as the
5680*3ac0a46fSAndroid Build Coastguard Worker * entry is owned (and thus freed) by tif_map_dir_offset_to_number.
5681*3ac0a46fSAndroid Build Coastguard Worker * However, we need firstly to find the directory number from offset. */
5682*3ac0a46fSAndroid Build Coastguard Worker
5683*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber *foundEntryOldOff =
5684*3ac0a46fSAndroid Build Coastguard Worker (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5685*3ac0a46fSAndroid Build Coastguard Worker tif->tif_map_dir_offset_to_number, &entryOld);
5686*3ac0a46fSAndroid Build Coastguard Worker if (foundEntryOldOff)
5687*3ac0a46fSAndroid Build Coastguard Worker {
5688*3ac0a46fSAndroid Build Coastguard Worker entryOld.dirNumber = foundEntryOldOff->dirNumber;
5689*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_map_dir_number_to_offset != NULL)
5690*3ac0a46fSAndroid Build Coastguard Worker {
5691*3ac0a46fSAndroid Build Coastguard Worker TIFFOffsetAndDirNumber *foundEntryOldDir =
5692*3ac0a46fSAndroid Build Coastguard Worker (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5693*3ac0a46fSAndroid Build Coastguard Worker tif->tif_map_dir_number_to_offset, &entryOld);
5694*3ac0a46fSAndroid Build Coastguard Worker if (foundEntryOldDir)
5695*3ac0a46fSAndroid Build Coastguard Worker {
5696*3ac0a46fSAndroid Build Coastguard Worker TIFFHashSetRemove(tif->tif_map_dir_number_to_offset,
5697*3ac0a46fSAndroid Build Coastguard Worker foundEntryOldDir);
5698*3ac0a46fSAndroid Build Coastguard Worker TIFFHashSetRemove(tif->tif_map_dir_offset_to_number,
5699*3ac0a46fSAndroid Build Coastguard Worker foundEntryOldOff);
5700*3ac0a46fSAndroid Build Coastguard Worker return 1;
5701*3ac0a46fSAndroid Build Coastguard Worker }
5702*3ac0a46fSAndroid Build Coastguard Worker }
5703*3ac0a46fSAndroid Build Coastguard Worker else
5704*3ac0a46fSAndroid Build Coastguard Worker {
5705*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, "_TIFFRemoveEntryFromDirectoryListByOffset",
5706*3ac0a46fSAndroid Build Coastguard Worker "Unexpectedly tif_map_dir_number_to_offset is "
5707*3ac0a46fSAndroid Build Coastguard Worker "missing but tif_map_dir_offset_to_number exists.");
5708*3ac0a46fSAndroid Build Coastguard Worker return 0;
5709*3ac0a46fSAndroid Build Coastguard Worker }
5710*3ac0a46fSAndroid Build Coastguard Worker }
5711*3ac0a46fSAndroid Build Coastguard Worker return 1;
5712*3ac0a46fSAndroid Build Coastguard Worker } /*--- _TIFFRemoveEntryFromDirectoryListByOffset() ---*/
5713*3ac0a46fSAndroid Build Coastguard Worker
5714*3ac0a46fSAndroid Build Coastguard Worker /*
5715*3ac0a46fSAndroid Build Coastguard Worker * Check the count field of a directory entry against a known value. The
5716*3ac0a46fSAndroid Build Coastguard Worker * caller is expected to skip/ignore the tag if there is a mismatch.
5717*3ac0a46fSAndroid Build Coastguard Worker */
CheckDirCount(TIFF * tif,TIFFDirEntry * dir,uint32_t count)5718*3ac0a46fSAndroid Build Coastguard Worker static int CheckDirCount(TIFF *tif, TIFFDirEntry *dir, uint32_t count)
5719*3ac0a46fSAndroid Build Coastguard Worker {
5720*3ac0a46fSAndroid Build Coastguard Worker if ((uint64_t)count > dir->tdir_count)
5721*3ac0a46fSAndroid Build Coastguard Worker {
5722*3ac0a46fSAndroid Build Coastguard Worker const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag);
5723*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, tif->tif_name,
5724*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\" (%" PRIu64
5725*3ac0a46fSAndroid Build Coastguard Worker ", expecting %" PRIu32 "); tag ignored",
5726*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name : "unknown tagname",
5727*3ac0a46fSAndroid Build Coastguard Worker dir->tdir_count, count);
5728*3ac0a46fSAndroid Build Coastguard Worker return (0);
5729*3ac0a46fSAndroid Build Coastguard Worker }
5730*3ac0a46fSAndroid Build Coastguard Worker else if ((uint64_t)count < dir->tdir_count)
5731*3ac0a46fSAndroid Build Coastguard Worker {
5732*3ac0a46fSAndroid Build Coastguard Worker const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag);
5733*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, tif->tif_name,
5734*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\" (%" PRIu64
5735*3ac0a46fSAndroid Build Coastguard Worker ", expecting %" PRIu32 "); tag trimmed",
5736*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name : "unknown tagname",
5737*3ac0a46fSAndroid Build Coastguard Worker dir->tdir_count, count);
5738*3ac0a46fSAndroid Build Coastguard Worker dir->tdir_count = count;
5739*3ac0a46fSAndroid Build Coastguard Worker return (1);
5740*3ac0a46fSAndroid Build Coastguard Worker }
5741*3ac0a46fSAndroid Build Coastguard Worker return (1);
5742*3ac0a46fSAndroid Build Coastguard Worker }
5743*3ac0a46fSAndroid Build Coastguard Worker
5744*3ac0a46fSAndroid Build Coastguard Worker /*
5745*3ac0a46fSAndroid Build Coastguard Worker * Read IFD structure from the specified offset. If the pointer to
5746*3ac0a46fSAndroid Build Coastguard Worker * nextdiroff variable has been specified, read it too. Function returns a
5747*3ac0a46fSAndroid Build Coastguard Worker * number of fields in the directory or 0 if failed.
5748*3ac0a46fSAndroid Build Coastguard Worker */
TIFFFetchDirectory(TIFF * tif,uint64_t diroff,TIFFDirEntry ** pdir,uint64_t * nextdiroff)5749*3ac0a46fSAndroid Build Coastguard Worker static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
5750*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry **pdir, uint64_t *nextdiroff)
5751*3ac0a46fSAndroid Build Coastguard Worker {
5752*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFFetchDirectory";
5753*3ac0a46fSAndroid Build Coastguard Worker
5754*3ac0a46fSAndroid Build Coastguard Worker void *origdir;
5755*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount16;
5756*3ac0a46fSAndroid Build Coastguard Worker uint32_t dirsize;
5757*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir;
5758*3ac0a46fSAndroid Build Coastguard Worker uint8_t *ma;
5759*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *mb;
5760*3ac0a46fSAndroid Build Coastguard Worker uint16_t n;
5761*3ac0a46fSAndroid Build Coastguard Worker
5762*3ac0a46fSAndroid Build Coastguard Worker assert(pdir);
5763*3ac0a46fSAndroid Build Coastguard Worker
5764*3ac0a46fSAndroid Build Coastguard Worker tif->tif_diroff = diroff;
5765*3ac0a46fSAndroid Build Coastguard Worker if (nextdiroff)
5766*3ac0a46fSAndroid Build Coastguard Worker *nextdiroff = 0;
5767*3ac0a46fSAndroid Build Coastguard Worker if (!isMapped(tif))
5768*3ac0a46fSAndroid Build Coastguard Worker {
5769*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, tif->tif_diroff))
5770*3ac0a46fSAndroid Build Coastguard Worker {
5771*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
5772*3ac0a46fSAndroid Build Coastguard Worker "%s: Seek error accessing TIFF directory",
5773*3ac0a46fSAndroid Build Coastguard Worker tif->tif_name);
5774*3ac0a46fSAndroid Build Coastguard Worker return 0;
5775*3ac0a46fSAndroid Build Coastguard Worker }
5776*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
5777*3ac0a46fSAndroid Build Coastguard Worker {
5778*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, &dircount16, sizeof(uint16_t)))
5779*3ac0a46fSAndroid Build Coastguard Worker {
5780*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
5781*3ac0a46fSAndroid Build Coastguard Worker "%s: Can not read TIFF directory count",
5782*3ac0a46fSAndroid Build Coastguard Worker tif->tif_name);
5783*3ac0a46fSAndroid Build Coastguard Worker return 0;
5784*3ac0a46fSAndroid Build Coastguard Worker }
5785*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
5786*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(&dircount16);
5787*3ac0a46fSAndroid Build Coastguard Worker if (dircount16 > 4096)
5788*3ac0a46fSAndroid Build Coastguard Worker {
5789*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
5790*3ac0a46fSAndroid Build Coastguard Worker "Sanity check on directory count failed, this is "
5791*3ac0a46fSAndroid Build Coastguard Worker "probably not a valid IFD offset");
5792*3ac0a46fSAndroid Build Coastguard Worker return 0;
5793*3ac0a46fSAndroid Build Coastguard Worker }
5794*3ac0a46fSAndroid Build Coastguard Worker dirsize = 12;
5795*3ac0a46fSAndroid Build Coastguard Worker }
5796*3ac0a46fSAndroid Build Coastguard Worker else
5797*3ac0a46fSAndroid Build Coastguard Worker {
5798*3ac0a46fSAndroid Build Coastguard Worker uint64_t dircount64;
5799*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, &dircount64, sizeof(uint64_t)))
5800*3ac0a46fSAndroid Build Coastguard Worker {
5801*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
5802*3ac0a46fSAndroid Build Coastguard Worker "%s: Can not read TIFF directory count",
5803*3ac0a46fSAndroid Build Coastguard Worker tif->tif_name);
5804*3ac0a46fSAndroid Build Coastguard Worker return 0;
5805*3ac0a46fSAndroid Build Coastguard Worker }
5806*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
5807*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&dircount64);
5808*3ac0a46fSAndroid Build Coastguard Worker if (dircount64 > 4096)
5809*3ac0a46fSAndroid Build Coastguard Worker {
5810*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
5811*3ac0a46fSAndroid Build Coastguard Worker "Sanity check on directory count failed, this is "
5812*3ac0a46fSAndroid Build Coastguard Worker "probably not a valid IFD offset");
5813*3ac0a46fSAndroid Build Coastguard Worker return 0;
5814*3ac0a46fSAndroid Build Coastguard Worker }
5815*3ac0a46fSAndroid Build Coastguard Worker dircount16 = (uint16_t)dircount64;
5816*3ac0a46fSAndroid Build Coastguard Worker dirsize = 20;
5817*3ac0a46fSAndroid Build Coastguard Worker }
5818*3ac0a46fSAndroid Build Coastguard Worker origdir = _TIFFCheckMalloc(tif, dircount16, dirsize,
5819*3ac0a46fSAndroid Build Coastguard Worker "to read TIFF directory");
5820*3ac0a46fSAndroid Build Coastguard Worker if (origdir == NULL)
5821*3ac0a46fSAndroid Build Coastguard Worker return 0;
5822*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, origdir, (tmsize_t)(dircount16 * dirsize)))
5823*3ac0a46fSAndroid Build Coastguard Worker {
5824*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "%.100s: Can not read TIFF directory",
5825*3ac0a46fSAndroid Build Coastguard Worker tif->tif_name);
5826*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdir);
5827*3ac0a46fSAndroid Build Coastguard Worker return 0;
5828*3ac0a46fSAndroid Build Coastguard Worker }
5829*3ac0a46fSAndroid Build Coastguard Worker /*
5830*3ac0a46fSAndroid Build Coastguard Worker * Read offset to next directory for sequential scans if
5831*3ac0a46fSAndroid Build Coastguard Worker * needed.
5832*3ac0a46fSAndroid Build Coastguard Worker */
5833*3ac0a46fSAndroid Build Coastguard Worker if (nextdiroff)
5834*3ac0a46fSAndroid Build Coastguard Worker {
5835*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
5836*3ac0a46fSAndroid Build Coastguard Worker {
5837*3ac0a46fSAndroid Build Coastguard Worker uint32_t nextdiroff32;
5838*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, &nextdiroff32, sizeof(uint32_t)))
5839*3ac0a46fSAndroid Build Coastguard Worker nextdiroff32 = 0;
5840*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
5841*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&nextdiroff32);
5842*3ac0a46fSAndroid Build Coastguard Worker *nextdiroff = nextdiroff32;
5843*3ac0a46fSAndroid Build Coastguard Worker }
5844*3ac0a46fSAndroid Build Coastguard Worker else
5845*3ac0a46fSAndroid Build Coastguard Worker {
5846*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
5847*3ac0a46fSAndroid Build Coastguard Worker *nextdiroff = 0;
5848*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
5849*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(nextdiroff);
5850*3ac0a46fSAndroid Build Coastguard Worker }
5851*3ac0a46fSAndroid Build Coastguard Worker }
5852*3ac0a46fSAndroid Build Coastguard Worker }
5853*3ac0a46fSAndroid Build Coastguard Worker else
5854*3ac0a46fSAndroid Build Coastguard Worker {
5855*3ac0a46fSAndroid Build Coastguard Worker tmsize_t m;
5856*3ac0a46fSAndroid Build Coastguard Worker tmsize_t off;
5857*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_diroff > (uint64_t)INT64_MAX)
5858*3ac0a46fSAndroid Build Coastguard Worker {
5859*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
5860*3ac0a46fSAndroid Build Coastguard Worker return (0);
5861*3ac0a46fSAndroid Build Coastguard Worker }
5862*3ac0a46fSAndroid Build Coastguard Worker off = (tmsize_t)tif->tif_diroff;
5863*3ac0a46fSAndroid Build Coastguard Worker
5864*3ac0a46fSAndroid Build Coastguard Worker /*
5865*3ac0a46fSAndroid Build Coastguard Worker * Check for integer overflow when validating the dir_off,
5866*3ac0a46fSAndroid Build Coastguard Worker * otherwise a very high offset may cause an OOB read and
5867*3ac0a46fSAndroid Build Coastguard Worker * crash the client. Make two comparisons instead of
5868*3ac0a46fSAndroid Build Coastguard Worker *
5869*3ac0a46fSAndroid Build Coastguard Worker * off + sizeof(uint16_t) > tif->tif_size
5870*3ac0a46fSAndroid Build Coastguard Worker *
5871*3ac0a46fSAndroid Build Coastguard Worker * to avoid overflow.
5872*3ac0a46fSAndroid Build Coastguard Worker */
5873*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
5874*3ac0a46fSAndroid Build Coastguard Worker {
5875*3ac0a46fSAndroid Build Coastguard Worker m = off + sizeof(uint16_t);
5876*3ac0a46fSAndroid Build Coastguard Worker if ((m < off) || (m < (tmsize_t)sizeof(uint16_t)) ||
5877*3ac0a46fSAndroid Build Coastguard Worker (m > tif->tif_size))
5878*3ac0a46fSAndroid Build Coastguard Worker {
5879*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
5880*3ac0a46fSAndroid Build Coastguard Worker return 0;
5881*3ac0a46fSAndroid Build Coastguard Worker }
5882*3ac0a46fSAndroid Build Coastguard Worker else
5883*3ac0a46fSAndroid Build Coastguard Worker {
5884*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&dircount16, tif->tif_base + off, sizeof(uint16_t));
5885*3ac0a46fSAndroid Build Coastguard Worker }
5886*3ac0a46fSAndroid Build Coastguard Worker off += sizeof(uint16_t);
5887*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
5888*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(&dircount16);
5889*3ac0a46fSAndroid Build Coastguard Worker if (dircount16 > 4096)
5890*3ac0a46fSAndroid Build Coastguard Worker {
5891*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
5892*3ac0a46fSAndroid Build Coastguard Worker "Sanity check on directory count failed, this is "
5893*3ac0a46fSAndroid Build Coastguard Worker "probably not a valid IFD offset");
5894*3ac0a46fSAndroid Build Coastguard Worker return 0;
5895*3ac0a46fSAndroid Build Coastguard Worker }
5896*3ac0a46fSAndroid Build Coastguard Worker dirsize = 12;
5897*3ac0a46fSAndroid Build Coastguard Worker }
5898*3ac0a46fSAndroid Build Coastguard Worker else
5899*3ac0a46fSAndroid Build Coastguard Worker {
5900*3ac0a46fSAndroid Build Coastguard Worker uint64_t dircount64;
5901*3ac0a46fSAndroid Build Coastguard Worker m = off + sizeof(uint64_t);
5902*3ac0a46fSAndroid Build Coastguard Worker if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) ||
5903*3ac0a46fSAndroid Build Coastguard Worker (m > tif->tif_size))
5904*3ac0a46fSAndroid Build Coastguard Worker {
5905*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
5906*3ac0a46fSAndroid Build Coastguard Worker return 0;
5907*3ac0a46fSAndroid Build Coastguard Worker }
5908*3ac0a46fSAndroid Build Coastguard Worker else
5909*3ac0a46fSAndroid Build Coastguard Worker {
5910*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&dircount64, tif->tif_base + off, sizeof(uint64_t));
5911*3ac0a46fSAndroid Build Coastguard Worker }
5912*3ac0a46fSAndroid Build Coastguard Worker off += sizeof(uint64_t);
5913*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
5914*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&dircount64);
5915*3ac0a46fSAndroid Build Coastguard Worker if (dircount64 > 4096)
5916*3ac0a46fSAndroid Build Coastguard Worker {
5917*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
5918*3ac0a46fSAndroid Build Coastguard Worker "Sanity check on directory count failed, this is "
5919*3ac0a46fSAndroid Build Coastguard Worker "probably not a valid IFD offset");
5920*3ac0a46fSAndroid Build Coastguard Worker return 0;
5921*3ac0a46fSAndroid Build Coastguard Worker }
5922*3ac0a46fSAndroid Build Coastguard Worker dircount16 = (uint16_t)dircount64;
5923*3ac0a46fSAndroid Build Coastguard Worker dirsize = 20;
5924*3ac0a46fSAndroid Build Coastguard Worker }
5925*3ac0a46fSAndroid Build Coastguard Worker if (dircount16 == 0)
5926*3ac0a46fSAndroid Build Coastguard Worker {
5927*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
5928*3ac0a46fSAndroid Build Coastguard Worker "Sanity check on directory count failed, zero tag "
5929*3ac0a46fSAndroid Build Coastguard Worker "directories not supported");
5930*3ac0a46fSAndroid Build Coastguard Worker return 0;
5931*3ac0a46fSAndroid Build Coastguard Worker }
5932*3ac0a46fSAndroid Build Coastguard Worker origdir = _TIFFCheckMalloc(tif, dircount16, dirsize,
5933*3ac0a46fSAndroid Build Coastguard Worker "to read TIFF directory");
5934*3ac0a46fSAndroid Build Coastguard Worker if (origdir == NULL)
5935*3ac0a46fSAndroid Build Coastguard Worker return 0;
5936*3ac0a46fSAndroid Build Coastguard Worker m = off + dircount16 * dirsize;
5937*3ac0a46fSAndroid Build Coastguard Worker if ((m < off) || (m < (tmsize_t)(dircount16 * dirsize)) ||
5938*3ac0a46fSAndroid Build Coastguard Worker (m > tif->tif_size))
5939*3ac0a46fSAndroid Build Coastguard Worker {
5940*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Can not read TIFF directory");
5941*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdir);
5942*3ac0a46fSAndroid Build Coastguard Worker return 0;
5943*3ac0a46fSAndroid Build Coastguard Worker }
5944*3ac0a46fSAndroid Build Coastguard Worker else
5945*3ac0a46fSAndroid Build Coastguard Worker {
5946*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(origdir, tif->tif_base + off, dircount16 * dirsize);
5947*3ac0a46fSAndroid Build Coastguard Worker }
5948*3ac0a46fSAndroid Build Coastguard Worker if (nextdiroff)
5949*3ac0a46fSAndroid Build Coastguard Worker {
5950*3ac0a46fSAndroid Build Coastguard Worker off += dircount16 * dirsize;
5951*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
5952*3ac0a46fSAndroid Build Coastguard Worker {
5953*3ac0a46fSAndroid Build Coastguard Worker uint32_t nextdiroff32;
5954*3ac0a46fSAndroid Build Coastguard Worker m = off + sizeof(uint32_t);
5955*3ac0a46fSAndroid Build Coastguard Worker if ((m < off) || (m < (tmsize_t)sizeof(uint32_t)) ||
5956*3ac0a46fSAndroid Build Coastguard Worker (m > tif->tif_size))
5957*3ac0a46fSAndroid Build Coastguard Worker nextdiroff32 = 0;
5958*3ac0a46fSAndroid Build Coastguard Worker else
5959*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&nextdiroff32, tif->tif_base + off,
5960*3ac0a46fSAndroid Build Coastguard Worker sizeof(uint32_t));
5961*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
5962*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&nextdiroff32);
5963*3ac0a46fSAndroid Build Coastguard Worker *nextdiroff = nextdiroff32;
5964*3ac0a46fSAndroid Build Coastguard Worker }
5965*3ac0a46fSAndroid Build Coastguard Worker else
5966*3ac0a46fSAndroid Build Coastguard Worker {
5967*3ac0a46fSAndroid Build Coastguard Worker m = off + sizeof(uint64_t);
5968*3ac0a46fSAndroid Build Coastguard Worker if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) ||
5969*3ac0a46fSAndroid Build Coastguard Worker (m > tif->tif_size))
5970*3ac0a46fSAndroid Build Coastguard Worker *nextdiroff = 0;
5971*3ac0a46fSAndroid Build Coastguard Worker else
5972*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(nextdiroff, tif->tif_base + off,
5973*3ac0a46fSAndroid Build Coastguard Worker sizeof(uint64_t));
5974*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
5975*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(nextdiroff);
5976*3ac0a46fSAndroid Build Coastguard Worker }
5977*3ac0a46fSAndroid Build Coastguard Worker }
5978*3ac0a46fSAndroid Build Coastguard Worker }
5979*3ac0a46fSAndroid Build Coastguard Worker dir = (TIFFDirEntry *)_TIFFCheckMalloc(
5980*3ac0a46fSAndroid Build Coastguard Worker tif, dircount16, sizeof(TIFFDirEntry), "to read TIFF directory");
5981*3ac0a46fSAndroid Build Coastguard Worker if (dir == 0)
5982*3ac0a46fSAndroid Build Coastguard Worker {
5983*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdir);
5984*3ac0a46fSAndroid Build Coastguard Worker return 0;
5985*3ac0a46fSAndroid Build Coastguard Worker }
5986*3ac0a46fSAndroid Build Coastguard Worker ma = (uint8_t *)origdir;
5987*3ac0a46fSAndroid Build Coastguard Worker mb = dir;
5988*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < dircount16; n++)
5989*3ac0a46fSAndroid Build Coastguard Worker {
5990*3ac0a46fSAndroid Build Coastguard Worker mb->tdir_ignore = FALSE;
5991*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
5992*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)ma);
5993*3ac0a46fSAndroid Build Coastguard Worker mb->tdir_tag = *(uint16_t *)ma;
5994*3ac0a46fSAndroid Build Coastguard Worker ma += sizeof(uint16_t);
5995*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
5996*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)ma);
5997*3ac0a46fSAndroid Build Coastguard Worker mb->tdir_type = *(uint16_t *)ma;
5998*3ac0a46fSAndroid Build Coastguard Worker ma += sizeof(uint16_t);
5999*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
6000*3ac0a46fSAndroid Build Coastguard Worker {
6001*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
6002*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)ma);
6003*3ac0a46fSAndroid Build Coastguard Worker mb->tdir_count = (uint64_t)(*(uint32_t *)ma);
6004*3ac0a46fSAndroid Build Coastguard Worker ma += sizeof(uint32_t);
6005*3ac0a46fSAndroid Build Coastguard Worker mb->tdir_offset.toff_long8 = 0;
6006*3ac0a46fSAndroid Build Coastguard Worker *(uint32_t *)(&mb->tdir_offset) = *(uint32_t *)ma;
6007*3ac0a46fSAndroid Build Coastguard Worker ma += sizeof(uint32_t);
6008*3ac0a46fSAndroid Build Coastguard Worker }
6009*3ac0a46fSAndroid Build Coastguard Worker else
6010*3ac0a46fSAndroid Build Coastguard Worker {
6011*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
6012*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)ma);
6013*3ac0a46fSAndroid Build Coastguard Worker mb->tdir_count = TIFFReadUInt64(ma);
6014*3ac0a46fSAndroid Build Coastguard Worker ma += sizeof(uint64_t);
6015*3ac0a46fSAndroid Build Coastguard Worker mb->tdir_offset.toff_long8 = TIFFReadUInt64(ma);
6016*3ac0a46fSAndroid Build Coastguard Worker ma += sizeof(uint64_t);
6017*3ac0a46fSAndroid Build Coastguard Worker }
6018*3ac0a46fSAndroid Build Coastguard Worker mb++;
6019*3ac0a46fSAndroid Build Coastguard Worker }
6020*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, origdir);
6021*3ac0a46fSAndroid Build Coastguard Worker *pdir = dir;
6022*3ac0a46fSAndroid Build Coastguard Worker return dircount16;
6023*3ac0a46fSAndroid Build Coastguard Worker }
6024*3ac0a46fSAndroid Build Coastguard Worker
6025*3ac0a46fSAndroid Build Coastguard Worker /*
6026*3ac0a46fSAndroid Build Coastguard Worker * Fetch a tag that is not handled by special case code.
6027*3ac0a46fSAndroid Build Coastguard Worker */
TIFFFetchNormalTag(TIFF * tif,TIFFDirEntry * dp,int recover)6028*3ac0a46fSAndroid Build Coastguard Worker static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
6029*3ac0a46fSAndroid Build Coastguard Worker {
6030*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFFetchNormalTag";
6031*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
6032*3ac0a46fSAndroid Build Coastguard Worker uint32_t fii;
6033*3ac0a46fSAndroid Build Coastguard Worker const TIFFField *fip = NULL;
6034*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
6035*3ac0a46fSAndroid Build Coastguard Worker if (fii == FAILED_FII)
6036*3ac0a46fSAndroid Build Coastguard Worker {
6037*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, "TIFFFetchNormalTag",
6038*3ac0a46fSAndroid Build Coastguard Worker "No definition found for tag %" PRIu16, dp->tdir_tag);
6039*3ac0a46fSAndroid Build Coastguard Worker return 0;
6040*3ac0a46fSAndroid Build Coastguard Worker }
6041*3ac0a46fSAndroid Build Coastguard Worker fip = tif->tif_fields[fii];
6042*3ac0a46fSAndroid Build Coastguard Worker assert(fip != NULL); /* should not happen */
6043*3ac0a46fSAndroid Build Coastguard Worker assert(fip->set_field_type !=
6044*3ac0a46fSAndroid Build Coastguard Worker TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with
6045*3ac0a46fSAndroid Build Coastguard Worker this in specialized code */
6046*3ac0a46fSAndroid Build Coastguard Worker assert(fip->set_field_type !=
6047*3ac0a46fSAndroid Build Coastguard Worker TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only
6048*3ac0a46fSAndroid Build Coastguard Worker the case for pseudo-tags */
6049*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrOk;
6050*3ac0a46fSAndroid Build Coastguard Worker switch (fip->set_field_type)
6051*3ac0a46fSAndroid Build Coastguard Worker {
6052*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_UNDEFINED:
6053*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(
6054*3ac0a46fSAndroid Build Coastguard Worker tif, "TIFFFetchNormalTag",
6055*3ac0a46fSAndroid Build Coastguard Worker "Defined set_field_type of custom tag %u (%s) is "
6056*3ac0a46fSAndroid Build Coastguard Worker "TIFF_SETGET_UNDEFINED and thus tag is not read from file",
6057*3ac0a46fSAndroid Build Coastguard Worker fip->field_tag, fip->field_name);
6058*3ac0a46fSAndroid Build Coastguard Worker break;
6059*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_ASCII:
6060*3ac0a46fSAndroid Build Coastguard Worker {
6061*3ac0a46fSAndroid Build Coastguard Worker uint8_t *data;
6062*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6063*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryByteArray(tif, dp, &data);
6064*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6065*3ac0a46fSAndroid Build Coastguard Worker {
6066*3ac0a46fSAndroid Build Coastguard Worker size_t mb = 0;
6067*3ac0a46fSAndroid Build Coastguard Worker int n;
6068*3ac0a46fSAndroid Build Coastguard Worker if (data != NULL)
6069*3ac0a46fSAndroid Build Coastguard Worker {
6070*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0 && data[dp->tdir_count - 1] == 0)
6071*3ac0a46fSAndroid Build Coastguard Worker {
6072*3ac0a46fSAndroid Build Coastguard Worker /* optimization: if data is known to be 0 terminated, we
6073*3ac0a46fSAndroid Build Coastguard Worker * can use strlen() */
6074*3ac0a46fSAndroid Build Coastguard Worker mb = strlen((const char *)data);
6075*3ac0a46fSAndroid Build Coastguard Worker }
6076*3ac0a46fSAndroid Build Coastguard Worker else
6077*3ac0a46fSAndroid Build Coastguard Worker {
6078*3ac0a46fSAndroid Build Coastguard Worker /* general case. equivalent to non-portable */
6079*3ac0a46fSAndroid Build Coastguard Worker /* mb = strnlen((const char*)data,
6080*3ac0a46fSAndroid Build Coastguard Worker * (uint32_t)dp->tdir_count); */
6081*3ac0a46fSAndroid Build Coastguard Worker uint8_t *ma = data;
6082*3ac0a46fSAndroid Build Coastguard Worker while (mb < (uint32_t)dp->tdir_count)
6083*3ac0a46fSAndroid Build Coastguard Worker {
6084*3ac0a46fSAndroid Build Coastguard Worker if (*ma == 0)
6085*3ac0a46fSAndroid Build Coastguard Worker break;
6086*3ac0a46fSAndroid Build Coastguard Worker ma++;
6087*3ac0a46fSAndroid Build Coastguard Worker mb++;
6088*3ac0a46fSAndroid Build Coastguard Worker }
6089*3ac0a46fSAndroid Build Coastguard Worker }
6090*3ac0a46fSAndroid Build Coastguard Worker }
6091*3ac0a46fSAndroid Build Coastguard Worker if (mb + 1 < (uint32_t)dp->tdir_count)
6092*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
6093*3ac0a46fSAndroid Build Coastguard Worker tif, module,
6094*3ac0a46fSAndroid Build Coastguard Worker "ASCII value for tag \"%s\" contains null byte in "
6095*3ac0a46fSAndroid Build Coastguard Worker "value; value incorrectly truncated during reading due "
6096*3ac0a46fSAndroid Build Coastguard Worker "to implementation limitations",
6097*3ac0a46fSAndroid Build Coastguard Worker fip->field_name);
6098*3ac0a46fSAndroid Build Coastguard Worker else if (mb + 1 > (uint32_t)dp->tdir_count)
6099*3ac0a46fSAndroid Build Coastguard Worker {
6100*3ac0a46fSAndroid Build Coastguard Worker uint8_t *o;
6101*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
6102*3ac0a46fSAndroid Build Coastguard Worker tif, module,
6103*3ac0a46fSAndroid Build Coastguard Worker "ASCII value for tag \"%s\" does not end in null byte",
6104*3ac0a46fSAndroid Build Coastguard Worker fip->field_name);
6105*3ac0a46fSAndroid Build Coastguard Worker /* TIFFReadDirEntryArrayWithLimit() ensures this can't be
6106*3ac0a46fSAndroid Build Coastguard Worker * larger than MAX_SIZE_TAG_DATA */
6107*3ac0a46fSAndroid Build Coastguard Worker assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1);
6108*3ac0a46fSAndroid Build Coastguard Worker o = _TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1);
6109*3ac0a46fSAndroid Build Coastguard Worker if (o == NULL)
6110*3ac0a46fSAndroid Build Coastguard Worker {
6111*3ac0a46fSAndroid Build Coastguard Worker if (data != NULL)
6112*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6113*3ac0a46fSAndroid Build Coastguard Worker return (0);
6114*3ac0a46fSAndroid Build Coastguard Worker }
6115*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0)
6116*3ac0a46fSAndroid Build Coastguard Worker {
6117*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(o, data, (uint32_t)dp->tdir_count);
6118*3ac0a46fSAndroid Build Coastguard Worker }
6119*3ac0a46fSAndroid Build Coastguard Worker o[(uint32_t)dp->tdir_count] = 0;
6120*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6121*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6122*3ac0a46fSAndroid Build Coastguard Worker data = o;
6123*3ac0a46fSAndroid Build Coastguard Worker }
6124*3ac0a46fSAndroid Build Coastguard Worker n = TIFFSetField(tif, dp->tdir_tag, data);
6125*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6126*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6127*3ac0a46fSAndroid Build Coastguard Worker if (!n)
6128*3ac0a46fSAndroid Build Coastguard Worker return (0);
6129*3ac0a46fSAndroid Build Coastguard Worker }
6130*3ac0a46fSAndroid Build Coastguard Worker }
6131*3ac0a46fSAndroid Build Coastguard Worker break;
6132*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_UINT8:
6133*3ac0a46fSAndroid Build Coastguard Worker {
6134*3ac0a46fSAndroid Build Coastguard Worker uint8_t data = 0;
6135*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == 1);
6136*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6137*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryByte(tif, dp, &data);
6138*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6139*3ac0a46fSAndroid Build Coastguard Worker {
6140*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, dp->tdir_tag, data))
6141*3ac0a46fSAndroid Build Coastguard Worker return (0);
6142*3ac0a46fSAndroid Build Coastguard Worker }
6143*3ac0a46fSAndroid Build Coastguard Worker }
6144*3ac0a46fSAndroid Build Coastguard Worker break;
6145*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_SINT8:
6146*3ac0a46fSAndroid Build Coastguard Worker {
6147*3ac0a46fSAndroid Build Coastguard Worker int8_t data = 0;
6148*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == 1);
6149*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6150*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySbyte(tif, dp, &data);
6151*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6152*3ac0a46fSAndroid Build Coastguard Worker {
6153*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, dp->tdir_tag, data))
6154*3ac0a46fSAndroid Build Coastguard Worker return (0);
6155*3ac0a46fSAndroid Build Coastguard Worker }
6156*3ac0a46fSAndroid Build Coastguard Worker }
6157*3ac0a46fSAndroid Build Coastguard Worker break;
6158*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_UINT16:
6159*3ac0a46fSAndroid Build Coastguard Worker {
6160*3ac0a46fSAndroid Build Coastguard Worker uint16_t data;
6161*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == 1);
6162*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6163*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryShort(tif, dp, &data);
6164*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6165*3ac0a46fSAndroid Build Coastguard Worker {
6166*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, dp->tdir_tag, data))
6167*3ac0a46fSAndroid Build Coastguard Worker return (0);
6168*3ac0a46fSAndroid Build Coastguard Worker }
6169*3ac0a46fSAndroid Build Coastguard Worker }
6170*3ac0a46fSAndroid Build Coastguard Worker break;
6171*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_SINT16:
6172*3ac0a46fSAndroid Build Coastguard Worker {
6173*3ac0a46fSAndroid Build Coastguard Worker int16_t data;
6174*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == 1);
6175*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6176*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySshort(tif, dp, &data);
6177*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6178*3ac0a46fSAndroid Build Coastguard Worker {
6179*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, dp->tdir_tag, data))
6180*3ac0a46fSAndroid Build Coastguard Worker return (0);
6181*3ac0a46fSAndroid Build Coastguard Worker }
6182*3ac0a46fSAndroid Build Coastguard Worker }
6183*3ac0a46fSAndroid Build Coastguard Worker break;
6184*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_UINT32:
6185*3ac0a46fSAndroid Build Coastguard Worker {
6186*3ac0a46fSAndroid Build Coastguard Worker uint32_t data;
6187*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == 1);
6188*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6189*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryLong(tif, dp, &data);
6190*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6191*3ac0a46fSAndroid Build Coastguard Worker {
6192*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, dp->tdir_tag, data))
6193*3ac0a46fSAndroid Build Coastguard Worker return (0);
6194*3ac0a46fSAndroid Build Coastguard Worker }
6195*3ac0a46fSAndroid Build Coastguard Worker }
6196*3ac0a46fSAndroid Build Coastguard Worker break;
6197*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_SINT32:
6198*3ac0a46fSAndroid Build Coastguard Worker {
6199*3ac0a46fSAndroid Build Coastguard Worker int32_t data;
6200*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == 1);
6201*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6202*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySlong(tif, dp, &data);
6203*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6204*3ac0a46fSAndroid Build Coastguard Worker {
6205*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, dp->tdir_tag, data))
6206*3ac0a46fSAndroid Build Coastguard Worker return (0);
6207*3ac0a46fSAndroid Build Coastguard Worker }
6208*3ac0a46fSAndroid Build Coastguard Worker }
6209*3ac0a46fSAndroid Build Coastguard Worker break;
6210*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_UINT64:
6211*3ac0a46fSAndroid Build Coastguard Worker {
6212*3ac0a46fSAndroid Build Coastguard Worker uint64_t data;
6213*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == 1);
6214*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6215*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryLong8(tif, dp, &data);
6216*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6217*3ac0a46fSAndroid Build Coastguard Worker {
6218*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, dp->tdir_tag, data))
6219*3ac0a46fSAndroid Build Coastguard Worker return (0);
6220*3ac0a46fSAndroid Build Coastguard Worker }
6221*3ac0a46fSAndroid Build Coastguard Worker }
6222*3ac0a46fSAndroid Build Coastguard Worker break;
6223*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_SINT64:
6224*3ac0a46fSAndroid Build Coastguard Worker {
6225*3ac0a46fSAndroid Build Coastguard Worker int64_t data;
6226*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == 1);
6227*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6228*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySlong8(tif, dp, &data);
6229*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6230*3ac0a46fSAndroid Build Coastguard Worker {
6231*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, dp->tdir_tag, data))
6232*3ac0a46fSAndroid Build Coastguard Worker return (0);
6233*3ac0a46fSAndroid Build Coastguard Worker }
6234*3ac0a46fSAndroid Build Coastguard Worker }
6235*3ac0a46fSAndroid Build Coastguard Worker break;
6236*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_FLOAT:
6237*3ac0a46fSAndroid Build Coastguard Worker {
6238*3ac0a46fSAndroid Build Coastguard Worker float data;
6239*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == 1);
6240*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6241*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryFloat(tif, dp, &data);
6242*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6243*3ac0a46fSAndroid Build Coastguard Worker {
6244*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, dp->tdir_tag, data))
6245*3ac0a46fSAndroid Build Coastguard Worker return (0);
6246*3ac0a46fSAndroid Build Coastguard Worker }
6247*3ac0a46fSAndroid Build Coastguard Worker }
6248*3ac0a46fSAndroid Build Coastguard Worker break;
6249*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_DOUBLE:
6250*3ac0a46fSAndroid Build Coastguard Worker {
6251*3ac0a46fSAndroid Build Coastguard Worker double data;
6252*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == 1);
6253*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6254*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryDouble(tif, dp, &data);
6255*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6256*3ac0a46fSAndroid Build Coastguard Worker {
6257*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, dp->tdir_tag, data))
6258*3ac0a46fSAndroid Build Coastguard Worker return (0);
6259*3ac0a46fSAndroid Build Coastguard Worker }
6260*3ac0a46fSAndroid Build Coastguard Worker }
6261*3ac0a46fSAndroid Build Coastguard Worker break;
6262*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_IFD8:
6263*3ac0a46fSAndroid Build Coastguard Worker {
6264*3ac0a46fSAndroid Build Coastguard Worker uint64_t data;
6265*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == 1);
6266*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6267*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryIfd8(tif, dp, &data);
6268*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6269*3ac0a46fSAndroid Build Coastguard Worker {
6270*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFSetField(tif, dp->tdir_tag, data))
6271*3ac0a46fSAndroid Build Coastguard Worker return (0);
6272*3ac0a46fSAndroid Build Coastguard Worker }
6273*3ac0a46fSAndroid Build Coastguard Worker }
6274*3ac0a46fSAndroid Build Coastguard Worker break;
6275*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_UINT16_PAIR:
6276*3ac0a46fSAndroid Build Coastguard Worker {
6277*3ac0a46fSAndroid Build Coastguard Worker uint16_t *data;
6278*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == 2);
6279*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6280*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count != 2)
6281*3ac0a46fSAndroid Build Coastguard Worker {
6282*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
6283*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\", expected 2, "
6284*3ac0a46fSAndroid Build Coastguard Worker "got %" PRIu64,
6285*3ac0a46fSAndroid Build Coastguard Worker fip->field_name, dp->tdir_count);
6286*3ac0a46fSAndroid Build Coastguard Worker return (0);
6287*3ac0a46fSAndroid Build Coastguard Worker }
6288*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryShortArray(tif, dp, &data);
6289*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6290*3ac0a46fSAndroid Build Coastguard Worker {
6291*3ac0a46fSAndroid Build Coastguard Worker int m;
6292*3ac0a46fSAndroid Build Coastguard Worker assert(data); /* avoid CLang static Analyzer false positive */
6293*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, data[0], data[1]);
6294*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6295*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6296*3ac0a46fSAndroid Build Coastguard Worker return (0);
6297*3ac0a46fSAndroid Build Coastguard Worker }
6298*3ac0a46fSAndroid Build Coastguard Worker }
6299*3ac0a46fSAndroid Build Coastguard Worker break;
6300*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C0_UINT8:
6301*3ac0a46fSAndroid Build Coastguard Worker {
6302*3ac0a46fSAndroid Build Coastguard Worker uint8_t *data;
6303*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount >= 1);
6304*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6305*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count != (uint64_t)fip->field_readcount)
6306*3ac0a46fSAndroid Build Coastguard Worker {
6307*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
6308*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\", expected "
6309*3ac0a46fSAndroid Build Coastguard Worker "%d, got %" PRIu64,
6310*3ac0a46fSAndroid Build Coastguard Worker fip->field_name, (int)fip->field_readcount,
6311*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_count);
6312*3ac0a46fSAndroid Build Coastguard Worker return (0);
6313*3ac0a46fSAndroid Build Coastguard Worker }
6314*3ac0a46fSAndroid Build Coastguard Worker else
6315*3ac0a46fSAndroid Build Coastguard Worker {
6316*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryByteArray(tif, dp, &data);
6317*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6318*3ac0a46fSAndroid Build Coastguard Worker {
6319*3ac0a46fSAndroid Build Coastguard Worker int m;
6320*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, data);
6321*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6322*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6323*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6324*3ac0a46fSAndroid Build Coastguard Worker return (0);
6325*3ac0a46fSAndroid Build Coastguard Worker }
6326*3ac0a46fSAndroid Build Coastguard Worker }
6327*3ac0a46fSAndroid Build Coastguard Worker }
6328*3ac0a46fSAndroid Build Coastguard Worker break;
6329*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C0_SINT8:
6330*3ac0a46fSAndroid Build Coastguard Worker {
6331*3ac0a46fSAndroid Build Coastguard Worker int8_t *data;
6332*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount >= 1);
6333*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6334*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count != (uint64_t)fip->field_readcount)
6335*3ac0a46fSAndroid Build Coastguard Worker {
6336*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
6337*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\", expected "
6338*3ac0a46fSAndroid Build Coastguard Worker "%d, got %" PRIu64,
6339*3ac0a46fSAndroid Build Coastguard Worker fip->field_name, (int)fip->field_readcount,
6340*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_count);
6341*3ac0a46fSAndroid Build Coastguard Worker return (0);
6342*3ac0a46fSAndroid Build Coastguard Worker }
6343*3ac0a46fSAndroid Build Coastguard Worker else
6344*3ac0a46fSAndroid Build Coastguard Worker {
6345*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySbyteArray(tif, dp, &data);
6346*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6347*3ac0a46fSAndroid Build Coastguard Worker {
6348*3ac0a46fSAndroid Build Coastguard Worker int m;
6349*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, data);
6350*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6351*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6352*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6353*3ac0a46fSAndroid Build Coastguard Worker return (0);
6354*3ac0a46fSAndroid Build Coastguard Worker }
6355*3ac0a46fSAndroid Build Coastguard Worker }
6356*3ac0a46fSAndroid Build Coastguard Worker }
6357*3ac0a46fSAndroid Build Coastguard Worker break;
6358*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C0_UINT16:
6359*3ac0a46fSAndroid Build Coastguard Worker {
6360*3ac0a46fSAndroid Build Coastguard Worker uint16_t *data;
6361*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount >= 1);
6362*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6363*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count != (uint64_t)fip->field_readcount)
6364*3ac0a46fSAndroid Build Coastguard Worker {
6365*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
6366*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\", expected "
6367*3ac0a46fSAndroid Build Coastguard Worker "%d, got %" PRIu64,
6368*3ac0a46fSAndroid Build Coastguard Worker fip->field_name, (int)fip->field_readcount,
6369*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_count);
6370*3ac0a46fSAndroid Build Coastguard Worker return (0);
6371*3ac0a46fSAndroid Build Coastguard Worker }
6372*3ac0a46fSAndroid Build Coastguard Worker else
6373*3ac0a46fSAndroid Build Coastguard Worker {
6374*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryShortArray(tif, dp, &data);
6375*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6376*3ac0a46fSAndroid Build Coastguard Worker {
6377*3ac0a46fSAndroid Build Coastguard Worker int m;
6378*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, data);
6379*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6380*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6381*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6382*3ac0a46fSAndroid Build Coastguard Worker return (0);
6383*3ac0a46fSAndroid Build Coastguard Worker }
6384*3ac0a46fSAndroid Build Coastguard Worker }
6385*3ac0a46fSAndroid Build Coastguard Worker }
6386*3ac0a46fSAndroid Build Coastguard Worker break;
6387*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C0_SINT16:
6388*3ac0a46fSAndroid Build Coastguard Worker {
6389*3ac0a46fSAndroid Build Coastguard Worker int16_t *data;
6390*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount >= 1);
6391*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6392*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count != (uint64_t)fip->field_readcount)
6393*3ac0a46fSAndroid Build Coastguard Worker {
6394*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
6395*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\", expected "
6396*3ac0a46fSAndroid Build Coastguard Worker "%d, got %" PRIu64,
6397*3ac0a46fSAndroid Build Coastguard Worker fip->field_name, (int)fip->field_readcount,
6398*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_count);
6399*3ac0a46fSAndroid Build Coastguard Worker return (0);
6400*3ac0a46fSAndroid Build Coastguard Worker }
6401*3ac0a46fSAndroid Build Coastguard Worker else
6402*3ac0a46fSAndroid Build Coastguard Worker {
6403*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySshortArray(tif, dp, &data);
6404*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6405*3ac0a46fSAndroid Build Coastguard Worker {
6406*3ac0a46fSAndroid Build Coastguard Worker int m;
6407*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, data);
6408*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6409*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6410*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6411*3ac0a46fSAndroid Build Coastguard Worker return (0);
6412*3ac0a46fSAndroid Build Coastguard Worker }
6413*3ac0a46fSAndroid Build Coastguard Worker }
6414*3ac0a46fSAndroid Build Coastguard Worker }
6415*3ac0a46fSAndroid Build Coastguard Worker break;
6416*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C0_UINT32:
6417*3ac0a46fSAndroid Build Coastguard Worker {
6418*3ac0a46fSAndroid Build Coastguard Worker uint32_t *data;
6419*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount >= 1);
6420*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6421*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count != (uint64_t)fip->field_readcount)
6422*3ac0a46fSAndroid Build Coastguard Worker {
6423*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
6424*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\", expected "
6425*3ac0a46fSAndroid Build Coastguard Worker "%d, got %" PRIu64,
6426*3ac0a46fSAndroid Build Coastguard Worker fip->field_name, (int)fip->field_readcount,
6427*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_count);
6428*3ac0a46fSAndroid Build Coastguard Worker return (0);
6429*3ac0a46fSAndroid Build Coastguard Worker }
6430*3ac0a46fSAndroid Build Coastguard Worker else
6431*3ac0a46fSAndroid Build Coastguard Worker {
6432*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryLongArray(tif, dp, &data);
6433*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6434*3ac0a46fSAndroid Build Coastguard Worker {
6435*3ac0a46fSAndroid Build Coastguard Worker int m;
6436*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, data);
6437*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6438*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6439*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6440*3ac0a46fSAndroid Build Coastguard Worker return (0);
6441*3ac0a46fSAndroid Build Coastguard Worker }
6442*3ac0a46fSAndroid Build Coastguard Worker }
6443*3ac0a46fSAndroid Build Coastguard Worker }
6444*3ac0a46fSAndroid Build Coastguard Worker break;
6445*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C0_SINT32:
6446*3ac0a46fSAndroid Build Coastguard Worker {
6447*3ac0a46fSAndroid Build Coastguard Worker int32_t *data;
6448*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount >= 1);
6449*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6450*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count != (uint64_t)fip->field_readcount)
6451*3ac0a46fSAndroid Build Coastguard Worker {
6452*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
6453*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\", expected "
6454*3ac0a46fSAndroid Build Coastguard Worker "%d, got %" PRIu64,
6455*3ac0a46fSAndroid Build Coastguard Worker fip->field_name, (int)fip->field_readcount,
6456*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_count);
6457*3ac0a46fSAndroid Build Coastguard Worker return (0);
6458*3ac0a46fSAndroid Build Coastguard Worker }
6459*3ac0a46fSAndroid Build Coastguard Worker else
6460*3ac0a46fSAndroid Build Coastguard Worker {
6461*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySlongArray(tif, dp, &data);
6462*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6463*3ac0a46fSAndroid Build Coastguard Worker {
6464*3ac0a46fSAndroid Build Coastguard Worker int m;
6465*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, data);
6466*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6467*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6468*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6469*3ac0a46fSAndroid Build Coastguard Worker return (0);
6470*3ac0a46fSAndroid Build Coastguard Worker }
6471*3ac0a46fSAndroid Build Coastguard Worker }
6472*3ac0a46fSAndroid Build Coastguard Worker }
6473*3ac0a46fSAndroid Build Coastguard Worker break;
6474*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C0_UINT64:
6475*3ac0a46fSAndroid Build Coastguard Worker {
6476*3ac0a46fSAndroid Build Coastguard Worker uint64_t *data;
6477*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount >= 1);
6478*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6479*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count != (uint64_t)fip->field_readcount)
6480*3ac0a46fSAndroid Build Coastguard Worker {
6481*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
6482*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\", expected "
6483*3ac0a46fSAndroid Build Coastguard Worker "%d, got %" PRIu64,
6484*3ac0a46fSAndroid Build Coastguard Worker fip->field_name, (int)fip->field_readcount,
6485*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_count);
6486*3ac0a46fSAndroid Build Coastguard Worker return (0);
6487*3ac0a46fSAndroid Build Coastguard Worker }
6488*3ac0a46fSAndroid Build Coastguard Worker else
6489*3ac0a46fSAndroid Build Coastguard Worker {
6490*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryLong8Array(tif, dp, &data);
6491*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6492*3ac0a46fSAndroid Build Coastguard Worker {
6493*3ac0a46fSAndroid Build Coastguard Worker int m;
6494*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, data);
6495*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6496*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6497*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6498*3ac0a46fSAndroid Build Coastguard Worker return (0);
6499*3ac0a46fSAndroid Build Coastguard Worker }
6500*3ac0a46fSAndroid Build Coastguard Worker }
6501*3ac0a46fSAndroid Build Coastguard Worker }
6502*3ac0a46fSAndroid Build Coastguard Worker break;
6503*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C0_SINT64:
6504*3ac0a46fSAndroid Build Coastguard Worker {
6505*3ac0a46fSAndroid Build Coastguard Worker int64_t *data;
6506*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount >= 1);
6507*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6508*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count != (uint64_t)fip->field_readcount)
6509*3ac0a46fSAndroid Build Coastguard Worker {
6510*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
6511*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\", expected "
6512*3ac0a46fSAndroid Build Coastguard Worker "%d, got %" PRIu64,
6513*3ac0a46fSAndroid Build Coastguard Worker fip->field_name, (int)fip->field_readcount,
6514*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_count);
6515*3ac0a46fSAndroid Build Coastguard Worker return (0);
6516*3ac0a46fSAndroid Build Coastguard Worker }
6517*3ac0a46fSAndroid Build Coastguard Worker else
6518*3ac0a46fSAndroid Build Coastguard Worker {
6519*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySlong8Array(tif, dp, &data);
6520*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6521*3ac0a46fSAndroid Build Coastguard Worker {
6522*3ac0a46fSAndroid Build Coastguard Worker int m;
6523*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, data);
6524*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6525*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6526*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6527*3ac0a46fSAndroid Build Coastguard Worker return (0);
6528*3ac0a46fSAndroid Build Coastguard Worker }
6529*3ac0a46fSAndroid Build Coastguard Worker }
6530*3ac0a46fSAndroid Build Coastguard Worker }
6531*3ac0a46fSAndroid Build Coastguard Worker break;
6532*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C0_FLOAT:
6533*3ac0a46fSAndroid Build Coastguard Worker {
6534*3ac0a46fSAndroid Build Coastguard Worker float *data;
6535*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount >= 1);
6536*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6537*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count != (uint64_t)fip->field_readcount)
6538*3ac0a46fSAndroid Build Coastguard Worker {
6539*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
6540*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\", expected "
6541*3ac0a46fSAndroid Build Coastguard Worker "%d, got %" PRIu64,
6542*3ac0a46fSAndroid Build Coastguard Worker fip->field_name, (int)fip->field_readcount,
6543*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_count);
6544*3ac0a46fSAndroid Build Coastguard Worker return (0);
6545*3ac0a46fSAndroid Build Coastguard Worker }
6546*3ac0a46fSAndroid Build Coastguard Worker else
6547*3ac0a46fSAndroid Build Coastguard Worker {
6548*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryFloatArray(tif, dp, &data);
6549*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6550*3ac0a46fSAndroid Build Coastguard Worker {
6551*3ac0a46fSAndroid Build Coastguard Worker int m;
6552*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, data);
6553*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6554*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6555*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6556*3ac0a46fSAndroid Build Coastguard Worker return (0);
6557*3ac0a46fSAndroid Build Coastguard Worker }
6558*3ac0a46fSAndroid Build Coastguard Worker }
6559*3ac0a46fSAndroid Build Coastguard Worker }
6560*3ac0a46fSAndroid Build Coastguard Worker break;
6561*3ac0a46fSAndroid Build Coastguard Worker /*--: Rational2Double: Extend for Double Arrays and Rational-Arrays read
6562*3ac0a46fSAndroid Build Coastguard Worker * into Double-Arrays. */
6563*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C0_DOUBLE:
6564*3ac0a46fSAndroid Build Coastguard Worker {
6565*3ac0a46fSAndroid Build Coastguard Worker double *data;
6566*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount >= 1);
6567*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 0);
6568*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count != (uint64_t)fip->field_readcount)
6569*3ac0a46fSAndroid Build Coastguard Worker {
6570*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
6571*3ac0a46fSAndroid Build Coastguard Worker "incorrect count for field \"%s\", expected "
6572*3ac0a46fSAndroid Build Coastguard Worker "%d, got %" PRIu64,
6573*3ac0a46fSAndroid Build Coastguard Worker fip->field_name, (int)fip->field_readcount,
6574*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_count);
6575*3ac0a46fSAndroid Build Coastguard Worker return (0);
6576*3ac0a46fSAndroid Build Coastguard Worker }
6577*3ac0a46fSAndroid Build Coastguard Worker else
6578*3ac0a46fSAndroid Build Coastguard Worker {
6579*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
6580*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6581*3ac0a46fSAndroid Build Coastguard Worker {
6582*3ac0a46fSAndroid Build Coastguard Worker int m;
6583*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, data);
6584*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6585*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6586*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6587*3ac0a46fSAndroid Build Coastguard Worker return (0);
6588*3ac0a46fSAndroid Build Coastguard Worker }
6589*3ac0a46fSAndroid Build Coastguard Worker }
6590*3ac0a46fSAndroid Build Coastguard Worker }
6591*3ac0a46fSAndroid Build Coastguard Worker break;
6592*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C16_ASCII:
6593*3ac0a46fSAndroid Build Coastguard Worker {
6594*3ac0a46fSAndroid Build Coastguard Worker uint8_t *data;
6595*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE);
6596*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6597*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0xFFFF)
6598*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
6599*3ac0a46fSAndroid Build Coastguard Worker else
6600*3ac0a46fSAndroid Build Coastguard Worker {
6601*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryByteArray(tif, dp, &data);
6602*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6603*3ac0a46fSAndroid Build Coastguard Worker {
6604*3ac0a46fSAndroid Build Coastguard Worker int m;
6605*3ac0a46fSAndroid Build Coastguard Worker if (data != 0 && dp->tdir_count > 0 &&
6606*3ac0a46fSAndroid Build Coastguard Worker data[dp->tdir_count - 1] != '\0')
6607*3ac0a46fSAndroid Build Coastguard Worker {
6608*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(
6609*3ac0a46fSAndroid Build Coastguard Worker tif, module,
6610*3ac0a46fSAndroid Build Coastguard Worker "ASCII value for tag \"%s\" does not end in null "
6611*3ac0a46fSAndroid Build Coastguard Worker "byte. Forcing it to be null",
6612*3ac0a46fSAndroid Build Coastguard Worker fip->field_name);
6613*3ac0a46fSAndroid Build Coastguard Worker data[dp->tdir_count - 1] = '\0';
6614*3ac0a46fSAndroid Build Coastguard Worker }
6615*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag,
6616*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(dp->tdir_count), data);
6617*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6618*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6619*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6620*3ac0a46fSAndroid Build Coastguard Worker return (0);
6621*3ac0a46fSAndroid Build Coastguard Worker }
6622*3ac0a46fSAndroid Build Coastguard Worker }
6623*3ac0a46fSAndroid Build Coastguard Worker }
6624*3ac0a46fSAndroid Build Coastguard Worker break;
6625*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C16_UINT8:
6626*3ac0a46fSAndroid Build Coastguard Worker {
6627*3ac0a46fSAndroid Build Coastguard Worker uint8_t *data;
6628*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE);
6629*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6630*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0xFFFF)
6631*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
6632*3ac0a46fSAndroid Build Coastguard Worker else
6633*3ac0a46fSAndroid Build Coastguard Worker {
6634*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryByteArray(tif, dp, &data);
6635*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6636*3ac0a46fSAndroid Build Coastguard Worker {
6637*3ac0a46fSAndroid Build Coastguard Worker int m;
6638*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag,
6639*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(dp->tdir_count), data);
6640*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6641*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6642*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6643*3ac0a46fSAndroid Build Coastguard Worker return (0);
6644*3ac0a46fSAndroid Build Coastguard Worker }
6645*3ac0a46fSAndroid Build Coastguard Worker }
6646*3ac0a46fSAndroid Build Coastguard Worker }
6647*3ac0a46fSAndroid Build Coastguard Worker break;
6648*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C16_SINT8:
6649*3ac0a46fSAndroid Build Coastguard Worker {
6650*3ac0a46fSAndroid Build Coastguard Worker int8_t *data;
6651*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE);
6652*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6653*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0xFFFF)
6654*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
6655*3ac0a46fSAndroid Build Coastguard Worker else
6656*3ac0a46fSAndroid Build Coastguard Worker {
6657*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySbyteArray(tif, dp, &data);
6658*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6659*3ac0a46fSAndroid Build Coastguard Worker {
6660*3ac0a46fSAndroid Build Coastguard Worker int m;
6661*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag,
6662*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(dp->tdir_count), data);
6663*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6664*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6665*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6666*3ac0a46fSAndroid Build Coastguard Worker return (0);
6667*3ac0a46fSAndroid Build Coastguard Worker }
6668*3ac0a46fSAndroid Build Coastguard Worker }
6669*3ac0a46fSAndroid Build Coastguard Worker }
6670*3ac0a46fSAndroid Build Coastguard Worker break;
6671*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C16_UINT16:
6672*3ac0a46fSAndroid Build Coastguard Worker {
6673*3ac0a46fSAndroid Build Coastguard Worker uint16_t *data;
6674*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE);
6675*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6676*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0xFFFF)
6677*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
6678*3ac0a46fSAndroid Build Coastguard Worker else
6679*3ac0a46fSAndroid Build Coastguard Worker {
6680*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryShortArray(tif, dp, &data);
6681*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6682*3ac0a46fSAndroid Build Coastguard Worker {
6683*3ac0a46fSAndroid Build Coastguard Worker int m;
6684*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag,
6685*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(dp->tdir_count), data);
6686*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6687*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6688*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6689*3ac0a46fSAndroid Build Coastguard Worker return (0);
6690*3ac0a46fSAndroid Build Coastguard Worker }
6691*3ac0a46fSAndroid Build Coastguard Worker }
6692*3ac0a46fSAndroid Build Coastguard Worker }
6693*3ac0a46fSAndroid Build Coastguard Worker break;
6694*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C16_SINT16:
6695*3ac0a46fSAndroid Build Coastguard Worker {
6696*3ac0a46fSAndroid Build Coastguard Worker int16_t *data;
6697*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE);
6698*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6699*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0xFFFF)
6700*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
6701*3ac0a46fSAndroid Build Coastguard Worker else
6702*3ac0a46fSAndroid Build Coastguard Worker {
6703*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySshortArray(tif, dp, &data);
6704*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6705*3ac0a46fSAndroid Build Coastguard Worker {
6706*3ac0a46fSAndroid Build Coastguard Worker int m;
6707*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag,
6708*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(dp->tdir_count), data);
6709*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6710*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6711*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6712*3ac0a46fSAndroid Build Coastguard Worker return (0);
6713*3ac0a46fSAndroid Build Coastguard Worker }
6714*3ac0a46fSAndroid Build Coastguard Worker }
6715*3ac0a46fSAndroid Build Coastguard Worker }
6716*3ac0a46fSAndroid Build Coastguard Worker break;
6717*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C16_UINT32:
6718*3ac0a46fSAndroid Build Coastguard Worker {
6719*3ac0a46fSAndroid Build Coastguard Worker uint32_t *data;
6720*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE);
6721*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6722*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0xFFFF)
6723*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
6724*3ac0a46fSAndroid Build Coastguard Worker else
6725*3ac0a46fSAndroid Build Coastguard Worker {
6726*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryLongArray(tif, dp, &data);
6727*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6728*3ac0a46fSAndroid Build Coastguard Worker {
6729*3ac0a46fSAndroid Build Coastguard Worker int m;
6730*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag,
6731*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(dp->tdir_count), data);
6732*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6733*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6734*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6735*3ac0a46fSAndroid Build Coastguard Worker return (0);
6736*3ac0a46fSAndroid Build Coastguard Worker }
6737*3ac0a46fSAndroid Build Coastguard Worker }
6738*3ac0a46fSAndroid Build Coastguard Worker }
6739*3ac0a46fSAndroid Build Coastguard Worker break;
6740*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C16_SINT32:
6741*3ac0a46fSAndroid Build Coastguard Worker {
6742*3ac0a46fSAndroid Build Coastguard Worker int32_t *data;
6743*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE);
6744*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6745*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0xFFFF)
6746*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
6747*3ac0a46fSAndroid Build Coastguard Worker else
6748*3ac0a46fSAndroid Build Coastguard Worker {
6749*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySlongArray(tif, dp, &data);
6750*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6751*3ac0a46fSAndroid Build Coastguard Worker {
6752*3ac0a46fSAndroid Build Coastguard Worker int m;
6753*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag,
6754*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(dp->tdir_count), data);
6755*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6756*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6757*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6758*3ac0a46fSAndroid Build Coastguard Worker return (0);
6759*3ac0a46fSAndroid Build Coastguard Worker }
6760*3ac0a46fSAndroid Build Coastguard Worker }
6761*3ac0a46fSAndroid Build Coastguard Worker }
6762*3ac0a46fSAndroid Build Coastguard Worker break;
6763*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C16_UINT64:
6764*3ac0a46fSAndroid Build Coastguard Worker {
6765*3ac0a46fSAndroid Build Coastguard Worker uint64_t *data;
6766*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE);
6767*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6768*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0xFFFF)
6769*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
6770*3ac0a46fSAndroid Build Coastguard Worker else
6771*3ac0a46fSAndroid Build Coastguard Worker {
6772*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryLong8Array(tif, dp, &data);
6773*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6774*3ac0a46fSAndroid Build Coastguard Worker {
6775*3ac0a46fSAndroid Build Coastguard Worker int m;
6776*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag,
6777*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(dp->tdir_count), data);
6778*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6779*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6780*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6781*3ac0a46fSAndroid Build Coastguard Worker return (0);
6782*3ac0a46fSAndroid Build Coastguard Worker }
6783*3ac0a46fSAndroid Build Coastguard Worker }
6784*3ac0a46fSAndroid Build Coastguard Worker }
6785*3ac0a46fSAndroid Build Coastguard Worker break;
6786*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C16_SINT64:
6787*3ac0a46fSAndroid Build Coastguard Worker {
6788*3ac0a46fSAndroid Build Coastguard Worker int64_t *data;
6789*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE);
6790*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6791*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0xFFFF)
6792*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
6793*3ac0a46fSAndroid Build Coastguard Worker else
6794*3ac0a46fSAndroid Build Coastguard Worker {
6795*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySlong8Array(tif, dp, &data);
6796*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6797*3ac0a46fSAndroid Build Coastguard Worker {
6798*3ac0a46fSAndroid Build Coastguard Worker int m;
6799*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag,
6800*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(dp->tdir_count), data);
6801*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6802*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6803*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6804*3ac0a46fSAndroid Build Coastguard Worker return (0);
6805*3ac0a46fSAndroid Build Coastguard Worker }
6806*3ac0a46fSAndroid Build Coastguard Worker }
6807*3ac0a46fSAndroid Build Coastguard Worker }
6808*3ac0a46fSAndroid Build Coastguard Worker break;
6809*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C16_FLOAT:
6810*3ac0a46fSAndroid Build Coastguard Worker {
6811*3ac0a46fSAndroid Build Coastguard Worker float *data;
6812*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE);
6813*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6814*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0xFFFF)
6815*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
6816*3ac0a46fSAndroid Build Coastguard Worker else
6817*3ac0a46fSAndroid Build Coastguard Worker {
6818*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryFloatArray(tif, dp, &data);
6819*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6820*3ac0a46fSAndroid Build Coastguard Worker {
6821*3ac0a46fSAndroid Build Coastguard Worker int m;
6822*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag,
6823*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(dp->tdir_count), data);
6824*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6825*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6826*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6827*3ac0a46fSAndroid Build Coastguard Worker return (0);
6828*3ac0a46fSAndroid Build Coastguard Worker }
6829*3ac0a46fSAndroid Build Coastguard Worker }
6830*3ac0a46fSAndroid Build Coastguard Worker }
6831*3ac0a46fSAndroid Build Coastguard Worker break;
6832*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C16_DOUBLE:
6833*3ac0a46fSAndroid Build Coastguard Worker {
6834*3ac0a46fSAndroid Build Coastguard Worker double *data;
6835*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE);
6836*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6837*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0xFFFF)
6838*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
6839*3ac0a46fSAndroid Build Coastguard Worker else
6840*3ac0a46fSAndroid Build Coastguard Worker {
6841*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
6842*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6843*3ac0a46fSAndroid Build Coastguard Worker {
6844*3ac0a46fSAndroid Build Coastguard Worker int m;
6845*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag,
6846*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(dp->tdir_count), data);
6847*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6848*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6849*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6850*3ac0a46fSAndroid Build Coastguard Worker return (0);
6851*3ac0a46fSAndroid Build Coastguard Worker }
6852*3ac0a46fSAndroid Build Coastguard Worker }
6853*3ac0a46fSAndroid Build Coastguard Worker }
6854*3ac0a46fSAndroid Build Coastguard Worker break;
6855*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C16_IFD8:
6856*3ac0a46fSAndroid Build Coastguard Worker {
6857*3ac0a46fSAndroid Build Coastguard Worker uint64_t *data;
6858*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE);
6859*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6860*3ac0a46fSAndroid Build Coastguard Worker if (dp->tdir_count > 0xFFFF)
6861*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
6862*3ac0a46fSAndroid Build Coastguard Worker else
6863*3ac0a46fSAndroid Build Coastguard Worker {
6864*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryIfd8Array(tif, dp, &data);
6865*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6866*3ac0a46fSAndroid Build Coastguard Worker {
6867*3ac0a46fSAndroid Build Coastguard Worker int m;
6868*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag,
6869*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)(dp->tdir_count), data);
6870*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6871*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6872*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6873*3ac0a46fSAndroid Build Coastguard Worker return (0);
6874*3ac0a46fSAndroid Build Coastguard Worker }
6875*3ac0a46fSAndroid Build Coastguard Worker }
6876*3ac0a46fSAndroid Build Coastguard Worker }
6877*3ac0a46fSAndroid Build Coastguard Worker break;
6878*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_ASCII:
6879*3ac0a46fSAndroid Build Coastguard Worker {
6880*3ac0a46fSAndroid Build Coastguard Worker uint8_t *data;
6881*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE2);
6882*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6883*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryByteArray(tif, dp, &data);
6884*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6885*3ac0a46fSAndroid Build Coastguard Worker {
6886*3ac0a46fSAndroid Build Coastguard Worker int m;
6887*3ac0a46fSAndroid Build Coastguard Worker if (data != 0 && dp->tdir_count > 0 &&
6888*3ac0a46fSAndroid Build Coastguard Worker data[dp->tdir_count - 1] != '\0')
6889*3ac0a46fSAndroid Build Coastguard Worker {
6890*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
6891*3ac0a46fSAndroid Build Coastguard Worker "ASCII value for tag \"%s\" does not end "
6892*3ac0a46fSAndroid Build Coastguard Worker "in null byte. Forcing it to be null",
6893*3ac0a46fSAndroid Build Coastguard Worker fip->field_name);
6894*3ac0a46fSAndroid Build Coastguard Worker data[dp->tdir_count - 1] = '\0';
6895*3ac0a46fSAndroid Build Coastguard Worker }
6896*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6897*3ac0a46fSAndroid Build Coastguard Worker data);
6898*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6899*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6900*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6901*3ac0a46fSAndroid Build Coastguard Worker return (0);
6902*3ac0a46fSAndroid Build Coastguard Worker }
6903*3ac0a46fSAndroid Build Coastguard Worker }
6904*3ac0a46fSAndroid Build Coastguard Worker break;
6905*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_UINT8:
6906*3ac0a46fSAndroid Build Coastguard Worker {
6907*3ac0a46fSAndroid Build Coastguard Worker uint8_t *data;
6908*3ac0a46fSAndroid Build Coastguard Worker uint32_t count = 0;
6909*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE2);
6910*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6911*3ac0a46fSAndroid Build Coastguard Worker if (fip->field_tag == TIFFTAG_RICHTIFFIPTC &&
6912*3ac0a46fSAndroid Build Coastguard Worker dp->tdir_type == TIFF_LONG)
6913*3ac0a46fSAndroid Build Coastguard Worker {
6914*3ac0a46fSAndroid Build Coastguard Worker /* Adobe's software (wrongly) writes RichTIFFIPTC tag with
6915*3ac0a46fSAndroid Build Coastguard Worker * data type LONG instead of UNDEFINED. Work around this
6916*3ac0a46fSAndroid Build Coastguard Worker * frequently found issue */
6917*3ac0a46fSAndroid Build Coastguard Worker void *origdata;
6918*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryArray(tif, dp, &count, 4, &origdata);
6919*3ac0a46fSAndroid Build Coastguard Worker if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
6920*3ac0a46fSAndroid Build Coastguard Worker {
6921*3ac0a46fSAndroid Build Coastguard Worker data = NULL;
6922*3ac0a46fSAndroid Build Coastguard Worker }
6923*3ac0a46fSAndroid Build Coastguard Worker else
6924*3ac0a46fSAndroid Build Coastguard Worker {
6925*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
6926*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong((uint32_t *)origdata, count);
6927*3ac0a46fSAndroid Build Coastguard Worker data = (uint8_t *)origdata;
6928*3ac0a46fSAndroid Build Coastguard Worker count = (uint32_t)(count * 4);
6929*3ac0a46fSAndroid Build Coastguard Worker }
6930*3ac0a46fSAndroid Build Coastguard Worker }
6931*3ac0a46fSAndroid Build Coastguard Worker else
6932*3ac0a46fSAndroid Build Coastguard Worker {
6933*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryByteArray(tif, dp, &data);
6934*3ac0a46fSAndroid Build Coastguard Worker count = (uint32_t)(dp->tdir_count);
6935*3ac0a46fSAndroid Build Coastguard Worker }
6936*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6937*3ac0a46fSAndroid Build Coastguard Worker {
6938*3ac0a46fSAndroid Build Coastguard Worker int m;
6939*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, count, data);
6940*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6941*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6942*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6943*3ac0a46fSAndroid Build Coastguard Worker return (0);
6944*3ac0a46fSAndroid Build Coastguard Worker }
6945*3ac0a46fSAndroid Build Coastguard Worker }
6946*3ac0a46fSAndroid Build Coastguard Worker break;
6947*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_SINT8:
6948*3ac0a46fSAndroid Build Coastguard Worker {
6949*3ac0a46fSAndroid Build Coastguard Worker int8_t *data = NULL;
6950*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE2);
6951*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6952*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySbyteArray(tif, dp, &data);
6953*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6954*3ac0a46fSAndroid Build Coastguard Worker {
6955*3ac0a46fSAndroid Build Coastguard Worker int m;
6956*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6957*3ac0a46fSAndroid Build Coastguard Worker data);
6958*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6959*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6960*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6961*3ac0a46fSAndroid Build Coastguard Worker return (0);
6962*3ac0a46fSAndroid Build Coastguard Worker }
6963*3ac0a46fSAndroid Build Coastguard Worker }
6964*3ac0a46fSAndroid Build Coastguard Worker break;
6965*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_UINT16:
6966*3ac0a46fSAndroid Build Coastguard Worker {
6967*3ac0a46fSAndroid Build Coastguard Worker uint16_t *data;
6968*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE2);
6969*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6970*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryShortArray(tif, dp, &data);
6971*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6972*3ac0a46fSAndroid Build Coastguard Worker {
6973*3ac0a46fSAndroid Build Coastguard Worker int m;
6974*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6975*3ac0a46fSAndroid Build Coastguard Worker data);
6976*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6977*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6978*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6979*3ac0a46fSAndroid Build Coastguard Worker return (0);
6980*3ac0a46fSAndroid Build Coastguard Worker }
6981*3ac0a46fSAndroid Build Coastguard Worker }
6982*3ac0a46fSAndroid Build Coastguard Worker break;
6983*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_SINT16:
6984*3ac0a46fSAndroid Build Coastguard Worker {
6985*3ac0a46fSAndroid Build Coastguard Worker int16_t *data = NULL;
6986*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE2);
6987*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
6988*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySshortArray(tif, dp, &data);
6989*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
6990*3ac0a46fSAndroid Build Coastguard Worker {
6991*3ac0a46fSAndroid Build Coastguard Worker int m;
6992*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6993*3ac0a46fSAndroid Build Coastguard Worker data);
6994*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
6995*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
6996*3ac0a46fSAndroid Build Coastguard Worker if (!m)
6997*3ac0a46fSAndroid Build Coastguard Worker return (0);
6998*3ac0a46fSAndroid Build Coastguard Worker }
6999*3ac0a46fSAndroid Build Coastguard Worker }
7000*3ac0a46fSAndroid Build Coastguard Worker break;
7001*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_UINT32:
7002*3ac0a46fSAndroid Build Coastguard Worker {
7003*3ac0a46fSAndroid Build Coastguard Worker uint32_t *data;
7004*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE2);
7005*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
7006*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryLongArray(tif, dp, &data);
7007*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
7008*3ac0a46fSAndroid Build Coastguard Worker {
7009*3ac0a46fSAndroid Build Coastguard Worker int m;
7010*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
7011*3ac0a46fSAndroid Build Coastguard Worker data);
7012*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
7013*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
7014*3ac0a46fSAndroid Build Coastguard Worker if (!m)
7015*3ac0a46fSAndroid Build Coastguard Worker return (0);
7016*3ac0a46fSAndroid Build Coastguard Worker }
7017*3ac0a46fSAndroid Build Coastguard Worker }
7018*3ac0a46fSAndroid Build Coastguard Worker break;
7019*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_SINT32:
7020*3ac0a46fSAndroid Build Coastguard Worker {
7021*3ac0a46fSAndroid Build Coastguard Worker int32_t *data = NULL;
7022*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE2);
7023*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
7024*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySlongArray(tif, dp, &data);
7025*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
7026*3ac0a46fSAndroid Build Coastguard Worker {
7027*3ac0a46fSAndroid Build Coastguard Worker int m;
7028*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
7029*3ac0a46fSAndroid Build Coastguard Worker data);
7030*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
7031*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
7032*3ac0a46fSAndroid Build Coastguard Worker if (!m)
7033*3ac0a46fSAndroid Build Coastguard Worker return (0);
7034*3ac0a46fSAndroid Build Coastguard Worker }
7035*3ac0a46fSAndroid Build Coastguard Worker }
7036*3ac0a46fSAndroid Build Coastguard Worker break;
7037*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_UINT64:
7038*3ac0a46fSAndroid Build Coastguard Worker {
7039*3ac0a46fSAndroid Build Coastguard Worker uint64_t *data;
7040*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE2);
7041*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
7042*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryLong8Array(tif, dp, &data);
7043*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
7044*3ac0a46fSAndroid Build Coastguard Worker {
7045*3ac0a46fSAndroid Build Coastguard Worker int m;
7046*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
7047*3ac0a46fSAndroid Build Coastguard Worker data);
7048*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
7049*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
7050*3ac0a46fSAndroid Build Coastguard Worker if (!m)
7051*3ac0a46fSAndroid Build Coastguard Worker return (0);
7052*3ac0a46fSAndroid Build Coastguard Worker }
7053*3ac0a46fSAndroid Build Coastguard Worker }
7054*3ac0a46fSAndroid Build Coastguard Worker break;
7055*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_SINT64:
7056*3ac0a46fSAndroid Build Coastguard Worker {
7057*3ac0a46fSAndroid Build Coastguard Worker int64_t *data = NULL;
7058*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE2);
7059*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
7060*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntrySlong8Array(tif, dp, &data);
7061*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
7062*3ac0a46fSAndroid Build Coastguard Worker {
7063*3ac0a46fSAndroid Build Coastguard Worker int m;
7064*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
7065*3ac0a46fSAndroid Build Coastguard Worker data);
7066*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
7067*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
7068*3ac0a46fSAndroid Build Coastguard Worker if (!m)
7069*3ac0a46fSAndroid Build Coastguard Worker return (0);
7070*3ac0a46fSAndroid Build Coastguard Worker }
7071*3ac0a46fSAndroid Build Coastguard Worker }
7072*3ac0a46fSAndroid Build Coastguard Worker break;
7073*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_FLOAT:
7074*3ac0a46fSAndroid Build Coastguard Worker {
7075*3ac0a46fSAndroid Build Coastguard Worker float *data;
7076*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE2);
7077*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
7078*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryFloatArray(tif, dp, &data);
7079*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
7080*3ac0a46fSAndroid Build Coastguard Worker {
7081*3ac0a46fSAndroid Build Coastguard Worker int m;
7082*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
7083*3ac0a46fSAndroid Build Coastguard Worker data);
7084*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
7085*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
7086*3ac0a46fSAndroid Build Coastguard Worker if (!m)
7087*3ac0a46fSAndroid Build Coastguard Worker return (0);
7088*3ac0a46fSAndroid Build Coastguard Worker }
7089*3ac0a46fSAndroid Build Coastguard Worker }
7090*3ac0a46fSAndroid Build Coastguard Worker break;
7091*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_DOUBLE:
7092*3ac0a46fSAndroid Build Coastguard Worker {
7093*3ac0a46fSAndroid Build Coastguard Worker double *data;
7094*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE2);
7095*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
7096*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
7097*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
7098*3ac0a46fSAndroid Build Coastguard Worker {
7099*3ac0a46fSAndroid Build Coastguard Worker int m;
7100*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
7101*3ac0a46fSAndroid Build Coastguard Worker data);
7102*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
7103*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
7104*3ac0a46fSAndroid Build Coastguard Worker if (!m)
7105*3ac0a46fSAndroid Build Coastguard Worker return (0);
7106*3ac0a46fSAndroid Build Coastguard Worker }
7107*3ac0a46fSAndroid Build Coastguard Worker }
7108*3ac0a46fSAndroid Build Coastguard Worker break;
7109*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_IFD8:
7110*3ac0a46fSAndroid Build Coastguard Worker {
7111*3ac0a46fSAndroid Build Coastguard Worker uint64_t *data;
7112*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_readcount == TIFF_VARIABLE2);
7113*3ac0a46fSAndroid Build Coastguard Worker assert(fip->field_passcount == 1);
7114*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryIfd8Array(tif, dp, &data);
7115*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
7116*3ac0a46fSAndroid Build Coastguard Worker {
7117*3ac0a46fSAndroid Build Coastguard Worker int m;
7118*3ac0a46fSAndroid Build Coastguard Worker m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
7119*3ac0a46fSAndroid Build Coastguard Worker data);
7120*3ac0a46fSAndroid Build Coastguard Worker if (data != 0)
7121*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
7122*3ac0a46fSAndroid Build Coastguard Worker if (!m)
7123*3ac0a46fSAndroid Build Coastguard Worker return (0);
7124*3ac0a46fSAndroid Build Coastguard Worker }
7125*3ac0a46fSAndroid Build Coastguard Worker }
7126*3ac0a46fSAndroid Build Coastguard Worker break;
7127*3ac0a46fSAndroid Build Coastguard Worker default:
7128*3ac0a46fSAndroid Build Coastguard Worker assert(0); /* we should never get here */
7129*3ac0a46fSAndroid Build Coastguard Worker break;
7130*3ac0a46fSAndroid Build Coastguard Worker }
7131*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
7132*3ac0a46fSAndroid Build Coastguard Worker {
7133*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryOutputErr(tif, err, module, fip->field_name, recover);
7134*3ac0a46fSAndroid Build Coastguard Worker return (0);
7135*3ac0a46fSAndroid Build Coastguard Worker }
7136*3ac0a46fSAndroid Build Coastguard Worker return (1);
7137*3ac0a46fSAndroid Build Coastguard Worker }
7138*3ac0a46fSAndroid Build Coastguard Worker
7139*3ac0a46fSAndroid Build Coastguard Worker /*
7140*3ac0a46fSAndroid Build Coastguard Worker * Fetch a set of offsets or lengths.
7141*3ac0a46fSAndroid Build Coastguard Worker * While this routine says "strips", in fact it's also used for tiles.
7142*3ac0a46fSAndroid Build Coastguard Worker */
TIFFFetchStripThing(TIFF * tif,TIFFDirEntry * dir,uint32_t nstrips,uint64_t ** lpp)7143*3ac0a46fSAndroid Build Coastguard Worker static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips,
7144*3ac0a46fSAndroid Build Coastguard Worker uint64_t **lpp)
7145*3ac0a46fSAndroid Build Coastguard Worker {
7146*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFFetchStripThing";
7147*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
7148*3ac0a46fSAndroid Build Coastguard Worker uint64_t *data;
7149*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryLong8ArrayWithLimit(tif, dir, &data, nstrips);
7150*3ac0a46fSAndroid Build Coastguard Worker if (err != TIFFReadDirEntryErrOk)
7151*3ac0a46fSAndroid Build Coastguard Worker {
7152*3ac0a46fSAndroid Build Coastguard Worker const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag);
7153*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryOutputErr(tif, err, module,
7154*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name : "unknown tagname", 0);
7155*3ac0a46fSAndroid Build Coastguard Worker return (0);
7156*3ac0a46fSAndroid Build Coastguard Worker }
7157*3ac0a46fSAndroid Build Coastguard Worker if (dir->tdir_count < (uint64_t)nstrips)
7158*3ac0a46fSAndroid Build Coastguard Worker {
7159*3ac0a46fSAndroid Build Coastguard Worker uint64_t *resizeddata;
7160*3ac0a46fSAndroid Build Coastguard Worker const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag);
7161*3ac0a46fSAndroid Build Coastguard Worker const char *pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT");
7162*3ac0a46fSAndroid Build Coastguard Worker uint32_t max_nstrips = 1000000;
7163*3ac0a46fSAndroid Build Coastguard Worker if (pszMax)
7164*3ac0a46fSAndroid Build Coastguard Worker max_nstrips = (uint32_t)atoi(pszMax);
7165*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryOutputErr(tif, TIFFReadDirEntryErrCount, module,
7166*3ac0a46fSAndroid Build Coastguard Worker fip ? fip->field_name : "unknown tagname",
7167*3ac0a46fSAndroid Build Coastguard Worker (nstrips <= max_nstrips));
7168*3ac0a46fSAndroid Build Coastguard Worker
7169*3ac0a46fSAndroid Build Coastguard Worker if (nstrips > max_nstrips)
7170*3ac0a46fSAndroid Build Coastguard Worker {
7171*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
7172*3ac0a46fSAndroid Build Coastguard Worker return (0);
7173*3ac0a46fSAndroid Build Coastguard Worker }
7174*3ac0a46fSAndroid Build Coastguard Worker
7175*3ac0a46fSAndroid Build Coastguard Worker resizeddata = (uint64_t *)_TIFFCheckMalloc(
7176*3ac0a46fSAndroid Build Coastguard Worker tif, nstrips, sizeof(uint64_t), "for strip array");
7177*3ac0a46fSAndroid Build Coastguard Worker if (resizeddata == 0)
7178*3ac0a46fSAndroid Build Coastguard Worker {
7179*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
7180*3ac0a46fSAndroid Build Coastguard Worker return (0);
7181*3ac0a46fSAndroid Build Coastguard Worker }
7182*3ac0a46fSAndroid Build Coastguard Worker if (dir->tdir_count)
7183*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(resizeddata, data,
7184*3ac0a46fSAndroid Build Coastguard Worker (uint32_t)dir->tdir_count * sizeof(uint64_t));
7185*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemset(resizeddata + (uint32_t)dir->tdir_count, 0,
7186*3ac0a46fSAndroid Build Coastguard Worker (nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t));
7187*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, data);
7188*3ac0a46fSAndroid Build Coastguard Worker data = resizeddata;
7189*3ac0a46fSAndroid Build Coastguard Worker }
7190*3ac0a46fSAndroid Build Coastguard Worker *lpp = data;
7191*3ac0a46fSAndroid Build Coastguard Worker return (1);
7192*3ac0a46fSAndroid Build Coastguard Worker }
7193*3ac0a46fSAndroid Build Coastguard Worker
7194*3ac0a46fSAndroid Build Coastguard Worker /*
7195*3ac0a46fSAndroid Build Coastguard Worker * Fetch and set the SubjectDistance EXIF tag.
7196*3ac0a46fSAndroid Build Coastguard Worker */
TIFFFetchSubjectDistance(TIFF * tif,TIFFDirEntry * dir)7197*3ac0a46fSAndroid Build Coastguard Worker static int TIFFFetchSubjectDistance(TIFF *tif, TIFFDirEntry *dir)
7198*3ac0a46fSAndroid Build Coastguard Worker {
7199*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFFetchSubjectDistance";
7200*3ac0a46fSAndroid Build Coastguard Worker enum TIFFReadDirEntryErr err;
7201*3ac0a46fSAndroid Build Coastguard Worker UInt64Aligned_t m;
7202*3ac0a46fSAndroid Build Coastguard Worker m.l = 0;
7203*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(double) == 8);
7204*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint64_t) == 8);
7205*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint32_t) == 4);
7206*3ac0a46fSAndroid Build Coastguard Worker if (dir->tdir_count != 1)
7207*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrCount;
7208*3ac0a46fSAndroid Build Coastguard Worker else if (dir->tdir_type != TIFF_RATIONAL)
7209*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrType;
7210*3ac0a46fSAndroid Build Coastguard Worker else
7211*3ac0a46fSAndroid Build Coastguard Worker {
7212*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
7213*3ac0a46fSAndroid Build Coastguard Worker {
7214*3ac0a46fSAndroid Build Coastguard Worker uint32_t offset;
7215*3ac0a46fSAndroid Build Coastguard Worker offset = *(uint32_t *)(&dir->tdir_offset);
7216*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
7217*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&offset);
7218*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryData(tif, offset, 8, m.i);
7219*3ac0a46fSAndroid Build Coastguard Worker }
7220*3ac0a46fSAndroid Build Coastguard Worker else
7221*3ac0a46fSAndroid Build Coastguard Worker {
7222*3ac0a46fSAndroid Build Coastguard Worker m.l = dir->tdir_offset.toff_long8;
7223*3ac0a46fSAndroid Build Coastguard Worker err = TIFFReadDirEntryErrOk;
7224*3ac0a46fSAndroid Build Coastguard Worker }
7225*3ac0a46fSAndroid Build Coastguard Worker }
7226*3ac0a46fSAndroid Build Coastguard Worker if (err == TIFFReadDirEntryErrOk)
7227*3ac0a46fSAndroid Build Coastguard Worker {
7228*3ac0a46fSAndroid Build Coastguard Worker double n;
7229*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
7230*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong(m.i, 2);
7231*3ac0a46fSAndroid Build Coastguard Worker if (m.i[0] == 0)
7232*3ac0a46fSAndroid Build Coastguard Worker n = 0.0;
7233*3ac0a46fSAndroid Build Coastguard Worker else if (m.i[0] == 0xFFFFFFFF || m.i[1] == 0)
7234*3ac0a46fSAndroid Build Coastguard Worker /*
7235*3ac0a46fSAndroid Build Coastguard Worker * XXX: Numerator 0xFFFFFFFF means that we have infinite
7236*3ac0a46fSAndroid Build Coastguard Worker * distance. Indicate that with a negative floating point
7237*3ac0a46fSAndroid Build Coastguard Worker * SubjectDistance value.
7238*3ac0a46fSAndroid Build Coastguard Worker */
7239*3ac0a46fSAndroid Build Coastguard Worker n = -1.0;
7240*3ac0a46fSAndroid Build Coastguard Worker else
7241*3ac0a46fSAndroid Build Coastguard Worker n = (double)m.i[0] / (double)m.i[1];
7242*3ac0a46fSAndroid Build Coastguard Worker return (TIFFSetField(tif, dir->tdir_tag, n));
7243*3ac0a46fSAndroid Build Coastguard Worker }
7244*3ac0a46fSAndroid Build Coastguard Worker else
7245*3ac0a46fSAndroid Build Coastguard Worker {
7246*3ac0a46fSAndroid Build Coastguard Worker TIFFReadDirEntryOutputErr(tif, err, module, "SubjectDistance", TRUE);
7247*3ac0a46fSAndroid Build Coastguard Worker return (0);
7248*3ac0a46fSAndroid Build Coastguard Worker }
7249*3ac0a46fSAndroid Build Coastguard Worker }
7250*3ac0a46fSAndroid Build Coastguard Worker
allocChoppedUpStripArrays(TIFF * tif,uint32_t nstrips,uint64_t stripbytes,uint32_t rowsperstrip)7251*3ac0a46fSAndroid Build Coastguard Worker static void allocChoppedUpStripArrays(TIFF *tif, uint32_t nstrips,
7252*3ac0a46fSAndroid Build Coastguard Worker uint64_t stripbytes,
7253*3ac0a46fSAndroid Build Coastguard Worker uint32_t rowsperstrip)
7254*3ac0a46fSAndroid Build Coastguard Worker {
7255*3ac0a46fSAndroid Build Coastguard Worker TIFFDirectory *td = &tif->tif_dir;
7256*3ac0a46fSAndroid Build Coastguard Worker uint64_t bytecount;
7257*3ac0a46fSAndroid Build Coastguard Worker uint64_t offset;
7258*3ac0a46fSAndroid Build Coastguard Worker uint64_t last_offset;
7259*3ac0a46fSAndroid Build Coastguard Worker uint64_t last_bytecount;
7260*3ac0a46fSAndroid Build Coastguard Worker uint32_t i;
7261*3ac0a46fSAndroid Build Coastguard Worker uint64_t *newcounts;
7262*3ac0a46fSAndroid Build Coastguard Worker uint64_t *newoffsets;
7263*3ac0a46fSAndroid Build Coastguard Worker
7264*3ac0a46fSAndroid Build Coastguard Worker offset = TIFFGetStrileOffset(tif, 0);
7265*3ac0a46fSAndroid Build Coastguard Worker last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1);
7266*3ac0a46fSAndroid Build Coastguard Worker last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips - 1);
7267*3ac0a46fSAndroid Build Coastguard Worker if (last_offset > UINT64_MAX - last_bytecount ||
7268*3ac0a46fSAndroid Build Coastguard Worker last_offset + last_bytecount < offset)
7269*3ac0a46fSAndroid Build Coastguard Worker {
7270*3ac0a46fSAndroid Build Coastguard Worker return;
7271*3ac0a46fSAndroid Build Coastguard Worker }
7272*3ac0a46fSAndroid Build Coastguard Worker bytecount = last_offset + last_bytecount - offset;
7273*3ac0a46fSAndroid Build Coastguard Worker
7274*3ac0a46fSAndroid Build Coastguard Worker newcounts =
7275*3ac0a46fSAndroid Build Coastguard Worker (uint64_t *)_TIFFCheckMalloc(tif, nstrips, sizeof(uint64_t),
7276*3ac0a46fSAndroid Build Coastguard Worker "for chopped \"StripByteCounts\" array");
7277*3ac0a46fSAndroid Build Coastguard Worker newoffsets = (uint64_t *)_TIFFCheckMalloc(
7278*3ac0a46fSAndroid Build Coastguard Worker tif, nstrips, sizeof(uint64_t), "for chopped \"StripOffsets\" array");
7279*3ac0a46fSAndroid Build Coastguard Worker if (newcounts == NULL || newoffsets == NULL)
7280*3ac0a46fSAndroid Build Coastguard Worker {
7281*3ac0a46fSAndroid Build Coastguard Worker /*
7282*3ac0a46fSAndroid Build Coastguard Worker * Unable to allocate new strip information, give up and use
7283*3ac0a46fSAndroid Build Coastguard Worker * the original one strip information.
7284*3ac0a46fSAndroid Build Coastguard Worker */
7285*3ac0a46fSAndroid Build Coastguard Worker if (newcounts != NULL)
7286*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, newcounts);
7287*3ac0a46fSAndroid Build Coastguard Worker if (newoffsets != NULL)
7288*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, newoffsets);
7289*3ac0a46fSAndroid Build Coastguard Worker return;
7290*3ac0a46fSAndroid Build Coastguard Worker }
7291*3ac0a46fSAndroid Build Coastguard Worker
7292*3ac0a46fSAndroid Build Coastguard Worker /*
7293*3ac0a46fSAndroid Build Coastguard Worker * Fill the strip information arrays with new bytecounts and offsets
7294*3ac0a46fSAndroid Build Coastguard Worker * that reflect the broken-up format.
7295*3ac0a46fSAndroid Build Coastguard Worker */
7296*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < nstrips; i++)
7297*3ac0a46fSAndroid Build Coastguard Worker {
7298*3ac0a46fSAndroid Build Coastguard Worker if (stripbytes > bytecount)
7299*3ac0a46fSAndroid Build Coastguard Worker stripbytes = bytecount;
7300*3ac0a46fSAndroid Build Coastguard Worker newcounts[i] = stripbytes;
7301*3ac0a46fSAndroid Build Coastguard Worker newoffsets[i] = stripbytes ? offset : 0;
7302*3ac0a46fSAndroid Build Coastguard Worker offset += stripbytes;
7303*3ac0a46fSAndroid Build Coastguard Worker bytecount -= stripbytes;
7304*3ac0a46fSAndroid Build Coastguard Worker }
7305*3ac0a46fSAndroid Build Coastguard Worker
7306*3ac0a46fSAndroid Build Coastguard Worker /*
7307*3ac0a46fSAndroid Build Coastguard Worker * Replace old single strip info with multi-strip info.
7308*3ac0a46fSAndroid Build Coastguard Worker */
7309*3ac0a46fSAndroid Build Coastguard Worker td->td_stripsperimage = td->td_nstrips = nstrips;
7310*3ac0a46fSAndroid Build Coastguard Worker TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
7311*3ac0a46fSAndroid Build Coastguard Worker
7312*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, td->td_stripbytecount_p);
7313*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, td->td_stripoffset_p);
7314*3ac0a46fSAndroid Build Coastguard Worker td->td_stripbytecount_p = newcounts;
7315*3ac0a46fSAndroid Build Coastguard Worker td->td_stripoffset_p = newoffsets;
7316*3ac0a46fSAndroid Build Coastguard Worker #ifdef STRIPBYTECOUNTSORTED_UNUSED
7317*3ac0a46fSAndroid Build Coastguard Worker td->td_stripbytecountsorted = 1;
7318*3ac0a46fSAndroid Build Coastguard Worker #endif
7319*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags |= TIFF_CHOPPEDUPARRAYS;
7320*3ac0a46fSAndroid Build Coastguard Worker }
7321*3ac0a46fSAndroid Build Coastguard Worker
7322*3ac0a46fSAndroid Build Coastguard Worker /*
7323*3ac0a46fSAndroid Build Coastguard Worker * Replace a single strip (tile) of uncompressed data by multiple strips
7324*3ac0a46fSAndroid Build Coastguard Worker * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
7325*3ac0a46fSAndroid Build Coastguard Worker * dealing with large images or for dealing with machines with a limited
7326*3ac0a46fSAndroid Build Coastguard Worker * amount memory.
7327*3ac0a46fSAndroid Build Coastguard Worker */
ChopUpSingleUncompressedStrip(TIFF * tif)7328*3ac0a46fSAndroid Build Coastguard Worker static void ChopUpSingleUncompressedStrip(TIFF *tif)
7329*3ac0a46fSAndroid Build Coastguard Worker {
7330*3ac0a46fSAndroid Build Coastguard Worker register TIFFDirectory *td = &tif->tif_dir;
7331*3ac0a46fSAndroid Build Coastguard Worker uint64_t bytecount;
7332*3ac0a46fSAndroid Build Coastguard Worker uint64_t offset;
7333*3ac0a46fSAndroid Build Coastguard Worker uint32_t rowblock;
7334*3ac0a46fSAndroid Build Coastguard Worker uint64_t rowblockbytes;
7335*3ac0a46fSAndroid Build Coastguard Worker uint64_t stripbytes;
7336*3ac0a46fSAndroid Build Coastguard Worker uint32_t nstrips;
7337*3ac0a46fSAndroid Build Coastguard Worker uint32_t rowsperstrip;
7338*3ac0a46fSAndroid Build Coastguard Worker
7339*3ac0a46fSAndroid Build Coastguard Worker bytecount = TIFFGetStrileByteCount(tif, 0);
7340*3ac0a46fSAndroid Build Coastguard Worker /* On a newly created file, just re-opened to be filled, we */
7341*3ac0a46fSAndroid Build Coastguard Worker /* don't want strip chop to trigger as it is going to cause issues */
7342*3ac0a46fSAndroid Build Coastguard Worker /* later ( StripOffsets and StripByteCounts improperly filled) . */
7343*3ac0a46fSAndroid Build Coastguard Worker if (bytecount == 0 && tif->tif_mode != O_RDONLY)
7344*3ac0a46fSAndroid Build Coastguard Worker return;
7345*3ac0a46fSAndroid Build Coastguard Worker offset = TIFFGetStrileByteCount(tif, 0);
7346*3ac0a46fSAndroid Build Coastguard Worker assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
7347*3ac0a46fSAndroid Build Coastguard Worker if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
7348*3ac0a46fSAndroid Build Coastguard Worker rowblock = td->td_ycbcrsubsampling[1];
7349*3ac0a46fSAndroid Build Coastguard Worker else
7350*3ac0a46fSAndroid Build Coastguard Worker rowblock = 1;
7351*3ac0a46fSAndroid Build Coastguard Worker rowblockbytes = TIFFVTileSize64(tif, rowblock);
7352*3ac0a46fSAndroid Build Coastguard Worker /*
7353*3ac0a46fSAndroid Build Coastguard Worker * Make the rows hold at least one scanline, but fill specified amount
7354*3ac0a46fSAndroid Build Coastguard Worker * of data if possible.
7355*3ac0a46fSAndroid Build Coastguard Worker */
7356*3ac0a46fSAndroid Build Coastguard Worker if (rowblockbytes > STRIP_SIZE_DEFAULT)
7357*3ac0a46fSAndroid Build Coastguard Worker {
7358*3ac0a46fSAndroid Build Coastguard Worker stripbytes = rowblockbytes;
7359*3ac0a46fSAndroid Build Coastguard Worker rowsperstrip = rowblock;
7360*3ac0a46fSAndroid Build Coastguard Worker }
7361*3ac0a46fSAndroid Build Coastguard Worker else if (rowblockbytes > 0)
7362*3ac0a46fSAndroid Build Coastguard Worker {
7363*3ac0a46fSAndroid Build Coastguard Worker uint32_t rowblocksperstrip;
7364*3ac0a46fSAndroid Build Coastguard Worker rowblocksperstrip = (uint32_t)(STRIP_SIZE_DEFAULT / rowblockbytes);
7365*3ac0a46fSAndroid Build Coastguard Worker rowsperstrip = rowblocksperstrip * rowblock;
7366*3ac0a46fSAndroid Build Coastguard Worker stripbytes = rowblocksperstrip * rowblockbytes;
7367*3ac0a46fSAndroid Build Coastguard Worker }
7368*3ac0a46fSAndroid Build Coastguard Worker else
7369*3ac0a46fSAndroid Build Coastguard Worker return;
7370*3ac0a46fSAndroid Build Coastguard Worker
7371*3ac0a46fSAndroid Build Coastguard Worker /*
7372*3ac0a46fSAndroid Build Coastguard Worker * never increase the number of rows per strip
7373*3ac0a46fSAndroid Build Coastguard Worker */
7374*3ac0a46fSAndroid Build Coastguard Worker if (rowsperstrip >= td->td_rowsperstrip)
7375*3ac0a46fSAndroid Build Coastguard Worker return;
7376*3ac0a46fSAndroid Build Coastguard Worker nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
7377*3ac0a46fSAndroid Build Coastguard Worker if (nstrips == 0)
7378*3ac0a46fSAndroid Build Coastguard Worker return;
7379*3ac0a46fSAndroid Build Coastguard Worker
7380*3ac0a46fSAndroid Build Coastguard Worker /* If we are going to allocate a lot of memory, make sure that the */
7381*3ac0a46fSAndroid Build Coastguard Worker /* file is as big as needed */
7382*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_mode == O_RDONLY && nstrips > 1000000 &&
7383*3ac0a46fSAndroid Build Coastguard Worker (offset >= TIFFGetFileSize(tif) ||
7384*3ac0a46fSAndroid Build Coastguard Worker stripbytes > (TIFFGetFileSize(tif) - offset) / (nstrips - 1)))
7385*3ac0a46fSAndroid Build Coastguard Worker {
7386*3ac0a46fSAndroid Build Coastguard Worker return;
7387*3ac0a46fSAndroid Build Coastguard Worker }
7388*3ac0a46fSAndroid Build Coastguard Worker
7389*3ac0a46fSAndroid Build Coastguard Worker allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
7390*3ac0a46fSAndroid Build Coastguard Worker }
7391*3ac0a46fSAndroid Build Coastguard Worker
7392*3ac0a46fSAndroid Build Coastguard Worker /*
7393*3ac0a46fSAndroid Build Coastguard Worker * Replace a file with contiguous strips > 2 GB of uncompressed data by
7394*3ac0a46fSAndroid Build Coastguard Worker * multiple smaller strips. This is useful for
7395*3ac0a46fSAndroid Build Coastguard Worker * dealing with large images or for dealing with machines with a limited
7396*3ac0a46fSAndroid Build Coastguard Worker * amount memory.
7397*3ac0a46fSAndroid Build Coastguard Worker */
TryChopUpUncompressedBigTiff(TIFF * tif)7398*3ac0a46fSAndroid Build Coastguard Worker static void TryChopUpUncompressedBigTiff(TIFF *tif)
7399*3ac0a46fSAndroid Build Coastguard Worker {
7400*3ac0a46fSAndroid Build Coastguard Worker TIFFDirectory *td = &tif->tif_dir;
7401*3ac0a46fSAndroid Build Coastguard Worker uint32_t rowblock;
7402*3ac0a46fSAndroid Build Coastguard Worker uint64_t rowblockbytes;
7403*3ac0a46fSAndroid Build Coastguard Worker uint32_t i;
7404*3ac0a46fSAndroid Build Coastguard Worker uint64_t stripsize;
7405*3ac0a46fSAndroid Build Coastguard Worker uint32_t rowblocksperstrip;
7406*3ac0a46fSAndroid Build Coastguard Worker uint32_t rowsperstrip;
7407*3ac0a46fSAndroid Build Coastguard Worker uint64_t stripbytes;
7408*3ac0a46fSAndroid Build Coastguard Worker uint32_t nstrips;
7409*3ac0a46fSAndroid Build Coastguard Worker
7410*3ac0a46fSAndroid Build Coastguard Worker stripsize = TIFFStripSize64(tif);
7411*3ac0a46fSAndroid Build Coastguard Worker
7412*3ac0a46fSAndroid Build Coastguard Worker assert(tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG);
7413*3ac0a46fSAndroid Build Coastguard Worker assert(tif->tif_dir.td_compression == COMPRESSION_NONE);
7414*3ac0a46fSAndroid Build Coastguard Worker assert((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) ==
7415*3ac0a46fSAndroid Build Coastguard Worker TIFF_STRIPCHOP);
7416*3ac0a46fSAndroid Build Coastguard Worker assert(stripsize > 0x7FFFFFFFUL);
7417*3ac0a46fSAndroid Build Coastguard Worker
7418*3ac0a46fSAndroid Build Coastguard Worker /* On a newly created file, just re-opened to be filled, we */
7419*3ac0a46fSAndroid Build Coastguard Worker /* don't want strip chop to trigger as it is going to cause issues */
7420*3ac0a46fSAndroid Build Coastguard Worker /* later ( StripOffsets and StripByteCounts improperly filled) . */
7421*3ac0a46fSAndroid Build Coastguard Worker if (TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY)
7422*3ac0a46fSAndroid Build Coastguard Worker return;
7423*3ac0a46fSAndroid Build Coastguard Worker
7424*3ac0a46fSAndroid Build Coastguard Worker if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
7425*3ac0a46fSAndroid Build Coastguard Worker rowblock = td->td_ycbcrsubsampling[1];
7426*3ac0a46fSAndroid Build Coastguard Worker else
7427*3ac0a46fSAndroid Build Coastguard Worker rowblock = 1;
7428*3ac0a46fSAndroid Build Coastguard Worker rowblockbytes = TIFFVStripSize64(tif, rowblock);
7429*3ac0a46fSAndroid Build Coastguard Worker if (rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL)
7430*3ac0a46fSAndroid Build Coastguard Worker {
7431*3ac0a46fSAndroid Build Coastguard Worker /* In case of file with gigantic width */
7432*3ac0a46fSAndroid Build Coastguard Worker return;
7433*3ac0a46fSAndroid Build Coastguard Worker }
7434*3ac0a46fSAndroid Build Coastguard Worker
7435*3ac0a46fSAndroid Build Coastguard Worker /* Check that the strips are contiguous and of the expected size */
7436*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < td->td_nstrips; i++)
7437*3ac0a46fSAndroid Build Coastguard Worker {
7438*3ac0a46fSAndroid Build Coastguard Worker if (i == td->td_nstrips - 1)
7439*3ac0a46fSAndroid Build Coastguard Worker {
7440*3ac0a46fSAndroid Build Coastguard Worker if (TIFFGetStrileByteCount(tif, i) <
7441*3ac0a46fSAndroid Build Coastguard Worker TIFFVStripSize64(tif,
7442*3ac0a46fSAndroid Build Coastguard Worker td->td_imagelength - i * td->td_rowsperstrip))
7443*3ac0a46fSAndroid Build Coastguard Worker {
7444*3ac0a46fSAndroid Build Coastguard Worker return;
7445*3ac0a46fSAndroid Build Coastguard Worker }
7446*3ac0a46fSAndroid Build Coastguard Worker }
7447*3ac0a46fSAndroid Build Coastguard Worker else
7448*3ac0a46fSAndroid Build Coastguard Worker {
7449*3ac0a46fSAndroid Build Coastguard Worker if (TIFFGetStrileByteCount(tif, i) != stripsize)
7450*3ac0a46fSAndroid Build Coastguard Worker {
7451*3ac0a46fSAndroid Build Coastguard Worker return;
7452*3ac0a46fSAndroid Build Coastguard Worker }
7453*3ac0a46fSAndroid Build Coastguard Worker if (i > 0 && TIFFGetStrileOffset(tif, i) !=
7454*3ac0a46fSAndroid Build Coastguard Worker TIFFGetStrileOffset(tif, i - 1) +
7455*3ac0a46fSAndroid Build Coastguard Worker TIFFGetStrileByteCount(tif, i - 1))
7456*3ac0a46fSAndroid Build Coastguard Worker {
7457*3ac0a46fSAndroid Build Coastguard Worker return;
7458*3ac0a46fSAndroid Build Coastguard Worker }
7459*3ac0a46fSAndroid Build Coastguard Worker }
7460*3ac0a46fSAndroid Build Coastguard Worker }
7461*3ac0a46fSAndroid Build Coastguard Worker
7462*3ac0a46fSAndroid Build Coastguard Worker /* Aim for 512 MB strips (that will still be manageable by 32 bit builds */
7463*3ac0a46fSAndroid Build Coastguard Worker rowblocksperstrip = (uint32_t)(512 * 1024 * 1024 / rowblockbytes);
7464*3ac0a46fSAndroid Build Coastguard Worker if (rowblocksperstrip == 0)
7465*3ac0a46fSAndroid Build Coastguard Worker rowblocksperstrip = 1;
7466*3ac0a46fSAndroid Build Coastguard Worker rowsperstrip = rowblocksperstrip * rowblock;
7467*3ac0a46fSAndroid Build Coastguard Worker stripbytes = rowblocksperstrip * rowblockbytes;
7468*3ac0a46fSAndroid Build Coastguard Worker assert(stripbytes <= 0x7FFFFFFFUL);
7469*3ac0a46fSAndroid Build Coastguard Worker
7470*3ac0a46fSAndroid Build Coastguard Worker nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
7471*3ac0a46fSAndroid Build Coastguard Worker if (nstrips == 0)
7472*3ac0a46fSAndroid Build Coastguard Worker return;
7473*3ac0a46fSAndroid Build Coastguard Worker
7474*3ac0a46fSAndroid Build Coastguard Worker /* If we are going to allocate a lot of memory, make sure that the */
7475*3ac0a46fSAndroid Build Coastguard Worker /* file is as big as needed */
7476*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_mode == O_RDONLY && nstrips > 1000000)
7477*3ac0a46fSAndroid Build Coastguard Worker {
7478*3ac0a46fSAndroid Build Coastguard Worker uint64_t last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1);
7479*3ac0a46fSAndroid Build Coastguard Worker uint64_t filesize = TIFFGetFileSize(tif);
7480*3ac0a46fSAndroid Build Coastguard Worker uint64_t last_bytecount =
7481*3ac0a46fSAndroid Build Coastguard Worker TIFFGetStrileByteCount(tif, td->td_nstrips - 1);
7482*3ac0a46fSAndroid Build Coastguard Worker if (last_offset > filesize || last_bytecount > filesize - last_offset)
7483*3ac0a46fSAndroid Build Coastguard Worker {
7484*3ac0a46fSAndroid Build Coastguard Worker return;
7485*3ac0a46fSAndroid Build Coastguard Worker }
7486*3ac0a46fSAndroid Build Coastguard Worker }
7487*3ac0a46fSAndroid Build Coastguard Worker
7488*3ac0a46fSAndroid Build Coastguard Worker allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
7489*3ac0a46fSAndroid Build Coastguard Worker }
7490*3ac0a46fSAndroid Build Coastguard Worker
7491*3ac0a46fSAndroid Build Coastguard Worker TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
_TIFFUnsanitizedAddUInt64AndInt(uint64_t a,int b)7492*3ac0a46fSAndroid Build Coastguard Worker static uint64_t _TIFFUnsanitizedAddUInt64AndInt(uint64_t a, int b)
7493*3ac0a46fSAndroid Build Coastguard Worker {
7494*3ac0a46fSAndroid Build Coastguard Worker return a + b;
7495*3ac0a46fSAndroid Build Coastguard Worker }
7496*3ac0a46fSAndroid Build Coastguard Worker
7497*3ac0a46fSAndroid Build Coastguard Worker /* Read the value of [Strip|Tile]Offset or [Strip|Tile]ByteCount around
7498*3ac0a46fSAndroid Build Coastguard Worker * strip/tile of number strile. Also fetch the neighbouring values using a
7499*3ac0a46fSAndroid Build Coastguard Worker * 4096 byte page size.
7500*3ac0a46fSAndroid Build Coastguard Worker */
_TIFFPartialReadStripArray(TIFF * tif,TIFFDirEntry * dirent,int strile,uint64_t * panVals)7501*3ac0a46fSAndroid Build Coastguard Worker static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent,
7502*3ac0a46fSAndroid Build Coastguard Worker int strile, uint64_t *panVals)
7503*3ac0a46fSAndroid Build Coastguard Worker {
7504*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "_TIFFPartialReadStripArray";
7505*3ac0a46fSAndroid Build Coastguard Worker #define IO_CACHE_PAGE_SIZE 4096
7506*3ac0a46fSAndroid Build Coastguard Worker
7507*3ac0a46fSAndroid Build Coastguard Worker size_t sizeofval;
7508*3ac0a46fSAndroid Build Coastguard Worker const int bSwab = (tif->tif_flags & TIFF_SWAB) != 0;
7509*3ac0a46fSAndroid Build Coastguard Worker int sizeofvalint;
7510*3ac0a46fSAndroid Build Coastguard Worker uint64_t nBaseOffset;
7511*3ac0a46fSAndroid Build Coastguard Worker uint64_t nOffset;
7512*3ac0a46fSAndroid Build Coastguard Worker uint64_t nOffsetStartPage;
7513*3ac0a46fSAndroid Build Coastguard Worker uint64_t nOffsetEndPage;
7514*3ac0a46fSAndroid Build Coastguard Worker tmsize_t nToRead;
7515*3ac0a46fSAndroid Build Coastguard Worker tmsize_t nRead;
7516*3ac0a46fSAndroid Build Coastguard Worker uint64_t nLastStripOffset;
7517*3ac0a46fSAndroid Build Coastguard Worker int iStartBefore;
7518*3ac0a46fSAndroid Build Coastguard Worker int i;
7519*3ac0a46fSAndroid Build Coastguard Worker const uint32_t arraySize = tif->tif_dir.td_stripoffsetbyteallocsize;
7520*3ac0a46fSAndroid Build Coastguard Worker unsigned char buffer[2 * IO_CACHE_PAGE_SIZE];
7521*3ac0a46fSAndroid Build Coastguard Worker
7522*3ac0a46fSAndroid Build Coastguard Worker assert(dirent->tdir_count > 4);
7523*3ac0a46fSAndroid Build Coastguard Worker
7524*3ac0a46fSAndroid Build Coastguard Worker if (dirent->tdir_type == TIFF_SHORT)
7525*3ac0a46fSAndroid Build Coastguard Worker {
7526*3ac0a46fSAndroid Build Coastguard Worker sizeofval = sizeof(uint16_t);
7527*3ac0a46fSAndroid Build Coastguard Worker }
7528*3ac0a46fSAndroid Build Coastguard Worker else if (dirent->tdir_type == TIFF_LONG)
7529*3ac0a46fSAndroid Build Coastguard Worker {
7530*3ac0a46fSAndroid Build Coastguard Worker sizeofval = sizeof(uint32_t);
7531*3ac0a46fSAndroid Build Coastguard Worker }
7532*3ac0a46fSAndroid Build Coastguard Worker else if (dirent->tdir_type == TIFF_LONG8)
7533*3ac0a46fSAndroid Build Coastguard Worker {
7534*3ac0a46fSAndroid Build Coastguard Worker sizeofval = sizeof(uint64_t);
7535*3ac0a46fSAndroid Build Coastguard Worker }
7536*3ac0a46fSAndroid Build Coastguard Worker else if (dirent->tdir_type == TIFF_SLONG8)
7537*3ac0a46fSAndroid Build Coastguard Worker {
7538*3ac0a46fSAndroid Build Coastguard Worker /* Non conformant but used by some images as in */
7539*3ac0a46fSAndroid Build Coastguard Worker /* https://github.com/OSGeo/gdal/issues/2165 */
7540*3ac0a46fSAndroid Build Coastguard Worker sizeofval = sizeof(int64_t);
7541*3ac0a46fSAndroid Build Coastguard Worker }
7542*3ac0a46fSAndroid Build Coastguard Worker else
7543*3ac0a46fSAndroid Build Coastguard Worker {
7544*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
7545*3ac0a46fSAndroid Build Coastguard Worker "Invalid type for [Strip|Tile][Offset/ByteCount] tag");
7546*3ac0a46fSAndroid Build Coastguard Worker panVals[strile] = 0;
7547*3ac0a46fSAndroid Build Coastguard Worker return 0;
7548*3ac0a46fSAndroid Build Coastguard Worker }
7549*3ac0a46fSAndroid Build Coastguard Worker sizeofvalint = (int)(sizeofval);
7550*3ac0a46fSAndroid Build Coastguard Worker
7551*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_BIGTIFF)
7552*3ac0a46fSAndroid Build Coastguard Worker {
7553*3ac0a46fSAndroid Build Coastguard Worker uint64_t offset = dirent->tdir_offset.toff_long8;
7554*3ac0a46fSAndroid Build Coastguard Worker if (bSwab)
7555*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&offset);
7556*3ac0a46fSAndroid Build Coastguard Worker nBaseOffset = offset;
7557*3ac0a46fSAndroid Build Coastguard Worker }
7558*3ac0a46fSAndroid Build Coastguard Worker else
7559*3ac0a46fSAndroid Build Coastguard Worker {
7560*3ac0a46fSAndroid Build Coastguard Worker uint32_t offset = dirent->tdir_offset.toff_long;
7561*3ac0a46fSAndroid Build Coastguard Worker if (bSwab)
7562*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&offset);
7563*3ac0a46fSAndroid Build Coastguard Worker nBaseOffset = offset;
7564*3ac0a46fSAndroid Build Coastguard Worker }
7565*3ac0a46fSAndroid Build Coastguard Worker /* To avoid later unsigned integer overflows */
7566*3ac0a46fSAndroid Build Coastguard Worker if (nBaseOffset > (uint64_t)INT64_MAX)
7567*3ac0a46fSAndroid Build Coastguard Worker {
7568*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d",
7569*3ac0a46fSAndroid Build Coastguard Worker strile);
7570*3ac0a46fSAndroid Build Coastguard Worker panVals[strile] = 0;
7571*3ac0a46fSAndroid Build Coastguard Worker return 0;
7572*3ac0a46fSAndroid Build Coastguard Worker }
7573*3ac0a46fSAndroid Build Coastguard Worker nOffset = nBaseOffset + sizeofval * strile;
7574*3ac0a46fSAndroid Build Coastguard Worker nOffsetStartPage = (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE;
7575*3ac0a46fSAndroid Build Coastguard Worker nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE;
7576*3ac0a46fSAndroid Build Coastguard Worker
7577*3ac0a46fSAndroid Build Coastguard Worker if (nOffset + sizeofval > nOffsetEndPage)
7578*3ac0a46fSAndroid Build Coastguard Worker nOffsetEndPage += IO_CACHE_PAGE_SIZE;
7579*3ac0a46fSAndroid Build Coastguard Worker #undef IO_CACHE_PAGE_SIZE
7580*3ac0a46fSAndroid Build Coastguard Worker
7581*3ac0a46fSAndroid Build Coastguard Worker nLastStripOffset = nBaseOffset + arraySize * sizeofval;
7582*3ac0a46fSAndroid Build Coastguard Worker if (nLastStripOffset < nOffsetEndPage)
7583*3ac0a46fSAndroid Build Coastguard Worker nOffsetEndPage = nLastStripOffset;
7584*3ac0a46fSAndroid Build Coastguard Worker if (nOffsetStartPage >= nOffsetEndPage)
7585*3ac0a46fSAndroid Build Coastguard Worker {
7586*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d",
7587*3ac0a46fSAndroid Build Coastguard Worker strile);
7588*3ac0a46fSAndroid Build Coastguard Worker panVals[strile] = 0;
7589*3ac0a46fSAndroid Build Coastguard Worker return 0;
7590*3ac0a46fSAndroid Build Coastguard Worker }
7591*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, nOffsetStartPage))
7592*3ac0a46fSAndroid Build Coastguard Worker {
7593*3ac0a46fSAndroid Build Coastguard Worker panVals[strile] = 0;
7594*3ac0a46fSAndroid Build Coastguard Worker return 0;
7595*3ac0a46fSAndroid Build Coastguard Worker }
7596*3ac0a46fSAndroid Build Coastguard Worker
7597*3ac0a46fSAndroid Build Coastguard Worker nToRead = (tmsize_t)(nOffsetEndPage - nOffsetStartPage);
7598*3ac0a46fSAndroid Build Coastguard Worker nRead = TIFFReadFile(tif, buffer, nToRead);
7599*3ac0a46fSAndroid Build Coastguard Worker if (nRead < nToRead)
7600*3ac0a46fSAndroid Build Coastguard Worker {
7601*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
7602*3ac0a46fSAndroid Build Coastguard Worker "Cannot read offset/size for strile around ~%d", strile);
7603*3ac0a46fSAndroid Build Coastguard Worker return 0;
7604*3ac0a46fSAndroid Build Coastguard Worker }
7605*3ac0a46fSAndroid Build Coastguard Worker iStartBefore = -(int)((nOffset - nOffsetStartPage) / sizeofval);
7606*3ac0a46fSAndroid Build Coastguard Worker if (strile + iStartBefore < 0)
7607*3ac0a46fSAndroid Build Coastguard Worker iStartBefore = -strile;
7608*3ac0a46fSAndroid Build Coastguard Worker for (i = iStartBefore;
7609*3ac0a46fSAndroid Build Coastguard Worker (uint32_t)(strile + i) < arraySize &&
7610*3ac0a46fSAndroid Build Coastguard Worker _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <=
7611*3ac0a46fSAndroid Build Coastguard Worker nOffsetEndPage;
7612*3ac0a46fSAndroid Build Coastguard Worker ++i)
7613*3ac0a46fSAndroid Build Coastguard Worker {
7614*3ac0a46fSAndroid Build Coastguard Worker if (dirent->tdir_type == TIFF_SHORT)
7615*3ac0a46fSAndroid Build Coastguard Worker {
7616*3ac0a46fSAndroid Build Coastguard Worker uint16_t val;
7617*3ac0a46fSAndroid Build Coastguard Worker memcpy(&val,
7618*3ac0a46fSAndroid Build Coastguard Worker buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
7619*3ac0a46fSAndroid Build Coastguard Worker sizeof(val));
7620*3ac0a46fSAndroid Build Coastguard Worker if (bSwab)
7621*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(&val);
7622*3ac0a46fSAndroid Build Coastguard Worker panVals[strile + i] = val;
7623*3ac0a46fSAndroid Build Coastguard Worker }
7624*3ac0a46fSAndroid Build Coastguard Worker else if (dirent->tdir_type == TIFF_LONG)
7625*3ac0a46fSAndroid Build Coastguard Worker {
7626*3ac0a46fSAndroid Build Coastguard Worker uint32_t val;
7627*3ac0a46fSAndroid Build Coastguard Worker memcpy(&val,
7628*3ac0a46fSAndroid Build Coastguard Worker buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
7629*3ac0a46fSAndroid Build Coastguard Worker sizeof(val));
7630*3ac0a46fSAndroid Build Coastguard Worker if (bSwab)
7631*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&val);
7632*3ac0a46fSAndroid Build Coastguard Worker panVals[strile + i] = val;
7633*3ac0a46fSAndroid Build Coastguard Worker }
7634*3ac0a46fSAndroid Build Coastguard Worker else if (dirent->tdir_type == TIFF_LONG8)
7635*3ac0a46fSAndroid Build Coastguard Worker {
7636*3ac0a46fSAndroid Build Coastguard Worker uint64_t val;
7637*3ac0a46fSAndroid Build Coastguard Worker memcpy(&val,
7638*3ac0a46fSAndroid Build Coastguard Worker buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
7639*3ac0a46fSAndroid Build Coastguard Worker sizeof(val));
7640*3ac0a46fSAndroid Build Coastguard Worker if (bSwab)
7641*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&val);
7642*3ac0a46fSAndroid Build Coastguard Worker panVals[strile + i] = val;
7643*3ac0a46fSAndroid Build Coastguard Worker }
7644*3ac0a46fSAndroid Build Coastguard Worker else /* if( dirent->tdir_type == TIFF_SLONG8 ) */
7645*3ac0a46fSAndroid Build Coastguard Worker {
7646*3ac0a46fSAndroid Build Coastguard Worker /* Non conformant data type */
7647*3ac0a46fSAndroid Build Coastguard Worker int64_t val;
7648*3ac0a46fSAndroid Build Coastguard Worker memcpy(&val,
7649*3ac0a46fSAndroid Build Coastguard Worker buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
7650*3ac0a46fSAndroid Build Coastguard Worker sizeof(val));
7651*3ac0a46fSAndroid Build Coastguard Worker if (bSwab)
7652*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)&val);
7653*3ac0a46fSAndroid Build Coastguard Worker panVals[strile + i] = (uint64_t)val;
7654*3ac0a46fSAndroid Build Coastguard Worker }
7655*3ac0a46fSAndroid Build Coastguard Worker }
7656*3ac0a46fSAndroid Build Coastguard Worker return 1;
7657*3ac0a46fSAndroid Build Coastguard Worker }
7658*3ac0a46fSAndroid Build Coastguard Worker
_TIFFFetchStrileValue(TIFF * tif,uint32_t strile,TIFFDirEntry * dirent,uint64_t ** parray)7659*3ac0a46fSAndroid Build Coastguard Worker static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile,
7660*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dirent, uint64_t **parray)
7661*3ac0a46fSAndroid Build Coastguard Worker {
7662*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "_TIFFFetchStrileValue";
7663*3ac0a46fSAndroid Build Coastguard Worker TIFFDirectory *td = &tif->tif_dir;
7664*3ac0a46fSAndroid Build Coastguard Worker if (strile >= dirent->tdir_count)
7665*3ac0a46fSAndroid Build Coastguard Worker {
7666*3ac0a46fSAndroid Build Coastguard Worker return 0;
7667*3ac0a46fSAndroid Build Coastguard Worker }
7668*3ac0a46fSAndroid Build Coastguard Worker if (strile >= td->td_stripoffsetbyteallocsize)
7669*3ac0a46fSAndroid Build Coastguard Worker {
7670*3ac0a46fSAndroid Build Coastguard Worker uint32_t nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize;
7671*3ac0a46fSAndroid Build Coastguard Worker uint32_t nStripArrayAllocNew;
7672*3ac0a46fSAndroid Build Coastguard Worker uint64_t nArraySize64;
7673*3ac0a46fSAndroid Build Coastguard Worker size_t nArraySize;
7674*3ac0a46fSAndroid Build Coastguard Worker uint64_t *offsetArray;
7675*3ac0a46fSAndroid Build Coastguard Worker uint64_t *bytecountArray;
7676*3ac0a46fSAndroid Build Coastguard Worker
7677*3ac0a46fSAndroid Build Coastguard Worker if (strile > 1000000)
7678*3ac0a46fSAndroid Build Coastguard Worker {
7679*3ac0a46fSAndroid Build Coastguard Worker uint64_t filesize = TIFFGetFileSize(tif);
7680*3ac0a46fSAndroid Build Coastguard Worker /* Avoid excessive memory allocation attempt */
7681*3ac0a46fSAndroid Build Coastguard Worker /* For such a big blockid we need at least a TIFF_LONG per strile */
7682*3ac0a46fSAndroid Build Coastguard Worker /* for the offset array. */
7683*3ac0a46fSAndroid Build Coastguard Worker if (strile > filesize / sizeof(uint32_t))
7684*3ac0a46fSAndroid Build Coastguard Worker {
7685*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "File too short");
7686*3ac0a46fSAndroid Build Coastguard Worker return 0;
7687*3ac0a46fSAndroid Build Coastguard Worker }
7688*3ac0a46fSAndroid Build Coastguard Worker }
7689*3ac0a46fSAndroid Build Coastguard Worker
7690*3ac0a46fSAndroid Build Coastguard Worker if (td->td_stripoffsetbyteallocsize == 0 &&
7691*3ac0a46fSAndroid Build Coastguard Worker td->td_nstrips < 1024 * 1024)
7692*3ac0a46fSAndroid Build Coastguard Worker {
7693*3ac0a46fSAndroid Build Coastguard Worker nStripArrayAllocNew = td->td_nstrips;
7694*3ac0a46fSAndroid Build Coastguard Worker }
7695*3ac0a46fSAndroid Build Coastguard Worker else
7696*3ac0a46fSAndroid Build Coastguard Worker {
7697*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_MAX(a, b) (((a) > (b)) ? (a) : (b))
7698*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_MIN(a, b) (((a) < (b)) ? (a) : (b))
7699*3ac0a46fSAndroid Build Coastguard Worker nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U);
7700*3ac0a46fSAndroid Build Coastguard Worker if (nStripArrayAllocNew < 0xFFFFFFFFU / 2)
7701*3ac0a46fSAndroid Build Coastguard Worker nStripArrayAllocNew *= 2;
7702*3ac0a46fSAndroid Build Coastguard Worker nStripArrayAllocNew = TIFF_MIN(nStripArrayAllocNew, td->td_nstrips);
7703*3ac0a46fSAndroid Build Coastguard Worker }
7704*3ac0a46fSAndroid Build Coastguard Worker assert(strile < nStripArrayAllocNew);
7705*3ac0a46fSAndroid Build Coastguard Worker nArraySize64 = (uint64_t)sizeof(uint64_t) * nStripArrayAllocNew;
7706*3ac0a46fSAndroid Build Coastguard Worker nArraySize = (size_t)(nArraySize64);
7707*3ac0a46fSAndroid Build Coastguard Worker #if SIZEOF_SIZE_T == 4
7708*3ac0a46fSAndroid Build Coastguard Worker if (nArraySize != nArraySize64)
7709*3ac0a46fSAndroid Build Coastguard Worker {
7710*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
7711*3ac0a46fSAndroid Build Coastguard Worker "Cannot allocate strip offset and bytecount arrays");
7712*3ac0a46fSAndroid Build Coastguard Worker return 0;
7713*3ac0a46fSAndroid Build Coastguard Worker }
7714*3ac0a46fSAndroid Build Coastguard Worker #endif
7715*3ac0a46fSAndroid Build Coastguard Worker offsetArray = (uint64_t *)(_TIFFreallocExt(tif, td->td_stripoffset_p,
7716*3ac0a46fSAndroid Build Coastguard Worker nArraySize));
7717*3ac0a46fSAndroid Build Coastguard Worker bytecountArray = (uint64_t *)(_TIFFreallocExt(
7718*3ac0a46fSAndroid Build Coastguard Worker tif, td->td_stripbytecount_p, nArraySize));
7719*3ac0a46fSAndroid Build Coastguard Worker if (offsetArray)
7720*3ac0a46fSAndroid Build Coastguard Worker td->td_stripoffset_p = offsetArray;
7721*3ac0a46fSAndroid Build Coastguard Worker if (bytecountArray)
7722*3ac0a46fSAndroid Build Coastguard Worker td->td_stripbytecount_p = bytecountArray;
7723*3ac0a46fSAndroid Build Coastguard Worker if (offsetArray && bytecountArray)
7724*3ac0a46fSAndroid Build Coastguard Worker {
7725*3ac0a46fSAndroid Build Coastguard Worker td->td_stripoffsetbyteallocsize = nStripArrayAllocNew;
7726*3ac0a46fSAndroid Build Coastguard Worker /* Initialize new entries to ~0 / -1 */
7727*3ac0a46fSAndroid Build Coastguard Worker /* coverity[overrun-buffer-arg] */
7728*3ac0a46fSAndroid Build Coastguard Worker memset(td->td_stripoffset_p + nStripArrayAllocBefore, 0xFF,
7729*3ac0a46fSAndroid Build Coastguard Worker (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) *
7730*3ac0a46fSAndroid Build Coastguard Worker sizeof(uint64_t));
7731*3ac0a46fSAndroid Build Coastguard Worker /* coverity[overrun-buffer-arg] */
7732*3ac0a46fSAndroid Build Coastguard Worker memset(td->td_stripbytecount_p + nStripArrayAllocBefore, 0xFF,
7733*3ac0a46fSAndroid Build Coastguard Worker (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) *
7734*3ac0a46fSAndroid Build Coastguard Worker sizeof(uint64_t));
7735*3ac0a46fSAndroid Build Coastguard Worker }
7736*3ac0a46fSAndroid Build Coastguard Worker else
7737*3ac0a46fSAndroid Build Coastguard Worker {
7738*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
7739*3ac0a46fSAndroid Build Coastguard Worker "Cannot allocate strip offset and bytecount arrays");
7740*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, td->td_stripoffset_p);
7741*3ac0a46fSAndroid Build Coastguard Worker td->td_stripoffset_p = NULL;
7742*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, td->td_stripbytecount_p);
7743*3ac0a46fSAndroid Build Coastguard Worker td->td_stripbytecount_p = NULL;
7744*3ac0a46fSAndroid Build Coastguard Worker td->td_stripoffsetbyteallocsize = 0;
7745*3ac0a46fSAndroid Build Coastguard Worker }
7746*3ac0a46fSAndroid Build Coastguard Worker }
7747*3ac0a46fSAndroid Build Coastguard Worker if (*parray == NULL || strile >= td->td_stripoffsetbyteallocsize)
7748*3ac0a46fSAndroid Build Coastguard Worker return 0;
7749*3ac0a46fSAndroid Build Coastguard Worker
7750*3ac0a46fSAndroid Build Coastguard Worker if (~((*parray)[strile]) == 0)
7751*3ac0a46fSAndroid Build Coastguard Worker {
7752*3ac0a46fSAndroid Build Coastguard Worker if (!_TIFFPartialReadStripArray(tif, dirent, strile, *parray))
7753*3ac0a46fSAndroid Build Coastguard Worker {
7754*3ac0a46fSAndroid Build Coastguard Worker (*parray)[strile] = 0;
7755*3ac0a46fSAndroid Build Coastguard Worker return 0;
7756*3ac0a46fSAndroid Build Coastguard Worker }
7757*3ac0a46fSAndroid Build Coastguard Worker }
7758*3ac0a46fSAndroid Build Coastguard Worker
7759*3ac0a46fSAndroid Build Coastguard Worker return 1;
7760*3ac0a46fSAndroid Build Coastguard Worker }
7761*3ac0a46fSAndroid Build Coastguard Worker
_TIFFGetStrileOffsetOrByteCountValue(TIFF * tif,uint32_t strile,TIFFDirEntry * dirent,uint64_t ** parray,int * pbErr)7762*3ac0a46fSAndroid Build Coastguard Worker static uint64_t _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32_t strile,
7763*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dirent,
7764*3ac0a46fSAndroid Build Coastguard Worker uint64_t **parray,
7765*3ac0a46fSAndroid Build Coastguard Worker int *pbErr)
7766*3ac0a46fSAndroid Build Coastguard Worker {
7767*3ac0a46fSAndroid Build Coastguard Worker TIFFDirectory *td = &tif->tif_dir;
7768*3ac0a46fSAndroid Build Coastguard Worker if (pbErr)
7769*3ac0a46fSAndroid Build Coastguard Worker *pbErr = 0;
7770*3ac0a46fSAndroid Build Coastguard Worker if ((tif->tif_flags & TIFF_DEFERSTRILELOAD) &&
7771*3ac0a46fSAndroid Build Coastguard Worker !(tif->tif_flags & TIFF_CHOPPEDUPARRAYS))
7772*3ac0a46fSAndroid Build Coastguard Worker {
7773*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD) ||
7774*3ac0a46fSAndroid Build Coastguard Worker /* If the values may fit in the toff_long/toff_long8 member */
7775*3ac0a46fSAndroid Build Coastguard Worker /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */
7776*3ac0a46fSAndroid Build Coastguard Worker dirent->tdir_count <= 4)
7777*3ac0a46fSAndroid Build Coastguard Worker {
7778*3ac0a46fSAndroid Build Coastguard Worker if (!_TIFFFillStriles(tif))
7779*3ac0a46fSAndroid Build Coastguard Worker {
7780*3ac0a46fSAndroid Build Coastguard Worker if (pbErr)
7781*3ac0a46fSAndroid Build Coastguard Worker *pbErr = 1;
7782*3ac0a46fSAndroid Build Coastguard Worker /* Do not return, as we want this function to always */
7783*3ac0a46fSAndroid Build Coastguard Worker /* return the same value if called several times with */
7784*3ac0a46fSAndroid Build Coastguard Worker /* the same arguments */
7785*3ac0a46fSAndroid Build Coastguard Worker }
7786*3ac0a46fSAndroid Build Coastguard Worker }
7787*3ac0a46fSAndroid Build Coastguard Worker else
7788*3ac0a46fSAndroid Build Coastguard Worker {
7789*3ac0a46fSAndroid Build Coastguard Worker if (!_TIFFFetchStrileValue(tif, strile, dirent, parray))
7790*3ac0a46fSAndroid Build Coastguard Worker {
7791*3ac0a46fSAndroid Build Coastguard Worker if (pbErr)
7792*3ac0a46fSAndroid Build Coastguard Worker *pbErr = 1;
7793*3ac0a46fSAndroid Build Coastguard Worker return 0;
7794*3ac0a46fSAndroid Build Coastguard Worker }
7795*3ac0a46fSAndroid Build Coastguard Worker }
7796*3ac0a46fSAndroid Build Coastguard Worker }
7797*3ac0a46fSAndroid Build Coastguard Worker if (*parray == NULL || strile >= td->td_nstrips)
7798*3ac0a46fSAndroid Build Coastguard Worker {
7799*3ac0a46fSAndroid Build Coastguard Worker if (pbErr)
7800*3ac0a46fSAndroid Build Coastguard Worker *pbErr = 1;
7801*3ac0a46fSAndroid Build Coastguard Worker return 0;
7802*3ac0a46fSAndroid Build Coastguard Worker }
7803*3ac0a46fSAndroid Build Coastguard Worker return (*parray)[strile];
7804*3ac0a46fSAndroid Build Coastguard Worker }
7805*3ac0a46fSAndroid Build Coastguard Worker
7806*3ac0a46fSAndroid Build Coastguard Worker /* Return the value of the TileOffsets/StripOffsets array for the specified
7807*3ac0a46fSAndroid Build Coastguard Worker * tile/strile */
TIFFGetStrileOffset(TIFF * tif,uint32_t strile)7808*3ac0a46fSAndroid Build Coastguard Worker uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile)
7809*3ac0a46fSAndroid Build Coastguard Worker {
7810*3ac0a46fSAndroid Build Coastguard Worker return TIFFGetStrileOffsetWithErr(tif, strile, NULL);
7811*3ac0a46fSAndroid Build Coastguard Worker }
7812*3ac0a46fSAndroid Build Coastguard Worker
7813*3ac0a46fSAndroid Build Coastguard Worker /* Return the value of the TileOffsets/StripOffsets array for the specified
7814*3ac0a46fSAndroid Build Coastguard Worker * tile/strile */
TIFFGetStrileOffsetWithErr(TIFF * tif,uint32_t strile,int * pbErr)7815*3ac0a46fSAndroid Build Coastguard Worker uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile, int *pbErr)
7816*3ac0a46fSAndroid Build Coastguard Worker {
7817*3ac0a46fSAndroid Build Coastguard Worker TIFFDirectory *td = &tif->tif_dir;
7818*3ac0a46fSAndroid Build Coastguard Worker return _TIFFGetStrileOffsetOrByteCountValue(tif, strile,
7819*3ac0a46fSAndroid Build Coastguard Worker &(td->td_stripoffset_entry),
7820*3ac0a46fSAndroid Build Coastguard Worker &(td->td_stripoffset_p), pbErr);
7821*3ac0a46fSAndroid Build Coastguard Worker }
7822*3ac0a46fSAndroid Build Coastguard Worker
7823*3ac0a46fSAndroid Build Coastguard Worker /* Return the value of the TileByteCounts/StripByteCounts array for the
7824*3ac0a46fSAndroid Build Coastguard Worker * specified tile/strile */
TIFFGetStrileByteCount(TIFF * tif,uint32_t strile)7825*3ac0a46fSAndroid Build Coastguard Worker uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile)
7826*3ac0a46fSAndroid Build Coastguard Worker {
7827*3ac0a46fSAndroid Build Coastguard Worker return TIFFGetStrileByteCountWithErr(tif, strile, NULL);
7828*3ac0a46fSAndroid Build Coastguard Worker }
7829*3ac0a46fSAndroid Build Coastguard Worker
7830*3ac0a46fSAndroid Build Coastguard Worker /* Return the value of the TileByteCounts/StripByteCounts array for the
7831*3ac0a46fSAndroid Build Coastguard Worker * specified tile/strile */
TIFFGetStrileByteCountWithErr(TIFF * tif,uint32_t strile,int * pbErr)7832*3ac0a46fSAndroid Build Coastguard Worker uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile, int *pbErr)
7833*3ac0a46fSAndroid Build Coastguard Worker {
7834*3ac0a46fSAndroid Build Coastguard Worker TIFFDirectory *td = &tif->tif_dir;
7835*3ac0a46fSAndroid Build Coastguard Worker return _TIFFGetStrileOffsetOrByteCountValue(
7836*3ac0a46fSAndroid Build Coastguard Worker tif, strile, &(td->td_stripbytecount_entry), &(td->td_stripbytecount_p),
7837*3ac0a46fSAndroid Build Coastguard Worker pbErr);
7838*3ac0a46fSAndroid Build Coastguard Worker }
7839*3ac0a46fSAndroid Build Coastguard Worker
_TIFFFillStriles(TIFF * tif)7840*3ac0a46fSAndroid Build Coastguard Worker int _TIFFFillStriles(TIFF *tif) { return _TIFFFillStrilesInternal(tif, 1); }
7841*3ac0a46fSAndroid Build Coastguard Worker
_TIFFFillStrilesInternal(TIFF * tif,int loadStripByteCount)7842*3ac0a46fSAndroid Build Coastguard Worker static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount)
7843*3ac0a46fSAndroid Build Coastguard Worker {
7844*3ac0a46fSAndroid Build Coastguard Worker register TIFFDirectory *td = &tif->tif_dir;
7845*3ac0a46fSAndroid Build Coastguard Worker int return_value = 1;
7846*3ac0a46fSAndroid Build Coastguard Worker
7847*3ac0a46fSAndroid Build Coastguard Worker /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */
7848*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) ||
7849*3ac0a46fSAndroid Build Coastguard Worker (tif->tif_flags & TIFF_CHOPPEDUPARRAYS) != 0)
7850*3ac0a46fSAndroid Build Coastguard Worker return 1;
7851*3ac0a46fSAndroid Build Coastguard Worker
7852*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_LAZYSTRILELOAD)
7853*3ac0a46fSAndroid Build Coastguard Worker {
7854*3ac0a46fSAndroid Build Coastguard Worker /* In case of lazy loading, reload completely the arrays */
7855*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, td->td_stripoffset_p);
7856*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, td->td_stripbytecount_p);
7857*3ac0a46fSAndroid Build Coastguard Worker td->td_stripoffset_p = NULL;
7858*3ac0a46fSAndroid Build Coastguard Worker td->td_stripbytecount_p = NULL;
7859*3ac0a46fSAndroid Build Coastguard Worker td->td_stripoffsetbyteallocsize = 0;
7860*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_LAZYSTRILELOAD;
7861*3ac0a46fSAndroid Build Coastguard Worker }
7862*3ac0a46fSAndroid Build Coastguard Worker
7863*3ac0a46fSAndroid Build Coastguard Worker /* If stripoffset array is already loaded, exit with success */
7864*3ac0a46fSAndroid Build Coastguard Worker if (td->td_stripoffset_p != NULL)
7865*3ac0a46fSAndroid Build Coastguard Worker return 1;
7866*3ac0a46fSAndroid Build Coastguard Worker
7867*3ac0a46fSAndroid Build Coastguard Worker /* If tdir_count was canceled, then we already got there, but in error */
7868*3ac0a46fSAndroid Build Coastguard Worker if (td->td_stripoffset_entry.tdir_count == 0)
7869*3ac0a46fSAndroid Build Coastguard Worker return 0;
7870*3ac0a46fSAndroid Build Coastguard Worker
7871*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFetchStripThing(tif, &(td->td_stripoffset_entry), td->td_nstrips,
7872*3ac0a46fSAndroid Build Coastguard Worker &td->td_stripoffset_p))
7873*3ac0a46fSAndroid Build Coastguard Worker {
7874*3ac0a46fSAndroid Build Coastguard Worker return_value = 0;
7875*3ac0a46fSAndroid Build Coastguard Worker }
7876*3ac0a46fSAndroid Build Coastguard Worker
7877*3ac0a46fSAndroid Build Coastguard Worker if (loadStripByteCount &&
7878*3ac0a46fSAndroid Build Coastguard Worker !TIFFFetchStripThing(tif, &(td->td_stripbytecount_entry),
7879*3ac0a46fSAndroid Build Coastguard Worker td->td_nstrips, &td->td_stripbytecount_p))
7880*3ac0a46fSAndroid Build Coastguard Worker {
7881*3ac0a46fSAndroid Build Coastguard Worker return_value = 0;
7882*3ac0a46fSAndroid Build Coastguard Worker }
7883*3ac0a46fSAndroid Build Coastguard Worker
7884*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
7885*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
7886*3ac0a46fSAndroid Build Coastguard Worker
7887*3ac0a46fSAndroid Build Coastguard Worker #ifdef STRIPBYTECOUNTSORTED_UNUSED
7888*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_nstrips > 1 && return_value == 1)
7889*3ac0a46fSAndroid Build Coastguard Worker {
7890*3ac0a46fSAndroid Build Coastguard Worker uint32_t strip;
7891*3ac0a46fSAndroid Build Coastguard Worker
7892*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecountsorted = 1;
7893*3ac0a46fSAndroid Build Coastguard Worker for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++)
7894*3ac0a46fSAndroid Build Coastguard Worker {
7895*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_stripoffset_p[strip - 1] >
7896*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_p[strip])
7897*3ac0a46fSAndroid Build Coastguard Worker {
7898*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecountsorted = 0;
7899*3ac0a46fSAndroid Build Coastguard Worker break;
7900*3ac0a46fSAndroid Build Coastguard Worker }
7901*3ac0a46fSAndroid Build Coastguard Worker }
7902*3ac0a46fSAndroid Build Coastguard Worker }
7903*3ac0a46fSAndroid Build Coastguard Worker #endif
7904*3ac0a46fSAndroid Build Coastguard Worker
7905*3ac0a46fSAndroid Build Coastguard Worker return return_value;
7906*3ac0a46fSAndroid Build Coastguard Worker }
7907