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