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