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