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