LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_dirwrite.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 846 1561 54.2 %
Date: 2024-05-03 15:49:35 Functions: 40 72 55.6 %

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

Generated by: LCOV version 1.14