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