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 Write Support Routines.
29*3ac0a46fSAndroid Build Coastguard Worker */
30*3ac0a46fSAndroid Build Coastguard Worker #include "tiffiop.h"
31*3ac0a46fSAndroid Build Coastguard Worker #include <float.h> /*--: for Rational2Double */
32*3ac0a46fSAndroid Build Coastguard Worker #include <math.h> /*--: for Rational2Double */
33*3ac0a46fSAndroid Build Coastguard Worker
34*3ac0a46fSAndroid Build Coastguard Worker #ifdef HAVE_IEEEFP
35*3ac0a46fSAndroid Build Coastguard Worker #define TIFFCvtNativeToIEEEFloat(tif, n, fp)
36*3ac0a46fSAndroid Build Coastguard Worker #define TIFFCvtNativeToIEEEDouble(tif, n, dp)
37*3ac0a46fSAndroid Build Coastguard Worker #else
38*3ac0a46fSAndroid Build Coastguard Worker extern void TIFFCvtNativeToIEEEFloat(TIFF *tif, uint32_t n, float *fp);
39*3ac0a46fSAndroid Build Coastguard Worker extern void TIFFCvtNativeToIEEEDouble(TIFF *tif, uint32_t n, double *dp);
40*3ac0a46fSAndroid Build Coastguard Worker #endif
41*3ac0a46fSAndroid Build Coastguard Worker
42*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
43*3ac0a46fSAndroid Build Coastguard Worker uint64_t *pdiroff);
44*3ac0a46fSAndroid Build Coastguard Worker
45*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
46*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
47*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
48*3ac0a46fSAndroid Build Coastguard Worker double *value);
49*3ac0a46fSAndroid Build Coastguard Worker
50*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
51*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
52*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, char *value);
53*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir,
54*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
55*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint8_t *value);
56*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir,
57*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
58*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint8_t *value);
59*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir,
60*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
61*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, int8_t *value);
62*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
63*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
64*3ac0a46fSAndroid Build Coastguard Worker uint16_t value);
65*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
66*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
67*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint16_t *value);
68*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
69*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
70*3ac0a46fSAndroid Build Coastguard Worker uint16_t value);
71*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir,
72*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
73*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, int16_t *value);
74*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir,
75*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
76*3ac0a46fSAndroid Build Coastguard Worker uint32_t value);
77*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir,
78*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
79*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint32_t *value);
80*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir,
81*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
82*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, int32_t *value);
83*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
84*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
85*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint64_t *value);
86*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
87*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
88*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, int64_t *value);
89*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir,
90*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
91*3ac0a46fSAndroid Build Coastguard Worker double value);
92*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir,
93*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
94*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, float *value);
95*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir,
96*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
97*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, float *value);
98*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir,
99*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
100*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, float *value);
101*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
102*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
103*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, double *value);
104*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir,
105*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
106*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint32_t *value);
107*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
108*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
109*3ac0a46fSAndroid Build Coastguard Worker uint32_t value);
110*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
111*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
112*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint64_t *value);
113*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
114*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
115*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint64_t *value);
116*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
117*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir);
118*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
119*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir);
120*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
121*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir);
122*3ac0a46fSAndroid Build Coastguard Worker
123*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
124*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
125*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, char *value);
126*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir,
127*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
128*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag,
129*3ac0a46fSAndroid Build Coastguard Worker uint32_t count,
130*3ac0a46fSAndroid Build Coastguard Worker uint8_t *value);
131*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir,
132*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
133*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
134*3ac0a46fSAndroid Build Coastguard Worker uint8_t *value);
135*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir,
136*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
137*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
138*3ac0a46fSAndroid Build Coastguard Worker int8_t *value);
139*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir,
140*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
141*3ac0a46fSAndroid Build Coastguard Worker uint16_t value);
142*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
143*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
144*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
145*3ac0a46fSAndroid Build Coastguard Worker uint16_t *value);
146*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir,
147*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
148*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
149*3ac0a46fSAndroid Build Coastguard Worker int16_t *value);
150*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir,
151*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
152*3ac0a46fSAndroid Build Coastguard Worker uint32_t value);
153*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
154*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
155*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
156*3ac0a46fSAndroid Build Coastguard Worker uint32_t *value);
157*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir,
158*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
159*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
160*3ac0a46fSAndroid Build Coastguard Worker int32_t *value);
161*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir,
162*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
163*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
164*3ac0a46fSAndroid Build Coastguard Worker uint64_t *value);
165*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir,
166*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
167*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
168*3ac0a46fSAndroid Build Coastguard Worker int64_t *value);
169*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
170*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
171*3ac0a46fSAndroid Build Coastguard Worker double value);
172*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
173*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
174*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag,
175*3ac0a46fSAndroid Build Coastguard Worker uint32_t count,
176*3ac0a46fSAndroid Build Coastguard Worker float *value);
177*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
178*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
179*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag,
180*3ac0a46fSAndroid Build Coastguard Worker uint32_t count,
181*3ac0a46fSAndroid Build Coastguard Worker float *value);
182*3ac0a46fSAndroid Build Coastguard Worker
183*3ac0a46fSAndroid Build Coastguard Worker /*--: Rational2Double: New functions to support true double-precision for custom
184*3ac0a46fSAndroid Build Coastguard Worker * rational tag types. */
185*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir,
186*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
187*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag,
188*3ac0a46fSAndroid Build Coastguard Worker uint32_t count,
189*3ac0a46fSAndroid Build Coastguard Worker double *value);
190*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir,
191*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
192*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag,
193*3ac0a46fSAndroid Build Coastguard Worker uint32_t count,
194*3ac0a46fSAndroid Build Coastguard Worker double *value);
195*3ac0a46fSAndroid Build Coastguard Worker static int
196*3ac0a46fSAndroid Build Coastguard Worker TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
197*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
198*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, double *value);
199*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
200*3ac0a46fSAndroid Build Coastguard Worker TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count,
201*3ac0a46fSAndroid Build Coastguard Worker double *value);
202*3ac0a46fSAndroid Build Coastguard Worker static void DoubleToRational(double value, uint32_t *num, uint32_t *denom);
203*3ac0a46fSAndroid Build Coastguard Worker static void DoubleToSrational(double value, int32_t *num, int32_t *denom);
204*3ac0a46fSAndroid Build Coastguard Worker
205*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
206*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
207*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
208*3ac0a46fSAndroid Build Coastguard Worker float *value);
209*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
210*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
211*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
212*3ac0a46fSAndroid Build Coastguard Worker double *value);
213*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir,
214*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
215*3ac0a46fSAndroid Build Coastguard Worker uint32_t count,
216*3ac0a46fSAndroid Build Coastguard Worker uint32_t *value);
217*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir,
218*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
219*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
220*3ac0a46fSAndroid Build Coastguard Worker uint64_t *value);
221*3ac0a46fSAndroid Build Coastguard Worker
222*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
223*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
224*3ac0a46fSAndroid Build Coastguard Worker uint16_t datatype, uint32_t count,
225*3ac0a46fSAndroid Build Coastguard Worker uint32_t datalength, void *data);
226*3ac0a46fSAndroid Build Coastguard Worker
227*3ac0a46fSAndroid Build Coastguard Worker static int TIFFLinkDirectory(TIFF *);
228*3ac0a46fSAndroid Build Coastguard Worker
229*3ac0a46fSAndroid Build Coastguard Worker /*
230*3ac0a46fSAndroid Build Coastguard Worker * Write the contents of the current directory
231*3ac0a46fSAndroid Build Coastguard Worker * to the specified file. This routine doesn't
232*3ac0a46fSAndroid Build Coastguard Worker * handle overwriting a directory with auxiliary
233*3ac0a46fSAndroid Build Coastguard Worker * storage that's been changed.
234*3ac0a46fSAndroid Build Coastguard Worker */
TIFFWriteDirectory(TIFF * tif)235*3ac0a46fSAndroid Build Coastguard Worker int TIFFWriteDirectory(TIFF *tif)
236*3ac0a46fSAndroid Build Coastguard Worker {
237*3ac0a46fSAndroid Build Coastguard Worker return TIFFWriteDirectorySec(tif, TRUE, TRUE, NULL);
238*3ac0a46fSAndroid Build Coastguard Worker }
239*3ac0a46fSAndroid Build Coastguard Worker
240*3ac0a46fSAndroid Build Coastguard Worker /*
241*3ac0a46fSAndroid Build Coastguard Worker * This is an advanced writing function that must be used in a particular
242*3ac0a46fSAndroid Build Coastguard Worker * sequence, and generally together with TIFFForceStrileArrayWriting(),
243*3ac0a46fSAndroid Build Coastguard Worker * to make its intended effect. Its aim is to modify the location
244*3ac0a46fSAndroid Build Coastguard Worker * where the [Strip/Tile][Offsets/ByteCounts] arrays are located in the file.
245*3ac0a46fSAndroid Build Coastguard Worker * More precisely, when TIFFWriteCheck() will be called, the tag entries for
246*3ac0a46fSAndroid Build Coastguard Worker * those arrays will be written with type = count = offset = 0 as a temporary
247*3ac0a46fSAndroid Build Coastguard Worker * value.
248*3ac0a46fSAndroid Build Coastguard Worker *
249*3ac0a46fSAndroid Build Coastguard Worker * Its effect is only valid for the current directory, and before
250*3ac0a46fSAndroid Build Coastguard Worker * TIFFWriteDirectory() is first called, and will be reset when
251*3ac0a46fSAndroid Build Coastguard Worker * changing directory.
252*3ac0a46fSAndroid Build Coastguard Worker *
253*3ac0a46fSAndroid Build Coastguard Worker * The typical sequence of calls is:
254*3ac0a46fSAndroid Build Coastguard Worker * TIFFOpen()
255*3ac0a46fSAndroid Build Coastguard Worker * [ TIFFCreateDirectory(tif) ]
256*3ac0a46fSAndroid Build Coastguard Worker * Set fields with calls to TIFFSetField(tif, ...)
257*3ac0a46fSAndroid Build Coastguard Worker * TIFFDeferStrileArrayWriting(tif)
258*3ac0a46fSAndroid Build Coastguard Worker * TIFFWriteCheck(tif, ...)
259*3ac0a46fSAndroid Build Coastguard Worker * TIFFWriteDirectory(tif)
260*3ac0a46fSAndroid Build Coastguard Worker * ... potentially create other directories and come back to the above directory
261*3ac0a46fSAndroid Build Coastguard Worker * TIFFForceStrileArrayWriting(tif): emit the arrays at the end of file
262*3ac0a46fSAndroid Build Coastguard Worker *
263*3ac0a46fSAndroid Build Coastguard Worker * Returns 1 in case of success, 0 otherwise.
264*3ac0a46fSAndroid Build Coastguard Worker */
TIFFDeferStrileArrayWriting(TIFF * tif)265*3ac0a46fSAndroid Build Coastguard Worker int TIFFDeferStrileArrayWriting(TIFF *tif)
266*3ac0a46fSAndroid Build Coastguard Worker {
267*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFDeferStrileArrayWriting";
268*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_mode == O_RDONLY)
269*3ac0a46fSAndroid Build Coastguard Worker {
270*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode");
271*3ac0a46fSAndroid Build Coastguard Worker return 0;
272*3ac0a46fSAndroid Build Coastguard Worker }
273*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_diroff != 0)
274*3ac0a46fSAndroid Build Coastguard Worker {
275*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Directory has already been written");
276*3ac0a46fSAndroid Build Coastguard Worker return 0;
277*3ac0a46fSAndroid Build Coastguard Worker }
278*3ac0a46fSAndroid Build Coastguard Worker
279*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_deferstrilearraywriting = TRUE;
280*3ac0a46fSAndroid Build Coastguard Worker return 1;
281*3ac0a46fSAndroid Build Coastguard Worker }
282*3ac0a46fSAndroid Build Coastguard Worker
283*3ac0a46fSAndroid Build Coastguard Worker /*
284*3ac0a46fSAndroid Build Coastguard Worker * Similar to TIFFWriteDirectory(), writes the directory out
285*3ac0a46fSAndroid Build Coastguard Worker * but leaves all data structures in memory so that it can be
286*3ac0a46fSAndroid Build Coastguard Worker * written again. This will make a partially written TIFF file
287*3ac0a46fSAndroid Build Coastguard Worker * readable before it is successfully completed/closed.
288*3ac0a46fSAndroid Build Coastguard Worker */
TIFFCheckpointDirectory(TIFF * tif)289*3ac0a46fSAndroid Build Coastguard Worker int TIFFCheckpointDirectory(TIFF *tif)
290*3ac0a46fSAndroid Build Coastguard Worker {
291*3ac0a46fSAndroid Build Coastguard Worker int rc;
292*3ac0a46fSAndroid Build Coastguard Worker /* Setup the strips arrays, if they haven't already been. */
293*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_stripoffset_p == NULL)
294*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSetupStrips(tif);
295*3ac0a46fSAndroid Build Coastguard Worker rc = TIFFWriteDirectorySec(tif, TRUE, FALSE, NULL);
296*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
297*3ac0a46fSAndroid Build Coastguard Worker return rc;
298*3ac0a46fSAndroid Build Coastguard Worker }
299*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteCustomDirectory(TIFF * tif,uint64_t * pdiroff)300*3ac0a46fSAndroid Build Coastguard Worker int TIFFWriteCustomDirectory(TIFF *tif, uint64_t *pdiroff)
301*3ac0a46fSAndroid Build Coastguard Worker {
302*3ac0a46fSAndroid Build Coastguard Worker return TIFFWriteDirectorySec(tif, FALSE, FALSE, pdiroff);
303*3ac0a46fSAndroid Build Coastguard Worker }
304*3ac0a46fSAndroid Build Coastguard Worker
305*3ac0a46fSAndroid Build Coastguard Worker /*
306*3ac0a46fSAndroid Build Coastguard Worker * Similar to TIFFWriteDirectory(), but if the directory has already
307*3ac0a46fSAndroid Build Coastguard Worker * been written once, it is relocated to the end of the file, in case it
308*3ac0a46fSAndroid Build Coastguard Worker * has changed in size. Note that this will result in the loss of the
309*3ac0a46fSAndroid Build Coastguard Worker * previously used directory space.
310*3ac0a46fSAndroid Build Coastguard Worker */
TIFFRewriteDirectory(TIFF * tif)311*3ac0a46fSAndroid Build Coastguard Worker int TIFFRewriteDirectory(TIFF *tif)
312*3ac0a46fSAndroid Build Coastguard Worker {
313*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFRewriteDirectory";
314*3ac0a46fSAndroid Build Coastguard Worker
315*3ac0a46fSAndroid Build Coastguard Worker /* We don't need to do anything special if it hasn't been written. */
316*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_diroff == 0)
317*3ac0a46fSAndroid Build Coastguard Worker return TIFFWriteDirectory(tif);
318*3ac0a46fSAndroid Build Coastguard Worker
319*3ac0a46fSAndroid Build Coastguard Worker /*
320*3ac0a46fSAndroid Build Coastguard Worker * Find and zero the pointer to this directory, so that TIFFLinkDirectory
321*3ac0a46fSAndroid Build Coastguard Worker * will cause it to be added after this directories current pre-link.
322*3ac0a46fSAndroid Build Coastguard Worker */
323*3ac0a46fSAndroid Build Coastguard Worker uint64_t torewritediroff = tif->tif_diroff;
324*3ac0a46fSAndroid Build Coastguard Worker
325*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
326*3ac0a46fSAndroid Build Coastguard Worker {
327*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
328*3ac0a46fSAndroid Build Coastguard Worker {
329*3ac0a46fSAndroid Build Coastguard Worker tif->tif_header.classic.tiff_diroff = 0;
330*3ac0a46fSAndroid Build Coastguard Worker tif->tif_diroff = 0;
331*3ac0a46fSAndroid Build Coastguard Worker
332*3ac0a46fSAndroid Build Coastguard Worker TIFFSeekFile(tif, 4, SEEK_SET);
333*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff), 4))
334*3ac0a46fSAndroid Build Coastguard Worker {
335*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header");
336*3ac0a46fSAndroid Build Coastguard Worker return (0);
337*3ac0a46fSAndroid Build Coastguard Worker }
338*3ac0a46fSAndroid Build Coastguard Worker }
339*3ac0a46fSAndroid Build Coastguard Worker else if (tif->tif_diroff > 0xFFFFFFFFU)
340*3ac0a46fSAndroid Build Coastguard Worker {
341*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
342*3ac0a46fSAndroid Build Coastguard Worker "tif->tif_diroff exceeds 32 bit range allowed for "
343*3ac0a46fSAndroid Build Coastguard Worker "Classic TIFF");
344*3ac0a46fSAndroid Build Coastguard Worker return (0);
345*3ac0a46fSAndroid Build Coastguard Worker }
346*3ac0a46fSAndroid Build Coastguard Worker else
347*3ac0a46fSAndroid Build Coastguard Worker {
348*3ac0a46fSAndroid Build Coastguard Worker uint32_t nextdir;
349*3ac0a46fSAndroid Build Coastguard Worker nextdir = tif->tif_header.classic.tiff_diroff;
350*3ac0a46fSAndroid Build Coastguard Worker while (1)
351*3ac0a46fSAndroid Build Coastguard Worker {
352*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount;
353*3ac0a46fSAndroid Build Coastguard Worker uint32_t nextnextdir;
354*3ac0a46fSAndroid Build Coastguard Worker
355*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
356*3ac0a46fSAndroid Build Coastguard Worker {
357*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
358*3ac0a46fSAndroid Build Coastguard Worker "Error fetching directory count");
359*3ac0a46fSAndroid Build Coastguard Worker return (0);
360*3ac0a46fSAndroid Build Coastguard Worker }
361*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
362*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(&dircount);
363*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
364*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, &nextnextdir, 4))
365*3ac0a46fSAndroid Build Coastguard Worker {
366*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Error fetching directory link");
367*3ac0a46fSAndroid Build Coastguard Worker return (0);
368*3ac0a46fSAndroid Build Coastguard Worker }
369*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
370*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&nextnextdir);
371*3ac0a46fSAndroid Build Coastguard Worker if (nextnextdir == tif->tif_diroff)
372*3ac0a46fSAndroid Build Coastguard Worker {
373*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
374*3ac0a46fSAndroid Build Coastguard Worker m = 0;
375*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12,
376*3ac0a46fSAndroid Build Coastguard Worker SEEK_SET);
377*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, &m, 4))
378*3ac0a46fSAndroid Build Coastguard Worker {
379*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
380*3ac0a46fSAndroid Build Coastguard Worker "Error writing directory link");
381*3ac0a46fSAndroid Build Coastguard Worker return (0);
382*3ac0a46fSAndroid Build Coastguard Worker }
383*3ac0a46fSAndroid Build Coastguard Worker tif->tif_diroff = 0;
384*3ac0a46fSAndroid Build Coastguard Worker /* Force a full-traversal to reach the zeroed pointer */
385*3ac0a46fSAndroid Build Coastguard Worker tif->tif_lastdiroff = 0;
386*3ac0a46fSAndroid Build Coastguard Worker break;
387*3ac0a46fSAndroid Build Coastguard Worker }
388*3ac0a46fSAndroid Build Coastguard Worker nextdir = nextnextdir;
389*3ac0a46fSAndroid Build Coastguard Worker }
390*3ac0a46fSAndroid Build Coastguard Worker }
391*3ac0a46fSAndroid Build Coastguard Worker /* Remove skipped offset from IFD loop directory list. */
392*3ac0a46fSAndroid Build Coastguard Worker _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
393*3ac0a46fSAndroid Build Coastguard Worker }
394*3ac0a46fSAndroid Build Coastguard Worker else
395*3ac0a46fSAndroid Build Coastguard Worker {
396*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
397*3ac0a46fSAndroid Build Coastguard Worker {
398*3ac0a46fSAndroid Build Coastguard Worker tif->tif_header.big.tiff_diroff = 0;
399*3ac0a46fSAndroid Build Coastguard Worker tif->tif_diroff = 0;
400*3ac0a46fSAndroid Build Coastguard Worker
401*3ac0a46fSAndroid Build Coastguard Worker TIFFSeekFile(tif, 8, SEEK_SET);
402*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff), 8))
403*3ac0a46fSAndroid Build Coastguard Worker {
404*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header");
405*3ac0a46fSAndroid Build Coastguard Worker return (0);
406*3ac0a46fSAndroid Build Coastguard Worker }
407*3ac0a46fSAndroid Build Coastguard Worker }
408*3ac0a46fSAndroid Build Coastguard Worker else
409*3ac0a46fSAndroid Build Coastguard Worker {
410*3ac0a46fSAndroid Build Coastguard Worker uint64_t nextdir;
411*3ac0a46fSAndroid Build Coastguard Worker nextdir = tif->tif_header.big.tiff_diroff;
412*3ac0a46fSAndroid Build Coastguard Worker while (1)
413*3ac0a46fSAndroid Build Coastguard Worker {
414*3ac0a46fSAndroid Build Coastguard Worker uint64_t dircount64;
415*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount;
416*3ac0a46fSAndroid Build Coastguard Worker uint64_t nextnextdir;
417*3ac0a46fSAndroid Build Coastguard Worker
418*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
419*3ac0a46fSAndroid Build Coastguard Worker {
420*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
421*3ac0a46fSAndroid Build Coastguard Worker "Error fetching directory count");
422*3ac0a46fSAndroid Build Coastguard Worker return (0);
423*3ac0a46fSAndroid Build Coastguard Worker }
424*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
425*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&dircount64);
426*3ac0a46fSAndroid Build Coastguard Worker if (dircount64 > 0xFFFF)
427*3ac0a46fSAndroid Build Coastguard Worker {
428*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
429*3ac0a46fSAndroid Build Coastguard Worker "Sanity check on tag count failed, likely "
430*3ac0a46fSAndroid Build Coastguard Worker "corrupt TIFF");
431*3ac0a46fSAndroid Build Coastguard Worker return (0);
432*3ac0a46fSAndroid Build Coastguard Worker }
433*3ac0a46fSAndroid Build Coastguard Worker dircount = (uint16_t)dircount64;
434*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
435*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, &nextnextdir, 8))
436*3ac0a46fSAndroid Build Coastguard Worker {
437*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Error fetching directory link");
438*3ac0a46fSAndroid Build Coastguard Worker return (0);
439*3ac0a46fSAndroid Build Coastguard Worker }
440*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
441*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&nextnextdir);
442*3ac0a46fSAndroid Build Coastguard Worker if (nextnextdir == tif->tif_diroff)
443*3ac0a46fSAndroid Build Coastguard Worker {
444*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
445*3ac0a46fSAndroid Build Coastguard Worker m = 0;
446*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20,
447*3ac0a46fSAndroid Build Coastguard Worker SEEK_SET);
448*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, &m, 8))
449*3ac0a46fSAndroid Build Coastguard Worker {
450*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
451*3ac0a46fSAndroid Build Coastguard Worker "Error writing directory link");
452*3ac0a46fSAndroid Build Coastguard Worker return (0);
453*3ac0a46fSAndroid Build Coastguard Worker }
454*3ac0a46fSAndroid Build Coastguard Worker tif->tif_diroff = 0;
455*3ac0a46fSAndroid Build Coastguard Worker /* Force a full-traversal to reach the zeroed pointer */
456*3ac0a46fSAndroid Build Coastguard Worker tif->tif_lastdiroff = 0;
457*3ac0a46fSAndroid Build Coastguard Worker break;
458*3ac0a46fSAndroid Build Coastguard Worker }
459*3ac0a46fSAndroid Build Coastguard Worker nextdir = nextnextdir;
460*3ac0a46fSAndroid Build Coastguard Worker }
461*3ac0a46fSAndroid Build Coastguard Worker }
462*3ac0a46fSAndroid Build Coastguard Worker /* Remove skipped offset from IFD loop directory list. */
463*3ac0a46fSAndroid Build Coastguard Worker _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
464*3ac0a46fSAndroid Build Coastguard Worker }
465*3ac0a46fSAndroid Build Coastguard Worker
466*3ac0a46fSAndroid Build Coastguard Worker /*
467*3ac0a46fSAndroid Build Coastguard Worker * Now use TIFFWriteDirectory() normally.
468*3ac0a46fSAndroid Build Coastguard Worker */
469*3ac0a46fSAndroid Build Coastguard Worker
470*3ac0a46fSAndroid Build Coastguard Worker return TIFFWriteDirectory(tif);
471*3ac0a46fSAndroid Build Coastguard Worker }
472*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectorySec(TIFF * tif,int isimage,int imagedone,uint64_t * pdiroff)473*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
474*3ac0a46fSAndroid Build Coastguard Worker uint64_t *pdiroff)
475*3ac0a46fSAndroid Build Coastguard Worker {
476*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectorySec";
477*3ac0a46fSAndroid Build Coastguard Worker uint32_t ndir;
478*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir;
479*3ac0a46fSAndroid Build Coastguard Worker uint32_t dirsize;
480*3ac0a46fSAndroid Build Coastguard Worker void *dirmem;
481*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
482*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_mode == O_RDONLY)
483*3ac0a46fSAndroid Build Coastguard Worker return (1);
484*3ac0a46fSAndroid Build Coastguard Worker
485*3ac0a46fSAndroid Build Coastguard Worker _TIFFFillStriles(tif);
486*3ac0a46fSAndroid Build Coastguard Worker
487*3ac0a46fSAndroid Build Coastguard Worker /*
488*3ac0a46fSAndroid Build Coastguard Worker * Clear write state so that subsequent images with
489*3ac0a46fSAndroid Build Coastguard Worker * different characteristics get the right buffers
490*3ac0a46fSAndroid Build Coastguard Worker * setup for them.
491*3ac0a46fSAndroid Build Coastguard Worker */
492*3ac0a46fSAndroid Build Coastguard Worker if (imagedone)
493*3ac0a46fSAndroid Build Coastguard Worker {
494*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_POSTENCODE)
495*3ac0a46fSAndroid Build Coastguard Worker {
496*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_POSTENCODE;
497*3ac0a46fSAndroid Build Coastguard Worker if (!(*tif->tif_postencode)(tif))
498*3ac0a46fSAndroid Build Coastguard Worker {
499*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
500*3ac0a46fSAndroid Build Coastguard Worker "Error post-encoding before directory write");
501*3ac0a46fSAndroid Build Coastguard Worker return (0);
502*3ac0a46fSAndroid Build Coastguard Worker }
503*3ac0a46fSAndroid Build Coastguard Worker }
504*3ac0a46fSAndroid Build Coastguard Worker (*tif->tif_close)(tif); /* shutdown encoder */
505*3ac0a46fSAndroid Build Coastguard Worker /*
506*3ac0a46fSAndroid Build Coastguard Worker * Flush any data that might have been written
507*3ac0a46fSAndroid Build Coastguard Worker * by the compression close+cleanup routines. But
508*3ac0a46fSAndroid Build Coastguard Worker * be careful not to write stuff if we didn't add data
509*3ac0a46fSAndroid Build Coastguard Worker * in the previous steps as the "rawcc" data may well be
510*3ac0a46fSAndroid Build Coastguard Worker * a previously read tile/strip in mixed read/write mode.
511*3ac0a46fSAndroid Build Coastguard Worker */
512*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_rawcc > 0 && (tif->tif_flags & TIFF_BEENWRITING) != 0)
513*3ac0a46fSAndroid Build Coastguard Worker {
514*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFlushData1(tif))
515*3ac0a46fSAndroid Build Coastguard Worker {
516*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
517*3ac0a46fSAndroid Build Coastguard Worker "Error flushing data before directory write");
518*3ac0a46fSAndroid Build Coastguard Worker return (0);
519*3ac0a46fSAndroid Build Coastguard Worker }
520*3ac0a46fSAndroid Build Coastguard Worker }
521*3ac0a46fSAndroid Build Coastguard Worker if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
522*3ac0a46fSAndroid Build Coastguard Worker {
523*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, tif->tif_rawdata);
524*3ac0a46fSAndroid Build Coastguard Worker tif->tif_rawdata = NULL;
525*3ac0a46fSAndroid Build Coastguard Worker tif->tif_rawcc = 0;
526*3ac0a46fSAndroid Build Coastguard Worker tif->tif_rawdatasize = 0;
527*3ac0a46fSAndroid Build Coastguard Worker tif->tif_rawdataoff = 0;
528*3ac0a46fSAndroid Build Coastguard Worker tif->tif_rawdataloaded = 0;
529*3ac0a46fSAndroid Build Coastguard Worker }
530*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP);
531*3ac0a46fSAndroid Build Coastguard Worker }
532*3ac0a46fSAndroid Build Coastguard Worker
533*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_COMPRESSION) &&
534*3ac0a46fSAndroid Build Coastguard Worker (tif->tif_dir.td_compression == COMPRESSION_DEFLATE))
535*3ac0a46fSAndroid Build Coastguard Worker {
536*3ac0a46fSAndroid Build Coastguard Worker TIFFWarningExtR(tif, module,
537*3ac0a46fSAndroid Build Coastguard Worker "Creating TIFF with legacy Deflate codec identifier, "
538*3ac0a46fSAndroid Build Coastguard Worker "COMPRESSION_ADOBE_DEFLATE is more widely supported");
539*3ac0a46fSAndroid Build Coastguard Worker }
540*3ac0a46fSAndroid Build Coastguard Worker dir = NULL;
541*3ac0a46fSAndroid Build Coastguard Worker dirmem = NULL;
542*3ac0a46fSAndroid Build Coastguard Worker dirsize = 0;
543*3ac0a46fSAndroid Build Coastguard Worker while (1)
544*3ac0a46fSAndroid Build Coastguard Worker {
545*3ac0a46fSAndroid Build Coastguard Worker ndir = 0;
546*3ac0a46fSAndroid Build Coastguard Worker if (isimage)
547*3ac0a46fSAndroid Build Coastguard Worker {
548*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
549*3ac0a46fSAndroid Build Coastguard Worker {
550*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
551*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_IMAGEWIDTH,
552*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_imagewidth))
553*3ac0a46fSAndroid Build Coastguard Worker goto bad;
554*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortLong(
555*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_IMAGELENGTH,
556*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_imagelength))
557*3ac0a46fSAndroid Build Coastguard Worker goto bad;
558*3ac0a46fSAndroid Build Coastguard Worker }
559*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
560*3ac0a46fSAndroid Build Coastguard Worker {
561*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
562*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_TILEWIDTH,
563*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_tilewidth))
564*3ac0a46fSAndroid Build Coastguard Worker goto bad;
565*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
566*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_TILELENGTH,
567*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_tilelength))
568*3ac0a46fSAndroid Build Coastguard Worker goto bad;
569*3ac0a46fSAndroid Build Coastguard Worker }
570*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_RESOLUTION))
571*3ac0a46fSAndroid Build Coastguard Worker {
572*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
573*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_XRESOLUTION,
574*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_xresolution))
575*3ac0a46fSAndroid Build Coastguard Worker goto bad;
576*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
577*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_YRESOLUTION,
578*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_yresolution))
579*3ac0a46fSAndroid Build Coastguard Worker goto bad;
580*3ac0a46fSAndroid Build Coastguard Worker }
581*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_POSITION))
582*3ac0a46fSAndroid Build Coastguard Worker {
583*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
584*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_XPOSITION,
585*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_xposition))
586*3ac0a46fSAndroid Build Coastguard Worker goto bad;
587*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
588*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_YPOSITION,
589*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_yposition))
590*3ac0a46fSAndroid Build Coastguard Worker goto bad;
591*3ac0a46fSAndroid Build Coastguard Worker }
592*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_SUBFILETYPE))
593*3ac0a46fSAndroid Build Coastguard Worker {
594*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
595*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_SUBFILETYPE,
596*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_subfiletype))
597*3ac0a46fSAndroid Build Coastguard Worker goto bad;
598*3ac0a46fSAndroid Build Coastguard Worker }
599*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
600*3ac0a46fSAndroid Build Coastguard Worker {
601*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortPerSample(
602*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_BITSPERSAMPLE,
603*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_bitspersample))
604*3ac0a46fSAndroid Build Coastguard Worker goto bad;
605*3ac0a46fSAndroid Build Coastguard Worker }
606*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_COMPRESSION))
607*3ac0a46fSAndroid Build Coastguard Worker {
608*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
609*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_COMPRESSION,
610*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_compression))
611*3ac0a46fSAndroid Build Coastguard Worker goto bad;
612*3ac0a46fSAndroid Build Coastguard Worker }
613*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC))
614*3ac0a46fSAndroid Build Coastguard Worker {
615*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
616*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_PHOTOMETRIC,
617*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_photometric))
618*3ac0a46fSAndroid Build Coastguard Worker goto bad;
619*3ac0a46fSAndroid Build Coastguard Worker }
620*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_THRESHHOLDING))
621*3ac0a46fSAndroid Build Coastguard Worker {
622*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
623*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_THRESHHOLDING,
624*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_threshholding))
625*3ac0a46fSAndroid Build Coastguard Worker goto bad;
626*3ac0a46fSAndroid Build Coastguard Worker }
627*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_FILLORDER))
628*3ac0a46fSAndroid Build Coastguard Worker {
629*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
630*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_FILLORDER,
631*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_fillorder))
632*3ac0a46fSAndroid Build Coastguard Worker goto bad;
633*3ac0a46fSAndroid Build Coastguard Worker }
634*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_ORIENTATION))
635*3ac0a46fSAndroid Build Coastguard Worker {
636*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
637*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_ORIENTATION,
638*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_orientation))
639*3ac0a46fSAndroid Build Coastguard Worker goto bad;
640*3ac0a46fSAndroid Build Coastguard Worker }
641*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
642*3ac0a46fSAndroid Build Coastguard Worker {
643*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShort(
644*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_SAMPLESPERPIXEL,
645*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_samplesperpixel))
646*3ac0a46fSAndroid Build Coastguard Worker goto bad;
647*3ac0a46fSAndroid Build Coastguard Worker }
648*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
649*3ac0a46fSAndroid Build Coastguard Worker {
650*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortLong(
651*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_ROWSPERSTRIP,
652*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_rowsperstrip))
653*3ac0a46fSAndroid Build Coastguard Worker goto bad;
654*3ac0a46fSAndroid Build Coastguard Worker }
655*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE))
656*3ac0a46fSAndroid Build Coastguard Worker {
657*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortPerSample(
658*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_MINSAMPLEVALUE,
659*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_minsamplevalue))
660*3ac0a46fSAndroid Build Coastguard Worker goto bad;
661*3ac0a46fSAndroid Build Coastguard Worker }
662*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
663*3ac0a46fSAndroid Build Coastguard Worker {
664*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortPerSample(
665*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_MAXSAMPLEVALUE,
666*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_maxsamplevalue))
667*3ac0a46fSAndroid Build Coastguard Worker goto bad;
668*3ac0a46fSAndroid Build Coastguard Worker }
669*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_PLANARCONFIG))
670*3ac0a46fSAndroid Build Coastguard Worker {
671*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
672*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_PLANARCONFIG,
673*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_planarconfig))
674*3ac0a46fSAndroid Build Coastguard Worker goto bad;
675*3ac0a46fSAndroid Build Coastguard Worker }
676*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT))
677*3ac0a46fSAndroid Build Coastguard Worker {
678*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
679*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_RESOLUTIONUNIT,
680*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_resolutionunit))
681*3ac0a46fSAndroid Build Coastguard Worker goto bad;
682*3ac0a46fSAndroid Build Coastguard Worker }
683*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_PAGENUMBER))
684*3ac0a46fSAndroid Build Coastguard Worker {
685*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortArray(
686*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_PAGENUMBER, 2,
687*3ac0a46fSAndroid Build Coastguard Worker &tif->tif_dir.td_pagenumber[0]))
688*3ac0a46fSAndroid Build Coastguard Worker goto bad;
689*3ac0a46fSAndroid Build Coastguard Worker }
690*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS))
691*3ac0a46fSAndroid Build Coastguard Worker {
692*3ac0a46fSAndroid Build Coastguard Worker if (!isTiled(tif))
693*3ac0a46fSAndroid Build Coastguard Worker {
694*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagLongLong8Array(
695*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_STRIPBYTECOUNTS,
696*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nstrips,
697*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_p))
698*3ac0a46fSAndroid Build Coastguard Worker goto bad;
699*3ac0a46fSAndroid Build Coastguard Worker }
700*3ac0a46fSAndroid Build Coastguard Worker else
701*3ac0a46fSAndroid Build Coastguard Worker {
702*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagLongLong8Array(
703*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_TILEBYTECOUNTS,
704*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nstrips,
705*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_p))
706*3ac0a46fSAndroid Build Coastguard Worker goto bad;
707*3ac0a46fSAndroid Build Coastguard Worker }
708*3ac0a46fSAndroid Build Coastguard Worker }
709*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
710*3ac0a46fSAndroid Build Coastguard Worker {
711*3ac0a46fSAndroid Build Coastguard Worker if (!isTiled(tif))
712*3ac0a46fSAndroid Build Coastguard Worker {
713*3ac0a46fSAndroid Build Coastguard Worker /* td_stripoffset_p might be NULL in an odd OJPEG case. See
714*3ac0a46fSAndroid Build Coastguard Worker * tif_dirread.c around line 3634.
715*3ac0a46fSAndroid Build Coastguard Worker * XXX: OJPEG hack.
716*3ac0a46fSAndroid Build Coastguard Worker * If a) compression is OJPEG, b) it's not a tiled TIFF,
717*3ac0a46fSAndroid Build Coastguard Worker * and c) the number of strips is 1,
718*3ac0a46fSAndroid Build Coastguard Worker * then we tolerate the absence of stripoffsets tag,
719*3ac0a46fSAndroid Build Coastguard Worker * because, presumably, all required data is in the
720*3ac0a46fSAndroid Build Coastguard Worker * JpegInterchangeFormat stream.
721*3ac0a46fSAndroid Build Coastguard Worker * We can get here when using tiffset on such a file.
722*3ac0a46fSAndroid Build Coastguard Worker * See http://bugzilla.maptools.org/show_bug.cgi?id=2500
723*3ac0a46fSAndroid Build Coastguard Worker */
724*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_stripoffset_p != NULL &&
725*3ac0a46fSAndroid Build Coastguard Worker !TIFFWriteDirectoryTagLongLong8Array(
726*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_STRIPOFFSETS,
727*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nstrips,
728*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_p))
729*3ac0a46fSAndroid Build Coastguard Worker goto bad;
730*3ac0a46fSAndroid Build Coastguard Worker }
731*3ac0a46fSAndroid Build Coastguard Worker else
732*3ac0a46fSAndroid Build Coastguard Worker {
733*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagLongLong8Array(
734*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_TILEOFFSETS,
735*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nstrips,
736*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_p))
737*3ac0a46fSAndroid Build Coastguard Worker goto bad;
738*3ac0a46fSAndroid Build Coastguard Worker }
739*3ac0a46fSAndroid Build Coastguard Worker }
740*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_COLORMAP))
741*3ac0a46fSAndroid Build Coastguard Worker {
742*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagColormap(tif, &ndir, dir))
743*3ac0a46fSAndroid Build Coastguard Worker goto bad;
744*3ac0a46fSAndroid Build Coastguard Worker }
745*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES))
746*3ac0a46fSAndroid Build Coastguard Worker {
747*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_extrasamples)
748*3ac0a46fSAndroid Build Coastguard Worker {
749*3ac0a46fSAndroid Build Coastguard Worker uint16_t na;
750*3ac0a46fSAndroid Build Coastguard Worker uint16_t *nb;
751*3ac0a46fSAndroid Build Coastguard Worker TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &na, &nb);
752*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortArray(
753*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_EXTRASAMPLES, na, nb))
754*3ac0a46fSAndroid Build Coastguard Worker goto bad;
755*3ac0a46fSAndroid Build Coastguard Worker }
756*3ac0a46fSAndroid Build Coastguard Worker }
757*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT))
758*3ac0a46fSAndroid Build Coastguard Worker {
759*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortPerSample(
760*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_SAMPLEFORMAT,
761*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_sampleformat))
762*3ac0a46fSAndroid Build Coastguard Worker goto bad;
763*3ac0a46fSAndroid Build Coastguard Worker }
764*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE))
765*3ac0a46fSAndroid Build Coastguard Worker {
766*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagSampleformatArray(
767*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_SMINSAMPLEVALUE,
768*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_samplesperpixel,
769*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_sminsamplevalue))
770*3ac0a46fSAndroid Build Coastguard Worker goto bad;
771*3ac0a46fSAndroid Build Coastguard Worker }
772*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE))
773*3ac0a46fSAndroid Build Coastguard Worker {
774*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagSampleformatArray(
775*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_SMAXSAMPLEVALUE,
776*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_samplesperpixel,
777*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_smaxsamplevalue))
778*3ac0a46fSAndroid Build Coastguard Worker goto bad;
779*3ac0a46fSAndroid Build Coastguard Worker }
780*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH))
781*3ac0a46fSAndroid Build Coastguard Worker {
782*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
783*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_IMAGEDEPTH,
784*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_imagedepth))
785*3ac0a46fSAndroid Build Coastguard Worker goto bad;
786*3ac0a46fSAndroid Build Coastguard Worker }
787*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_TILEDEPTH))
788*3ac0a46fSAndroid Build Coastguard Worker {
789*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
790*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_TILEDEPTH,
791*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_tiledepth))
792*3ac0a46fSAndroid Build Coastguard Worker goto bad;
793*3ac0a46fSAndroid Build Coastguard Worker }
794*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS))
795*3ac0a46fSAndroid Build Coastguard Worker {
796*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortArray(
797*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_HALFTONEHINTS, 2,
798*3ac0a46fSAndroid Build Coastguard Worker &tif->tif_dir.td_halftonehints[0]))
799*3ac0a46fSAndroid Build Coastguard Worker goto bad;
800*3ac0a46fSAndroid Build Coastguard Worker }
801*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING))
802*3ac0a46fSAndroid Build Coastguard Worker {
803*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortArray(
804*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_YCBCRSUBSAMPLING, 2,
805*3ac0a46fSAndroid Build Coastguard Worker &tif->tif_dir.td_ycbcrsubsampling[0]))
806*3ac0a46fSAndroid Build Coastguard Worker goto bad;
807*3ac0a46fSAndroid Build Coastguard Worker }
808*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING))
809*3ac0a46fSAndroid Build Coastguard Worker {
810*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShort(
811*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_YCBCRPOSITIONING,
812*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_ycbcrpositioning))
813*3ac0a46fSAndroid Build Coastguard Worker goto bad;
814*3ac0a46fSAndroid Build Coastguard Worker }
815*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE))
816*3ac0a46fSAndroid Build Coastguard Worker {
817*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagRationalArray(
818*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_REFERENCEBLACKWHITE, 6,
819*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_refblackwhite))
820*3ac0a46fSAndroid Build Coastguard Worker goto bad;
821*3ac0a46fSAndroid Build Coastguard Worker }
822*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION))
823*3ac0a46fSAndroid Build Coastguard Worker {
824*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagTransferfunction(tif, &ndir, dir))
825*3ac0a46fSAndroid Build Coastguard Worker goto bad;
826*3ac0a46fSAndroid Build Coastguard Worker }
827*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_INKNAMES))
828*3ac0a46fSAndroid Build Coastguard Worker {
829*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagAscii(
830*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, TIFFTAG_INKNAMES,
831*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_inknameslen, tif->tif_dir.td_inknames))
832*3ac0a46fSAndroid Build Coastguard Worker goto bad;
833*3ac0a46fSAndroid Build Coastguard Worker }
834*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
835*3ac0a46fSAndroid Build Coastguard Worker {
836*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
837*3ac0a46fSAndroid Build Coastguard Worker TIFFTAG_NUMBEROFINKS,
838*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_numberofinks))
839*3ac0a46fSAndroid Build Coastguard Worker goto bad;
840*3ac0a46fSAndroid Build Coastguard Worker }
841*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_SUBIFD))
842*3ac0a46fSAndroid Build Coastguard Worker {
843*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagSubifd(tif, &ndir, dir))
844*3ac0a46fSAndroid Build Coastguard Worker goto bad;
845*3ac0a46fSAndroid Build Coastguard Worker }
846*3ac0a46fSAndroid Build Coastguard Worker {
847*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
848*3ac0a46fSAndroid Build Coastguard Worker for (n = 0; n < tif->tif_nfields; n++)
849*3ac0a46fSAndroid Build Coastguard Worker {
850*3ac0a46fSAndroid Build Coastguard Worker const TIFFField *o;
851*3ac0a46fSAndroid Build Coastguard Worker o = tif->tif_fields[n];
852*3ac0a46fSAndroid Build Coastguard Worker if ((o->field_bit >= FIELD_CODEC) &&
853*3ac0a46fSAndroid Build Coastguard Worker (TIFFFieldSet(tif, o->field_bit)))
854*3ac0a46fSAndroid Build Coastguard Worker {
855*3ac0a46fSAndroid Build Coastguard Worker switch (o->get_field_type)
856*3ac0a46fSAndroid Build Coastguard Worker {
857*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_ASCII:
858*3ac0a46fSAndroid Build Coastguard Worker {
859*3ac0a46fSAndroid Build Coastguard Worker uint32_t pa;
860*3ac0a46fSAndroid Build Coastguard Worker char *pb;
861*3ac0a46fSAndroid Build Coastguard Worker assert(o->field_type == TIFF_ASCII);
862*3ac0a46fSAndroid Build Coastguard Worker assert(o->field_readcount == TIFF_VARIABLE);
863*3ac0a46fSAndroid Build Coastguard Worker assert(o->field_passcount == 0);
864*3ac0a46fSAndroid Build Coastguard Worker TIFFGetField(tif, o->field_tag, &pb);
865*3ac0a46fSAndroid Build Coastguard Worker pa = (uint32_t)(strlen(pb));
866*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagAscii(
867*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, (uint16_t)o->field_tag,
868*3ac0a46fSAndroid Build Coastguard Worker pa, pb))
869*3ac0a46fSAndroid Build Coastguard Worker goto bad;
870*3ac0a46fSAndroid Build Coastguard Worker }
871*3ac0a46fSAndroid Build Coastguard Worker break;
872*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_UINT16:
873*3ac0a46fSAndroid Build Coastguard Worker {
874*3ac0a46fSAndroid Build Coastguard Worker uint16_t p;
875*3ac0a46fSAndroid Build Coastguard Worker assert(o->field_type == TIFF_SHORT);
876*3ac0a46fSAndroid Build Coastguard Worker assert(o->field_readcount == 1);
877*3ac0a46fSAndroid Build Coastguard Worker assert(o->field_passcount == 0);
878*3ac0a46fSAndroid Build Coastguard Worker TIFFGetField(tif, o->field_tag, &p);
879*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShort(
880*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, (uint16_t)o->field_tag,
881*3ac0a46fSAndroid Build Coastguard Worker p))
882*3ac0a46fSAndroid Build Coastguard Worker goto bad;
883*3ac0a46fSAndroid Build Coastguard Worker }
884*3ac0a46fSAndroid Build Coastguard Worker break;
885*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_UINT32:
886*3ac0a46fSAndroid Build Coastguard Worker {
887*3ac0a46fSAndroid Build Coastguard Worker uint32_t p;
888*3ac0a46fSAndroid Build Coastguard Worker assert(o->field_type == TIFF_LONG);
889*3ac0a46fSAndroid Build Coastguard Worker assert(o->field_readcount == 1);
890*3ac0a46fSAndroid Build Coastguard Worker assert(o->field_passcount == 0);
891*3ac0a46fSAndroid Build Coastguard Worker TIFFGetField(tif, o->field_tag, &p);
892*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagLong(
893*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, (uint16_t)o->field_tag,
894*3ac0a46fSAndroid Build Coastguard Worker p))
895*3ac0a46fSAndroid Build Coastguard Worker goto bad;
896*3ac0a46fSAndroid Build Coastguard Worker }
897*3ac0a46fSAndroid Build Coastguard Worker break;
898*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SETGET_C32_UINT8:
899*3ac0a46fSAndroid Build Coastguard Worker {
900*3ac0a46fSAndroid Build Coastguard Worker uint32_t pa;
901*3ac0a46fSAndroid Build Coastguard Worker void *pb;
902*3ac0a46fSAndroid Build Coastguard Worker assert(o->field_type == TIFF_UNDEFINED);
903*3ac0a46fSAndroid Build Coastguard Worker assert(o->field_readcount == TIFF_VARIABLE2);
904*3ac0a46fSAndroid Build Coastguard Worker assert(o->field_passcount == 1);
905*3ac0a46fSAndroid Build Coastguard Worker TIFFGetField(tif, o->field_tag, &pa, &pb);
906*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagUndefinedArray(
907*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, (uint16_t)o->field_tag,
908*3ac0a46fSAndroid Build Coastguard Worker pa, pb))
909*3ac0a46fSAndroid Build Coastguard Worker goto bad;
910*3ac0a46fSAndroid Build Coastguard Worker }
911*3ac0a46fSAndroid Build Coastguard Worker break;
912*3ac0a46fSAndroid Build Coastguard Worker default:
913*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(
914*3ac0a46fSAndroid Build Coastguard Worker tif, module,
915*3ac0a46fSAndroid Build Coastguard Worker "Cannot write tag %" PRIu32 " (%s)",
916*3ac0a46fSAndroid Build Coastguard Worker TIFFFieldTag(o),
917*3ac0a46fSAndroid Build Coastguard Worker o->field_name ? o->field_name : "unknown");
918*3ac0a46fSAndroid Build Coastguard Worker goto bad;
919*3ac0a46fSAndroid Build Coastguard Worker }
920*3ac0a46fSAndroid Build Coastguard Worker }
921*3ac0a46fSAndroid Build Coastguard Worker }
922*3ac0a46fSAndroid Build Coastguard Worker }
923*3ac0a46fSAndroid Build Coastguard Worker }
924*3ac0a46fSAndroid Build Coastguard Worker for (m = 0; m < (uint32_t)(tif->tif_dir.td_customValueCount); m++)
925*3ac0a46fSAndroid Build Coastguard Worker {
926*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag =
927*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)tif->tif_dir.td_customValues[m].info->field_tag;
928*3ac0a46fSAndroid Build Coastguard Worker uint32_t count = tif->tif_dir.td_customValues[m].count;
929*3ac0a46fSAndroid Build Coastguard Worker switch (tif->tif_dir.td_customValues[m].info->field_type)
930*3ac0a46fSAndroid Build Coastguard Worker {
931*3ac0a46fSAndroid Build Coastguard Worker case TIFF_ASCII:
932*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagAscii(
933*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
934*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
935*3ac0a46fSAndroid Build Coastguard Worker goto bad;
936*3ac0a46fSAndroid Build Coastguard Worker break;
937*3ac0a46fSAndroid Build Coastguard Worker case TIFF_UNDEFINED:
938*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagUndefinedArray(
939*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
940*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
941*3ac0a46fSAndroid Build Coastguard Worker goto bad;
942*3ac0a46fSAndroid Build Coastguard Worker break;
943*3ac0a46fSAndroid Build Coastguard Worker case TIFF_BYTE:
944*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagByteArray(
945*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
946*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
947*3ac0a46fSAndroid Build Coastguard Worker goto bad;
948*3ac0a46fSAndroid Build Coastguard Worker break;
949*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SBYTE:
950*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagSbyteArray(
951*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
952*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
953*3ac0a46fSAndroid Build Coastguard Worker goto bad;
954*3ac0a46fSAndroid Build Coastguard Worker break;
955*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SHORT:
956*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagShortArray(
957*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
958*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
959*3ac0a46fSAndroid Build Coastguard Worker goto bad;
960*3ac0a46fSAndroid Build Coastguard Worker break;
961*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SSHORT:
962*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagSshortArray(
963*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
964*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
965*3ac0a46fSAndroid Build Coastguard Worker goto bad;
966*3ac0a46fSAndroid Build Coastguard Worker break;
967*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG:
968*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagLongArray(
969*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
970*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
971*3ac0a46fSAndroid Build Coastguard Worker goto bad;
972*3ac0a46fSAndroid Build Coastguard Worker break;
973*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG:
974*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagSlongArray(
975*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
976*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
977*3ac0a46fSAndroid Build Coastguard Worker goto bad;
978*3ac0a46fSAndroid Build Coastguard Worker break;
979*3ac0a46fSAndroid Build Coastguard Worker case TIFF_LONG8:
980*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagLong8Array(
981*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
982*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
983*3ac0a46fSAndroid Build Coastguard Worker goto bad;
984*3ac0a46fSAndroid Build Coastguard Worker break;
985*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SLONG8:
986*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagSlong8Array(
987*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
988*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
989*3ac0a46fSAndroid Build Coastguard Worker goto bad;
990*3ac0a46fSAndroid Build Coastguard Worker break;
991*3ac0a46fSAndroid Build Coastguard Worker case TIFF_RATIONAL:
992*3ac0a46fSAndroid Build Coastguard Worker {
993*3ac0a46fSAndroid Build Coastguard Worker /*-- Rational2Double: For Rationals evaluate
994*3ac0a46fSAndroid Build Coastguard Worker * "set_field_type" to determine internal storage size. */
995*3ac0a46fSAndroid Build Coastguard Worker int tv_size;
996*3ac0a46fSAndroid Build Coastguard Worker tv_size = TIFFFieldSetGetSize(
997*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].info);
998*3ac0a46fSAndroid Build Coastguard Worker if (tv_size == 8)
999*3ac0a46fSAndroid Build Coastguard Worker {
1000*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagRationalDoubleArray(
1001*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
1002*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
1003*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1004*3ac0a46fSAndroid Build Coastguard Worker }
1005*3ac0a46fSAndroid Build Coastguard Worker else
1006*3ac0a46fSAndroid Build Coastguard Worker {
1007*3ac0a46fSAndroid Build Coastguard Worker /*-- default should be tv_size == 4 */
1008*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagRationalArray(
1009*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
1010*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
1011*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1012*3ac0a46fSAndroid Build Coastguard Worker /*-- ToDo: After Testing, this should be removed and
1013*3ac0a46fSAndroid Build Coastguard Worker * tv_size==4 should be set as default. */
1014*3ac0a46fSAndroid Build Coastguard Worker if (tv_size != 4)
1015*3ac0a46fSAndroid Build Coastguard Worker {
1016*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif,
1017*3ac0a46fSAndroid Build Coastguard Worker "TIFFLib: _TIFFWriteDirectorySec()",
1018*3ac0a46fSAndroid Build Coastguard Worker "Rational2Double: .set_field_type is "
1019*3ac0a46fSAndroid Build Coastguard Worker "not 4 but %d",
1020*3ac0a46fSAndroid Build Coastguard Worker tv_size);
1021*3ac0a46fSAndroid Build Coastguard Worker }
1022*3ac0a46fSAndroid Build Coastguard Worker }
1023*3ac0a46fSAndroid Build Coastguard Worker }
1024*3ac0a46fSAndroid Build Coastguard Worker break;
1025*3ac0a46fSAndroid Build Coastguard Worker case TIFF_SRATIONAL:
1026*3ac0a46fSAndroid Build Coastguard Worker {
1027*3ac0a46fSAndroid Build Coastguard Worker /*-- Rational2Double: For Rationals evaluate
1028*3ac0a46fSAndroid Build Coastguard Worker * "set_field_type" to determine internal storage size. */
1029*3ac0a46fSAndroid Build Coastguard Worker int tv_size;
1030*3ac0a46fSAndroid Build Coastguard Worker tv_size = TIFFFieldSetGetSize(
1031*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].info);
1032*3ac0a46fSAndroid Build Coastguard Worker if (tv_size == 8)
1033*3ac0a46fSAndroid Build Coastguard Worker {
1034*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagSrationalDoubleArray(
1035*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
1036*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
1037*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1038*3ac0a46fSAndroid Build Coastguard Worker }
1039*3ac0a46fSAndroid Build Coastguard Worker else
1040*3ac0a46fSAndroid Build Coastguard Worker {
1041*3ac0a46fSAndroid Build Coastguard Worker /*-- default should be tv_size == 4 */
1042*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagSrationalArray(
1043*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
1044*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
1045*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1046*3ac0a46fSAndroid Build Coastguard Worker /*-- ToDo: After Testing, this should be removed and
1047*3ac0a46fSAndroid Build Coastguard Worker * tv_size==4 should be set as default. */
1048*3ac0a46fSAndroid Build Coastguard Worker if (tv_size != 4)
1049*3ac0a46fSAndroid Build Coastguard Worker {
1050*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif,
1051*3ac0a46fSAndroid Build Coastguard Worker "TIFFLib: _TIFFWriteDirectorySec()",
1052*3ac0a46fSAndroid Build Coastguard Worker "Rational2Double: .set_field_type is "
1053*3ac0a46fSAndroid Build Coastguard Worker "not 4 but %d",
1054*3ac0a46fSAndroid Build Coastguard Worker tv_size);
1055*3ac0a46fSAndroid Build Coastguard Worker }
1056*3ac0a46fSAndroid Build Coastguard Worker }
1057*3ac0a46fSAndroid Build Coastguard Worker }
1058*3ac0a46fSAndroid Build Coastguard Worker break;
1059*3ac0a46fSAndroid Build Coastguard Worker case TIFF_FLOAT:
1060*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagFloatArray(
1061*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
1062*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
1063*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1064*3ac0a46fSAndroid Build Coastguard Worker break;
1065*3ac0a46fSAndroid Build Coastguard Worker case TIFF_DOUBLE:
1066*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagDoubleArray(
1067*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
1068*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
1069*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1070*3ac0a46fSAndroid Build Coastguard Worker break;
1071*3ac0a46fSAndroid Build Coastguard Worker case TIFF_IFD:
1072*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagIfdArray(
1073*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
1074*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
1075*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1076*3ac0a46fSAndroid Build Coastguard Worker break;
1077*3ac0a46fSAndroid Build Coastguard Worker case TIFF_IFD8:
1078*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFWriteDirectoryTagIfdIfd8Array(
1079*3ac0a46fSAndroid Build Coastguard Worker tif, &ndir, dir, tag, count,
1080*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_customValues[m].value))
1081*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1082*3ac0a46fSAndroid Build Coastguard Worker break;
1083*3ac0a46fSAndroid Build Coastguard Worker default:
1084*3ac0a46fSAndroid Build Coastguard Worker assert(0); /* we should never get here */
1085*3ac0a46fSAndroid Build Coastguard Worker break;
1086*3ac0a46fSAndroid Build Coastguard Worker }
1087*3ac0a46fSAndroid Build Coastguard Worker }
1088*3ac0a46fSAndroid Build Coastguard Worker if (dir != NULL)
1089*3ac0a46fSAndroid Build Coastguard Worker break;
1090*3ac0a46fSAndroid Build Coastguard Worker dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry));
1091*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1092*3ac0a46fSAndroid Build Coastguard Worker {
1093*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
1094*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1095*3ac0a46fSAndroid Build Coastguard Worker }
1096*3ac0a46fSAndroid Build Coastguard Worker if (isimage)
1097*3ac0a46fSAndroid Build Coastguard Worker {
1098*3ac0a46fSAndroid Build Coastguard Worker if ((tif->tif_diroff == 0) && (!TIFFLinkDirectory(tif)))
1099*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1100*3ac0a46fSAndroid Build Coastguard Worker }
1101*3ac0a46fSAndroid Build Coastguard Worker else
1102*3ac0a46fSAndroid Build Coastguard Worker tif->tif_diroff =
1103*3ac0a46fSAndroid Build Coastguard Worker (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
1104*3ac0a46fSAndroid Build Coastguard Worker if (pdiroff != NULL)
1105*3ac0a46fSAndroid Build Coastguard Worker *pdiroff = tif->tif_diroff;
1106*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
1107*3ac0a46fSAndroid Build Coastguard Worker dirsize = 2 + ndir * 12 + 4;
1108*3ac0a46fSAndroid Build Coastguard Worker else
1109*3ac0a46fSAndroid Build Coastguard Worker dirsize = 8 + ndir * 20 + 8;
1110*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dataoff = tif->tif_diroff + dirsize;
1111*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
1112*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dataoff = (uint32_t)tif->tif_dataoff;
1113*3ac0a46fSAndroid Build Coastguard Worker if ((tif->tif_dataoff < tif->tif_diroff) ||
1114*3ac0a46fSAndroid Build Coastguard Worker (tif->tif_dataoff < (uint64_t)dirsize))
1115*3ac0a46fSAndroid Build Coastguard Worker {
1116*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
1117*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1118*3ac0a46fSAndroid Build Coastguard Worker }
1119*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dataoff & 1)
1120*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dataoff++;
1121*3ac0a46fSAndroid Build Coastguard Worker if (isimage)
1122*3ac0a46fSAndroid Build Coastguard Worker {
1123*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
1124*3ac0a46fSAndroid Build Coastguard Worker tif->tif_curdir = 0;
1125*3ac0a46fSAndroid Build Coastguard Worker else
1126*3ac0a46fSAndroid Build Coastguard Worker tif->tif_curdir++;
1127*3ac0a46fSAndroid Build Coastguard Worker }
1128*3ac0a46fSAndroid Build Coastguard Worker }
1129*3ac0a46fSAndroid Build Coastguard Worker if (isimage)
1130*3ac0a46fSAndroid Build Coastguard Worker {
1131*3ac0a46fSAndroid Build Coastguard Worker if (TIFFFieldSet(tif, FIELD_SUBIFD) && (tif->tif_subifdoff == 0))
1132*3ac0a46fSAndroid Build Coastguard Worker {
1133*3ac0a46fSAndroid Build Coastguard Worker uint32_t na;
1134*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *nb;
1135*3ac0a46fSAndroid Build Coastguard Worker for (na = 0, nb = dir;; na++, nb++)
1136*3ac0a46fSAndroid Build Coastguard Worker {
1137*3ac0a46fSAndroid Build Coastguard Worker if (na == ndir)
1138*3ac0a46fSAndroid Build Coastguard Worker {
1139*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Cannot find SubIFD tag");
1140*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1141*3ac0a46fSAndroid Build Coastguard Worker }
1142*3ac0a46fSAndroid Build Coastguard Worker if (nb->tdir_tag == TIFFTAG_SUBIFD)
1143*3ac0a46fSAndroid Build Coastguard Worker break;
1144*3ac0a46fSAndroid Build Coastguard Worker }
1145*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
1146*3ac0a46fSAndroid Build Coastguard Worker tif->tif_subifdoff = tif->tif_diroff + 2 + na * 12 + 8;
1147*3ac0a46fSAndroid Build Coastguard Worker else
1148*3ac0a46fSAndroid Build Coastguard Worker tif->tif_subifdoff = tif->tif_diroff + 8 + na * 20 + 12;
1149*3ac0a46fSAndroid Build Coastguard Worker }
1150*3ac0a46fSAndroid Build Coastguard Worker }
1151*3ac0a46fSAndroid Build Coastguard Worker dirmem = _TIFFmallocExt(tif, dirsize);
1152*3ac0a46fSAndroid Build Coastguard Worker if (dirmem == NULL)
1153*3ac0a46fSAndroid Build Coastguard Worker {
1154*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
1155*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1156*3ac0a46fSAndroid Build Coastguard Worker }
1157*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
1158*3ac0a46fSAndroid Build Coastguard Worker {
1159*3ac0a46fSAndroid Build Coastguard Worker uint8_t *n;
1160*3ac0a46fSAndroid Build Coastguard Worker uint32_t nTmp;
1161*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *o;
1162*3ac0a46fSAndroid Build Coastguard Worker n = dirmem;
1163*3ac0a46fSAndroid Build Coastguard Worker *(uint16_t *)n = (uint16_t)ndir;
1164*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1165*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)n);
1166*3ac0a46fSAndroid Build Coastguard Worker n += 2;
1167*3ac0a46fSAndroid Build Coastguard Worker o = dir;
1168*3ac0a46fSAndroid Build Coastguard Worker for (m = 0; m < ndir; m++)
1169*3ac0a46fSAndroid Build Coastguard Worker {
1170*3ac0a46fSAndroid Build Coastguard Worker *(uint16_t *)n = o->tdir_tag;
1171*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1172*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)n);
1173*3ac0a46fSAndroid Build Coastguard Worker n += 2;
1174*3ac0a46fSAndroid Build Coastguard Worker *(uint16_t *)n = o->tdir_type;
1175*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1176*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)n);
1177*3ac0a46fSAndroid Build Coastguard Worker n += 2;
1178*3ac0a46fSAndroid Build Coastguard Worker nTmp = (uint32_t)o->tdir_count;
1179*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(n, &nTmp, 4);
1180*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1181*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)n);
1182*3ac0a46fSAndroid Build Coastguard Worker n += 4;
1183*3ac0a46fSAndroid Build Coastguard Worker /* This is correct. The data has been */
1184*3ac0a46fSAndroid Build Coastguard Worker /* swabbed previously in TIFFWriteDirectoryTagData */
1185*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(n, &o->tdir_offset, 4);
1186*3ac0a46fSAndroid Build Coastguard Worker n += 4;
1187*3ac0a46fSAndroid Build Coastguard Worker o++;
1188*3ac0a46fSAndroid Build Coastguard Worker }
1189*3ac0a46fSAndroid Build Coastguard Worker nTmp = (uint32_t)tif->tif_nextdiroff;
1190*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1191*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&nTmp);
1192*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(n, &nTmp, 4);
1193*3ac0a46fSAndroid Build Coastguard Worker }
1194*3ac0a46fSAndroid Build Coastguard Worker else
1195*3ac0a46fSAndroid Build Coastguard Worker {
1196*3ac0a46fSAndroid Build Coastguard Worker uint8_t *n;
1197*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *o;
1198*3ac0a46fSAndroid Build Coastguard Worker n = dirmem;
1199*3ac0a46fSAndroid Build Coastguard Worker *(uint64_t *)n = ndir;
1200*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1201*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)n);
1202*3ac0a46fSAndroid Build Coastguard Worker n += 8;
1203*3ac0a46fSAndroid Build Coastguard Worker o = dir;
1204*3ac0a46fSAndroid Build Coastguard Worker for (m = 0; m < ndir; m++)
1205*3ac0a46fSAndroid Build Coastguard Worker {
1206*3ac0a46fSAndroid Build Coastguard Worker *(uint16_t *)n = o->tdir_tag;
1207*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1208*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)n);
1209*3ac0a46fSAndroid Build Coastguard Worker n += 2;
1210*3ac0a46fSAndroid Build Coastguard Worker *(uint16_t *)n = o->tdir_type;
1211*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1212*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)n);
1213*3ac0a46fSAndroid Build Coastguard Worker n += 2;
1214*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(n, &o->tdir_count, 8);
1215*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1216*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)n);
1217*3ac0a46fSAndroid Build Coastguard Worker n += 8;
1218*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(n, &o->tdir_offset, 8);
1219*3ac0a46fSAndroid Build Coastguard Worker n += 8;
1220*3ac0a46fSAndroid Build Coastguard Worker o++;
1221*3ac0a46fSAndroid Build Coastguard Worker }
1222*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(n, &tif->tif_nextdiroff, 8);
1223*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
1224*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)n);
1225*3ac0a46fSAndroid Build Coastguard Worker }
1226*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, dir);
1227*3ac0a46fSAndroid Build Coastguard Worker dir = NULL;
1228*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, tif->tif_diroff))
1229*3ac0a46fSAndroid Build Coastguard Worker {
1230*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "IO error writing directory");
1231*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1232*3ac0a46fSAndroid Build Coastguard Worker }
1233*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, dirmem, (tmsize_t)dirsize))
1234*3ac0a46fSAndroid Build Coastguard Worker {
1235*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "IO error writing directory");
1236*3ac0a46fSAndroid Build Coastguard Worker goto bad;
1237*3ac0a46fSAndroid Build Coastguard Worker }
1238*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, dirmem);
1239*3ac0a46fSAndroid Build Coastguard Worker if (imagedone)
1240*3ac0a46fSAndroid Build Coastguard Worker {
1241*3ac0a46fSAndroid Build Coastguard Worker TIFFFreeDirectory(tif);
1242*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1243*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_DIRTYSTRIP;
1244*3ac0a46fSAndroid Build Coastguard Worker (*tif->tif_cleanup)(tif);
1245*3ac0a46fSAndroid Build Coastguard Worker /*
1246*3ac0a46fSAndroid Build Coastguard Worker * Reset directory-related state for subsequent
1247*3ac0a46fSAndroid Build Coastguard Worker * directories.
1248*3ac0a46fSAndroid Build Coastguard Worker */
1249*3ac0a46fSAndroid Build Coastguard Worker TIFFCreateDirectory(tif);
1250*3ac0a46fSAndroid Build Coastguard Worker }
1251*3ac0a46fSAndroid Build Coastguard Worker return (1);
1252*3ac0a46fSAndroid Build Coastguard Worker bad:
1253*3ac0a46fSAndroid Build Coastguard Worker if (dir != NULL)
1254*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, dir);
1255*3ac0a46fSAndroid Build Coastguard Worker if (dirmem != NULL)
1256*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, dirmem);
1257*3ac0a46fSAndroid Build Coastguard Worker return (0);
1258*3ac0a46fSAndroid Build Coastguard Worker }
1259*3ac0a46fSAndroid Build Coastguard Worker
TIFFClampDoubleToInt8(double val)1260*3ac0a46fSAndroid Build Coastguard Worker static int8_t TIFFClampDoubleToInt8(double val)
1261*3ac0a46fSAndroid Build Coastguard Worker {
1262*3ac0a46fSAndroid Build Coastguard Worker if (val > 127)
1263*3ac0a46fSAndroid Build Coastguard Worker return 127;
1264*3ac0a46fSAndroid Build Coastguard Worker if (val < -128 || val != val)
1265*3ac0a46fSAndroid Build Coastguard Worker return -128;
1266*3ac0a46fSAndroid Build Coastguard Worker return (int8_t)val;
1267*3ac0a46fSAndroid Build Coastguard Worker }
1268*3ac0a46fSAndroid Build Coastguard Worker
TIFFClampDoubleToInt16(double val)1269*3ac0a46fSAndroid Build Coastguard Worker static int16_t TIFFClampDoubleToInt16(double val)
1270*3ac0a46fSAndroid Build Coastguard Worker {
1271*3ac0a46fSAndroid Build Coastguard Worker if (val > 32767)
1272*3ac0a46fSAndroid Build Coastguard Worker return 32767;
1273*3ac0a46fSAndroid Build Coastguard Worker if (val < -32768 || val != val)
1274*3ac0a46fSAndroid Build Coastguard Worker return -32768;
1275*3ac0a46fSAndroid Build Coastguard Worker return (int16_t)val;
1276*3ac0a46fSAndroid Build Coastguard Worker }
1277*3ac0a46fSAndroid Build Coastguard Worker
TIFFClampDoubleToInt32(double val)1278*3ac0a46fSAndroid Build Coastguard Worker static int32_t TIFFClampDoubleToInt32(double val)
1279*3ac0a46fSAndroid Build Coastguard Worker {
1280*3ac0a46fSAndroid Build Coastguard Worker if (val > 0x7FFFFFFF)
1281*3ac0a46fSAndroid Build Coastguard Worker return 0x7FFFFFFF;
1282*3ac0a46fSAndroid Build Coastguard Worker if (val < -0x7FFFFFFF - 1 || val != val)
1283*3ac0a46fSAndroid Build Coastguard Worker return -0x7FFFFFFF - 1;
1284*3ac0a46fSAndroid Build Coastguard Worker return (int32_t)val;
1285*3ac0a46fSAndroid Build Coastguard Worker }
1286*3ac0a46fSAndroid Build Coastguard Worker
TIFFClampDoubleToUInt8(double val)1287*3ac0a46fSAndroid Build Coastguard Worker static uint8_t TIFFClampDoubleToUInt8(double val)
1288*3ac0a46fSAndroid Build Coastguard Worker {
1289*3ac0a46fSAndroid Build Coastguard Worker if (val < 0)
1290*3ac0a46fSAndroid Build Coastguard Worker return 0;
1291*3ac0a46fSAndroid Build Coastguard Worker if (val > 255 || val != val)
1292*3ac0a46fSAndroid Build Coastguard Worker return 255;
1293*3ac0a46fSAndroid Build Coastguard Worker return (uint8_t)val;
1294*3ac0a46fSAndroid Build Coastguard Worker }
1295*3ac0a46fSAndroid Build Coastguard Worker
TIFFClampDoubleToUInt16(double val)1296*3ac0a46fSAndroid Build Coastguard Worker static uint16_t TIFFClampDoubleToUInt16(double val)
1297*3ac0a46fSAndroid Build Coastguard Worker {
1298*3ac0a46fSAndroid Build Coastguard Worker if (val < 0)
1299*3ac0a46fSAndroid Build Coastguard Worker return 0;
1300*3ac0a46fSAndroid Build Coastguard Worker if (val > 65535 || val != val)
1301*3ac0a46fSAndroid Build Coastguard Worker return 65535;
1302*3ac0a46fSAndroid Build Coastguard Worker return (uint16_t)val;
1303*3ac0a46fSAndroid Build Coastguard Worker }
1304*3ac0a46fSAndroid Build Coastguard Worker
TIFFClampDoubleToUInt32(double val)1305*3ac0a46fSAndroid Build Coastguard Worker static uint32_t TIFFClampDoubleToUInt32(double val)
1306*3ac0a46fSAndroid Build Coastguard Worker {
1307*3ac0a46fSAndroid Build Coastguard Worker if (val < 0)
1308*3ac0a46fSAndroid Build Coastguard Worker return 0;
1309*3ac0a46fSAndroid Build Coastguard Worker if (val > 0xFFFFFFFFU || val != val)
1310*3ac0a46fSAndroid Build Coastguard Worker return 0xFFFFFFFFU;
1311*3ac0a46fSAndroid Build Coastguard Worker return (uint32_t)val;
1312*3ac0a46fSAndroid Build Coastguard Worker }
1313*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagSampleformatArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,double * value)1314*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
1315*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
1316*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
1317*3ac0a46fSAndroid Build Coastguard Worker double *value)
1318*3ac0a46fSAndroid Build Coastguard Worker {
1319*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
1320*3ac0a46fSAndroid Build Coastguard Worker void *conv;
1321*3ac0a46fSAndroid Build Coastguard Worker uint32_t i;
1322*3ac0a46fSAndroid Build Coastguard Worker int ok;
1323*3ac0a46fSAndroid Build Coastguard Worker conv = _TIFFmallocExt(tif, count * sizeof(double));
1324*3ac0a46fSAndroid Build Coastguard Worker if (conv == NULL)
1325*3ac0a46fSAndroid Build Coastguard Worker {
1326*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
1327*3ac0a46fSAndroid Build Coastguard Worker return (0);
1328*3ac0a46fSAndroid Build Coastguard Worker }
1329*3ac0a46fSAndroid Build Coastguard Worker
1330*3ac0a46fSAndroid Build Coastguard Worker switch (tif->tif_dir.td_sampleformat)
1331*3ac0a46fSAndroid Build Coastguard Worker {
1332*3ac0a46fSAndroid Build Coastguard Worker case SAMPLEFORMAT_IEEEFP:
1333*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_bitspersample <= 32)
1334*3ac0a46fSAndroid Build Coastguard Worker {
1335*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < count; ++i)
1336*3ac0a46fSAndroid Build Coastguard Worker ((float *)conv)[i] = _TIFFClampDoubleToFloat(value[i]);
1337*3ac0a46fSAndroid Build Coastguard Worker ok = TIFFWriteDirectoryTagFloatArray(tif, ndir, dir, tag, count,
1338*3ac0a46fSAndroid Build Coastguard Worker (float *)conv);
1339*3ac0a46fSAndroid Build Coastguard Worker }
1340*3ac0a46fSAndroid Build Coastguard Worker else
1341*3ac0a46fSAndroid Build Coastguard Worker {
1342*3ac0a46fSAndroid Build Coastguard Worker ok = TIFFWriteDirectoryTagDoubleArray(tif, ndir, dir, tag,
1343*3ac0a46fSAndroid Build Coastguard Worker count, value);
1344*3ac0a46fSAndroid Build Coastguard Worker }
1345*3ac0a46fSAndroid Build Coastguard Worker break;
1346*3ac0a46fSAndroid Build Coastguard Worker case SAMPLEFORMAT_INT:
1347*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_bitspersample <= 8)
1348*3ac0a46fSAndroid Build Coastguard Worker {
1349*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < count; ++i)
1350*3ac0a46fSAndroid Build Coastguard Worker ((int8_t *)conv)[i] = TIFFClampDoubleToInt8(value[i]);
1351*3ac0a46fSAndroid Build Coastguard Worker ok = TIFFWriteDirectoryTagSbyteArray(tif, ndir, dir, tag, count,
1352*3ac0a46fSAndroid Build Coastguard Worker (int8_t *)conv);
1353*3ac0a46fSAndroid Build Coastguard Worker }
1354*3ac0a46fSAndroid Build Coastguard Worker else if (tif->tif_dir.td_bitspersample <= 16)
1355*3ac0a46fSAndroid Build Coastguard Worker {
1356*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < count; ++i)
1357*3ac0a46fSAndroid Build Coastguard Worker ((int16_t *)conv)[i] = TIFFClampDoubleToInt16(value[i]);
1358*3ac0a46fSAndroid Build Coastguard Worker ok = TIFFWriteDirectoryTagSshortArray(tif, ndir, dir, tag,
1359*3ac0a46fSAndroid Build Coastguard Worker count, (int16_t *)conv);
1360*3ac0a46fSAndroid Build Coastguard Worker }
1361*3ac0a46fSAndroid Build Coastguard Worker else
1362*3ac0a46fSAndroid Build Coastguard Worker {
1363*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < count; ++i)
1364*3ac0a46fSAndroid Build Coastguard Worker ((int32_t *)conv)[i] = TIFFClampDoubleToInt32(value[i]);
1365*3ac0a46fSAndroid Build Coastguard Worker ok = TIFFWriteDirectoryTagSlongArray(tif, ndir, dir, tag, count,
1366*3ac0a46fSAndroid Build Coastguard Worker (int32_t *)conv);
1367*3ac0a46fSAndroid Build Coastguard Worker }
1368*3ac0a46fSAndroid Build Coastguard Worker break;
1369*3ac0a46fSAndroid Build Coastguard Worker case SAMPLEFORMAT_UINT:
1370*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_bitspersample <= 8)
1371*3ac0a46fSAndroid Build Coastguard Worker {
1372*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < count; ++i)
1373*3ac0a46fSAndroid Build Coastguard Worker ((uint8_t *)conv)[i] = TIFFClampDoubleToUInt8(value[i]);
1374*3ac0a46fSAndroid Build Coastguard Worker ok = TIFFWriteDirectoryTagByteArray(tif, ndir, dir, tag, count,
1375*3ac0a46fSAndroid Build Coastguard Worker (uint8_t *)conv);
1376*3ac0a46fSAndroid Build Coastguard Worker }
1377*3ac0a46fSAndroid Build Coastguard Worker else if (tif->tif_dir.td_bitspersample <= 16)
1378*3ac0a46fSAndroid Build Coastguard Worker {
1379*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < count; ++i)
1380*3ac0a46fSAndroid Build Coastguard Worker ((uint16_t *)conv)[i] = TIFFClampDoubleToUInt16(value[i]);
1381*3ac0a46fSAndroid Build Coastguard Worker ok = TIFFWriteDirectoryTagShortArray(tif, ndir, dir, tag, count,
1382*3ac0a46fSAndroid Build Coastguard Worker (uint16_t *)conv);
1383*3ac0a46fSAndroid Build Coastguard Worker }
1384*3ac0a46fSAndroid Build Coastguard Worker else
1385*3ac0a46fSAndroid Build Coastguard Worker {
1386*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < count; ++i)
1387*3ac0a46fSAndroid Build Coastguard Worker ((uint32_t *)conv)[i] = TIFFClampDoubleToUInt32(value[i]);
1388*3ac0a46fSAndroid Build Coastguard Worker ok = TIFFWriteDirectoryTagLongArray(tif, ndir, dir, tag, count,
1389*3ac0a46fSAndroid Build Coastguard Worker (uint32_t *)conv);
1390*3ac0a46fSAndroid Build Coastguard Worker }
1391*3ac0a46fSAndroid Build Coastguard Worker break;
1392*3ac0a46fSAndroid Build Coastguard Worker default:
1393*3ac0a46fSAndroid Build Coastguard Worker ok = 0;
1394*3ac0a46fSAndroid Build Coastguard Worker }
1395*3ac0a46fSAndroid Build Coastguard Worker
1396*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, conv);
1397*3ac0a46fSAndroid Build Coastguard Worker return (ok);
1398*3ac0a46fSAndroid Build Coastguard Worker }
1399*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagAscii(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,char * value)1400*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
1401*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1402*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, char *value)
1403*3ac0a46fSAndroid Build Coastguard Worker {
1404*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1405*3ac0a46fSAndroid Build Coastguard Worker {
1406*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1407*3ac0a46fSAndroid Build Coastguard Worker return (1);
1408*3ac0a46fSAndroid Build Coastguard Worker }
1409*3ac0a46fSAndroid Build Coastguard Worker return (
1410*3ac0a46fSAndroid Build Coastguard Worker TIFFWriteDirectoryTagCheckedAscii(tif, ndir, dir, tag, count, value));
1411*3ac0a46fSAndroid Build Coastguard Worker }
1412*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagUndefinedArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint8_t * value)1413*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir,
1414*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1415*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint8_t *value)
1416*3ac0a46fSAndroid Build Coastguard Worker {
1417*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1418*3ac0a46fSAndroid Build Coastguard Worker {
1419*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1420*3ac0a46fSAndroid Build Coastguard Worker return (1);
1421*3ac0a46fSAndroid Build Coastguard Worker }
1422*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedUndefinedArray(tif, ndir, dir, tag,
1423*3ac0a46fSAndroid Build Coastguard Worker count, value));
1424*3ac0a46fSAndroid Build Coastguard Worker }
1425*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagByteArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint8_t * value)1426*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir,
1427*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1428*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint8_t *value)
1429*3ac0a46fSAndroid Build Coastguard Worker {
1430*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1431*3ac0a46fSAndroid Build Coastguard Worker {
1432*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1433*3ac0a46fSAndroid Build Coastguard Worker return (1);
1434*3ac0a46fSAndroid Build Coastguard Worker }
1435*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedByteArray(tif, ndir, dir, tag, count,
1436*3ac0a46fSAndroid Build Coastguard Worker value));
1437*3ac0a46fSAndroid Build Coastguard Worker }
1438*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagSbyteArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,int8_t * value)1439*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir,
1440*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1441*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, int8_t *value)
1442*3ac0a46fSAndroid Build Coastguard Worker {
1443*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1444*3ac0a46fSAndroid Build Coastguard Worker {
1445*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1446*3ac0a46fSAndroid Build Coastguard Worker return (1);
1447*3ac0a46fSAndroid Build Coastguard Worker }
1448*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedSbyteArray(tif, ndir, dir, tag, count,
1449*3ac0a46fSAndroid Build Coastguard Worker value));
1450*3ac0a46fSAndroid Build Coastguard Worker }
1451*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagShort(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint16_t value)1452*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
1453*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1454*3ac0a46fSAndroid Build Coastguard Worker uint16_t value)
1455*3ac0a46fSAndroid Build Coastguard Worker {
1456*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1457*3ac0a46fSAndroid Build Coastguard Worker {
1458*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1459*3ac0a46fSAndroid Build Coastguard Worker return (1);
1460*3ac0a46fSAndroid Build Coastguard Worker }
1461*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, value));
1462*3ac0a46fSAndroid Build Coastguard Worker }
1463*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagShortArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint16_t * value)1464*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
1465*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1466*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint16_t *value)
1467*3ac0a46fSAndroid Build Coastguard Worker {
1468*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1469*3ac0a46fSAndroid Build Coastguard Worker {
1470*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1471*3ac0a46fSAndroid Build Coastguard Worker return (1);
1472*3ac0a46fSAndroid Build Coastguard Worker }
1473*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
1474*3ac0a46fSAndroid Build Coastguard Worker value));
1475*3ac0a46fSAndroid Build Coastguard Worker }
1476*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagShortPerSample(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint16_t value)1477*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
1478*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1479*3ac0a46fSAndroid Build Coastguard Worker uint16_t value)
1480*3ac0a46fSAndroid Build Coastguard Worker {
1481*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
1482*3ac0a46fSAndroid Build Coastguard Worker uint16_t *m;
1483*3ac0a46fSAndroid Build Coastguard Worker uint16_t *na;
1484*3ac0a46fSAndroid Build Coastguard Worker uint16_t nb;
1485*3ac0a46fSAndroid Build Coastguard Worker int o;
1486*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1487*3ac0a46fSAndroid Build Coastguard Worker {
1488*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1489*3ac0a46fSAndroid Build Coastguard Worker return (1);
1490*3ac0a46fSAndroid Build Coastguard Worker }
1491*3ac0a46fSAndroid Build Coastguard Worker m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t));
1492*3ac0a46fSAndroid Build Coastguard Worker if (m == NULL)
1493*3ac0a46fSAndroid Build Coastguard Worker {
1494*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
1495*3ac0a46fSAndroid Build Coastguard Worker return (0);
1496*3ac0a46fSAndroid Build Coastguard Worker }
1497*3ac0a46fSAndroid Build Coastguard Worker for (na = m, nb = 0; nb < tif->tif_dir.td_samplesperpixel; na++, nb++)
1498*3ac0a46fSAndroid Build Coastguard Worker *na = value;
1499*3ac0a46fSAndroid Build Coastguard Worker o = TIFFWriteDirectoryTagCheckedShortArray(
1500*3ac0a46fSAndroid Build Coastguard Worker tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, m);
1501*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, m);
1502*3ac0a46fSAndroid Build Coastguard Worker return (o);
1503*3ac0a46fSAndroid Build Coastguard Worker }
1504*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagSshortArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,int16_t * value)1505*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir,
1506*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1507*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, int16_t *value)
1508*3ac0a46fSAndroid Build Coastguard Worker {
1509*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1510*3ac0a46fSAndroid Build Coastguard Worker {
1511*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1512*3ac0a46fSAndroid Build Coastguard Worker return (1);
1513*3ac0a46fSAndroid Build Coastguard Worker }
1514*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedSshortArray(tif, ndir, dir, tag, count,
1515*3ac0a46fSAndroid Build Coastguard Worker value));
1516*3ac0a46fSAndroid Build Coastguard Worker }
1517*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagLong(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t value)1518*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir,
1519*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1520*3ac0a46fSAndroid Build Coastguard Worker uint32_t value)
1521*3ac0a46fSAndroid Build Coastguard Worker {
1522*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1523*3ac0a46fSAndroid Build Coastguard Worker {
1524*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1525*3ac0a46fSAndroid Build Coastguard Worker return (1);
1526*3ac0a46fSAndroid Build Coastguard Worker }
1527*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
1528*3ac0a46fSAndroid Build Coastguard Worker }
1529*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagLongArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint32_t * value)1530*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir,
1531*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1532*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint32_t *value)
1533*3ac0a46fSAndroid Build Coastguard Worker {
1534*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1535*3ac0a46fSAndroid Build Coastguard Worker {
1536*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1537*3ac0a46fSAndroid Build Coastguard Worker return (1);
1538*3ac0a46fSAndroid Build Coastguard Worker }
1539*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
1540*3ac0a46fSAndroid Build Coastguard Worker value));
1541*3ac0a46fSAndroid Build Coastguard Worker }
1542*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagSlongArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,int32_t * value)1543*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir,
1544*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1545*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, int32_t *value)
1546*3ac0a46fSAndroid Build Coastguard Worker {
1547*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1548*3ac0a46fSAndroid Build Coastguard Worker {
1549*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1550*3ac0a46fSAndroid Build Coastguard Worker return (1);
1551*3ac0a46fSAndroid Build Coastguard Worker }
1552*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count,
1553*3ac0a46fSAndroid Build Coastguard Worker value));
1554*3ac0a46fSAndroid Build Coastguard Worker }
1555*3ac0a46fSAndroid Build Coastguard Worker
1556*3ac0a46fSAndroid Build Coastguard Worker /************************************************************************/
1557*3ac0a46fSAndroid Build Coastguard Worker /* TIFFWriteDirectoryTagLong8Array() */
1558*3ac0a46fSAndroid Build Coastguard Worker /* */
1559*3ac0a46fSAndroid Build Coastguard Worker /* Write either Long8 or Long array depending on file type. */
1560*3ac0a46fSAndroid Build Coastguard Worker /************************************************************************/
TIFFWriteDirectoryTagLong8Array(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint64_t * value)1561*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
1562*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1563*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint64_t *value)
1564*3ac0a46fSAndroid Build Coastguard Worker {
1565*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagLong8Array";
1566*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ma;
1567*3ac0a46fSAndroid Build Coastguard Worker uint32_t mb;
1568*3ac0a46fSAndroid Build Coastguard Worker uint32_t *p;
1569*3ac0a46fSAndroid Build Coastguard Worker uint32_t *q;
1570*3ac0a46fSAndroid Build Coastguard Worker int o;
1571*3ac0a46fSAndroid Build Coastguard Worker
1572*3ac0a46fSAndroid Build Coastguard Worker /* is this just a counting pass? */
1573*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1574*3ac0a46fSAndroid Build Coastguard Worker {
1575*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1576*3ac0a46fSAndroid Build Coastguard Worker return (1);
1577*3ac0a46fSAndroid Build Coastguard Worker }
1578*3ac0a46fSAndroid Build Coastguard Worker
1579*3ac0a46fSAndroid Build Coastguard Worker /* We always write Long8 for BigTIFF, no checking needed. */
1580*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_BIGTIFF)
1581*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
1582*3ac0a46fSAndroid Build Coastguard Worker count, value));
1583*3ac0a46fSAndroid Build Coastguard Worker
1584*3ac0a46fSAndroid Build Coastguard Worker /*
1585*3ac0a46fSAndroid Build Coastguard Worker ** For classic tiff we want to verify everything is in range for long
1586*3ac0a46fSAndroid Build Coastguard Worker ** and convert to long format.
1587*3ac0a46fSAndroid Build Coastguard Worker */
1588*3ac0a46fSAndroid Build Coastguard Worker p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1589*3ac0a46fSAndroid Build Coastguard Worker if (p == NULL)
1590*3ac0a46fSAndroid Build Coastguard Worker {
1591*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
1592*3ac0a46fSAndroid Build Coastguard Worker return (0);
1593*3ac0a46fSAndroid Build Coastguard Worker }
1594*3ac0a46fSAndroid Build Coastguard Worker
1595*3ac0a46fSAndroid Build Coastguard Worker for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1596*3ac0a46fSAndroid Build Coastguard Worker {
1597*3ac0a46fSAndroid Build Coastguard Worker if (*ma > 0xFFFFFFFF)
1598*3ac0a46fSAndroid Build Coastguard Worker {
1599*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
1600*3ac0a46fSAndroid Build Coastguard Worker "Attempt to write unsigned long value %" PRIu64
1601*3ac0a46fSAndroid Build Coastguard Worker " larger than 0xFFFFFFFF for tag %d in Classic TIFF "
1602*3ac0a46fSAndroid Build Coastguard Worker "file. TIFF file writing aborted",
1603*3ac0a46fSAndroid Build Coastguard Worker *ma, tag);
1604*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, p);
1605*3ac0a46fSAndroid Build Coastguard Worker return (0);
1606*3ac0a46fSAndroid Build Coastguard Worker }
1607*3ac0a46fSAndroid Build Coastguard Worker *q = (uint32_t)(*ma);
1608*3ac0a46fSAndroid Build Coastguard Worker }
1609*3ac0a46fSAndroid Build Coastguard Worker
1610*3ac0a46fSAndroid Build Coastguard Worker o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, p);
1611*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, p);
1612*3ac0a46fSAndroid Build Coastguard Worker
1613*3ac0a46fSAndroid Build Coastguard Worker return (o);
1614*3ac0a46fSAndroid Build Coastguard Worker }
1615*3ac0a46fSAndroid Build Coastguard Worker
1616*3ac0a46fSAndroid Build Coastguard Worker /************************************************************************/
1617*3ac0a46fSAndroid Build Coastguard Worker /* TIFFWriteDirectoryTagSlong8Array() */
1618*3ac0a46fSAndroid Build Coastguard Worker /* */
1619*3ac0a46fSAndroid Build Coastguard Worker /* Write either SLong8 or SLong array depending on file type. */
1620*3ac0a46fSAndroid Build Coastguard Worker /************************************************************************/
TIFFWriteDirectoryTagSlong8Array(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,int64_t * value)1621*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
1622*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1623*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, int64_t *value)
1624*3ac0a46fSAndroid Build Coastguard Worker {
1625*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagSlong8Array";
1626*3ac0a46fSAndroid Build Coastguard Worker int64_t *ma;
1627*3ac0a46fSAndroid Build Coastguard Worker uint32_t mb;
1628*3ac0a46fSAndroid Build Coastguard Worker int32_t *p;
1629*3ac0a46fSAndroid Build Coastguard Worker int32_t *q;
1630*3ac0a46fSAndroid Build Coastguard Worker int o;
1631*3ac0a46fSAndroid Build Coastguard Worker
1632*3ac0a46fSAndroid Build Coastguard Worker /* is this just a counting pass? */
1633*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1634*3ac0a46fSAndroid Build Coastguard Worker {
1635*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1636*3ac0a46fSAndroid Build Coastguard Worker return (1);
1637*3ac0a46fSAndroid Build Coastguard Worker }
1638*3ac0a46fSAndroid Build Coastguard Worker /* We always write SLong8 for BigTIFF, no checking needed. */
1639*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_BIGTIFF)
1640*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
1641*3ac0a46fSAndroid Build Coastguard Worker count, value));
1642*3ac0a46fSAndroid Build Coastguard Worker
1643*3ac0a46fSAndroid Build Coastguard Worker /*
1644*3ac0a46fSAndroid Build Coastguard Worker ** For classic tiff we want to verify everything is in range for signed-long
1645*3ac0a46fSAndroid Build Coastguard Worker ** and convert to signed-long format.
1646*3ac0a46fSAndroid Build Coastguard Worker */
1647*3ac0a46fSAndroid Build Coastguard Worker p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1648*3ac0a46fSAndroid Build Coastguard Worker if (p == NULL)
1649*3ac0a46fSAndroid Build Coastguard Worker {
1650*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
1651*3ac0a46fSAndroid Build Coastguard Worker return (0);
1652*3ac0a46fSAndroid Build Coastguard Worker }
1653*3ac0a46fSAndroid Build Coastguard Worker
1654*3ac0a46fSAndroid Build Coastguard Worker for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1655*3ac0a46fSAndroid Build Coastguard Worker {
1656*3ac0a46fSAndroid Build Coastguard Worker if (*ma > (2147483647))
1657*3ac0a46fSAndroid Build Coastguard Worker {
1658*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
1659*3ac0a46fSAndroid Build Coastguard Worker "Attempt to write signed long value %" PRIi64
1660*3ac0a46fSAndroid Build Coastguard Worker " larger than 0x7FFFFFFF (2147483647) for tag %d in "
1661*3ac0a46fSAndroid Build Coastguard Worker "Classic TIFF file. TIFF writing to file aborted",
1662*3ac0a46fSAndroid Build Coastguard Worker *ma, tag);
1663*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, p);
1664*3ac0a46fSAndroid Build Coastguard Worker return (0);
1665*3ac0a46fSAndroid Build Coastguard Worker }
1666*3ac0a46fSAndroid Build Coastguard Worker else if (*ma < (-2147483647 - 1))
1667*3ac0a46fSAndroid Build Coastguard Worker {
1668*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
1669*3ac0a46fSAndroid Build Coastguard Worker "Attempt to write signed long value %" PRIi64
1670*3ac0a46fSAndroid Build Coastguard Worker " smaller than 0x80000000 (-2147483648) for tag %d "
1671*3ac0a46fSAndroid Build Coastguard Worker "in Classic TIFF file. TIFF writing to file aborted",
1672*3ac0a46fSAndroid Build Coastguard Worker *ma, tag);
1673*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, p);
1674*3ac0a46fSAndroid Build Coastguard Worker return (0);
1675*3ac0a46fSAndroid Build Coastguard Worker }
1676*3ac0a46fSAndroid Build Coastguard Worker *q = (int32_t)(*ma);
1677*3ac0a46fSAndroid Build Coastguard Worker }
1678*3ac0a46fSAndroid Build Coastguard Worker
1679*3ac0a46fSAndroid Build Coastguard Worker o = TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, p);
1680*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, p);
1681*3ac0a46fSAndroid Build Coastguard Worker
1682*3ac0a46fSAndroid Build Coastguard Worker return (o);
1683*3ac0a46fSAndroid Build Coastguard Worker }
1684*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagRational(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,double value)1685*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir,
1686*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1687*3ac0a46fSAndroid Build Coastguard Worker double value)
1688*3ac0a46fSAndroid Build Coastguard Worker {
1689*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1690*3ac0a46fSAndroid Build Coastguard Worker {
1691*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1692*3ac0a46fSAndroid Build Coastguard Worker return (1);
1693*3ac0a46fSAndroid Build Coastguard Worker }
1694*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedRational(tif, ndir, dir, tag, value));
1695*3ac0a46fSAndroid Build Coastguard Worker }
1696*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagRationalArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,float * value)1697*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir,
1698*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1699*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, float *value)
1700*3ac0a46fSAndroid Build Coastguard Worker {
1701*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1702*3ac0a46fSAndroid Build Coastguard Worker {
1703*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1704*3ac0a46fSAndroid Build Coastguard Worker return (1);
1705*3ac0a46fSAndroid Build Coastguard Worker }
1706*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedRationalArray(tif, ndir, dir, tag,
1707*3ac0a46fSAndroid Build Coastguard Worker count, value));
1708*3ac0a46fSAndroid Build Coastguard Worker }
1709*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagSrationalArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,float * value)1710*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir,
1711*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1712*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, float *value)
1713*3ac0a46fSAndroid Build Coastguard Worker {
1714*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1715*3ac0a46fSAndroid Build Coastguard Worker {
1716*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1717*3ac0a46fSAndroid Build Coastguard Worker return (1);
1718*3ac0a46fSAndroid Build Coastguard Worker }
1719*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedSrationalArray(tif, ndir, dir, tag,
1720*3ac0a46fSAndroid Build Coastguard Worker count, value));
1721*3ac0a46fSAndroid Build Coastguard Worker }
1722*3ac0a46fSAndroid Build Coastguard Worker
1723*3ac0a46fSAndroid Build Coastguard Worker /*-- Rational2Double: additional write functions */
TIFFWriteDirectoryTagRationalDoubleArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,double * value)1724*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir,
1725*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
1726*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag,
1727*3ac0a46fSAndroid Build Coastguard Worker uint32_t count,
1728*3ac0a46fSAndroid Build Coastguard Worker double *value)
1729*3ac0a46fSAndroid Build Coastguard Worker {
1730*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1731*3ac0a46fSAndroid Build Coastguard Worker {
1732*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1733*3ac0a46fSAndroid Build Coastguard Worker return (1);
1734*3ac0a46fSAndroid Build Coastguard Worker }
1735*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif, ndir, dir, tag,
1736*3ac0a46fSAndroid Build Coastguard Worker count, value));
1737*3ac0a46fSAndroid Build Coastguard Worker }
1738*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagSrationalDoubleArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,double * value)1739*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir,
1740*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
1741*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag,
1742*3ac0a46fSAndroid Build Coastguard Worker uint32_t count,
1743*3ac0a46fSAndroid Build Coastguard Worker double *value)
1744*3ac0a46fSAndroid Build Coastguard Worker {
1745*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1746*3ac0a46fSAndroid Build Coastguard Worker {
1747*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1748*3ac0a46fSAndroid Build Coastguard Worker return (1);
1749*3ac0a46fSAndroid Build Coastguard Worker }
1750*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
1751*3ac0a46fSAndroid Build Coastguard Worker tif, ndir, dir, tag, count, value));
1752*3ac0a46fSAndroid Build Coastguard Worker }
1753*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagFloatArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,float * value)1754*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir,
1755*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1756*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, float *value)
1757*3ac0a46fSAndroid Build Coastguard Worker {
1758*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1759*3ac0a46fSAndroid Build Coastguard Worker {
1760*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1761*3ac0a46fSAndroid Build Coastguard Worker return (1);
1762*3ac0a46fSAndroid Build Coastguard Worker }
1763*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedFloatArray(tif, ndir, dir, tag, count,
1764*3ac0a46fSAndroid Build Coastguard Worker value));
1765*3ac0a46fSAndroid Build Coastguard Worker }
1766*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagDoubleArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,double * value)1767*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
1768*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1769*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, double *value)
1770*3ac0a46fSAndroid Build Coastguard Worker {
1771*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1772*3ac0a46fSAndroid Build Coastguard Worker {
1773*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1774*3ac0a46fSAndroid Build Coastguard Worker return (1);
1775*3ac0a46fSAndroid Build Coastguard Worker }
1776*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedDoubleArray(tif, ndir, dir, tag, count,
1777*3ac0a46fSAndroid Build Coastguard Worker value));
1778*3ac0a46fSAndroid Build Coastguard Worker }
1779*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagIfdArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint32_t * value)1780*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir,
1781*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1782*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint32_t *value)
1783*3ac0a46fSAndroid Build Coastguard Worker {
1784*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1785*3ac0a46fSAndroid Build Coastguard Worker {
1786*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1787*3ac0a46fSAndroid Build Coastguard Worker return (1);
1788*3ac0a46fSAndroid Build Coastguard Worker }
1789*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count,
1790*3ac0a46fSAndroid Build Coastguard Worker value));
1791*3ac0a46fSAndroid Build Coastguard Worker }
1792*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagShortLong(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t value)1793*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
1794*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1795*3ac0a46fSAndroid Build Coastguard Worker uint32_t value)
1796*3ac0a46fSAndroid Build Coastguard Worker {
1797*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1798*3ac0a46fSAndroid Build Coastguard Worker {
1799*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1800*3ac0a46fSAndroid Build Coastguard Worker return (1);
1801*3ac0a46fSAndroid Build Coastguard Worker }
1802*3ac0a46fSAndroid Build Coastguard Worker if (value <= 0xFFFF)
1803*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag,
1804*3ac0a46fSAndroid Build Coastguard Worker (uint16_t)value));
1805*3ac0a46fSAndroid Build Coastguard Worker else
1806*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
1807*3ac0a46fSAndroid Build Coastguard Worker }
1808*3ac0a46fSAndroid Build Coastguard Worker
_WriteAsType(TIFF * tif,uint64_t strile_size,uint64_t uncompressed_threshold)1809*3ac0a46fSAndroid Build Coastguard Worker static int _WriteAsType(TIFF *tif, uint64_t strile_size,
1810*3ac0a46fSAndroid Build Coastguard Worker uint64_t uncompressed_threshold)
1811*3ac0a46fSAndroid Build Coastguard Worker {
1812*3ac0a46fSAndroid Build Coastguard Worker const uint16_t compression = tif->tif_dir.td_compression;
1813*3ac0a46fSAndroid Build Coastguard Worker if (compression == COMPRESSION_NONE)
1814*3ac0a46fSAndroid Build Coastguard Worker {
1815*3ac0a46fSAndroid Build Coastguard Worker return strile_size > uncompressed_threshold;
1816*3ac0a46fSAndroid Build Coastguard Worker }
1817*3ac0a46fSAndroid Build Coastguard Worker else if (compression == COMPRESSION_JPEG ||
1818*3ac0a46fSAndroid Build Coastguard Worker compression == COMPRESSION_LZW ||
1819*3ac0a46fSAndroid Build Coastguard Worker compression == COMPRESSION_ADOBE_DEFLATE ||
1820*3ac0a46fSAndroid Build Coastguard Worker compression == COMPRESSION_DEFLATE ||
1821*3ac0a46fSAndroid Build Coastguard Worker compression == COMPRESSION_LZMA ||
1822*3ac0a46fSAndroid Build Coastguard Worker compression == COMPRESSION_LERC ||
1823*3ac0a46fSAndroid Build Coastguard Worker compression == COMPRESSION_ZSTD ||
1824*3ac0a46fSAndroid Build Coastguard Worker compression == COMPRESSION_WEBP || compression == COMPRESSION_JXL)
1825*3ac0a46fSAndroid Build Coastguard Worker {
1826*3ac0a46fSAndroid Build Coastguard Worker /* For a few select compression types, we assume that in the worst */
1827*3ac0a46fSAndroid Build Coastguard Worker /* case the compressed size will be 10 times the uncompressed size */
1828*3ac0a46fSAndroid Build Coastguard Worker /* This is overly pessismistic ! */
1829*3ac0a46fSAndroid Build Coastguard Worker return strile_size >= uncompressed_threshold / 10;
1830*3ac0a46fSAndroid Build Coastguard Worker }
1831*3ac0a46fSAndroid Build Coastguard Worker return 1;
1832*3ac0a46fSAndroid Build Coastguard Worker }
1833*3ac0a46fSAndroid Build Coastguard Worker
WriteAsLong8(TIFF * tif,uint64_t strile_size)1834*3ac0a46fSAndroid Build Coastguard Worker static int WriteAsLong8(TIFF *tif, uint64_t strile_size)
1835*3ac0a46fSAndroid Build Coastguard Worker {
1836*3ac0a46fSAndroid Build Coastguard Worker return _WriteAsType(tif, strile_size, 0xFFFFFFFFU);
1837*3ac0a46fSAndroid Build Coastguard Worker }
1838*3ac0a46fSAndroid Build Coastguard Worker
WriteAsLong4(TIFF * tif,uint64_t strile_size)1839*3ac0a46fSAndroid Build Coastguard Worker static int WriteAsLong4(TIFF *tif, uint64_t strile_size)
1840*3ac0a46fSAndroid Build Coastguard Worker {
1841*3ac0a46fSAndroid Build Coastguard Worker return _WriteAsType(tif, strile_size, 0xFFFFU);
1842*3ac0a46fSAndroid Build Coastguard Worker }
1843*3ac0a46fSAndroid Build Coastguard Worker
1844*3ac0a46fSAndroid Build Coastguard Worker /************************************************************************/
1845*3ac0a46fSAndroid Build Coastguard Worker /* TIFFWriteDirectoryTagLongLong8Array() */
1846*3ac0a46fSAndroid Build Coastguard Worker /* */
1847*3ac0a46fSAndroid Build Coastguard Worker /* Write out LONG8 array and write a SHORT/LONG/LONG8 depending */
1848*3ac0a46fSAndroid Build Coastguard Worker /* on strile size and Classic/BigTIFF mode. */
1849*3ac0a46fSAndroid Build Coastguard Worker /************************************************************************/
1850*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagLongLong8Array(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint64_t * value)1851*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
1852*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1853*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint64_t *value)
1854*3ac0a46fSAndroid Build Coastguard Worker {
1855*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
1856*3ac0a46fSAndroid Build Coastguard Worker int o;
1857*3ac0a46fSAndroid Build Coastguard Worker int write_aslong4;
1858*3ac0a46fSAndroid Build Coastguard Worker
1859*3ac0a46fSAndroid Build Coastguard Worker /* is this just a counting pass? */
1860*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1861*3ac0a46fSAndroid Build Coastguard Worker {
1862*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1863*3ac0a46fSAndroid Build Coastguard Worker return (1);
1864*3ac0a46fSAndroid Build Coastguard Worker }
1865*3ac0a46fSAndroid Build Coastguard Worker
1866*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_deferstrilearraywriting)
1867*3ac0a46fSAndroid Build Coastguard Worker {
1868*3ac0a46fSAndroid Build Coastguard Worker return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0,
1869*3ac0a46fSAndroid Build Coastguard Worker NULL);
1870*3ac0a46fSAndroid Build Coastguard Worker }
1871*3ac0a46fSAndroid Build Coastguard Worker
1872*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_BIGTIFF)
1873*3ac0a46fSAndroid Build Coastguard Worker {
1874*3ac0a46fSAndroid Build Coastguard Worker int write_aslong8 = 1;
1875*3ac0a46fSAndroid Build Coastguard Worker /* In the case of ByteCounts array, we may be able to write them on */
1876*3ac0a46fSAndroid Build Coastguard Worker /* LONG if the strip/tilesize is not too big. */
1877*3ac0a46fSAndroid Build Coastguard Worker /* Also do that for count > 1 in the case someone would want to create
1878*3ac0a46fSAndroid Build Coastguard Worker */
1879*3ac0a46fSAndroid Build Coastguard Worker /* a single-strip file with a growing height, in which case using */
1880*3ac0a46fSAndroid Build Coastguard Worker /* LONG8 will be safer. */
1881*3ac0a46fSAndroid Build Coastguard Worker if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
1882*3ac0a46fSAndroid Build Coastguard Worker {
1883*3ac0a46fSAndroid Build Coastguard Worker write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
1884*3ac0a46fSAndroid Build Coastguard Worker }
1885*3ac0a46fSAndroid Build Coastguard Worker else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
1886*3ac0a46fSAndroid Build Coastguard Worker {
1887*3ac0a46fSAndroid Build Coastguard Worker write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
1888*3ac0a46fSAndroid Build Coastguard Worker }
1889*3ac0a46fSAndroid Build Coastguard Worker if (write_aslong8)
1890*3ac0a46fSAndroid Build Coastguard Worker {
1891*3ac0a46fSAndroid Build Coastguard Worker return TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
1892*3ac0a46fSAndroid Build Coastguard Worker count, value);
1893*3ac0a46fSAndroid Build Coastguard Worker }
1894*3ac0a46fSAndroid Build Coastguard Worker }
1895*3ac0a46fSAndroid Build Coastguard Worker
1896*3ac0a46fSAndroid Build Coastguard Worker write_aslong4 = 1;
1897*3ac0a46fSAndroid Build Coastguard Worker if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
1898*3ac0a46fSAndroid Build Coastguard Worker {
1899*3ac0a46fSAndroid Build Coastguard Worker write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
1900*3ac0a46fSAndroid Build Coastguard Worker }
1901*3ac0a46fSAndroid Build Coastguard Worker else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
1902*3ac0a46fSAndroid Build Coastguard Worker {
1903*3ac0a46fSAndroid Build Coastguard Worker write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
1904*3ac0a46fSAndroid Build Coastguard Worker }
1905*3ac0a46fSAndroid Build Coastguard Worker if (write_aslong4)
1906*3ac0a46fSAndroid Build Coastguard Worker {
1907*3ac0a46fSAndroid Build Coastguard Worker /*
1908*3ac0a46fSAndroid Build Coastguard Worker ** For classic tiff we want to verify everything is in range for LONG
1909*3ac0a46fSAndroid Build Coastguard Worker ** and convert to long format.
1910*3ac0a46fSAndroid Build Coastguard Worker */
1911*3ac0a46fSAndroid Build Coastguard Worker
1912*3ac0a46fSAndroid Build Coastguard Worker uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1913*3ac0a46fSAndroid Build Coastguard Worker uint32_t *q;
1914*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ma;
1915*3ac0a46fSAndroid Build Coastguard Worker uint32_t mb;
1916*3ac0a46fSAndroid Build Coastguard Worker
1917*3ac0a46fSAndroid Build Coastguard Worker if (p == NULL)
1918*3ac0a46fSAndroid Build Coastguard Worker {
1919*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
1920*3ac0a46fSAndroid Build Coastguard Worker return (0);
1921*3ac0a46fSAndroid Build Coastguard Worker }
1922*3ac0a46fSAndroid Build Coastguard Worker
1923*3ac0a46fSAndroid Build Coastguard Worker for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1924*3ac0a46fSAndroid Build Coastguard Worker {
1925*3ac0a46fSAndroid Build Coastguard Worker if (*ma > 0xFFFFFFFF)
1926*3ac0a46fSAndroid Build Coastguard Worker {
1927*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
1928*3ac0a46fSAndroid Build Coastguard Worker "Attempt to write value larger than 0xFFFFFFFF "
1929*3ac0a46fSAndroid Build Coastguard Worker "in LONG array.");
1930*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, p);
1931*3ac0a46fSAndroid Build Coastguard Worker return (0);
1932*3ac0a46fSAndroid Build Coastguard Worker }
1933*3ac0a46fSAndroid Build Coastguard Worker *q = (uint32_t)(*ma);
1934*3ac0a46fSAndroid Build Coastguard Worker }
1935*3ac0a46fSAndroid Build Coastguard Worker
1936*3ac0a46fSAndroid Build Coastguard Worker o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
1937*3ac0a46fSAndroid Build Coastguard Worker p);
1938*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, p);
1939*3ac0a46fSAndroid Build Coastguard Worker }
1940*3ac0a46fSAndroid Build Coastguard Worker else
1941*3ac0a46fSAndroid Build Coastguard Worker {
1942*3ac0a46fSAndroid Build Coastguard Worker uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t));
1943*3ac0a46fSAndroid Build Coastguard Worker uint16_t *q;
1944*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ma;
1945*3ac0a46fSAndroid Build Coastguard Worker uint32_t mb;
1946*3ac0a46fSAndroid Build Coastguard Worker
1947*3ac0a46fSAndroid Build Coastguard Worker if (p == NULL)
1948*3ac0a46fSAndroid Build Coastguard Worker {
1949*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
1950*3ac0a46fSAndroid Build Coastguard Worker return (0);
1951*3ac0a46fSAndroid Build Coastguard Worker }
1952*3ac0a46fSAndroid Build Coastguard Worker
1953*3ac0a46fSAndroid Build Coastguard Worker for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1954*3ac0a46fSAndroid Build Coastguard Worker {
1955*3ac0a46fSAndroid Build Coastguard Worker if (*ma > 0xFFFF)
1956*3ac0a46fSAndroid Build Coastguard Worker {
1957*3ac0a46fSAndroid Build Coastguard Worker /* Should not happen normally given the check we did before */
1958*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
1959*3ac0a46fSAndroid Build Coastguard Worker "Attempt to write value larger than 0xFFFF in "
1960*3ac0a46fSAndroid Build Coastguard Worker "SHORT array.");
1961*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, p);
1962*3ac0a46fSAndroid Build Coastguard Worker return (0);
1963*3ac0a46fSAndroid Build Coastguard Worker }
1964*3ac0a46fSAndroid Build Coastguard Worker *q = (uint16_t)(*ma);
1965*3ac0a46fSAndroid Build Coastguard Worker }
1966*3ac0a46fSAndroid Build Coastguard Worker
1967*3ac0a46fSAndroid Build Coastguard Worker o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
1968*3ac0a46fSAndroid Build Coastguard Worker p);
1969*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, p);
1970*3ac0a46fSAndroid Build Coastguard Worker }
1971*3ac0a46fSAndroid Build Coastguard Worker
1972*3ac0a46fSAndroid Build Coastguard Worker return (o);
1973*3ac0a46fSAndroid Build Coastguard Worker }
1974*3ac0a46fSAndroid Build Coastguard Worker
1975*3ac0a46fSAndroid Build Coastguard Worker /************************************************************************/
1976*3ac0a46fSAndroid Build Coastguard Worker /* TIFFWriteDirectoryTagIfdIfd8Array() */
1977*3ac0a46fSAndroid Build Coastguard Worker /* */
1978*3ac0a46fSAndroid Build Coastguard Worker /* Write either IFD8 or IFD array depending on file type. */
1979*3ac0a46fSAndroid Build Coastguard Worker /************************************************************************/
1980*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagIfdIfd8Array(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint64_t * value)1981*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
1982*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
1983*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint64_t *value)
1984*3ac0a46fSAndroid Build Coastguard Worker {
1985*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
1986*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ma;
1987*3ac0a46fSAndroid Build Coastguard Worker uint32_t mb;
1988*3ac0a46fSAndroid Build Coastguard Worker uint32_t *p;
1989*3ac0a46fSAndroid Build Coastguard Worker uint32_t *q;
1990*3ac0a46fSAndroid Build Coastguard Worker int o;
1991*3ac0a46fSAndroid Build Coastguard Worker
1992*3ac0a46fSAndroid Build Coastguard Worker /* is this just a counting pass? */
1993*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
1994*3ac0a46fSAndroid Build Coastguard Worker {
1995*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
1996*3ac0a46fSAndroid Build Coastguard Worker return (1);
1997*3ac0a46fSAndroid Build Coastguard Worker }
1998*3ac0a46fSAndroid Build Coastguard Worker
1999*3ac0a46fSAndroid Build Coastguard Worker /* We always write IFD8 for BigTIFF, no checking needed. */
2000*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_BIGTIFF)
2001*3ac0a46fSAndroid Build Coastguard Worker return TIFFWriteDirectoryTagCheckedIfd8Array(tif, ndir, dir, tag, count,
2002*3ac0a46fSAndroid Build Coastguard Worker value);
2003*3ac0a46fSAndroid Build Coastguard Worker
2004*3ac0a46fSAndroid Build Coastguard Worker /*
2005*3ac0a46fSAndroid Build Coastguard Worker ** For classic tiff we want to verify everything is in range for IFD
2006*3ac0a46fSAndroid Build Coastguard Worker ** and convert to long format.
2007*3ac0a46fSAndroid Build Coastguard Worker */
2008*3ac0a46fSAndroid Build Coastguard Worker
2009*3ac0a46fSAndroid Build Coastguard Worker p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
2010*3ac0a46fSAndroid Build Coastguard Worker if (p == NULL)
2011*3ac0a46fSAndroid Build Coastguard Worker {
2012*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
2013*3ac0a46fSAndroid Build Coastguard Worker return (0);
2014*3ac0a46fSAndroid Build Coastguard Worker }
2015*3ac0a46fSAndroid Build Coastguard Worker
2016*3ac0a46fSAndroid Build Coastguard Worker for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
2017*3ac0a46fSAndroid Build Coastguard Worker {
2018*3ac0a46fSAndroid Build Coastguard Worker if (*ma > 0xFFFFFFFF)
2019*3ac0a46fSAndroid Build Coastguard Worker {
2020*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
2021*3ac0a46fSAndroid Build Coastguard Worker "Attempt to write value larger than 0xFFFFFFFF in "
2022*3ac0a46fSAndroid Build Coastguard Worker "Classic TIFF file.");
2023*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, p);
2024*3ac0a46fSAndroid Build Coastguard Worker return (0);
2025*3ac0a46fSAndroid Build Coastguard Worker }
2026*3ac0a46fSAndroid Build Coastguard Worker *q = (uint32_t)(*ma);
2027*3ac0a46fSAndroid Build Coastguard Worker }
2028*3ac0a46fSAndroid Build Coastguard Worker
2029*3ac0a46fSAndroid Build Coastguard Worker o = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, p);
2030*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, p);
2031*3ac0a46fSAndroid Build Coastguard Worker
2032*3ac0a46fSAndroid Build Coastguard Worker return (o);
2033*3ac0a46fSAndroid Build Coastguard Worker }
2034*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagColormap(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir)2035*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
2036*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir)
2037*3ac0a46fSAndroid Build Coastguard Worker {
2038*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagColormap";
2039*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
2040*3ac0a46fSAndroid Build Coastguard Worker uint16_t *n;
2041*3ac0a46fSAndroid Build Coastguard Worker int o;
2042*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
2043*3ac0a46fSAndroid Build Coastguard Worker {
2044*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
2045*3ac0a46fSAndroid Build Coastguard Worker return (1);
2046*3ac0a46fSAndroid Build Coastguard Worker }
2047*3ac0a46fSAndroid Build Coastguard Worker m = (1 << tif->tif_dir.td_bitspersample);
2048*3ac0a46fSAndroid Build Coastguard Worker n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t));
2049*3ac0a46fSAndroid Build Coastguard Worker if (n == NULL)
2050*3ac0a46fSAndroid Build Coastguard Worker {
2051*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
2052*3ac0a46fSAndroid Build Coastguard Worker return (0);
2053*3ac0a46fSAndroid Build Coastguard Worker }
2054*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], m * sizeof(uint16_t));
2055*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], m * sizeof(uint16_t));
2056*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], m * sizeof(uint16_t));
2057*3ac0a46fSAndroid Build Coastguard Worker o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, TIFFTAG_COLORMAP,
2058*3ac0a46fSAndroid Build Coastguard Worker 3 * m, n);
2059*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, n);
2060*3ac0a46fSAndroid Build Coastguard Worker return (o);
2061*3ac0a46fSAndroid Build Coastguard Worker }
2062*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagTransferfunction(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir)2063*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
2064*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir)
2065*3ac0a46fSAndroid Build Coastguard Worker {
2066*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
2067*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
2068*3ac0a46fSAndroid Build Coastguard Worker uint16_t n;
2069*3ac0a46fSAndroid Build Coastguard Worker uint16_t *o;
2070*3ac0a46fSAndroid Build Coastguard Worker int p;
2071*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
2072*3ac0a46fSAndroid Build Coastguard Worker {
2073*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
2074*3ac0a46fSAndroid Build Coastguard Worker return (1);
2075*3ac0a46fSAndroid Build Coastguard Worker }
2076*3ac0a46fSAndroid Build Coastguard Worker m = (1 << tif->tif_dir.td_bitspersample);
2077*3ac0a46fSAndroid Build Coastguard Worker n = tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples;
2078*3ac0a46fSAndroid Build Coastguard Worker /*
2079*3ac0a46fSAndroid Build Coastguard Worker * Check if the table can be written as a single column,
2080*3ac0a46fSAndroid Build Coastguard Worker * or if it must be written as 3 columns. Note that we
2081*3ac0a46fSAndroid Build Coastguard Worker * write a 3-column tag if there are 2 samples/pixel and
2082*3ac0a46fSAndroid Build Coastguard Worker * a single column of data won't suffice--hmm.
2083*3ac0a46fSAndroid Build Coastguard Worker */
2084*3ac0a46fSAndroid Build Coastguard Worker if (n > 3)
2085*3ac0a46fSAndroid Build Coastguard Worker n = 3;
2086*3ac0a46fSAndroid Build Coastguard Worker if (n == 3)
2087*3ac0a46fSAndroid Build Coastguard Worker {
2088*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_transferfunction[2] == NULL ||
2089*3ac0a46fSAndroid Build Coastguard Worker !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
2090*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_transferfunction[2],
2091*3ac0a46fSAndroid Build Coastguard Worker m * sizeof(uint16_t)))
2092*3ac0a46fSAndroid Build Coastguard Worker n = 2;
2093*3ac0a46fSAndroid Build Coastguard Worker }
2094*3ac0a46fSAndroid Build Coastguard Worker if (n == 2)
2095*3ac0a46fSAndroid Build Coastguard Worker {
2096*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_transferfunction[1] == NULL ||
2097*3ac0a46fSAndroid Build Coastguard Worker !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
2098*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_transferfunction[1],
2099*3ac0a46fSAndroid Build Coastguard Worker m * sizeof(uint16_t)))
2100*3ac0a46fSAndroid Build Coastguard Worker n = 1;
2101*3ac0a46fSAndroid Build Coastguard Worker }
2102*3ac0a46fSAndroid Build Coastguard Worker if (n == 0)
2103*3ac0a46fSAndroid Build Coastguard Worker n = 1;
2104*3ac0a46fSAndroid Build Coastguard Worker o = _TIFFmallocExt(tif, n * m * sizeof(uint16_t));
2105*3ac0a46fSAndroid Build Coastguard Worker if (o == NULL)
2106*3ac0a46fSAndroid Build Coastguard Worker {
2107*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
2108*3ac0a46fSAndroid Build Coastguard Worker return (0);
2109*3ac0a46fSAndroid Build Coastguard Worker }
2110*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0],
2111*3ac0a46fSAndroid Build Coastguard Worker m * sizeof(uint16_t));
2112*3ac0a46fSAndroid Build Coastguard Worker if (n > 1)
2113*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1],
2114*3ac0a46fSAndroid Build Coastguard Worker m * sizeof(uint16_t));
2115*3ac0a46fSAndroid Build Coastguard Worker if (n > 2)
2116*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&o[2 * m], tif->tif_dir.td_transferfunction[2],
2117*3ac0a46fSAndroid Build Coastguard Worker m * sizeof(uint16_t));
2118*3ac0a46fSAndroid Build Coastguard Worker p = TIFFWriteDirectoryTagCheckedShortArray(
2119*3ac0a46fSAndroid Build Coastguard Worker tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, n * m, o);
2120*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, o);
2121*3ac0a46fSAndroid Build Coastguard Worker return (p);
2122*3ac0a46fSAndroid Build Coastguard Worker }
2123*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagSubifd(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir)2124*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
2125*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir)
2126*3ac0a46fSAndroid Build Coastguard Worker {
2127*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagSubifd";
2128*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
2129*3ac0a46fSAndroid Build Coastguard Worker int n;
2130*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_nsubifd == 0)
2131*3ac0a46fSAndroid Build Coastguard Worker return (1);
2132*3ac0a46fSAndroid Build Coastguard Worker if (dir == NULL)
2133*3ac0a46fSAndroid Build Coastguard Worker {
2134*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
2135*3ac0a46fSAndroid Build Coastguard Worker return (1);
2136*3ac0a46fSAndroid Build Coastguard Worker }
2137*3ac0a46fSAndroid Build Coastguard Worker m = tif->tif_dataoff;
2138*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
2139*3ac0a46fSAndroid Build Coastguard Worker {
2140*3ac0a46fSAndroid Build Coastguard Worker uint32_t *o;
2141*3ac0a46fSAndroid Build Coastguard Worker uint64_t *pa;
2142*3ac0a46fSAndroid Build Coastguard Worker uint32_t *pb;
2143*3ac0a46fSAndroid Build Coastguard Worker uint16_t p;
2144*3ac0a46fSAndroid Build Coastguard Worker o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t));
2145*3ac0a46fSAndroid Build Coastguard Worker if (o == NULL)
2146*3ac0a46fSAndroid Build Coastguard Worker {
2147*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
2148*3ac0a46fSAndroid Build Coastguard Worker return (0);
2149*3ac0a46fSAndroid Build Coastguard Worker }
2150*3ac0a46fSAndroid Build Coastguard Worker pa = tif->tif_dir.td_subifd;
2151*3ac0a46fSAndroid Build Coastguard Worker pb = o;
2152*3ac0a46fSAndroid Build Coastguard Worker for (p = 0; p < tif->tif_dir.td_nsubifd; p++)
2153*3ac0a46fSAndroid Build Coastguard Worker {
2154*3ac0a46fSAndroid Build Coastguard Worker assert(pa != 0);
2155*3ac0a46fSAndroid Build Coastguard Worker
2156*3ac0a46fSAndroid Build Coastguard Worker /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which
2157*3ac0a46fSAndroid Build Coastguard Worker * is illegal) */
2158*3ac0a46fSAndroid Build Coastguard Worker if (*pa > 0xFFFFFFFFUL)
2159*3ac0a46fSAndroid Build Coastguard Worker {
2160*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Illegal value for SubIFD tag");
2161*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, o);
2162*3ac0a46fSAndroid Build Coastguard Worker return (0);
2163*3ac0a46fSAndroid Build Coastguard Worker }
2164*3ac0a46fSAndroid Build Coastguard Worker *pb++ = (uint32_t)(*pa++);
2165*3ac0a46fSAndroid Build Coastguard Worker }
2166*3ac0a46fSAndroid Build Coastguard Worker n = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, TIFFTAG_SUBIFD,
2167*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_nsubifd, o);
2168*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, o);
2169*3ac0a46fSAndroid Build Coastguard Worker }
2170*3ac0a46fSAndroid Build Coastguard Worker else
2171*3ac0a46fSAndroid Build Coastguard Worker n = TIFFWriteDirectoryTagCheckedIfd8Array(
2172*3ac0a46fSAndroid Build Coastguard Worker tif, ndir, dir, TIFFTAG_SUBIFD, tif->tif_dir.td_nsubifd,
2173*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_subifd);
2174*3ac0a46fSAndroid Build Coastguard Worker if (!n)
2175*3ac0a46fSAndroid Build Coastguard Worker return (0);
2176*3ac0a46fSAndroid Build Coastguard Worker /*
2177*3ac0a46fSAndroid Build Coastguard Worker * Total hack: if this directory includes a SubIFD
2178*3ac0a46fSAndroid Build Coastguard Worker * tag then force the next <n> directories to be
2179*3ac0a46fSAndroid Build Coastguard Worker * written as ``sub directories'' of this one. This
2180*3ac0a46fSAndroid Build Coastguard Worker * is used to write things like thumbnails and
2181*3ac0a46fSAndroid Build Coastguard Worker * image masks that one wants to keep out of the
2182*3ac0a46fSAndroid Build Coastguard Worker * normal directory linkage access mechanism.
2183*3ac0a46fSAndroid Build Coastguard Worker */
2184*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags |= TIFF_INSUBIFD;
2185*3ac0a46fSAndroid Build Coastguard Worker tif->tif_nsubifd = tif->tif_dir.td_nsubifd;
2186*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_nsubifd == 1)
2187*3ac0a46fSAndroid Build Coastguard Worker tif->tif_subifdoff = 0;
2188*3ac0a46fSAndroid Build Coastguard Worker else
2189*3ac0a46fSAndroid Build Coastguard Worker tif->tif_subifdoff = m;
2190*3ac0a46fSAndroid Build Coastguard Worker return (1);
2191*3ac0a46fSAndroid Build Coastguard Worker }
2192*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedAscii(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,char * value)2193*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
2194*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
2195*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, char *value)
2196*3ac0a46fSAndroid Build Coastguard Worker {
2197*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(char) == 1);
2198*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_ASCII, count,
2199*3ac0a46fSAndroid Build Coastguard Worker count, value));
2200*3ac0a46fSAndroid Build Coastguard Worker }
2201*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint8_t * value)2202*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir,
2203*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2204*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag,
2205*3ac0a46fSAndroid Build Coastguard Worker uint32_t count,
2206*3ac0a46fSAndroid Build Coastguard Worker uint8_t *value)
2207*3ac0a46fSAndroid Build Coastguard Worker {
2208*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint8_t) == 1);
2209*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_UNDEFINED,
2210*3ac0a46fSAndroid Build Coastguard Worker count, count, value));
2211*3ac0a46fSAndroid Build Coastguard Worker }
2212*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedByteArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint8_t * value)2213*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir,
2214*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2215*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
2216*3ac0a46fSAndroid Build Coastguard Worker uint8_t *value)
2217*3ac0a46fSAndroid Build Coastguard Worker {
2218*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint8_t) == 1);
2219*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_BYTE, count,
2220*3ac0a46fSAndroid Build Coastguard Worker count, value));
2221*3ac0a46fSAndroid Build Coastguard Worker }
2222*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedSbyteArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,int8_t * value)2223*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir,
2224*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2225*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
2226*3ac0a46fSAndroid Build Coastguard Worker int8_t *value)
2227*3ac0a46fSAndroid Build Coastguard Worker {
2228*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(int8_t) == 1);
2229*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SBYTE, count,
2230*3ac0a46fSAndroid Build Coastguard Worker count, value));
2231*3ac0a46fSAndroid Build Coastguard Worker }
2232*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedShort(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint16_t value)2233*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir,
2234*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
2235*3ac0a46fSAndroid Build Coastguard Worker uint16_t value)
2236*3ac0a46fSAndroid Build Coastguard Worker {
2237*3ac0a46fSAndroid Build Coastguard Worker uint16_t m;
2238*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint16_t) == 2);
2239*3ac0a46fSAndroid Build Coastguard Worker m = value;
2240*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2241*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(&m);
2242*3ac0a46fSAndroid Build Coastguard Worker return (
2243*3ac0a46fSAndroid Build Coastguard Worker TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, 1, 2, &m));
2244*3ac0a46fSAndroid Build Coastguard Worker }
2245*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedShortArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint16_t * value)2246*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
2247*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2248*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
2249*3ac0a46fSAndroid Build Coastguard Worker uint16_t *value)
2250*3ac0a46fSAndroid Build Coastguard Worker {
2251*3ac0a46fSAndroid Build Coastguard Worker assert(count < 0x80000000);
2252*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint16_t) == 2);
2253*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2254*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfShort(value, count);
2255*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, count,
2256*3ac0a46fSAndroid Build Coastguard Worker count * 2, value));
2257*3ac0a46fSAndroid Build Coastguard Worker }
2258*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedSshortArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,int16_t * value)2259*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir,
2260*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2261*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
2262*3ac0a46fSAndroid Build Coastguard Worker int16_t *value)
2263*3ac0a46fSAndroid Build Coastguard Worker {
2264*3ac0a46fSAndroid Build Coastguard Worker assert(count < 0x80000000);
2265*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(int16_t) == 2);
2266*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2267*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfShort((uint16_t *)value, count);
2268*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SSHORT, count,
2269*3ac0a46fSAndroid Build Coastguard Worker count * 2, value));
2270*3ac0a46fSAndroid Build Coastguard Worker }
2271*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedLong(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t value)2272*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir,
2273*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
2274*3ac0a46fSAndroid Build Coastguard Worker uint32_t value)
2275*3ac0a46fSAndroid Build Coastguard Worker {
2276*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
2277*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint32_t) == 4);
2278*3ac0a46fSAndroid Build Coastguard Worker m = value;
2279*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2280*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&m);
2281*3ac0a46fSAndroid Build Coastguard Worker return (
2282*3ac0a46fSAndroid Build Coastguard Worker TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, 1, 4, &m));
2283*3ac0a46fSAndroid Build Coastguard Worker }
2284*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedLongArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint32_t * value)2285*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
2286*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2287*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
2288*3ac0a46fSAndroid Build Coastguard Worker uint32_t *value)
2289*3ac0a46fSAndroid Build Coastguard Worker {
2290*3ac0a46fSAndroid Build Coastguard Worker assert(count < 0x40000000);
2291*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint32_t) == 4);
2292*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2293*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong(value, count);
2294*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, count,
2295*3ac0a46fSAndroid Build Coastguard Worker count * 4, value));
2296*3ac0a46fSAndroid Build Coastguard Worker }
2297*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedSlongArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,int32_t * value)2298*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir,
2299*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2300*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
2301*3ac0a46fSAndroid Build Coastguard Worker int32_t *value)
2302*3ac0a46fSAndroid Build Coastguard Worker {
2303*3ac0a46fSAndroid Build Coastguard Worker assert(count < 0x40000000);
2304*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(int32_t) == 4);
2305*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2306*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong((uint32_t *)value, count);
2307*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG, count,
2308*3ac0a46fSAndroid Build Coastguard Worker count * 4, value));
2309*3ac0a46fSAndroid Build Coastguard Worker }
2310*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedLong8Array(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint64_t * value)2311*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir,
2312*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2313*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
2314*3ac0a46fSAndroid Build Coastguard Worker uint64_t *value)
2315*3ac0a46fSAndroid Build Coastguard Worker {
2316*3ac0a46fSAndroid Build Coastguard Worker assert(count < 0x20000000);
2317*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint64_t) == 8);
2318*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
2319*3ac0a46fSAndroid Build Coastguard Worker {
2320*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedLong8Array",
2321*3ac0a46fSAndroid Build Coastguard Worker "LONG8 not allowed for ClassicTIFF");
2322*3ac0a46fSAndroid Build Coastguard Worker return (0);
2323*3ac0a46fSAndroid Build Coastguard Worker }
2324*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2325*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong8(value, count);
2326*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG8, count,
2327*3ac0a46fSAndroid Build Coastguard Worker count * 8, value));
2328*3ac0a46fSAndroid Build Coastguard Worker }
2329*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedSlong8Array(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,int64_t * value)2330*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir,
2331*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2332*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
2333*3ac0a46fSAndroid Build Coastguard Worker int64_t *value)
2334*3ac0a46fSAndroid Build Coastguard Worker {
2335*3ac0a46fSAndroid Build Coastguard Worker assert(count < 0x20000000);
2336*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(int64_t) == 8);
2337*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
2338*3ac0a46fSAndroid Build Coastguard Worker {
2339*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedSlong8Array",
2340*3ac0a46fSAndroid Build Coastguard Worker "SLONG8 not allowed for ClassicTIFF");
2341*3ac0a46fSAndroid Build Coastguard Worker return (0);
2342*3ac0a46fSAndroid Build Coastguard Worker }
2343*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2344*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong8((uint64_t *)value, count);
2345*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG8, count,
2346*3ac0a46fSAndroid Build Coastguard Worker count * 8, value));
2347*3ac0a46fSAndroid Build Coastguard Worker }
2348*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedRational(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,double value)2349*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
2350*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
2351*3ac0a46fSAndroid Build Coastguard Worker double value)
2352*3ac0a46fSAndroid Build Coastguard Worker {
2353*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
2354*3ac0a46fSAndroid Build Coastguard Worker uint32_t m[2];
2355*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint32_t) == 4);
2356*3ac0a46fSAndroid Build Coastguard Worker if (value < 0)
2357*3ac0a46fSAndroid Build Coastguard Worker {
2358*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Negative value is illegal");
2359*3ac0a46fSAndroid Build Coastguard Worker return 0;
2360*3ac0a46fSAndroid Build Coastguard Worker }
2361*3ac0a46fSAndroid Build Coastguard Worker else if (value != value)
2362*3ac0a46fSAndroid Build Coastguard Worker {
2363*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Not-a-number value is illegal");
2364*3ac0a46fSAndroid Build Coastguard Worker return 0;
2365*3ac0a46fSAndroid Build Coastguard Worker }
2366*3ac0a46fSAndroid Build Coastguard Worker /*--Rational2Double: New function also used for non-custom rational tags.
2367*3ac0a46fSAndroid Build Coastguard Worker * However, could be omitted here, because
2368*3ac0a46fSAndroid Build Coastguard Worker * TIFFWriteDirectoryTagCheckedRational() is not used by code for custom
2369*3ac0a46fSAndroid Build Coastguard Worker * tags, only by code for named-tiff-tags like FIELD_RESOLUTION and
2370*3ac0a46fSAndroid Build Coastguard Worker * FIELD_POSITION */
2371*3ac0a46fSAndroid Build Coastguard Worker else
2372*3ac0a46fSAndroid Build Coastguard Worker {
2373*3ac0a46fSAndroid Build Coastguard Worker DoubleToRational(value, &m[0], &m[1]);
2374*3ac0a46fSAndroid Build Coastguard Worker }
2375*3ac0a46fSAndroid Build Coastguard Worker
2376*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2377*3ac0a46fSAndroid Build Coastguard Worker {
2378*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&m[0]);
2379*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&m[1]);
2380*3ac0a46fSAndroid Build Coastguard Worker }
2381*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, 1, 8,
2382*3ac0a46fSAndroid Build Coastguard Worker &m[0]));
2383*3ac0a46fSAndroid Build Coastguard Worker }
2384*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedRationalArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,float * value)2385*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
2386*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2387*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag,
2388*3ac0a46fSAndroid Build Coastguard Worker uint32_t count,
2389*3ac0a46fSAndroid Build Coastguard Worker float *value)
2390*3ac0a46fSAndroid Build Coastguard Worker {
2391*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
2392*3ac0a46fSAndroid Build Coastguard Worker uint32_t *m;
2393*3ac0a46fSAndroid Build Coastguard Worker float *na;
2394*3ac0a46fSAndroid Build Coastguard Worker uint32_t *nb;
2395*3ac0a46fSAndroid Build Coastguard Worker uint32_t nc;
2396*3ac0a46fSAndroid Build Coastguard Worker int o;
2397*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint32_t) == 4);
2398*3ac0a46fSAndroid Build Coastguard Worker m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
2399*3ac0a46fSAndroid Build Coastguard Worker if (m == NULL)
2400*3ac0a46fSAndroid Build Coastguard Worker {
2401*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
2402*3ac0a46fSAndroid Build Coastguard Worker return (0);
2403*3ac0a46fSAndroid Build Coastguard Worker }
2404*3ac0a46fSAndroid Build Coastguard Worker for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2405*3ac0a46fSAndroid Build Coastguard Worker {
2406*3ac0a46fSAndroid Build Coastguard Worker DoubleToRational(*na, &nb[0], &nb[1]);
2407*3ac0a46fSAndroid Build Coastguard Worker }
2408*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2409*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong(m, count * 2);
2410*3ac0a46fSAndroid Build Coastguard Worker o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
2411*3ac0a46fSAndroid Build Coastguard Worker count * 8, &m[0]);
2412*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, m);
2413*3ac0a46fSAndroid Build Coastguard Worker return (o);
2414*3ac0a46fSAndroid Build Coastguard Worker }
2415*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedSrationalArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,float * value)2416*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
2417*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2418*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag,
2419*3ac0a46fSAndroid Build Coastguard Worker uint32_t count,
2420*3ac0a46fSAndroid Build Coastguard Worker float *value)
2421*3ac0a46fSAndroid Build Coastguard Worker {
2422*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
2423*3ac0a46fSAndroid Build Coastguard Worker int32_t *m;
2424*3ac0a46fSAndroid Build Coastguard Worker float *na;
2425*3ac0a46fSAndroid Build Coastguard Worker int32_t *nb;
2426*3ac0a46fSAndroid Build Coastguard Worker uint32_t nc;
2427*3ac0a46fSAndroid Build Coastguard Worker int o;
2428*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(int32_t) == 4);
2429*3ac0a46fSAndroid Build Coastguard Worker m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
2430*3ac0a46fSAndroid Build Coastguard Worker if (m == NULL)
2431*3ac0a46fSAndroid Build Coastguard Worker {
2432*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
2433*3ac0a46fSAndroid Build Coastguard Worker return (0);
2434*3ac0a46fSAndroid Build Coastguard Worker }
2435*3ac0a46fSAndroid Build Coastguard Worker for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2436*3ac0a46fSAndroid Build Coastguard Worker {
2437*3ac0a46fSAndroid Build Coastguard Worker DoubleToSrational(*na, &nb[0], &nb[1]);
2438*3ac0a46fSAndroid Build Coastguard Worker }
2439*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2440*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
2441*3ac0a46fSAndroid Build Coastguard Worker o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
2442*3ac0a46fSAndroid Build Coastguard Worker count * 8, &m[0]);
2443*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, m);
2444*3ac0a46fSAndroid Build Coastguard Worker return (o);
2445*3ac0a46fSAndroid Build Coastguard Worker }
2446*3ac0a46fSAndroid Build Coastguard Worker
2447*3ac0a46fSAndroid Build Coastguard Worker /*-- Rational2Double: additional write functions for double arrays */
2448*3ac0a46fSAndroid Build Coastguard Worker static int
TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,double * value)2449*3ac0a46fSAndroid Build Coastguard Worker TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
2450*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
2451*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, double *value)
2452*3ac0a46fSAndroid Build Coastguard Worker {
2453*3ac0a46fSAndroid Build Coastguard Worker static const char module[] =
2454*3ac0a46fSAndroid Build Coastguard Worker "TIFFWriteDirectoryTagCheckedRationalDoubleArray";
2455*3ac0a46fSAndroid Build Coastguard Worker uint32_t *m;
2456*3ac0a46fSAndroid Build Coastguard Worker double *na;
2457*3ac0a46fSAndroid Build Coastguard Worker uint32_t *nb;
2458*3ac0a46fSAndroid Build Coastguard Worker uint32_t nc;
2459*3ac0a46fSAndroid Build Coastguard Worker int o;
2460*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint32_t) == 4);
2461*3ac0a46fSAndroid Build Coastguard Worker m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
2462*3ac0a46fSAndroid Build Coastguard Worker if (m == NULL)
2463*3ac0a46fSAndroid Build Coastguard Worker {
2464*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
2465*3ac0a46fSAndroid Build Coastguard Worker return (0);
2466*3ac0a46fSAndroid Build Coastguard Worker }
2467*3ac0a46fSAndroid Build Coastguard Worker for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2468*3ac0a46fSAndroid Build Coastguard Worker {
2469*3ac0a46fSAndroid Build Coastguard Worker DoubleToRational(*na, &nb[0], &nb[1]);
2470*3ac0a46fSAndroid Build Coastguard Worker }
2471*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2472*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong(m, count * 2);
2473*3ac0a46fSAndroid Build Coastguard Worker o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
2474*3ac0a46fSAndroid Build Coastguard Worker count * 8, &m[0]);
2475*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, m);
2476*3ac0a46fSAndroid Build Coastguard Worker return (o);
2477*3ac0a46fSAndroid Build Coastguard Worker } /*-- TIFFWriteDirectoryTagCheckedRationalDoubleArray() ------- */
2478*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedSrationalDoubleArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,double * value)2479*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
2480*3ac0a46fSAndroid Build Coastguard Worker TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count,
2481*3ac0a46fSAndroid Build Coastguard Worker double *value)
2482*3ac0a46fSAndroid Build Coastguard Worker {
2483*3ac0a46fSAndroid Build Coastguard Worker static const char module[] =
2484*3ac0a46fSAndroid Build Coastguard Worker "TIFFWriteDirectoryTagCheckedSrationalDoubleArray";
2485*3ac0a46fSAndroid Build Coastguard Worker int32_t *m;
2486*3ac0a46fSAndroid Build Coastguard Worker double *na;
2487*3ac0a46fSAndroid Build Coastguard Worker int32_t *nb;
2488*3ac0a46fSAndroid Build Coastguard Worker uint32_t nc;
2489*3ac0a46fSAndroid Build Coastguard Worker int o;
2490*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(int32_t) == 4);
2491*3ac0a46fSAndroid Build Coastguard Worker m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
2492*3ac0a46fSAndroid Build Coastguard Worker if (m == NULL)
2493*3ac0a46fSAndroid Build Coastguard Worker {
2494*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Out of memory");
2495*3ac0a46fSAndroid Build Coastguard Worker return (0);
2496*3ac0a46fSAndroid Build Coastguard Worker }
2497*3ac0a46fSAndroid Build Coastguard Worker for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2498*3ac0a46fSAndroid Build Coastguard Worker {
2499*3ac0a46fSAndroid Build Coastguard Worker DoubleToSrational(*na, &nb[0], &nb[1]);
2500*3ac0a46fSAndroid Build Coastguard Worker }
2501*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2502*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
2503*3ac0a46fSAndroid Build Coastguard Worker o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
2504*3ac0a46fSAndroid Build Coastguard Worker count * 8, &m[0]);
2505*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, m);
2506*3ac0a46fSAndroid Build Coastguard Worker return (o);
2507*3ac0a46fSAndroid Build Coastguard Worker } /*--- TIFFWriteDirectoryTagCheckedSrationalDoubleArray() -------- */
2508*3ac0a46fSAndroid Build Coastguard Worker
2509*3ac0a46fSAndroid Build Coastguard Worker /** ----- Rational2Double: Double To Rational Conversion
2510*3ac0a46fSAndroid Build Coastguard Worker ----------------------------------------------------------
2511*3ac0a46fSAndroid Build Coastguard Worker * There is a mathematical theorem to convert real numbers into a rational
2512*3ac0a46fSAndroid Build Coastguard Worker (integer fraction) number.
2513*3ac0a46fSAndroid Build Coastguard Worker * This is called "continuous fraction" which uses the Euclidean algorithm to
2514*3ac0a46fSAndroid Build Coastguard Worker find the greatest common divisor (GCD).
2515*3ac0a46fSAndroid Build Coastguard Worker * (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or
2516*3ac0a46fSAndroid Build Coastguard Worker https://en.wikipedia.org/wiki/Continued_fraction
2517*3ac0a46fSAndroid Build Coastguard Worker * https://en.wikipedia.org/wiki/Euclidean_algorithm)
2518*3ac0a46fSAndroid Build Coastguard Worker * The following functions implement the
2519*3ac0a46fSAndroid Build Coastguard Worker * - ToRationalEuclideanGCD() auxiliary function which mainly
2520*3ac0a46fSAndroid Build Coastguard Worker implements euclidean GCD
2521*3ac0a46fSAndroid Build Coastguard Worker * - DoubleToRational() conversion function for un-signed
2522*3ac0a46fSAndroid Build Coastguard Worker rationals
2523*3ac0a46fSAndroid Build Coastguard Worker * - DoubleToSrational() conversion function for signed rationals
2524*3ac0a46fSAndroid Build Coastguard Worker ------------------------------------------------------------------------------------------------------------------*/
2525*3ac0a46fSAndroid Build Coastguard Worker
2526*3ac0a46fSAndroid Build Coastguard Worker /**---- ToRationalEuclideanGCD() -----------------------------------------
2527*3ac0a46fSAndroid Build Coastguard Worker * Calculates the rational fractional of a double input value
2528*3ac0a46fSAndroid Build Coastguard Worker * using the Euclidean algorithm to find the greatest common divisor (GCD)
2529*3ac0a46fSAndroid Build Coastguard Worker ------------------------------------------------------------------------*/
ToRationalEuclideanGCD(double value,int blnUseSignedRange,int blnUseSmallRange,uint64_t * ullNum,uint64_t * ullDenom)2530*3ac0a46fSAndroid Build Coastguard Worker static void ToRationalEuclideanGCD(double value, int blnUseSignedRange,
2531*3ac0a46fSAndroid Build Coastguard Worker int blnUseSmallRange, uint64_t *ullNum,
2532*3ac0a46fSAndroid Build Coastguard Worker uint64_t *ullDenom)
2533*3ac0a46fSAndroid Build Coastguard Worker {
2534*3ac0a46fSAndroid Build Coastguard Worker /* Internally, the integer variables can be bigger than the external ones,
2535*3ac0a46fSAndroid Build Coastguard Worker * as long as the result will fit into the external variable size.
2536*3ac0a46fSAndroid Build Coastguard Worker */
2537*3ac0a46fSAndroid Build Coastguard Worker uint64_t numSum[3] = {0, 1, 0}, denomSum[3] = {1, 0, 0};
2538*3ac0a46fSAndroid Build Coastguard Worker uint64_t aux, bigNum, bigDenom;
2539*3ac0a46fSAndroid Build Coastguard Worker uint64_t returnLimit;
2540*3ac0a46fSAndroid Build Coastguard Worker int i;
2541*3ac0a46fSAndroid Build Coastguard Worker uint64_t nMax;
2542*3ac0a46fSAndroid Build Coastguard Worker double fMax;
2543*3ac0a46fSAndroid Build Coastguard Worker unsigned long maxDenom;
2544*3ac0a46fSAndroid Build Coastguard Worker /*-- nMax and fMax defines the initial accuracy of the starting fractional,
2545*3ac0a46fSAndroid Build Coastguard Worker * or better, the highest used integer numbers used within the starting
2546*3ac0a46fSAndroid Build Coastguard Worker * fractional (bigNum/bigDenom). There are two approaches, which can
2547*3ac0a46fSAndroid Build Coastguard Worker * accidentally lead to different accuracies just depending on the value.
2548*3ac0a46fSAndroid Build Coastguard Worker * Therefore, blnUseSmallRange steers this behavior.
2549*3ac0a46fSAndroid Build Coastguard Worker * For long long nMax = ((9223372036854775807-1)/2); for long nMax =
2550*3ac0a46fSAndroid Build Coastguard Worker * ((2147483647-1)/2);
2551*3ac0a46fSAndroid Build Coastguard Worker */
2552*3ac0a46fSAndroid Build Coastguard Worker if (blnUseSmallRange)
2553*3ac0a46fSAndroid Build Coastguard Worker {
2554*3ac0a46fSAndroid Build Coastguard Worker nMax = (uint64_t)((2147483647 - 1) / 2); /* for ULONG range */
2555*3ac0a46fSAndroid Build Coastguard Worker }
2556*3ac0a46fSAndroid Build Coastguard Worker else
2557*3ac0a46fSAndroid Build Coastguard Worker {
2558*3ac0a46fSAndroid Build Coastguard Worker nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */
2559*3ac0a46fSAndroid Build Coastguard Worker }
2560*3ac0a46fSAndroid Build Coastguard Worker fMax = (double)nMax;
2561*3ac0a46fSAndroid Build Coastguard Worker
2562*3ac0a46fSAndroid Build Coastguard Worker /*-- For the Euclidean GCD define the denominator range, so that it stays
2563*3ac0a46fSAndroid Build Coastguard Worker * within size of unsigned long variables. maxDenom should be LONG_MAX for
2564*3ac0a46fSAndroid Build Coastguard Worker * negative values and ULONG_MAX for positive ones. Also the final returned
2565*3ac0a46fSAndroid Build Coastguard Worker * value of ullNum and ullDenom is limited according to signed- or
2566*3ac0a46fSAndroid Build Coastguard Worker * unsigned-range.
2567*3ac0a46fSAndroid Build Coastguard Worker */
2568*3ac0a46fSAndroid Build Coastguard Worker if (blnUseSignedRange)
2569*3ac0a46fSAndroid Build Coastguard Worker {
2570*3ac0a46fSAndroid Build Coastguard Worker maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/
2571*3ac0a46fSAndroid Build Coastguard Worker returnLimit = maxDenom;
2572*3ac0a46fSAndroid Build Coastguard Worker }
2573*3ac0a46fSAndroid Build Coastguard Worker else
2574*3ac0a46fSAndroid Build Coastguard Worker {
2575*3ac0a46fSAndroid Build Coastguard Worker maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/
2576*3ac0a46fSAndroid Build Coastguard Worker returnLimit = maxDenom;
2577*3ac0a46fSAndroid Build Coastguard Worker }
2578*3ac0a46fSAndroid Build Coastguard Worker
2579*3ac0a46fSAndroid Build Coastguard Worker /*-- First generate a rational fraction (bigNum/bigDenom) which represents
2580*3ac0a46fSAndroid Build Coastguard Worker *the value as a rational number with the highest accuracy. Therefore,
2581*3ac0a46fSAndroid Build Coastguard Worker *uint64_t (uint64_t) is needed. This rational fraction is then reduced
2582*3ac0a46fSAndroid Build Coastguard Worker *using the Euclidean algorithm to find the greatest common divisor (GCD).
2583*3ac0a46fSAndroid Build Coastguard Worker * bigNum = big numinator of value without fraction (or cut residual
2584*3ac0a46fSAndroid Build Coastguard Worker *fraction) bigDenom = big denominator of value
2585*3ac0a46fSAndroid Build Coastguard Worker *-- Break-criteria so that uint64_t cast to "bigNum" introduces no error
2586*3ac0a46fSAndroid Build Coastguard Worker *and bigDenom has no overflow, and stop with enlargement of fraction when
2587*3ac0a46fSAndroid Build Coastguard Worker *the double-value of it reaches an integer number without fractional part.
2588*3ac0a46fSAndroid Build Coastguard Worker */
2589*3ac0a46fSAndroid Build Coastguard Worker bigDenom = 1;
2590*3ac0a46fSAndroid Build Coastguard Worker while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax))
2591*3ac0a46fSAndroid Build Coastguard Worker {
2592*3ac0a46fSAndroid Build Coastguard Worker bigDenom <<= 1;
2593*3ac0a46fSAndroid Build Coastguard Worker value *= 2;
2594*3ac0a46fSAndroid Build Coastguard Worker }
2595*3ac0a46fSAndroid Build Coastguard Worker bigNum = (uint64_t)value;
2596*3ac0a46fSAndroid Build Coastguard Worker
2597*3ac0a46fSAndroid Build Coastguard Worker /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) --
2598*3ac0a46fSAndroid Build Coastguard Worker */
2599*3ac0a46fSAndroid Build Coastguard Worker #define MAX_ITERATIONS 64
2600*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < MAX_ITERATIONS; i++)
2601*3ac0a46fSAndroid Build Coastguard Worker {
2602*3ac0a46fSAndroid Build Coastguard Worker uint64_t val;
2603*3ac0a46fSAndroid Build Coastguard Worker /* if bigDenom is not zero, calculate integer part of fraction. */
2604*3ac0a46fSAndroid Build Coastguard Worker if (bigDenom == 0)
2605*3ac0a46fSAndroid Build Coastguard Worker {
2606*3ac0a46fSAndroid Build Coastguard Worker break;
2607*3ac0a46fSAndroid Build Coastguard Worker }
2608*3ac0a46fSAndroid Build Coastguard Worker val = bigNum / bigDenom;
2609*3ac0a46fSAndroid Build Coastguard Worker
2610*3ac0a46fSAndroid Build Coastguard Worker /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous
2611*3ac0a46fSAndroid Build Coastguard Worker * denominator bigDenom. */
2612*3ac0a46fSAndroid Build Coastguard Worker aux = bigNum;
2613*3ac0a46fSAndroid Build Coastguard Worker bigNum = bigDenom;
2614*3ac0a46fSAndroid Build Coastguard Worker bigDenom = aux % bigDenom;
2615*3ac0a46fSAndroid Build Coastguard Worker
2616*3ac0a46fSAndroid Build Coastguard Worker /* calculate next denominator and check for its given maximum */
2617*3ac0a46fSAndroid Build Coastguard Worker aux = val;
2618*3ac0a46fSAndroid Build Coastguard Worker if (denomSum[1] * val + denomSum[0] >= maxDenom)
2619*3ac0a46fSAndroid Build Coastguard Worker {
2620*3ac0a46fSAndroid Build Coastguard Worker aux = (maxDenom - denomSum[0]) / denomSum[1];
2621*3ac0a46fSAndroid Build Coastguard Worker if (aux * 2 >= val || denomSum[1] >= maxDenom)
2622*3ac0a46fSAndroid Build Coastguard Worker i = (MAX_ITERATIONS +
2623*3ac0a46fSAndroid Build Coastguard Worker 1); /* exit but execute rest of for-loop */
2624*3ac0a46fSAndroid Build Coastguard Worker else
2625*3ac0a46fSAndroid Build Coastguard Worker break;
2626*3ac0a46fSAndroid Build Coastguard Worker }
2627*3ac0a46fSAndroid Build Coastguard Worker /* calculate next numerator to numSum2 and save previous one to numSum0;
2628*3ac0a46fSAndroid Build Coastguard Worker * numSum1 just copy of numSum2. */
2629*3ac0a46fSAndroid Build Coastguard Worker numSum[2] = aux * numSum[1] + numSum[0];
2630*3ac0a46fSAndroid Build Coastguard Worker numSum[0] = numSum[1];
2631*3ac0a46fSAndroid Build Coastguard Worker numSum[1] = numSum[2];
2632*3ac0a46fSAndroid Build Coastguard Worker /* calculate next denominator to denomSum2 and save previous one to
2633*3ac0a46fSAndroid Build Coastguard Worker * denomSum0; denomSum1 just copy of denomSum2. */
2634*3ac0a46fSAndroid Build Coastguard Worker denomSum[2] = aux * denomSum[1] + denomSum[0];
2635*3ac0a46fSAndroid Build Coastguard Worker denomSum[0] = denomSum[1];
2636*3ac0a46fSAndroid Build Coastguard Worker denomSum[1] = denomSum[2];
2637*3ac0a46fSAndroid Build Coastguard Worker }
2638*3ac0a46fSAndroid Build Coastguard Worker
2639*3ac0a46fSAndroid Build Coastguard Worker /*-- Check and adapt for final variable size and return values; reduces
2640*3ac0a46fSAndroid Build Coastguard Worker * internal accuracy; denominator is kept in ULONG-range with maxDenom -- */
2641*3ac0a46fSAndroid Build Coastguard Worker while (numSum[1] > returnLimit || denomSum[1] > returnLimit)
2642*3ac0a46fSAndroid Build Coastguard Worker {
2643*3ac0a46fSAndroid Build Coastguard Worker numSum[1] = numSum[1] / 2;
2644*3ac0a46fSAndroid Build Coastguard Worker denomSum[1] = denomSum[1] / 2;
2645*3ac0a46fSAndroid Build Coastguard Worker }
2646*3ac0a46fSAndroid Build Coastguard Worker
2647*3ac0a46fSAndroid Build Coastguard Worker /* return values */
2648*3ac0a46fSAndroid Build Coastguard Worker *ullNum = numSum[1];
2649*3ac0a46fSAndroid Build Coastguard Worker *ullDenom = denomSum[1];
2650*3ac0a46fSAndroid Build Coastguard Worker
2651*3ac0a46fSAndroid Build Coastguard Worker } /*-- ToRationalEuclideanGCD() -------------- */
2652*3ac0a46fSAndroid Build Coastguard Worker
2653*3ac0a46fSAndroid Build Coastguard Worker /**---- DoubleToRational() -----------------------------------------------
2654*3ac0a46fSAndroid Build Coastguard Worker * Calculates the rational fractional of a double input value
2655*3ac0a46fSAndroid Build Coastguard Worker * for UN-SIGNED rationals,
2656*3ac0a46fSAndroid Build Coastguard Worker * using the Euclidean algorithm to find the greatest common divisor (GCD)
2657*3ac0a46fSAndroid Build Coastguard Worker ------------------------------------------------------------------------*/
DoubleToRational(double value,uint32_t * num,uint32_t * denom)2658*3ac0a46fSAndroid Build Coastguard Worker static void DoubleToRational(double value, uint32_t *num, uint32_t *denom)
2659*3ac0a46fSAndroid Build Coastguard Worker {
2660*3ac0a46fSAndroid Build Coastguard Worker /*---- UN-SIGNED RATIONAL ---- */
2661*3ac0a46fSAndroid Build Coastguard Worker double dblDiff, dblDiff2;
2662*3ac0a46fSAndroid Build Coastguard Worker uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
2663*3ac0a46fSAndroid Build Coastguard Worker
2664*3ac0a46fSAndroid Build Coastguard Worker /*-- Check for negative values. If so it is an error. */
2665*3ac0a46fSAndroid Build Coastguard Worker /* Test written that way to catch NaN */
2666*3ac0a46fSAndroid Build Coastguard Worker if (!(value >= 0))
2667*3ac0a46fSAndroid Build Coastguard Worker {
2668*3ac0a46fSAndroid Build Coastguard Worker *num = *denom = 0;
2669*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
2670*3ac0a46fSAndroid Build Coastguard Worker " Negative Value for Unsigned Rational given.");
2671*3ac0a46fSAndroid Build Coastguard Worker return;
2672*3ac0a46fSAndroid Build Coastguard Worker }
2673*3ac0a46fSAndroid Build Coastguard Worker
2674*3ac0a46fSAndroid Build Coastguard Worker /*-- Check for too big numbers (> ULONG_MAX) -- */
2675*3ac0a46fSAndroid Build Coastguard Worker if (value > 0xFFFFFFFFUL)
2676*3ac0a46fSAndroid Build Coastguard Worker {
2677*3ac0a46fSAndroid Build Coastguard Worker *num = 0xFFFFFFFFU;
2678*3ac0a46fSAndroid Build Coastguard Worker *denom = 0;
2679*3ac0a46fSAndroid Build Coastguard Worker return;
2680*3ac0a46fSAndroid Build Coastguard Worker }
2681*3ac0a46fSAndroid Build Coastguard Worker /*-- Check for easy integer numbers -- */
2682*3ac0a46fSAndroid Build Coastguard Worker if (value == (uint32_t)(value))
2683*3ac0a46fSAndroid Build Coastguard Worker {
2684*3ac0a46fSAndroid Build Coastguard Worker *num = (uint32_t)value;
2685*3ac0a46fSAndroid Build Coastguard Worker *denom = 1;
2686*3ac0a46fSAndroid Build Coastguard Worker return;
2687*3ac0a46fSAndroid Build Coastguard Worker }
2688*3ac0a46fSAndroid Build Coastguard Worker /*-- Check for too small numbers for "unsigned long" type rationals -- */
2689*3ac0a46fSAndroid Build Coastguard Worker if (value < 1.0 / (double)0xFFFFFFFFUL)
2690*3ac0a46fSAndroid Build Coastguard Worker {
2691*3ac0a46fSAndroid Build Coastguard Worker *num = 0;
2692*3ac0a46fSAndroid Build Coastguard Worker *denom = 0xFFFFFFFFU;
2693*3ac0a46fSAndroid Build Coastguard Worker return;
2694*3ac0a46fSAndroid Build Coastguard Worker }
2695*3ac0a46fSAndroid Build Coastguard Worker
2696*3ac0a46fSAndroid Build Coastguard Worker /*-- There are two approaches using the Euclidean algorithm,
2697*3ac0a46fSAndroid Build Coastguard Worker * which can accidentally lead to different accuracies just depending on
2698*3ac0a46fSAndroid Build Coastguard Worker * the value. Try both and define which one was better.
2699*3ac0a46fSAndroid Build Coastguard Worker */
2700*3ac0a46fSAndroid Build Coastguard Worker ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom);
2701*3ac0a46fSAndroid Build Coastguard Worker ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2);
2702*3ac0a46fSAndroid Build Coastguard Worker /*-- Double-Check, that returned values fit into ULONG :*/
2703*3ac0a46fSAndroid Build Coastguard Worker if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL ||
2704*3ac0a46fSAndroid Build Coastguard Worker ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL)
2705*3ac0a46fSAndroid Build Coastguard Worker {
2706*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
2707*3ac0a46fSAndroid Build Coastguard Worker " Num or Denom exceeds ULONG: val=%14.6f, num=%12" PRIu64
2708*3ac0a46fSAndroid Build Coastguard Worker ", denom=%12" PRIu64 " | num2=%12" PRIu64
2709*3ac0a46fSAndroid Build Coastguard Worker ", denom2=%12" PRIu64 "",
2710*3ac0a46fSAndroid Build Coastguard Worker value, ullNum, ullDenom, ullNum2, ullDenom2);
2711*3ac0a46fSAndroid Build Coastguard Worker assert(0);
2712*3ac0a46fSAndroid Build Coastguard Worker }
2713*3ac0a46fSAndroid Build Coastguard Worker
2714*3ac0a46fSAndroid Build Coastguard Worker /* Check, which one has higher accuracy and take that. */
2715*3ac0a46fSAndroid Build Coastguard Worker dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
2716*3ac0a46fSAndroid Build Coastguard Worker dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
2717*3ac0a46fSAndroid Build Coastguard Worker if (dblDiff < dblDiff2)
2718*3ac0a46fSAndroid Build Coastguard Worker {
2719*3ac0a46fSAndroid Build Coastguard Worker *num = (uint32_t)ullNum;
2720*3ac0a46fSAndroid Build Coastguard Worker *denom = (uint32_t)ullDenom;
2721*3ac0a46fSAndroid Build Coastguard Worker }
2722*3ac0a46fSAndroid Build Coastguard Worker else
2723*3ac0a46fSAndroid Build Coastguard Worker {
2724*3ac0a46fSAndroid Build Coastguard Worker *num = (uint32_t)ullNum2;
2725*3ac0a46fSAndroid Build Coastguard Worker *denom = (uint32_t)ullDenom2;
2726*3ac0a46fSAndroid Build Coastguard Worker }
2727*3ac0a46fSAndroid Build Coastguard Worker } /*-- DoubleToRational() -------------- */
2728*3ac0a46fSAndroid Build Coastguard Worker
2729*3ac0a46fSAndroid Build Coastguard Worker /**---- DoubleToSrational() -----------------------------------------------
2730*3ac0a46fSAndroid Build Coastguard Worker * Calculates the rational fractional of a double input value
2731*3ac0a46fSAndroid Build Coastguard Worker * for SIGNED rationals,
2732*3ac0a46fSAndroid Build Coastguard Worker * using the Euclidean algorithm to find the greatest common divisor (GCD)
2733*3ac0a46fSAndroid Build Coastguard Worker ------------------------------------------------------------------------*/
DoubleToSrational(double value,int32_t * num,int32_t * denom)2734*3ac0a46fSAndroid Build Coastguard Worker static void DoubleToSrational(double value, int32_t *num, int32_t *denom)
2735*3ac0a46fSAndroid Build Coastguard Worker {
2736*3ac0a46fSAndroid Build Coastguard Worker /*---- SIGNED RATIONAL ----*/
2737*3ac0a46fSAndroid Build Coastguard Worker int neg = 1;
2738*3ac0a46fSAndroid Build Coastguard Worker double dblDiff, dblDiff2;
2739*3ac0a46fSAndroid Build Coastguard Worker uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
2740*3ac0a46fSAndroid Build Coastguard Worker
2741*3ac0a46fSAndroid Build Coastguard Worker /*-- Check for negative values and use then the positive one for internal
2742*3ac0a46fSAndroid Build Coastguard Worker * calculations, but take the sign into account before returning. */
2743*3ac0a46fSAndroid Build Coastguard Worker if (value < 0)
2744*3ac0a46fSAndroid Build Coastguard Worker {
2745*3ac0a46fSAndroid Build Coastguard Worker neg = -1;
2746*3ac0a46fSAndroid Build Coastguard Worker value = -value;
2747*3ac0a46fSAndroid Build Coastguard Worker }
2748*3ac0a46fSAndroid Build Coastguard Worker
2749*3ac0a46fSAndroid Build Coastguard Worker /*-- Check for too big numbers (> LONG_MAX) -- */
2750*3ac0a46fSAndroid Build Coastguard Worker if (value > 0x7FFFFFFFL)
2751*3ac0a46fSAndroid Build Coastguard Worker {
2752*3ac0a46fSAndroid Build Coastguard Worker *num = 0x7FFFFFFFL;
2753*3ac0a46fSAndroid Build Coastguard Worker *denom = 0;
2754*3ac0a46fSAndroid Build Coastguard Worker return;
2755*3ac0a46fSAndroid Build Coastguard Worker }
2756*3ac0a46fSAndroid Build Coastguard Worker /*-- Check for easy numbers -- */
2757*3ac0a46fSAndroid Build Coastguard Worker if (value == (int32_t)(value))
2758*3ac0a46fSAndroid Build Coastguard Worker {
2759*3ac0a46fSAndroid Build Coastguard Worker *num = (int32_t)(neg * value);
2760*3ac0a46fSAndroid Build Coastguard Worker *denom = 1;
2761*3ac0a46fSAndroid Build Coastguard Worker return;
2762*3ac0a46fSAndroid Build Coastguard Worker }
2763*3ac0a46fSAndroid Build Coastguard Worker /*-- Check for too small numbers for "long" type rationals -- */
2764*3ac0a46fSAndroid Build Coastguard Worker if (value < 1.0 / (double)0x7FFFFFFFL)
2765*3ac0a46fSAndroid Build Coastguard Worker {
2766*3ac0a46fSAndroid Build Coastguard Worker *num = 0;
2767*3ac0a46fSAndroid Build Coastguard Worker *denom = 0x7FFFFFFFL;
2768*3ac0a46fSAndroid Build Coastguard Worker return;
2769*3ac0a46fSAndroid Build Coastguard Worker }
2770*3ac0a46fSAndroid Build Coastguard Worker
2771*3ac0a46fSAndroid Build Coastguard Worker /*-- There are two approaches using the Euclidean algorithm,
2772*3ac0a46fSAndroid Build Coastguard Worker * which can accidentally lead to different accuracies just depending on
2773*3ac0a46fSAndroid Build Coastguard Worker * the value. Try both and define which one was better. Furthermore, set
2774*3ac0a46fSAndroid Build Coastguard Worker * behavior of ToRationalEuclideanGCD() to the range of signed-long.
2775*3ac0a46fSAndroid Build Coastguard Worker */
2776*3ac0a46fSAndroid Build Coastguard Worker ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom);
2777*3ac0a46fSAndroid Build Coastguard Worker ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2);
2778*3ac0a46fSAndroid Build Coastguard Worker /*-- Double-Check, that returned values fit into LONG :*/
2779*3ac0a46fSAndroid Build Coastguard Worker if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL ||
2780*3ac0a46fSAndroid Build Coastguard Worker ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL)
2781*3ac0a46fSAndroid Build Coastguard Worker {
2782*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExt(0, "TIFFLib: DoubleToSrational()",
2783*3ac0a46fSAndroid Build Coastguard Worker " Num or Denom exceeds LONG: val=%14.6f, num=%12" PRIu64
2784*3ac0a46fSAndroid Build Coastguard Worker ", denom=%12" PRIu64 " | num2=%12" PRIu64
2785*3ac0a46fSAndroid Build Coastguard Worker ", denom2=%12" PRIu64 "",
2786*3ac0a46fSAndroid Build Coastguard Worker neg * value, ullNum, ullDenom, ullNum2, ullDenom2);
2787*3ac0a46fSAndroid Build Coastguard Worker assert(0);
2788*3ac0a46fSAndroid Build Coastguard Worker }
2789*3ac0a46fSAndroid Build Coastguard Worker
2790*3ac0a46fSAndroid Build Coastguard Worker /* Check, which one has higher accuracy and take that. */
2791*3ac0a46fSAndroid Build Coastguard Worker dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
2792*3ac0a46fSAndroid Build Coastguard Worker dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
2793*3ac0a46fSAndroid Build Coastguard Worker if (dblDiff < dblDiff2)
2794*3ac0a46fSAndroid Build Coastguard Worker {
2795*3ac0a46fSAndroid Build Coastguard Worker *num = (int32_t)(neg * (long)ullNum);
2796*3ac0a46fSAndroid Build Coastguard Worker *denom = (int32_t)ullDenom;
2797*3ac0a46fSAndroid Build Coastguard Worker }
2798*3ac0a46fSAndroid Build Coastguard Worker else
2799*3ac0a46fSAndroid Build Coastguard Worker {
2800*3ac0a46fSAndroid Build Coastguard Worker *num = (int32_t)(neg * (long)ullNum2);
2801*3ac0a46fSAndroid Build Coastguard Worker *denom = (int32_t)ullDenom2;
2802*3ac0a46fSAndroid Build Coastguard Worker }
2803*3ac0a46fSAndroid Build Coastguard Worker } /*-- DoubleToSrational() --------------*/
2804*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedFloatArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,float * value)2805*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
2806*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2807*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
2808*3ac0a46fSAndroid Build Coastguard Worker float *value)
2809*3ac0a46fSAndroid Build Coastguard Worker {
2810*3ac0a46fSAndroid Build Coastguard Worker assert(count < 0x40000000);
2811*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(float) == 4);
2812*3ac0a46fSAndroid Build Coastguard Worker TIFFCvtNativeToIEEEFloat(tif, count, &value);
2813*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2814*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfFloat(value, count);
2815*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_FLOAT, count,
2816*3ac0a46fSAndroid Build Coastguard Worker count * 4, value));
2817*3ac0a46fSAndroid Build Coastguard Worker }
2818*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedDoubleArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,double * value)2819*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
2820*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2821*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
2822*3ac0a46fSAndroid Build Coastguard Worker double *value)
2823*3ac0a46fSAndroid Build Coastguard Worker {
2824*3ac0a46fSAndroid Build Coastguard Worker assert(count < 0x20000000);
2825*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(double) == 8);
2826*3ac0a46fSAndroid Build Coastguard Worker TIFFCvtNativeToIEEEDouble(tif, count, &value);
2827*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2828*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfDouble(value, count);
2829*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_DOUBLE, count,
2830*3ac0a46fSAndroid Build Coastguard Worker count * 8, value));
2831*3ac0a46fSAndroid Build Coastguard Worker }
2832*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedIfdArray(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint32_t * value)2833*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir,
2834*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
2835*3ac0a46fSAndroid Build Coastguard Worker uint32_t count, uint32_t *value)
2836*3ac0a46fSAndroid Build Coastguard Worker {
2837*3ac0a46fSAndroid Build Coastguard Worker assert(count < 0x40000000);
2838*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint32_t) == 4);
2839*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2840*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong(value, count);
2841*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD, count,
2842*3ac0a46fSAndroid Build Coastguard Worker count * 4, value));
2843*3ac0a46fSAndroid Build Coastguard Worker }
2844*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagCheckedIfd8Array(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint32_t count,uint64_t * value)2845*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir,
2846*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir,
2847*3ac0a46fSAndroid Build Coastguard Worker uint16_t tag, uint32_t count,
2848*3ac0a46fSAndroid Build Coastguard Worker uint64_t *value)
2849*3ac0a46fSAndroid Build Coastguard Worker {
2850*3ac0a46fSAndroid Build Coastguard Worker assert(count < 0x20000000);
2851*3ac0a46fSAndroid Build Coastguard Worker assert(sizeof(uint64_t) == 8);
2852*3ac0a46fSAndroid Build Coastguard Worker assert(tif->tif_flags & TIFF_BIGTIFF);
2853*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2854*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong8(value, count);
2855*3ac0a46fSAndroid Build Coastguard Worker return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD8, count,
2856*3ac0a46fSAndroid Build Coastguard Worker count * 8, value));
2857*3ac0a46fSAndroid Build Coastguard Worker }
2858*3ac0a46fSAndroid Build Coastguard Worker
TIFFWriteDirectoryTagData(TIFF * tif,uint32_t * ndir,TIFFDirEntry * dir,uint16_t tag,uint16_t datatype,uint32_t count,uint32_t datalength,void * data)2859*3ac0a46fSAndroid Build Coastguard Worker static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
2860*3ac0a46fSAndroid Build Coastguard Worker TIFFDirEntry *dir, uint16_t tag,
2861*3ac0a46fSAndroid Build Coastguard Worker uint16_t datatype, uint32_t count,
2862*3ac0a46fSAndroid Build Coastguard Worker uint32_t datalength, void *data)
2863*3ac0a46fSAndroid Build Coastguard Worker {
2864*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFWriteDirectoryTagData";
2865*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
2866*3ac0a46fSAndroid Build Coastguard Worker m = 0;
2867*3ac0a46fSAndroid Build Coastguard Worker while (m < (*ndir))
2868*3ac0a46fSAndroid Build Coastguard Worker {
2869*3ac0a46fSAndroid Build Coastguard Worker assert(dir[m].tdir_tag != tag);
2870*3ac0a46fSAndroid Build Coastguard Worker if (dir[m].tdir_tag > tag)
2871*3ac0a46fSAndroid Build Coastguard Worker break;
2872*3ac0a46fSAndroid Build Coastguard Worker m++;
2873*3ac0a46fSAndroid Build Coastguard Worker }
2874*3ac0a46fSAndroid Build Coastguard Worker if (m < (*ndir))
2875*3ac0a46fSAndroid Build Coastguard Worker {
2876*3ac0a46fSAndroid Build Coastguard Worker uint32_t n;
2877*3ac0a46fSAndroid Build Coastguard Worker for (n = *ndir; n > m; n--)
2878*3ac0a46fSAndroid Build Coastguard Worker dir[n] = dir[n - 1];
2879*3ac0a46fSAndroid Build Coastguard Worker }
2880*3ac0a46fSAndroid Build Coastguard Worker dir[m].tdir_tag = tag;
2881*3ac0a46fSAndroid Build Coastguard Worker dir[m].tdir_type = datatype;
2882*3ac0a46fSAndroid Build Coastguard Worker dir[m].tdir_count = count;
2883*3ac0a46fSAndroid Build Coastguard Worker dir[m].tdir_offset.toff_long8 = 0;
2884*3ac0a46fSAndroid Build Coastguard Worker if (datalength <= ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
2885*3ac0a46fSAndroid Build Coastguard Worker {
2886*3ac0a46fSAndroid Build Coastguard Worker if (data && datalength)
2887*3ac0a46fSAndroid Build Coastguard Worker {
2888*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&dir[m].tdir_offset, data, datalength);
2889*3ac0a46fSAndroid Build Coastguard Worker }
2890*3ac0a46fSAndroid Build Coastguard Worker }
2891*3ac0a46fSAndroid Build Coastguard Worker else
2892*3ac0a46fSAndroid Build Coastguard Worker {
2893*3ac0a46fSAndroid Build Coastguard Worker uint64_t na, nb;
2894*3ac0a46fSAndroid Build Coastguard Worker na = tif->tif_dataoff;
2895*3ac0a46fSAndroid Build Coastguard Worker nb = na + datalength;
2896*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
2897*3ac0a46fSAndroid Build Coastguard Worker nb = (uint32_t)nb;
2898*3ac0a46fSAndroid Build Coastguard Worker if ((nb < na) || (nb < datalength))
2899*3ac0a46fSAndroid Build Coastguard Worker {
2900*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
2901*3ac0a46fSAndroid Build Coastguard Worker return (0);
2902*3ac0a46fSAndroid Build Coastguard Worker }
2903*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, na))
2904*3ac0a46fSAndroid Build Coastguard Worker {
2905*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "IO error writing tag data");
2906*3ac0a46fSAndroid Build Coastguard Worker return (0);
2907*3ac0a46fSAndroid Build Coastguard Worker }
2908*3ac0a46fSAndroid Build Coastguard Worker if (datalength >= 0x80000000UL)
2909*3ac0a46fSAndroid Build Coastguard Worker {
2910*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
2911*3ac0a46fSAndroid Build Coastguard Worker "libtiff does not allow writing more than 2147483647 "
2912*3ac0a46fSAndroid Build Coastguard Worker "bytes in a tag");
2913*3ac0a46fSAndroid Build Coastguard Worker return (0);
2914*3ac0a46fSAndroid Build Coastguard Worker }
2915*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, data, (tmsize_t)datalength))
2916*3ac0a46fSAndroid Build Coastguard Worker {
2917*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "IO error writing tag data");
2918*3ac0a46fSAndroid Build Coastguard Worker return (0);
2919*3ac0a46fSAndroid Build Coastguard Worker }
2920*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dataoff = nb;
2921*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dataoff & 1)
2922*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dataoff++;
2923*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
2924*3ac0a46fSAndroid Build Coastguard Worker {
2925*3ac0a46fSAndroid Build Coastguard Worker uint32_t o;
2926*3ac0a46fSAndroid Build Coastguard Worker o = (uint32_t)na;
2927*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2928*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&o);
2929*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(&dir[m].tdir_offset, &o, 4);
2930*3ac0a46fSAndroid Build Coastguard Worker }
2931*3ac0a46fSAndroid Build Coastguard Worker else
2932*3ac0a46fSAndroid Build Coastguard Worker {
2933*3ac0a46fSAndroid Build Coastguard Worker dir[m].tdir_offset.toff_long8 = na;
2934*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2935*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
2936*3ac0a46fSAndroid Build Coastguard Worker }
2937*3ac0a46fSAndroid Build Coastguard Worker }
2938*3ac0a46fSAndroid Build Coastguard Worker (*ndir)++;
2939*3ac0a46fSAndroid Build Coastguard Worker return (1);
2940*3ac0a46fSAndroid Build Coastguard Worker }
2941*3ac0a46fSAndroid Build Coastguard Worker
2942*3ac0a46fSAndroid Build Coastguard Worker /*
2943*3ac0a46fSAndroid Build Coastguard Worker * Link the current directory into the directory chain for the file.
2944*3ac0a46fSAndroid Build Coastguard Worker */
TIFFLinkDirectory(TIFF * tif)2945*3ac0a46fSAndroid Build Coastguard Worker static int TIFFLinkDirectory(TIFF *tif)
2946*3ac0a46fSAndroid Build Coastguard Worker {
2947*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFLinkDirectory";
2948*3ac0a46fSAndroid Build Coastguard Worker
2949*3ac0a46fSAndroid Build Coastguard Worker tif->tif_diroff = (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
2950*3ac0a46fSAndroid Build Coastguard Worker
2951*3ac0a46fSAndroid Build Coastguard Worker /*
2952*3ac0a46fSAndroid Build Coastguard Worker * Handle SubIFDs
2953*3ac0a46fSAndroid Build Coastguard Worker */
2954*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_INSUBIFD)
2955*3ac0a46fSAndroid Build Coastguard Worker {
2956*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
2957*3ac0a46fSAndroid Build Coastguard Worker {
2958*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
2959*3ac0a46fSAndroid Build Coastguard Worker m = (uint32_t)tif->tif_diroff;
2960*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2961*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&m);
2962*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
2963*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, &m, 4))
2964*3ac0a46fSAndroid Build Coastguard Worker {
2965*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
2966*3ac0a46fSAndroid Build Coastguard Worker "Error writing SubIFD directory link");
2967*3ac0a46fSAndroid Build Coastguard Worker return (0);
2968*3ac0a46fSAndroid Build Coastguard Worker }
2969*3ac0a46fSAndroid Build Coastguard Worker /*
2970*3ac0a46fSAndroid Build Coastguard Worker * Advance to the next SubIFD or, if this is
2971*3ac0a46fSAndroid Build Coastguard Worker * the last one configured, revert back to the
2972*3ac0a46fSAndroid Build Coastguard Worker * normal directory linkage.
2973*3ac0a46fSAndroid Build Coastguard Worker */
2974*3ac0a46fSAndroid Build Coastguard Worker if (--tif->tif_nsubifd)
2975*3ac0a46fSAndroid Build Coastguard Worker tif->tif_subifdoff += 4;
2976*3ac0a46fSAndroid Build Coastguard Worker else
2977*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_INSUBIFD;
2978*3ac0a46fSAndroid Build Coastguard Worker return (1);
2979*3ac0a46fSAndroid Build Coastguard Worker }
2980*3ac0a46fSAndroid Build Coastguard Worker else
2981*3ac0a46fSAndroid Build Coastguard Worker {
2982*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
2983*3ac0a46fSAndroid Build Coastguard Worker m = tif->tif_diroff;
2984*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
2985*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&m);
2986*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
2987*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, &m, 8))
2988*3ac0a46fSAndroid Build Coastguard Worker {
2989*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
2990*3ac0a46fSAndroid Build Coastguard Worker "Error writing SubIFD directory link");
2991*3ac0a46fSAndroid Build Coastguard Worker return (0);
2992*3ac0a46fSAndroid Build Coastguard Worker }
2993*3ac0a46fSAndroid Build Coastguard Worker /*
2994*3ac0a46fSAndroid Build Coastguard Worker * Advance to the next SubIFD or, if this is
2995*3ac0a46fSAndroid Build Coastguard Worker * the last one configured, revert back to the
2996*3ac0a46fSAndroid Build Coastguard Worker * normal directory linkage.
2997*3ac0a46fSAndroid Build Coastguard Worker */
2998*3ac0a46fSAndroid Build Coastguard Worker if (--tif->tif_nsubifd)
2999*3ac0a46fSAndroid Build Coastguard Worker tif->tif_subifdoff += 8;
3000*3ac0a46fSAndroid Build Coastguard Worker else
3001*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_INSUBIFD;
3002*3ac0a46fSAndroid Build Coastguard Worker return (1);
3003*3ac0a46fSAndroid Build Coastguard Worker }
3004*3ac0a46fSAndroid Build Coastguard Worker }
3005*3ac0a46fSAndroid Build Coastguard Worker
3006*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
3007*3ac0a46fSAndroid Build Coastguard Worker {
3008*3ac0a46fSAndroid Build Coastguard Worker uint32_t m;
3009*3ac0a46fSAndroid Build Coastguard Worker uint32_t nextdir;
3010*3ac0a46fSAndroid Build Coastguard Worker m = (uint32_t)(tif->tif_diroff);
3011*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3012*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&m);
3013*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_header.classic.tiff_diroff == 0)
3014*3ac0a46fSAndroid Build Coastguard Worker {
3015*3ac0a46fSAndroid Build Coastguard Worker /*
3016*3ac0a46fSAndroid Build Coastguard Worker * First directory, overwrite offset in header.
3017*3ac0a46fSAndroid Build Coastguard Worker */
3018*3ac0a46fSAndroid Build Coastguard Worker tif->tif_header.classic.tiff_diroff = (uint32_t)tif->tif_diroff;
3019*3ac0a46fSAndroid Build Coastguard Worker tif->tif_lastdiroff = tif->tif_diroff;
3020*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSeekFile(tif, 4, SEEK_SET);
3021*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, &m, 4))
3022*3ac0a46fSAndroid Build Coastguard Worker {
3023*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
3024*3ac0a46fSAndroid Build Coastguard Worker return (0);
3025*3ac0a46fSAndroid Build Coastguard Worker }
3026*3ac0a46fSAndroid Build Coastguard Worker return (1);
3027*3ac0a46fSAndroid Build Coastguard Worker }
3028*3ac0a46fSAndroid Build Coastguard Worker /*
3029*3ac0a46fSAndroid Build Coastguard Worker * Not the first directory, search to the last and append.
3030*3ac0a46fSAndroid Build Coastguard Worker */
3031*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_lastdiroff != 0)
3032*3ac0a46fSAndroid Build Coastguard Worker {
3033*3ac0a46fSAndroid Build Coastguard Worker nextdir = (uint32_t)tif->tif_lastdiroff;
3034*3ac0a46fSAndroid Build Coastguard Worker }
3035*3ac0a46fSAndroid Build Coastguard Worker else
3036*3ac0a46fSAndroid Build Coastguard Worker {
3037*3ac0a46fSAndroid Build Coastguard Worker nextdir = tif->tif_header.classic.tiff_diroff;
3038*3ac0a46fSAndroid Build Coastguard Worker }
3039*3ac0a46fSAndroid Build Coastguard Worker
3040*3ac0a46fSAndroid Build Coastguard Worker while (1)
3041*3ac0a46fSAndroid Build Coastguard Worker {
3042*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount;
3043*3ac0a46fSAndroid Build Coastguard Worker uint32_t nextnextdir;
3044*3ac0a46fSAndroid Build Coastguard Worker
3045*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
3046*3ac0a46fSAndroid Build Coastguard Worker {
3047*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Error fetching directory count");
3048*3ac0a46fSAndroid Build Coastguard Worker return (0);
3049*3ac0a46fSAndroid Build Coastguard Worker }
3050*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3051*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(&dircount);
3052*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
3053*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, &nextnextdir, 4))
3054*3ac0a46fSAndroid Build Coastguard Worker {
3055*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Error fetching directory link");
3056*3ac0a46fSAndroid Build Coastguard Worker return (0);
3057*3ac0a46fSAndroid Build Coastguard Worker }
3058*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3059*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&nextnextdir);
3060*3ac0a46fSAndroid Build Coastguard Worker if (nextnextdir == 0)
3061*3ac0a46fSAndroid Build Coastguard Worker {
3062*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
3063*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, &m, 4))
3064*3ac0a46fSAndroid Build Coastguard Worker {
3065*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Error writing directory link");
3066*3ac0a46fSAndroid Build Coastguard Worker return (0);
3067*3ac0a46fSAndroid Build Coastguard Worker }
3068*3ac0a46fSAndroid Build Coastguard Worker tif->tif_lastdiroff = tif->tif_diroff;
3069*3ac0a46fSAndroid Build Coastguard Worker break;
3070*3ac0a46fSAndroid Build Coastguard Worker }
3071*3ac0a46fSAndroid Build Coastguard Worker nextdir = nextnextdir;
3072*3ac0a46fSAndroid Build Coastguard Worker }
3073*3ac0a46fSAndroid Build Coastguard Worker }
3074*3ac0a46fSAndroid Build Coastguard Worker else
3075*3ac0a46fSAndroid Build Coastguard Worker {
3076*3ac0a46fSAndroid Build Coastguard Worker uint64_t m;
3077*3ac0a46fSAndroid Build Coastguard Worker uint64_t nextdir;
3078*3ac0a46fSAndroid Build Coastguard Worker m = tif->tif_diroff;
3079*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3080*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&m);
3081*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_header.big.tiff_diroff == 0)
3082*3ac0a46fSAndroid Build Coastguard Worker {
3083*3ac0a46fSAndroid Build Coastguard Worker /*
3084*3ac0a46fSAndroid Build Coastguard Worker * First directory, overwrite offset in header.
3085*3ac0a46fSAndroid Build Coastguard Worker */
3086*3ac0a46fSAndroid Build Coastguard Worker tif->tif_header.big.tiff_diroff = tif->tif_diroff;
3087*3ac0a46fSAndroid Build Coastguard Worker tif->tif_lastdiroff = tif->tif_diroff;
3088*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSeekFile(tif, 8, SEEK_SET);
3089*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, &m, 8))
3090*3ac0a46fSAndroid Build Coastguard Worker {
3091*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
3092*3ac0a46fSAndroid Build Coastguard Worker return (0);
3093*3ac0a46fSAndroid Build Coastguard Worker }
3094*3ac0a46fSAndroid Build Coastguard Worker return (1);
3095*3ac0a46fSAndroid Build Coastguard Worker }
3096*3ac0a46fSAndroid Build Coastguard Worker /*
3097*3ac0a46fSAndroid Build Coastguard Worker * Not the first directory, search to the last and append.
3098*3ac0a46fSAndroid Build Coastguard Worker */
3099*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_lastdiroff != 0)
3100*3ac0a46fSAndroid Build Coastguard Worker {
3101*3ac0a46fSAndroid Build Coastguard Worker nextdir = tif->tif_lastdiroff;
3102*3ac0a46fSAndroid Build Coastguard Worker }
3103*3ac0a46fSAndroid Build Coastguard Worker else
3104*3ac0a46fSAndroid Build Coastguard Worker {
3105*3ac0a46fSAndroid Build Coastguard Worker nextdir = tif->tif_header.big.tiff_diroff;
3106*3ac0a46fSAndroid Build Coastguard Worker }
3107*3ac0a46fSAndroid Build Coastguard Worker while (1)
3108*3ac0a46fSAndroid Build Coastguard Worker {
3109*3ac0a46fSAndroid Build Coastguard Worker uint64_t dircount64;
3110*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount;
3111*3ac0a46fSAndroid Build Coastguard Worker uint64_t nextnextdir;
3112*3ac0a46fSAndroid Build Coastguard Worker
3113*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
3114*3ac0a46fSAndroid Build Coastguard Worker {
3115*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Error fetching directory count");
3116*3ac0a46fSAndroid Build Coastguard Worker return (0);
3117*3ac0a46fSAndroid Build Coastguard Worker }
3118*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3119*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&dircount64);
3120*3ac0a46fSAndroid Build Coastguard Worker if (dircount64 > 0xFFFF)
3121*3ac0a46fSAndroid Build Coastguard Worker {
3122*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(
3123*3ac0a46fSAndroid Build Coastguard Worker tif, module,
3124*3ac0a46fSAndroid Build Coastguard Worker "Sanity check on tag count failed, likely corrupt TIFF");
3125*3ac0a46fSAndroid Build Coastguard Worker return (0);
3126*3ac0a46fSAndroid Build Coastguard Worker }
3127*3ac0a46fSAndroid Build Coastguard Worker dircount = (uint16_t)dircount64;
3128*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
3129*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, &nextnextdir, 8))
3130*3ac0a46fSAndroid Build Coastguard Worker {
3131*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Error fetching directory link");
3132*3ac0a46fSAndroid Build Coastguard Worker return (0);
3133*3ac0a46fSAndroid Build Coastguard Worker }
3134*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3135*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&nextnextdir);
3136*3ac0a46fSAndroid Build Coastguard Worker if (nextnextdir == 0)
3137*3ac0a46fSAndroid Build Coastguard Worker {
3138*3ac0a46fSAndroid Build Coastguard Worker (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
3139*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, &m, 8))
3140*3ac0a46fSAndroid Build Coastguard Worker {
3141*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Error writing directory link");
3142*3ac0a46fSAndroid Build Coastguard Worker return (0);
3143*3ac0a46fSAndroid Build Coastguard Worker }
3144*3ac0a46fSAndroid Build Coastguard Worker tif->tif_lastdiroff = tif->tif_diroff;
3145*3ac0a46fSAndroid Build Coastguard Worker break;
3146*3ac0a46fSAndroid Build Coastguard Worker }
3147*3ac0a46fSAndroid Build Coastguard Worker nextdir = nextnextdir;
3148*3ac0a46fSAndroid Build Coastguard Worker }
3149*3ac0a46fSAndroid Build Coastguard Worker }
3150*3ac0a46fSAndroid Build Coastguard Worker return (1);
3151*3ac0a46fSAndroid Build Coastguard Worker }
3152*3ac0a46fSAndroid Build Coastguard Worker
3153*3ac0a46fSAndroid Build Coastguard Worker /************************************************************************/
3154*3ac0a46fSAndroid Build Coastguard Worker /* TIFFRewriteField() */
3155*3ac0a46fSAndroid Build Coastguard Worker /* */
3156*3ac0a46fSAndroid Build Coastguard Worker /* Rewrite a field in the directory on disk without regard to */
3157*3ac0a46fSAndroid Build Coastguard Worker /* updating the TIFF directory structure in memory. Currently */
3158*3ac0a46fSAndroid Build Coastguard Worker /* only supported for field that already exist in the on-disk */
3159*3ac0a46fSAndroid Build Coastguard Worker /* directory. Mainly used for updating stripoffset / */
3160*3ac0a46fSAndroid Build Coastguard Worker /* stripbytecount values after the directory is already on */
3161*3ac0a46fSAndroid Build Coastguard Worker /* disk. */
3162*3ac0a46fSAndroid Build Coastguard Worker /* */
3163*3ac0a46fSAndroid Build Coastguard Worker /* Returns zero on failure, and one on success. */
3164*3ac0a46fSAndroid Build Coastguard Worker /************************************************************************/
3165*3ac0a46fSAndroid Build Coastguard Worker
_TIFFRewriteField(TIFF * tif,uint16_t tag,TIFFDataType in_datatype,tmsize_t count,void * data)3166*3ac0a46fSAndroid Build Coastguard Worker int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
3167*3ac0a46fSAndroid Build Coastguard Worker tmsize_t count, void *data)
3168*3ac0a46fSAndroid Build Coastguard Worker {
3169*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFResetField";
3170*3ac0a46fSAndroid Build Coastguard Worker /* const TIFFField* fip = NULL; */
3171*3ac0a46fSAndroid Build Coastguard Worker uint16_t dircount;
3172*3ac0a46fSAndroid Build Coastguard Worker tmsize_t dirsize;
3173*3ac0a46fSAndroid Build Coastguard Worker uint8_t direntry_raw[20];
3174*3ac0a46fSAndroid Build Coastguard Worker uint16_t entry_tag = 0;
3175*3ac0a46fSAndroid Build Coastguard Worker uint16_t entry_type = 0;
3176*3ac0a46fSAndroid Build Coastguard Worker uint64_t entry_count = 0;
3177*3ac0a46fSAndroid Build Coastguard Worker uint64_t entry_offset = 0;
3178*3ac0a46fSAndroid Build Coastguard Worker int value_in_entry = 0;
3179*3ac0a46fSAndroid Build Coastguard Worker uint64_t read_offset;
3180*3ac0a46fSAndroid Build Coastguard Worker uint8_t *buf_to_write = NULL;
3181*3ac0a46fSAndroid Build Coastguard Worker TIFFDataType datatype;
3182*3ac0a46fSAndroid Build Coastguard Worker
3183*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3184*3ac0a46fSAndroid Build Coastguard Worker /* Find field definition. */
3185*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3186*3ac0a46fSAndroid Build Coastguard Worker /*fip =*/TIFFFindField(tif, tag, TIFF_ANY);
3187*3ac0a46fSAndroid Build Coastguard Worker
3188*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3189*3ac0a46fSAndroid Build Coastguard Worker /* Do some checking this is a straight forward case. */
3190*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3191*3ac0a46fSAndroid Build Coastguard Worker if (isMapped(tif))
3192*3ac0a46fSAndroid Build Coastguard Worker {
3193*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(
3194*3ac0a46fSAndroid Build Coastguard Worker tif, module,
3195*3ac0a46fSAndroid Build Coastguard Worker "Memory mapped files not currently supported for this operation.");
3196*3ac0a46fSAndroid Build Coastguard Worker return 0;
3197*3ac0a46fSAndroid Build Coastguard Worker }
3198*3ac0a46fSAndroid Build Coastguard Worker
3199*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_diroff == 0)
3200*3ac0a46fSAndroid Build Coastguard Worker {
3201*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(
3202*3ac0a46fSAndroid Build Coastguard Worker tif, module,
3203*3ac0a46fSAndroid Build Coastguard Worker "Attempt to reset field on directory not already on disk.");
3204*3ac0a46fSAndroid Build Coastguard Worker return 0;
3205*3ac0a46fSAndroid Build Coastguard Worker }
3206*3ac0a46fSAndroid Build Coastguard Worker
3207*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3208*3ac0a46fSAndroid Build Coastguard Worker /* Read the directory entry count. */
3209*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3210*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, tif->tif_diroff))
3211*3ac0a46fSAndroid Build Coastguard Worker {
3212*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
3213*3ac0a46fSAndroid Build Coastguard Worker tif->tif_name);
3214*3ac0a46fSAndroid Build Coastguard Worker return 0;
3215*3ac0a46fSAndroid Build Coastguard Worker }
3216*3ac0a46fSAndroid Build Coastguard Worker
3217*3ac0a46fSAndroid Build Coastguard Worker read_offset = tif->tif_diroff;
3218*3ac0a46fSAndroid Build Coastguard Worker
3219*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
3220*3ac0a46fSAndroid Build Coastguard Worker {
3221*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, &dircount, sizeof(uint16_t)))
3222*3ac0a46fSAndroid Build Coastguard Worker {
3223*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
3224*3ac0a46fSAndroid Build Coastguard Worker tif->tif_name);
3225*3ac0a46fSAndroid Build Coastguard Worker return 0;
3226*3ac0a46fSAndroid Build Coastguard Worker }
3227*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3228*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(&dircount);
3229*3ac0a46fSAndroid Build Coastguard Worker dirsize = 12;
3230*3ac0a46fSAndroid Build Coastguard Worker read_offset += 2;
3231*3ac0a46fSAndroid Build Coastguard Worker }
3232*3ac0a46fSAndroid Build Coastguard Worker else
3233*3ac0a46fSAndroid Build Coastguard Worker {
3234*3ac0a46fSAndroid Build Coastguard Worker uint64_t dircount64;
3235*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, &dircount64, sizeof(uint64_t)))
3236*3ac0a46fSAndroid Build Coastguard Worker {
3237*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
3238*3ac0a46fSAndroid Build Coastguard Worker tif->tif_name);
3239*3ac0a46fSAndroid Build Coastguard Worker return 0;
3240*3ac0a46fSAndroid Build Coastguard Worker }
3241*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3242*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&dircount64);
3243*3ac0a46fSAndroid Build Coastguard Worker dircount = (uint16_t)dircount64;
3244*3ac0a46fSAndroid Build Coastguard Worker dirsize = 20;
3245*3ac0a46fSAndroid Build Coastguard Worker read_offset += 8;
3246*3ac0a46fSAndroid Build Coastguard Worker }
3247*3ac0a46fSAndroid Build Coastguard Worker
3248*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3249*3ac0a46fSAndroid Build Coastguard Worker /* Read through directory to find target tag. */
3250*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3251*3ac0a46fSAndroid Build Coastguard Worker while (dircount > 0)
3252*3ac0a46fSAndroid Build Coastguard Worker {
3253*3ac0a46fSAndroid Build Coastguard Worker if (!ReadOK(tif, direntry_raw, dirsize))
3254*3ac0a46fSAndroid Build Coastguard Worker {
3255*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory entry.",
3256*3ac0a46fSAndroid Build Coastguard Worker tif->tif_name);
3257*3ac0a46fSAndroid Build Coastguard Worker return 0;
3258*3ac0a46fSAndroid Build Coastguard Worker }
3259*3ac0a46fSAndroid Build Coastguard Worker
3260*3ac0a46fSAndroid Build Coastguard Worker memcpy(&entry_tag, direntry_raw + 0, sizeof(uint16_t));
3261*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3262*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(&entry_tag);
3263*3ac0a46fSAndroid Build Coastguard Worker
3264*3ac0a46fSAndroid Build Coastguard Worker if (entry_tag == tag)
3265*3ac0a46fSAndroid Build Coastguard Worker break;
3266*3ac0a46fSAndroid Build Coastguard Worker
3267*3ac0a46fSAndroid Build Coastguard Worker read_offset += dirsize;
3268*3ac0a46fSAndroid Build Coastguard Worker }
3269*3ac0a46fSAndroid Build Coastguard Worker
3270*3ac0a46fSAndroid Build Coastguard Worker if (entry_tag != tag)
3271*3ac0a46fSAndroid Build Coastguard Worker {
3272*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "%s: Could not find tag %" PRIu16 ".",
3273*3ac0a46fSAndroid Build Coastguard Worker tif->tif_name, tag);
3274*3ac0a46fSAndroid Build Coastguard Worker return 0;
3275*3ac0a46fSAndroid Build Coastguard Worker }
3276*3ac0a46fSAndroid Build Coastguard Worker
3277*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3278*3ac0a46fSAndroid Build Coastguard Worker /* Extract the type, count and offset for this entry. */
3279*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3280*3ac0a46fSAndroid Build Coastguard Worker memcpy(&entry_type, direntry_raw + 2, sizeof(uint16_t));
3281*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3282*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort(&entry_type);
3283*3ac0a46fSAndroid Build Coastguard Worker
3284*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
3285*3ac0a46fSAndroid Build Coastguard Worker {
3286*3ac0a46fSAndroid Build Coastguard Worker uint32_t value;
3287*3ac0a46fSAndroid Build Coastguard Worker
3288*3ac0a46fSAndroid Build Coastguard Worker memcpy(&value, direntry_raw + 4, sizeof(uint32_t));
3289*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3290*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&value);
3291*3ac0a46fSAndroid Build Coastguard Worker entry_count = value;
3292*3ac0a46fSAndroid Build Coastguard Worker
3293*3ac0a46fSAndroid Build Coastguard Worker memcpy(&value, direntry_raw + 8, sizeof(uint32_t));
3294*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3295*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong(&value);
3296*3ac0a46fSAndroid Build Coastguard Worker entry_offset = value;
3297*3ac0a46fSAndroid Build Coastguard Worker }
3298*3ac0a46fSAndroid Build Coastguard Worker else
3299*3ac0a46fSAndroid Build Coastguard Worker {
3300*3ac0a46fSAndroid Build Coastguard Worker memcpy(&entry_count, direntry_raw + 4, sizeof(uint64_t));
3301*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3302*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&entry_count);
3303*3ac0a46fSAndroid Build Coastguard Worker
3304*3ac0a46fSAndroid Build Coastguard Worker memcpy(&entry_offset, direntry_raw + 12, sizeof(uint64_t));
3305*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3306*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8(&entry_offset);
3307*3ac0a46fSAndroid Build Coastguard Worker }
3308*3ac0a46fSAndroid Build Coastguard Worker
3309*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3310*3ac0a46fSAndroid Build Coastguard Worker /* When a dummy tag was written due to TIFFDeferStrileArrayWriting() */
3311*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3312*3ac0a46fSAndroid Build Coastguard Worker if (entry_offset == 0 && entry_count == 0 && entry_type == 0)
3313*3ac0a46fSAndroid Build Coastguard Worker {
3314*3ac0a46fSAndroid Build Coastguard Worker if (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS)
3315*3ac0a46fSAndroid Build Coastguard Worker {
3316*3ac0a46fSAndroid Build Coastguard Worker entry_type =
3317*3ac0a46fSAndroid Build Coastguard Worker (tif->tif_flags & TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG;
3318*3ac0a46fSAndroid Build Coastguard Worker }
3319*3ac0a46fSAndroid Build Coastguard Worker else
3320*3ac0a46fSAndroid Build Coastguard Worker {
3321*3ac0a46fSAndroid Build Coastguard Worker int write_aslong8 = 1;
3322*3ac0a46fSAndroid Build Coastguard Worker if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
3323*3ac0a46fSAndroid Build Coastguard Worker {
3324*3ac0a46fSAndroid Build Coastguard Worker write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
3325*3ac0a46fSAndroid Build Coastguard Worker }
3326*3ac0a46fSAndroid Build Coastguard Worker else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
3327*3ac0a46fSAndroid Build Coastguard Worker {
3328*3ac0a46fSAndroid Build Coastguard Worker write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
3329*3ac0a46fSAndroid Build Coastguard Worker }
3330*3ac0a46fSAndroid Build Coastguard Worker if (write_aslong8)
3331*3ac0a46fSAndroid Build Coastguard Worker {
3332*3ac0a46fSAndroid Build Coastguard Worker entry_type = TIFF_LONG8;
3333*3ac0a46fSAndroid Build Coastguard Worker }
3334*3ac0a46fSAndroid Build Coastguard Worker else
3335*3ac0a46fSAndroid Build Coastguard Worker {
3336*3ac0a46fSAndroid Build Coastguard Worker int write_aslong4 = 1;
3337*3ac0a46fSAndroid Build Coastguard Worker if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
3338*3ac0a46fSAndroid Build Coastguard Worker {
3339*3ac0a46fSAndroid Build Coastguard Worker write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
3340*3ac0a46fSAndroid Build Coastguard Worker }
3341*3ac0a46fSAndroid Build Coastguard Worker else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
3342*3ac0a46fSAndroid Build Coastguard Worker {
3343*3ac0a46fSAndroid Build Coastguard Worker write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
3344*3ac0a46fSAndroid Build Coastguard Worker }
3345*3ac0a46fSAndroid Build Coastguard Worker if (write_aslong4)
3346*3ac0a46fSAndroid Build Coastguard Worker {
3347*3ac0a46fSAndroid Build Coastguard Worker entry_type = TIFF_LONG;
3348*3ac0a46fSAndroid Build Coastguard Worker }
3349*3ac0a46fSAndroid Build Coastguard Worker else
3350*3ac0a46fSAndroid Build Coastguard Worker {
3351*3ac0a46fSAndroid Build Coastguard Worker entry_type = TIFF_SHORT;
3352*3ac0a46fSAndroid Build Coastguard Worker }
3353*3ac0a46fSAndroid Build Coastguard Worker }
3354*3ac0a46fSAndroid Build Coastguard Worker }
3355*3ac0a46fSAndroid Build Coastguard Worker }
3356*3ac0a46fSAndroid Build Coastguard Worker
3357*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3358*3ac0a46fSAndroid Build Coastguard Worker /* What data type do we want to write this as? */
3359*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3360*3ac0a46fSAndroid Build Coastguard Worker if (TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags & TIFF_BIGTIFF))
3361*3ac0a46fSAndroid Build Coastguard Worker {
3362*3ac0a46fSAndroid Build Coastguard Worker if (in_datatype == TIFF_LONG8)
3363*3ac0a46fSAndroid Build Coastguard Worker datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG;
3364*3ac0a46fSAndroid Build Coastguard Worker else if (in_datatype == TIFF_SLONG8)
3365*3ac0a46fSAndroid Build Coastguard Worker datatype = TIFF_SLONG;
3366*3ac0a46fSAndroid Build Coastguard Worker else if (in_datatype == TIFF_IFD8)
3367*3ac0a46fSAndroid Build Coastguard Worker datatype = TIFF_IFD;
3368*3ac0a46fSAndroid Build Coastguard Worker else
3369*3ac0a46fSAndroid Build Coastguard Worker datatype = in_datatype;
3370*3ac0a46fSAndroid Build Coastguard Worker }
3371*3ac0a46fSAndroid Build Coastguard Worker else
3372*3ac0a46fSAndroid Build Coastguard Worker {
3373*3ac0a46fSAndroid Build Coastguard Worker if (in_datatype == TIFF_LONG8 &&
3374*3ac0a46fSAndroid Build Coastguard Worker (entry_type == TIFF_SHORT || entry_type == TIFF_LONG ||
3375*3ac0a46fSAndroid Build Coastguard Worker entry_type == TIFF_LONG8))
3376*3ac0a46fSAndroid Build Coastguard Worker datatype = entry_type;
3377*3ac0a46fSAndroid Build Coastguard Worker else if (in_datatype == TIFF_SLONG8 &&
3378*3ac0a46fSAndroid Build Coastguard Worker (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8))
3379*3ac0a46fSAndroid Build Coastguard Worker datatype = entry_type;
3380*3ac0a46fSAndroid Build Coastguard Worker else if (in_datatype == TIFF_IFD8 &&
3381*3ac0a46fSAndroid Build Coastguard Worker (entry_type == TIFF_IFD || entry_type == TIFF_IFD8))
3382*3ac0a46fSAndroid Build Coastguard Worker datatype = entry_type;
3383*3ac0a46fSAndroid Build Coastguard Worker else
3384*3ac0a46fSAndroid Build Coastguard Worker datatype = in_datatype;
3385*3ac0a46fSAndroid Build Coastguard Worker }
3386*3ac0a46fSAndroid Build Coastguard Worker
3387*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3388*3ac0a46fSAndroid Build Coastguard Worker /* Prepare buffer of actual data to write. This includes */
3389*3ac0a46fSAndroid Build Coastguard Worker /* swabbing as needed. */
3390*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3391*3ac0a46fSAndroid Build Coastguard Worker buf_to_write = (uint8_t *)_TIFFCheckMalloc(
3392*3ac0a46fSAndroid Build Coastguard Worker tif, count, TIFFDataWidth(datatype), "for field buffer.");
3393*3ac0a46fSAndroid Build Coastguard Worker if (!buf_to_write)
3394*3ac0a46fSAndroid Build Coastguard Worker return 0;
3395*3ac0a46fSAndroid Build Coastguard Worker
3396*3ac0a46fSAndroid Build Coastguard Worker if (datatype == in_datatype)
3397*3ac0a46fSAndroid Build Coastguard Worker memcpy(buf_to_write, data, count * TIFFDataWidth(datatype));
3398*3ac0a46fSAndroid Build Coastguard Worker else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8)
3399*3ac0a46fSAndroid Build Coastguard Worker {
3400*3ac0a46fSAndroid Build Coastguard Worker tmsize_t i;
3401*3ac0a46fSAndroid Build Coastguard Worker
3402*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < count; i++)
3403*3ac0a46fSAndroid Build Coastguard Worker {
3404*3ac0a46fSAndroid Build Coastguard Worker ((int32_t *)buf_to_write)[i] = (int32_t)((int64_t *)data)[i];
3405*3ac0a46fSAndroid Build Coastguard Worker if ((int64_t)((int32_t *)buf_to_write)[i] != ((int64_t *)data)[i])
3406*3ac0a46fSAndroid Build Coastguard Worker {
3407*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, buf_to_write);
3408*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
3409*3ac0a46fSAndroid Build Coastguard Worker "Value exceeds 32bit range of output type.");
3410*3ac0a46fSAndroid Build Coastguard Worker return 0;
3411*3ac0a46fSAndroid Build Coastguard Worker }
3412*3ac0a46fSAndroid Build Coastguard Worker }
3413*3ac0a46fSAndroid Build Coastguard Worker }
3414*3ac0a46fSAndroid Build Coastguard Worker else if ((datatype == TIFF_LONG && in_datatype == TIFF_LONG8) ||
3415*3ac0a46fSAndroid Build Coastguard Worker (datatype == TIFF_IFD && in_datatype == TIFF_IFD8))
3416*3ac0a46fSAndroid Build Coastguard Worker {
3417*3ac0a46fSAndroid Build Coastguard Worker tmsize_t i;
3418*3ac0a46fSAndroid Build Coastguard Worker
3419*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < count; i++)
3420*3ac0a46fSAndroid Build Coastguard Worker {
3421*3ac0a46fSAndroid Build Coastguard Worker ((uint32_t *)buf_to_write)[i] = (uint32_t)((uint64_t *)data)[i];
3422*3ac0a46fSAndroid Build Coastguard Worker if ((uint64_t)((uint32_t *)buf_to_write)[i] !=
3423*3ac0a46fSAndroid Build Coastguard Worker ((uint64_t *)data)[i])
3424*3ac0a46fSAndroid Build Coastguard Worker {
3425*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, buf_to_write);
3426*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
3427*3ac0a46fSAndroid Build Coastguard Worker "Value exceeds 32bit range of output type.");
3428*3ac0a46fSAndroid Build Coastguard Worker return 0;
3429*3ac0a46fSAndroid Build Coastguard Worker }
3430*3ac0a46fSAndroid Build Coastguard Worker }
3431*3ac0a46fSAndroid Build Coastguard Worker }
3432*3ac0a46fSAndroid Build Coastguard Worker else if (datatype == TIFF_SHORT && in_datatype == TIFF_LONG8)
3433*3ac0a46fSAndroid Build Coastguard Worker {
3434*3ac0a46fSAndroid Build Coastguard Worker tmsize_t i;
3435*3ac0a46fSAndroid Build Coastguard Worker
3436*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < count; i++)
3437*3ac0a46fSAndroid Build Coastguard Worker {
3438*3ac0a46fSAndroid Build Coastguard Worker ((uint16_t *)buf_to_write)[i] = (uint16_t)((uint64_t *)data)[i];
3439*3ac0a46fSAndroid Build Coastguard Worker if ((uint64_t)((uint16_t *)buf_to_write)[i] !=
3440*3ac0a46fSAndroid Build Coastguard Worker ((uint64_t *)data)[i])
3441*3ac0a46fSAndroid Build Coastguard Worker {
3442*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, buf_to_write);
3443*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
3444*3ac0a46fSAndroid Build Coastguard Worker "Value exceeds 16bit range of output type.");
3445*3ac0a46fSAndroid Build Coastguard Worker return 0;
3446*3ac0a46fSAndroid Build Coastguard Worker }
3447*3ac0a46fSAndroid Build Coastguard Worker }
3448*3ac0a46fSAndroid Build Coastguard Worker }
3449*3ac0a46fSAndroid Build Coastguard Worker else
3450*3ac0a46fSAndroid Build Coastguard Worker {
3451*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Unhandled type conversion.");
3452*3ac0a46fSAndroid Build Coastguard Worker return 0;
3453*3ac0a46fSAndroid Build Coastguard Worker }
3454*3ac0a46fSAndroid Build Coastguard Worker
3455*3ac0a46fSAndroid Build Coastguard Worker if (TIFFDataWidth(datatype) > 1 && (tif->tif_flags & TIFF_SWAB))
3456*3ac0a46fSAndroid Build Coastguard Worker {
3457*3ac0a46fSAndroid Build Coastguard Worker if (TIFFDataWidth(datatype) == 2)
3458*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfShort((uint16_t *)buf_to_write, count);
3459*3ac0a46fSAndroid Build Coastguard Worker else if (TIFFDataWidth(datatype) == 4)
3460*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong((uint32_t *)buf_to_write, count);
3461*3ac0a46fSAndroid Build Coastguard Worker else if (TIFFDataWidth(datatype) == 8)
3462*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabArrayOfLong8((uint64_t *)buf_to_write, count);
3463*3ac0a46fSAndroid Build Coastguard Worker }
3464*3ac0a46fSAndroid Build Coastguard Worker
3465*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3466*3ac0a46fSAndroid Build Coastguard Worker /* Is this a value that fits into the directory entry? */
3467*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3468*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
3469*3ac0a46fSAndroid Build Coastguard Worker {
3470*3ac0a46fSAndroid Build Coastguard Worker if (TIFFDataWidth(datatype) * count <= 4)
3471*3ac0a46fSAndroid Build Coastguard Worker {
3472*3ac0a46fSAndroid Build Coastguard Worker entry_offset = read_offset + 8;
3473*3ac0a46fSAndroid Build Coastguard Worker value_in_entry = 1;
3474*3ac0a46fSAndroid Build Coastguard Worker }
3475*3ac0a46fSAndroid Build Coastguard Worker }
3476*3ac0a46fSAndroid Build Coastguard Worker else
3477*3ac0a46fSAndroid Build Coastguard Worker {
3478*3ac0a46fSAndroid Build Coastguard Worker if (TIFFDataWidth(datatype) * count <= 8)
3479*3ac0a46fSAndroid Build Coastguard Worker {
3480*3ac0a46fSAndroid Build Coastguard Worker entry_offset = read_offset + 12;
3481*3ac0a46fSAndroid Build Coastguard Worker value_in_entry = 1;
3482*3ac0a46fSAndroid Build Coastguard Worker }
3483*3ac0a46fSAndroid Build Coastguard Worker }
3484*3ac0a46fSAndroid Build Coastguard Worker
3485*3ac0a46fSAndroid Build Coastguard Worker if ((tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) &&
3486*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
3487*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
3488*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0)
3489*3ac0a46fSAndroid Build Coastguard Worker {
3490*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_entry.tdir_type = datatype;
3491*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_entry.tdir_count = count;
3492*3ac0a46fSAndroid Build Coastguard Worker }
3493*3ac0a46fSAndroid Build Coastguard Worker else if ((tag == TIFFTAG_TILEBYTECOUNTS ||
3494*3ac0a46fSAndroid Build Coastguard Worker tag == TIFFTAG_STRIPBYTECOUNTS) &&
3495*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
3496*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
3497*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)
3498*3ac0a46fSAndroid Build Coastguard Worker {
3499*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
3500*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
3501*3ac0a46fSAndroid Build Coastguard Worker }
3502*3ac0a46fSAndroid Build Coastguard Worker
3503*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3504*3ac0a46fSAndroid Build Coastguard Worker /* If the tag type, and count match, then we just write it out */
3505*3ac0a46fSAndroid Build Coastguard Worker /* over the old values without altering the directory entry at */
3506*3ac0a46fSAndroid Build Coastguard Worker /* all. */
3507*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3508*3ac0a46fSAndroid Build Coastguard Worker if (entry_count == (uint64_t)count && entry_type == (uint16_t)datatype)
3509*3ac0a46fSAndroid Build Coastguard Worker {
3510*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, entry_offset))
3511*3ac0a46fSAndroid Build Coastguard Worker {
3512*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, buf_to_write);
3513*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
3514*3ac0a46fSAndroid Build Coastguard Worker "%s: Seek error accessing TIFF directory",
3515*3ac0a46fSAndroid Build Coastguard Worker tif->tif_name);
3516*3ac0a46fSAndroid Build Coastguard Worker return 0;
3517*3ac0a46fSAndroid Build Coastguard Worker }
3518*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
3519*3ac0a46fSAndroid Build Coastguard Worker {
3520*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, buf_to_write);
3521*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Error writing directory link");
3522*3ac0a46fSAndroid Build Coastguard Worker return (0);
3523*3ac0a46fSAndroid Build Coastguard Worker }
3524*3ac0a46fSAndroid Build Coastguard Worker
3525*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, buf_to_write);
3526*3ac0a46fSAndroid Build Coastguard Worker return 1;
3527*3ac0a46fSAndroid Build Coastguard Worker }
3528*3ac0a46fSAndroid Build Coastguard Worker
3529*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3530*3ac0a46fSAndroid Build Coastguard Worker /* Otherwise, we write the new tag data at the end of the file. */
3531*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3532*3ac0a46fSAndroid Build Coastguard Worker if (!value_in_entry)
3533*3ac0a46fSAndroid Build Coastguard Worker {
3534*3ac0a46fSAndroid Build Coastguard Worker entry_offset = TIFFSeekFile(tif, 0, SEEK_END);
3535*3ac0a46fSAndroid Build Coastguard Worker
3536*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
3537*3ac0a46fSAndroid Build Coastguard Worker {
3538*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, buf_to_write);
3539*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Error writing directory link");
3540*3ac0a46fSAndroid Build Coastguard Worker return (0);
3541*3ac0a46fSAndroid Build Coastguard Worker }
3542*3ac0a46fSAndroid Build Coastguard Worker }
3543*3ac0a46fSAndroid Build Coastguard Worker else
3544*3ac0a46fSAndroid Build Coastguard Worker {
3545*3ac0a46fSAndroid Build Coastguard Worker if (count * TIFFDataWidth(datatype) == 4)
3546*3ac0a46fSAndroid Build Coastguard Worker {
3547*3ac0a46fSAndroid Build Coastguard Worker uint32_t value;
3548*3ac0a46fSAndroid Build Coastguard Worker memcpy(&value, buf_to_write, count * TIFFDataWidth(datatype));
3549*3ac0a46fSAndroid Build Coastguard Worker entry_offset = value;
3550*3ac0a46fSAndroid Build Coastguard Worker }
3551*3ac0a46fSAndroid Build Coastguard Worker else
3552*3ac0a46fSAndroid Build Coastguard Worker {
3553*3ac0a46fSAndroid Build Coastguard Worker memcpy(&entry_offset, buf_to_write,
3554*3ac0a46fSAndroid Build Coastguard Worker count * TIFFDataWidth(datatype));
3555*3ac0a46fSAndroid Build Coastguard Worker }
3556*3ac0a46fSAndroid Build Coastguard Worker }
3557*3ac0a46fSAndroid Build Coastguard Worker
3558*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, buf_to_write);
3559*3ac0a46fSAndroid Build Coastguard Worker buf_to_write = 0;
3560*3ac0a46fSAndroid Build Coastguard Worker
3561*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3562*3ac0a46fSAndroid Build Coastguard Worker /* Adjust the directory entry. */
3563*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3564*3ac0a46fSAndroid Build Coastguard Worker entry_type = datatype;
3565*3ac0a46fSAndroid Build Coastguard Worker entry_count = (uint64_t)count;
3566*3ac0a46fSAndroid Build Coastguard Worker memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t));
3567*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3568*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabShort((uint16_t *)(direntry_raw + 2));
3569*3ac0a46fSAndroid Build Coastguard Worker
3570*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_BIGTIFF))
3571*3ac0a46fSAndroid Build Coastguard Worker {
3572*3ac0a46fSAndroid Build Coastguard Worker uint32_t value;
3573*3ac0a46fSAndroid Build Coastguard Worker
3574*3ac0a46fSAndroid Build Coastguard Worker value = (uint32_t)entry_count;
3575*3ac0a46fSAndroid Build Coastguard Worker memcpy(direntry_raw + 4, &value, sizeof(uint32_t));
3576*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3577*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)(direntry_raw + 4));
3578*3ac0a46fSAndroid Build Coastguard Worker
3579*3ac0a46fSAndroid Build Coastguard Worker value = (uint32_t)entry_offset;
3580*3ac0a46fSAndroid Build Coastguard Worker memcpy(direntry_raw + 8, &value, sizeof(uint32_t));
3581*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3582*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong((uint32_t *)(direntry_raw + 8));
3583*3ac0a46fSAndroid Build Coastguard Worker }
3584*3ac0a46fSAndroid Build Coastguard Worker else
3585*3ac0a46fSAndroid Build Coastguard Worker {
3586*3ac0a46fSAndroid Build Coastguard Worker memcpy(direntry_raw + 4, &entry_count, sizeof(uint64_t));
3587*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3588*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)(direntry_raw + 4));
3589*3ac0a46fSAndroid Build Coastguard Worker
3590*3ac0a46fSAndroid Build Coastguard Worker memcpy(direntry_raw + 12, &entry_offset, sizeof(uint64_t));
3591*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_SWAB)
3592*3ac0a46fSAndroid Build Coastguard Worker TIFFSwabLong8((uint64_t *)(direntry_raw + 12));
3593*3ac0a46fSAndroid Build Coastguard Worker }
3594*3ac0a46fSAndroid Build Coastguard Worker
3595*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3596*3ac0a46fSAndroid Build Coastguard Worker /* Write the directory entry out to disk. */
3597*3ac0a46fSAndroid Build Coastguard Worker /* -------------------------------------------------------------------- */
3598*3ac0a46fSAndroid Build Coastguard Worker if (!SeekOK(tif, read_offset))
3599*3ac0a46fSAndroid Build Coastguard Worker {
3600*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
3601*3ac0a46fSAndroid Build Coastguard Worker tif->tif_name);
3602*3ac0a46fSAndroid Build Coastguard Worker return 0;
3603*3ac0a46fSAndroid Build Coastguard Worker }
3604*3ac0a46fSAndroid Build Coastguard Worker
3605*3ac0a46fSAndroid Build Coastguard Worker if (!WriteOK(tif, direntry_raw, dirsize))
3606*3ac0a46fSAndroid Build Coastguard Worker {
3607*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "%s: Can not write TIFF directory entry.",
3608*3ac0a46fSAndroid Build Coastguard Worker tif->tif_name);
3609*3ac0a46fSAndroid Build Coastguard Worker return 0;
3610*3ac0a46fSAndroid Build Coastguard Worker }
3611*3ac0a46fSAndroid Build Coastguard Worker
3612*3ac0a46fSAndroid Build Coastguard Worker return 1;
3613*3ac0a46fSAndroid Build Coastguard Worker }
3614