]> git.saurik.com Git - wxWidgets.git/blobdiff - src/tiff/libtiff/tif_dirwrite.c
Reflect changes in stc.cpp in stc.cpp.in from which it's generated.
[wxWidgets.git] / src / tiff / libtiff / tif_dirwrite.c
index b5d888b3e1717bef3bd03b5a1bc96509d17978b8..8c44d4c7c2f046db5770198741bee88f43a0240c 100644 (file)
@@ -1,26 +1,25 @@
-/* $Id$ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  *
- * Permission to use, copy, modify, distribute, and sell this software and 
+ * Permission to use, copy, modify, distribute, and sell this software and
  * its documentation for any purpose is hereby granted without fee, provided
  * that (i) the above copyright notices and this permission notice appear in
  * all copies of the software and related documentation, and (ii) the names of
  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  * publicity relating to the software without the specific, prior written
  * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  * OF THIS SOFTWARE.
  */
 
 #include "tiffiop.h"
 
 #ifdef HAVE_IEEEFP
-# define       TIFFCvtNativeToIEEEFloat(tif, n, fp)
-# define       TIFFCvtNativeToIEEEDouble(tif, n, dp)
+#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
+#define TIFFCvtNativeToIEEEDouble(tif, n, dp)
 #else
-extern void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
-extern void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
+extern void TIFFCvtNativeToIEEEFloat(TIFF* tif, uint32 n, float* fp);
+extern void TIFFCvtNativeToIEEEDouble(TIFF* tif, uint32 n, double* dp);
 #endif
 
-static int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
-static void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
-static void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16);
-static int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
-static int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
-static int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
-static int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
-static int TIFFWriteShortArray(TIFF*, TIFFDirEntry*, uint16*);
-static int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*);
-static int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*);
-static int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*);
-static int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*);
-static int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
-static int TIFFWriteAnyArray(TIFF*,
-           TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
-static int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
-static int TIFFWriteInkNames(TIFF*, TIFFDirEntry*);
-static int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
-static int TIFFLinkDirectory(TIFF*);
-
-#define        WriteRationalPair(type, tag1, v1, tag2, v2) {           \
-       TIFFWriteRational((tif), (type), (tag1), (dir), (v1))   \
-       TIFFWriteRational((tif), (type), (tag2), (dir)+1, (v2)) \
-       (dir)++;                                                \
-}
-#define        TIFFWriteRational(tif, type, tag, dir, v)               \
-       (dir)->tdir_tag = (tag);                                \
-       (dir)->tdir_type = (type);                              \
-       (dir)->tdir_count = 1;                                  \
-       if (!TIFFWriteRationalArray((tif), (dir), &(v)))        \
-               goto bad;
+static int TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff);
+
+static int TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+#if 0
+static int TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+#endif
+
+static int TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value);
+static int TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
+#endif
+static int TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
+#if 0
+static int TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
+#endif
+#ifdef notdef
+static int TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
+#endif
+static int TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value);
+#if 0
+static int TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
+#endif
+static int TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
+static int TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value);
+static int TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
+#endif
+static int TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value);
+#if 0
+static int TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
+#endif
+static int TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
+static int TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
+#if 0
+static int TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
+#endif
+#ifdef notdef
+static int TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
+#endif
+static int TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value);
+#if 0
+static int TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
+#endif
+#ifdef notdef
+static int TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value);
+#endif
+static int TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value);
+#endif
+static int TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value);
+static int TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+static int TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+static int TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
+#endif
+static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+#if 0
+static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
+#endif
+#ifdef notdef
+static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+#endif
+static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+#if 0
+static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+#endif
+static int TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#endif
+static int TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
+static int TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#endif
+static int TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
+static int TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
+static int TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
+
+static int TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value);
+static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value);
+static int TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
+static int TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value);
+static int TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
+static int TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value);
+static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
+#endif
+static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+#endif
+static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
+static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+
+static int TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data);
+
+static int TIFFLinkDirectory(TIFF*);
 
 /*
  * Write the contents of the current directory
@@ -77,339 +176,10 @@ static    int TIFFLinkDirectory(TIFF*);
  * handle overwriting a directory with auxiliary
  * storage that's been changed.
  */
-static int
-_TIFFWriteDirectory(TIFF* tif, int done)
-{
-       uint16 dircount;
-       toff_t diroff;
-       ttag_t tag;
-       uint32 nfields;
-       tsize_t dirsize;
-       char* data;
-       TIFFDirEntry* dir;
-       TIFFDirectory* td;
-       unsigned long b, fields[FIELD_SETLONGS];
-       int fi, nfi;
-
-       if (tif->tif_mode == O_RDONLY)
-               return (1);
-       /*
-        * Clear write state so that subsequent images with
-        * different characteristics get the right buffers
-        * setup for them.
-        */
-       if (done)
-       {
-           if (tif->tif_flags & TIFF_POSTENCODE) {
-                   tif->tif_flags &= ~TIFF_POSTENCODE;
-                   if (!(*tif->tif_postencode)(tif)) {
-                               TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                               "Error post-encoding before directory write");
-                           return (0);
-                   }
-           }
-           (*tif->tif_close)(tif);             /* shutdown encoder */
-           /*
-            * Flush any data that might have been written
-            * by the compression close+cleanup routines.
-            */
-           if (tif->tif_rawcc > 0 && !TIFFFlushData1(tif)) {
-                       TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                       "Error flushing data before directory write");
-                   return (0);
-           }
-           if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
-                   _TIFFfree(tif->tif_rawdata);
-                   tif->tif_rawdata = NULL;
-                   tif->tif_rawcc = 0;
-                   tif->tif_rawdatasize = 0;
-           }
-           tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
-       }
-
-       td = &tif->tif_dir;
-       /*
-        * Size the directory so that we can calculate
-        * offsets for the data items that aren't kept
-        * in-place in each field.
-        */
-       nfields = 0;
-       for (b = 0; b <= FIELD_LAST; b++)
-               if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
-                       nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
-        nfields += td->td_customValueCount;
-       dirsize = nfields * sizeof (TIFFDirEntry);
-       data = (char*) _TIFFmalloc(dirsize);
-       if (data == NULL) {
-               TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                   "Cannot write directory, out of space");
-               return (0);
-       }
-       /*
-        * Directory hasn't been placed yet, put
-        * it at the end of the file and link it
-        * into the existing directory structure.
-        */
-       if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
-               goto bad;
-       tif->tif_dataoff = (toff_t)(
-           tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
-       if (tif->tif_dataoff & 1)
-               tif->tif_dataoff++;
-       (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
-       tif->tif_curdir++;
-       dir = (TIFFDirEntry*) data;
-       /*
-        * Setup external form of directory
-        * entries and write data items.
-        */
-       _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
-       /*
-        * Write out ExtraSamples tag only if
-        * extra samples are present in the data.
-        */
-       if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) {
-               ResetFieldBit(fields, FIELD_EXTRASAMPLES);
-               nfields--;
-               dirsize -= sizeof (TIFFDirEntry);
-       }                                                               /*XXX*/
-       for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
-               const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
-
-                /*
-                ** For custom fields, we test to see if the custom field
-                ** is set or not.  For normal fields, we just use the
-                ** FieldSet test. 
-                */
-                if( fip->field_bit == FIELD_CUSTOM )
-                {
-                    int ci, is_set = FALSE;
-
-                    for( ci = 0; ci < td->td_customValueCount; ci++ )
-                        is_set |= (td->td_customValues[ci].info == fip);
-
-                    if( !is_set )
-                        continue;
-                }
-               else if (!FieldSet(fields, fip->field_bit))
-                    continue;
-
-
-                /*
-                ** Handle other fields.
-                */
-               switch (fip->field_bit)
-                {
-               case FIELD_STRIPOFFSETS:
-                       /*
-                        * We use one field bit for both strip and tile
-
-                        * offsets, and so must be careful in selecting
-                        * the appropriate field descriptor (so that tags
-                        * are written in sorted order).
-                        */
-                       tag = isTiled(tif) ?
-                           TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
-                       if (tag != fip->field_tag)
-                               continue;
-                       
-                       dir->tdir_tag = (uint16) tag;
-                       dir->tdir_type = (uint16) TIFF_LONG;
-                       dir->tdir_count = (uint32) td->td_nstrips;
-                       if (!TIFFWriteLongArray(tif, dir, td->td_stripoffset))
-                               goto bad;
-                       break;
-               case FIELD_STRIPBYTECOUNTS:
-                       /*
-                        * We use one field bit for both strip and tile
-                        * byte counts, and so must be careful in selecting
-                        * the appropriate field descriptor (so that tags
-                        * are written in sorted order).
-                        */
-                       tag = isTiled(tif) ?
-                           TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
-                       if (tag != fip->field_tag)
-                               continue;
-                       
-                       dir->tdir_tag = (uint16) tag;
-                       dir->tdir_type = (uint16) TIFF_LONG;
-                       dir->tdir_count = (uint32) td->td_nstrips;
-                       if (!TIFFWriteLongArray(tif, dir,
-                                               td->td_stripbytecount))
-                               goto bad;
-                       break;
-               case FIELD_ROWSPERSTRIP:
-                       TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
-                           dir, td->td_rowsperstrip);
-                       break;
-               case FIELD_COLORMAP:
-                       if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
-                           3, td->td_colormap))
-                               goto bad;
-                       break;
-               case FIELD_IMAGEDIMENSIONS:
-                       TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
-                           dir++, td->td_imagewidth);
-                       TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
-                           dir, td->td_imagelength);
-                       break;
-               case FIELD_TILEDIMENSIONS:
-                       TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
-                           dir++, td->td_tilewidth);
-                       TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
-                           dir, td->td_tilelength);
-                       break;
-               case FIELD_COMPRESSION:
-                       TIFFSetupShort(tif, TIFFTAG_COMPRESSION,
-                           dir, td->td_compression);
-                       break;
-               case FIELD_PHOTOMETRIC:
-                       TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC,
-                           dir, td->td_photometric);
-                       break;
-               case FIELD_POSITION:
-                       WriteRationalPair(TIFF_RATIONAL,
-                           TIFFTAG_XPOSITION, td->td_xposition,
-                           TIFFTAG_YPOSITION, td->td_yposition);
-                       break;
-               case FIELD_RESOLUTION:
-                       WriteRationalPair(TIFF_RATIONAL,
-                           TIFFTAG_XRESOLUTION, td->td_xresolution,
-                           TIFFTAG_YRESOLUTION, td->td_yresolution);
-                       break;
-               case FIELD_BITSPERSAMPLE:
-               case FIELD_MINSAMPLEVALUE:
-               case FIELD_MAXSAMPLEVALUE:
-               case FIELD_SAMPLEFORMAT:
-                       if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
-                               goto bad;
-                       break;
-               case FIELD_SMINSAMPLEVALUE:
-               case FIELD_SMAXSAMPLEVALUE:
-                       if (!TIFFWritePerSampleAnys(tif,
-                           _TIFFSampleToTagType(tif), fip->field_tag, dir))
-                               goto bad;
-                       break;
-               case FIELD_PAGENUMBER:
-               case FIELD_HALFTONEHINTS:
-               case FIELD_YCBCRSUBSAMPLING:
-                       if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
-                               goto bad;
-                       break;
-               case FIELD_INKNAMES:
-                       if (!TIFFWriteInkNames(tif, dir))
-                               goto bad;
-                       break;
-               case FIELD_TRANSFERFUNCTION:
-                       if (!TIFFWriteTransferFunction(tif, dir))
-                               goto bad;
-                       break;
-               case FIELD_SUBIFD:
-                       /*
-                        * XXX: Always write this field using LONG type
-                        * for backward compatibility.
-                        */
-                       dir->tdir_tag = (uint16) fip->field_tag;
-                       dir->tdir_type = (uint16) TIFF_LONG;
-                       dir->tdir_count = (uint32) td->td_nsubifd;
-                       if (!TIFFWriteLongArray(tif, dir, td->td_subifd))
-                               goto bad;
-                       /*
-                        * Total hack: if this directory includes a SubIFD
-                        * tag then force the next <n> directories to be
-                        * written as ``sub directories'' of this one.  This
-                        * is used to write things like thumbnails and
-                        * image masks that one wants to keep out of the
-                        * normal directory linkage access mechanism.
-                        */
-                       if (dir->tdir_count > 0) {
-                               tif->tif_flags |= TIFF_INSUBIFD;
-                               tif->tif_nsubifd = (uint16) dir->tdir_count;
-                               if (dir->tdir_count > 1)
-                                       tif->tif_subifdoff = dir->tdir_offset;
-                               else
-                                       tif->tif_subifdoff = (uint32)(
-                                             tif->tif_diroff
-                                           + sizeof (uint16)
-                                           + ((char*)&dir->tdir_offset-data));
-                       }
-                       break;
-               default:
-                       /* XXX: Should be fixed and removed. */
-                       if (fip->field_tag == TIFFTAG_DOTRANGE) {
-                               if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
-                                       goto bad;
-                       }
-                       else if (!TIFFWriteNormalTag(tif, dir, fip))
-                               goto bad;
-                       break;
-               }
-               dir++;
-                
-                if( fip->field_bit != FIELD_CUSTOM )
-                    ResetFieldBit(fields, fip->field_bit);
-       }
-
-       /*
-        * Write directory.
-        */
-       dircount = (uint16) nfields;
-       diroff = (uint32) tif->tif_nextdiroff;
-       if (tif->tif_flags & TIFF_SWAB) {
-               /*
-                * The file's byte order is opposite to the
-                * native machine architecture.  We overwrite
-                * the directory information with impunity
-                * because it'll be released below after we
-                * write it to the file.  Note that all the
-                * other tag construction routines assume that
-                * we do this byte-swapping; i.e. they only
-                * byte-swap indirect data.
-                */
-               for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
-                       TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
-                       TIFFSwabArrayOfLong(&dir->tdir_count, 2);
-               }
-               dircount = (uint16) nfields;
-               TIFFSwabShort(&dircount);
-               TIFFSwabLong(&diroff);
-       }
-       (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
-       if (!WriteOK(tif, &dircount, sizeof (dircount))) {
-               TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing directory count");
-               goto bad;
-       }
-       if (!WriteOK(tif, data, dirsize)) {
-               TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing directory contents");
-               goto bad;
-       }
-       if (!WriteOK(tif, &diroff, sizeof (diroff))) {
-               TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing directory link");
-               goto bad;
-       }
-       if (done) {
-               TIFFFreeDirectory(tif);
-               tif->tif_flags &= ~TIFF_DIRTYDIRECT;
-               (*tif->tif_cleanup)(tif);
-
-               /*
-               * Reset directory-related state for subsequent
-               * directories.
-               */
-               TIFFCreateDirectory(tif);
-       }
-       _TIFFfree(data);
-       return (1);
-bad:
-       _TIFFfree(data);
-       return (0);
-}
-#undef WriteRationalPair
-
 int
 TIFFWriteDirectory(TIFF* tif)
 {
-       return _TIFFWriteDirectory(tif, TRUE);
+       return TIFFWriteDirectorySec(tif,TRUE,TRUE,NULL);
 }
 
 /*
@@ -417,7 +187,7 @@ TIFFWriteDirectory(TIFF* tif)
  * but leaves all data structures in memory so that it can be
  * written again.  This will make a partially written TIFF file
  * readable before it is successfully completed/closed.
- */ 
+ */
 int
 TIFFCheckpointDirectory(TIFF* tif)
 {
@@ -425,819 +195,2715 @@ TIFFCheckpointDirectory(TIFF* tif)
        /* Setup the strips arrays, if they haven't already been. */
        if (tif->tif_dir.td_stripoffset == NULL)
            (void) TIFFSetupStrips(tif);
-       rc = _TIFFWriteDirectory(tif, FALSE);
+       rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL);
        (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
        return rc;
 }
 
+int
+TIFFWriteCustomDirectory(TIFF* tif, uint64* pdiroff)
+{
+       return TIFFWriteDirectorySec(tif,FALSE,FALSE,pdiroff);
+}
+
 /*
- * Process tags that are not special cased.
- */
-static int
-TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip)
-{
-       uint16 wc = (uint16) fip->field_writecount;
-       uint32 wc2;
-
-       dir->tdir_tag = (uint16) fip->field_tag;
-       dir->tdir_type = (uint16) fip->field_type;
-       dir->tdir_count = wc;
-       
-       switch (fip->field_type) {
-       case TIFF_SHORT:
-       case TIFF_SSHORT:
-               if (fip->field_passcount) {
-                       uint16* wp;
-                       if (wc == (uint16) TIFF_VARIABLE2) {
-                               TIFFGetField(tif, fip->field_tag, &wc2, &wp);
-                               dir->tdir_count = wc2;
-                       } else {        /* Assume TIFF_VARIABLE */
-                               TIFFGetField(tif, fip->field_tag, &wc, &wp);
-                               dir->tdir_count = wc;
-                       }
-                       if (!TIFFWriteShortArray(tif, dir, wp))
-                               return 0;
-               } else {
-                       if (wc == 1) {
-                               uint16 sv;
-                               TIFFGetField(tif, fip->field_tag, &sv);
-                               dir->tdir_offset =
-                                       TIFFInsertData(tif, dir->tdir_type, sv);
-                       } else {
-                               uint16* wp;
-                               TIFFGetField(tif, fip->field_tag, &wp);
-                               if (!TIFFWriteShortArray(tif, dir, wp))
-                                       return 0;
-                       }
-               }
-               break;
-       case TIFF_LONG:
-       case TIFF_SLONG:
-       case TIFF_IFD:
-               if (fip->field_passcount) {
-                       uint32* lp;
-                       if (wc == (uint16) TIFF_VARIABLE2) {
-                               TIFFGetField(tif, fip->field_tag, &wc2, &lp);
-                               dir->tdir_count = wc2;
-                       } else {        /* Assume TIFF_VARIABLE */
-                               TIFFGetField(tif, fip->field_tag, &wc, &lp);
-                               dir->tdir_count = wc;
-                       }
-                       if (!TIFFWriteLongArray(tif, dir, lp))
-                               return 0;
-               } else {
-                       if (wc == 1) {
-                               /* XXX handle LONG->SHORT conversion */
-                               TIFFGetField(tif, fip->field_tag,
-                                            &dir->tdir_offset);
-                       } else {
-                               uint32* lp;
-                               TIFFGetField(tif, fip->field_tag, &lp);
-                               if (!TIFFWriteLongArray(tif, dir, lp))
-                                       return 0;
-                       }
-               }
-               break;
-       case TIFF_RATIONAL:
-       case TIFF_SRATIONAL:
-               if (fip->field_passcount) {
-                       float* fp;
-                       if (wc == (uint16) TIFF_VARIABLE2) {
-                               TIFFGetField(tif, fip->field_tag, &wc2, &fp);
-                               dir->tdir_count = wc2;
-                       } else {        /* Assume TIFF_VARIABLE */
-                               TIFFGetField(tif, fip->field_tag, &wc, &fp);
-                               dir->tdir_count = wc;
-                       }
-                       if (!TIFFWriteRationalArray(tif, dir, fp))
-                               return 0;
-               } else {
-                       if (wc == 1) {
-                               float fv;
-                               TIFFGetField(tif, fip->field_tag, &fv);
-                               if (!TIFFWriteRationalArray(tif, dir, &fv))
-                                       return 0;
-                       } else {
-                               float* fp;
-                               TIFFGetField(tif, fip->field_tag, &fp);
-                               if (!TIFFWriteRationalArray(tif, dir, fp))
-                                       return 0;
+ * Similar to TIFFWriteDirectory(), but if the directory has already
+ * been written once, it is relocated to the end of the file, in case it
+ * has changed in size.  Note that this will result in the loss of the
+ * previously used directory space. 
+ */ 
+int
+TIFFRewriteDirectory( TIFF *tif )
+{
+       static const char module[] = "TIFFRewriteDirectory";
+
+       /* We don't need to do anything special if it hasn't been written. */
+       if( tif->tif_diroff == 0 )
+               return TIFFWriteDirectory( tif );
+
+       /*
+        * Find and zero the pointer to this directory, so that TIFFLinkDirectory
+        * will cause it to be added after this directories current pre-link.
+        */
+
+       if (!(tif->tif_flags&TIFF_BIGTIFF))
+       {
+               if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
+               {
+                       tif->tif_header.classic.tiff_diroff = 0;
+                       tif->tif_diroff = 0;
+
+                       TIFFSeekFile(tif,4,SEEK_SET);
+                       if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff),4))
+                       {
+                               TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+                                   "Error updating TIFF header");
+                               return (0);
                        }
                }
-               break;
-       case TIFF_FLOAT:
-               if (fip->field_passcount) {
-                       float* fp;
-                       if (wc == (uint16) TIFF_VARIABLE2) {
-                               TIFFGetField(tif, fip->field_tag, &wc2, &fp);
-                               dir->tdir_count = wc2;
-                       } else {        /* Assume TIFF_VARIABLE */
-                               TIFFGetField(tif, fip->field_tag, &wc, &fp);
-                               dir->tdir_count = wc;
-                       }
-                       if (!TIFFWriteFloatArray(tif, dir, fp))
-                               return 0;
-               } else {
-                       if (wc == 1) {
-                               float fv;
-                               TIFFGetField(tif, fip->field_tag, &fv);
-                               if (!TIFFWriteFloatArray(tif, dir, &fv))
-                                       return 0;
-                       } else {
-                               float* fp;
-                               TIFFGetField(tif, fip->field_tag, &fp);
-                               if (!TIFFWriteFloatArray(tif, dir, fp))
-                                       return 0;
+               else
+               {
+                       uint32 nextdir;
+                       nextdir = tif->tif_header.classic.tiff_diroff;
+                       while(1) {
+                               uint16 dircount;
+                               uint32 nextnextdir;
+
+                               if (!SeekOK(tif, nextdir) ||
+                                   !ReadOK(tif, &dircount, 2)) {
+                                       TIFFErrorExt(tif->tif_clientdata, module,
+                                            "Error fetching directory count");
+                                       return (0);
+                               }
+                               if (tif->tif_flags & TIFF_SWAB)
+                                       TIFFSwabShort(&dircount);
+                               (void) TIFFSeekFile(tif,
+                                   nextdir+2+dircount*12, SEEK_SET);
+                               if (!ReadOK(tif, &nextnextdir, 4)) {
+                                       TIFFErrorExt(tif->tif_clientdata, module,
+                                            "Error fetching directory link");
+                                       return (0);
+                               }
+                               if (tif->tif_flags & TIFF_SWAB)
+                                       TIFFSwabLong(&nextnextdir);
+                               if (nextnextdir==tif->tif_diroff)
+                               {
+                                       uint32 m;
+                                       m=0;
+                                       (void) TIFFSeekFile(tif,
+                                           nextdir+2+dircount*12, SEEK_SET);
+                                       if (!WriteOK(tif, &m, 4)) {
+                                               TIFFErrorExt(tif->tif_clientdata, module,
+                                                    "Error writing directory link");
+                                               return (0);
+                                       }
+                                       tif->tif_diroff=0;
+                                       break;
+                               }
+                               nextdir=nextnextdir;
                        }
                }
-               break;
-       case TIFF_DOUBLE:
-               if (fip->field_passcount) {
-                       double* dp;
-                       if (wc == (uint16) TIFF_VARIABLE2) {
-                               TIFFGetField(tif, fip->field_tag, &wc2, &dp);
-                               dir->tdir_count = wc2;
-                       } else {        /* Assume TIFF_VARIABLE */
-                               TIFFGetField(tif, fip->field_tag, &wc, &dp);
-                               dir->tdir_count = wc;
-                       }
-                       if (!TIFFWriteDoubleArray(tif, dir, dp))
-                               return 0;
-               } else {
-                       if (wc == 1) {
-                               double dv;
-                               TIFFGetField(tif, fip->field_tag, &dv);
-                               if (!TIFFWriteDoubleArray(tif, dir, &dv))
-                                       return 0;
-                       } else {
-                               double* dp;
-                               TIFFGetField(tif, fip->field_tag, &dp);
-                               if (!TIFFWriteDoubleArray(tif, dir, dp))
-                                       return 0;
+       }
+       else
+       {
+               if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
+               {
+                       tif->tif_header.big.tiff_diroff = 0;
+                       tif->tif_diroff = 0;
+
+                       TIFFSeekFile(tif,8,SEEK_SET);
+                       if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff),8))
+                       {
+                               TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+                                   "Error updating TIFF header");
+                               return (0);
                        }
                }
-               break;
-       case TIFF_ASCII:
-               { 
-                    char* cp;
-                    if (fip->field_passcount)
-                        TIFFGetField(tif, fip->field_tag, &wc, &cp);
-                    else
-                        TIFFGetField(tif, fip->field_tag, &cp);
-
-                    dir->tdir_count = (uint32) (strlen(cp) + 1);
-                    if (!TIFFWriteByteArray(tif, dir, cp))
-                        return (0);
-               }
-               break;
-
-        case TIFF_BYTE:
-        case TIFF_SBYTE:          
-               if (fip->field_passcount) {
-                       char* cp;
-                       if (wc == (uint16) TIFF_VARIABLE2) {
-                               TIFFGetField(tif, fip->field_tag, &wc2, &cp);
-                               dir->tdir_count = wc2;
-                       } else {        /* Assume TIFF_VARIABLE */
-                               TIFFGetField(tif, fip->field_tag, &wc, &cp);
-                               dir->tdir_count = wc;
-                       }
-                       if (!TIFFWriteByteArray(tif, dir, cp))
-                               return 0;
-               } else {
-                       if (wc == 1) {
-                               char cv;
-                               TIFFGetField(tif, fip->field_tag, &cv);
-                               if (!TIFFWriteByteArray(tif, dir, &cv))
-                                       return 0;
-                       } else {
-                               char* cp;
-                               TIFFGetField(tif, fip->field_tag, &cp);
-                               if (!TIFFWriteByteArray(tif, dir, cp))
-                                       return 0;
+               else
+               {
+                       uint64 nextdir;
+                       nextdir = tif->tif_header.big.tiff_diroff;
+                       while(1) {
+                               uint64 dircount64;
+                               uint16 dircount;
+                               uint64 nextnextdir;
+
+                               if (!SeekOK(tif, nextdir) ||
+                                   !ReadOK(tif, &dircount64, 8)) {
+                                       TIFFErrorExt(tif->tif_clientdata, module,
+                                            "Error fetching directory count");
+                                       return (0);
+                               }
+                               if (tif->tif_flags & TIFF_SWAB)
+                                       TIFFSwabLong8(&dircount64);
+                               if (dircount64>0xFFFF)
+                               {
+                                       TIFFErrorExt(tif->tif_clientdata, module,
+                                            "Sanity check on tag count failed, likely corrupt TIFF");
+                                       return (0);
+                               }
+                               dircount=(uint16)dircount64;
+                               (void) TIFFSeekFile(tif,
+                                   nextdir+8+dircount*20, SEEK_SET);
+                               if (!ReadOK(tif, &nextnextdir, 8)) {
+                                       TIFFErrorExt(tif->tif_clientdata, module,
+                                            "Error fetching directory link");
+                                       return (0);
+                               }
+                               if (tif->tif_flags & TIFF_SWAB)
+                                       TIFFSwabLong8(&nextnextdir);
+                               if (nextnextdir==tif->tif_diroff)
+                               {
+                                       uint64 m;
+                                       m=0;
+                                       (void) TIFFSeekFile(tif,
+                                           nextdir+8+dircount*20, SEEK_SET);
+                                       if (!WriteOK(tif, &m, 8)) {
+                                               TIFFErrorExt(tif->tif_clientdata, module,
+                                                    "Error writing directory link");
+                                               return (0);
+                                       }
+                                       tif->tif_diroff=0;
+                                       break;
+                               }
+                               nextdir=nextnextdir;
                        }
                }
-                break;
-
-       case TIFF_UNDEFINED:
-               { char* cp;
-                 if (wc == (unsigned short) TIFF_VARIABLE) {
-                       TIFFGetField(tif, fip->field_tag, &wc, &cp);
-                       dir->tdir_count = wc;
-                 } else if (wc == (unsigned short) TIFF_VARIABLE2) {
-                       TIFFGetField(tif, fip->field_tag, &wc2, &cp);
-                       dir->tdir_count = wc2;
-                 } else 
-                       TIFFGetField(tif, fip->field_tag, &cp);
-                 if (!TIFFWriteByteArray(tif, dir, cp))
-                       return (0);
-               }
-               break;
-
-        case TIFF_NOTYPE:
-                break;
        }
-       return (1);
-}
 
-/*
- * Setup a directory entry with either a SHORT
- * or LONG type according to the value.
- */
-static void
-TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
-{
-       dir->tdir_tag = (uint16) tag;
-       dir->tdir_count = 1;
-       if (v > 0xffffL) {
-               dir->tdir_type = (short) TIFF_LONG;
-               dir->tdir_offset = v;
-       } else {
-               dir->tdir_type = (short) TIFF_SHORT;
-               dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
-       }
-}
+       /*
+        * Now use TIFFWriteDirectory() normally.
+        */
 
-/*
- * Setup a SHORT directory entry
- */
-static void
-TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v)
-{
-       dir->tdir_tag = (uint16) tag;
-       dir->tdir_count = 1;
-       dir->tdir_type = (short) TIFF_SHORT;
-       dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
+       return TIFFWriteDirectory( tif );
 }
-#undef MakeShortDirent
 
-#define        NITEMS(x)       (sizeof (x) / sizeof (x[0]))
-/*
- * Setup a directory entry that references a
- * samples/pixel array of SHORT values and
- * (potentially) write the associated indirect
- * values.
- */
 static int
-TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
+TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
 {
-       uint16 buf[10], v;
-       uint16* w = buf;
-       uint16 i, samples = tif->tif_dir.td_samplesperpixel;
-       int status;
+       static const char module[] = "TIFFWriteDirectorySec";
+       uint32 ndir;
+       TIFFDirEntry* dir;
+       uint32 dirsize;
+       void* dirmem;
+       uint32 m;
+       if (tif->tif_mode == O_RDONLY)
+               return (1);
 
-       if (samples > NITEMS(buf)) {
-               w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
-               if (w == NULL) {
-                       TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                           "No space to write per-sample shorts");
+        _TIFFFillStriles( tif );
+        
+       /*
+        * Clear write state so that subsequent images with
+        * different characteristics get the right buffers
+        * setup for them.
+        */
+       if (imagedone)
+       {
+               if (tif->tif_flags & TIFF_POSTENCODE)
+               {
+                       tif->tif_flags &= ~TIFF_POSTENCODE;
+                       if (!(*tif->tif_postencode)(tif))
+                       {
+                               TIFFErrorExt(tif->tif_clientdata,module,
+                                   "Error post-encoding before directory write");
+                               return (0);
+                       }
+               }
+               (*tif->tif_close)(tif);       /* shutdown encoder */
+               /*
+                * Flush any data that might have been written
+                * by the compression close+cleanup routines.  But
+                 * be careful not to write stuff if we didn't add data
+                 * in the previous steps as the "rawcc" data may well be
+                 * a previously read tile/strip in mixed read/write mode.
+                */
+               if (tif->tif_rawcc > 0 
+                   && (tif->tif_flags & TIFF_BEENWRITING) != 0 )
+               {
+                   if( !TIFFFlushData1(tif) )
+                    {
+                       TIFFErrorExt(tif->tif_clientdata, module,
+                           "Error flushing data before directory write");
                        return (0);
+                    }
+               }
+               if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
+               {
+                       _TIFFfree(tif->tif_rawdata);
+                       tif->tif_rawdata = NULL;
+                       tif->tif_rawcc = 0;
+                       tif->tif_rawdatasize = 0;
+                        tif->tif_rawdataoff = 0;
+                        tif->tif_rawdataloaded = 0;
+               }
+               tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
+       }
+       dir=NULL;
+       dirmem=NULL;
+       dirsize=0;
+       while (1)
+       {
+               ndir=0;
+               if (isimage)
+               {
+                       if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
+                       {
+                               if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGEWIDTH,tif->tif_dir.td_imagewidth))
+                                       goto bad;
+                               if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGELENGTH,tif->tif_dir.td_imagelength))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS))
+                       {
+                               if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILEWIDTH,tif->tif_dir.td_tilewidth))
+                                       goto bad;
+                               if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILELENGTH,tif->tif_dir.td_tilelength))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_RESOLUTION))
+                       {
+                               if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XRESOLUTION,tif->tif_dir.td_xresolution))
+                                       goto bad;
+                               if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YRESOLUTION,tif->tif_dir.td_yresolution))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_POSITION))
+                       {
+                               if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XPOSITION,tif->tif_dir.td_xposition))
+                                       goto bad;
+                               if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YPOSITION,tif->tif_dir.td_yposition))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_SUBFILETYPE))
+                       {
+                               if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_SUBFILETYPE,tif->tif_dir.td_subfiletype))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
+                       {
+                               if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_BITSPERSAMPLE,tif->tif_dir.td_bitspersample))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_COMPRESSION))
+                       {
+                               if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_COMPRESSION,tif->tif_dir.td_compression))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
+                       {
+                               if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PHOTOMETRIC,tif->tif_dir.td_photometric))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_THRESHHOLDING))
+                       {
+                               if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_THRESHHOLDING,tif->tif_dir.td_threshholding))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_FILLORDER))
+                       {
+                               if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_FILLORDER,tif->tif_dir.td_fillorder))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_ORIENTATION))
+                       {
+                               if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_ORIENTATION,tif->tif_dir.td_orientation))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
+                       {
+                               if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_SAMPLESPERPIXEL,tif->tif_dir.td_samplesperpixel))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP))
+                       {
+                               if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_ROWSPERSTRIP,tif->tif_dir.td_rowsperstrip))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
+                       {
+                               if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MINSAMPLEVALUE,tif->tif_dir.td_minsamplevalue))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
+                       {
+                               if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MAXSAMPLEVALUE,tif->tif_dir.td_maxsamplevalue))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_PLANARCONFIG))
+                       {
+                               if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PLANARCONFIG,tif->tif_dir.td_planarconfig))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT))
+                       {
+                               if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_RESOLUTIONUNIT,tif->tif_dir.td_resolutionunit))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
+                       {
+                               if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_PAGENUMBER,2,&tif->tif_dir.td_pagenumber[0]))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_STRIPBYTECOUNTS))
+                       {
+                               if (!isTiled(tif))
+                               {
+                                       if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
+                                               goto bad;
+                               }
+                               else
+                               {
+                                       if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
+                                               goto bad;
+                               }
+                       }
+                       if (TIFFFieldSet(tif,FIELD_STRIPOFFSETS))
+                       {
+                               if (!isTiled(tif))
+                               {
+                                       if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
+                                               goto bad;
+                               }
+                               else
+                               {
+                                       if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
+                                               goto bad;
+                               }
+                       }
+                       if (TIFFFieldSet(tif,FIELD_COLORMAP))
+                       {
+                               if (!TIFFWriteDirectoryTagColormap(tif,&ndir,dir))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES))
+                       {
+                               if (tif->tif_dir.td_extrasamples)
+                               {
+                                       uint16 na;
+                                       uint16* nb;
+                                       TIFFGetFieldDefaulted(tif,TIFFTAG_EXTRASAMPLES,&na,&nb);
+                                       if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_EXTRASAMPLES,na,nb))
+                                               goto bad;
+                               }
+                       }
+                       if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT))
+                       {
+                               if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_SAMPLEFORMAT,tif->tif_dir.td_sampleformat))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE))
+                       {
+                               if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMINSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_sminsamplevalue))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE))
+                       {
+                               if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMAXSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_smaxsamplevalue))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
+                       {
+                               if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_IMAGEDEPTH,tif->tif_dir.td_imagedepth))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
+                       {
+                               if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_TILEDEPTH,tif->tif_dir.td_tiledepth))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
+                       {
+                               if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_HALFTONEHINTS,2,&tif->tif_dir.td_halftonehints[0]))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
+                       {
+                               if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_YCBCRSUBSAMPLING,2,&tif->tif_dir.td_ycbcrsubsampling[0]))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING))
+                       {
+                               if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_YCBCRPOSITIONING,tif->tif_dir.td_ycbcrpositioning))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE))
+                       {
+                               if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,TIFFTAG_REFERENCEBLACKWHITE,6,tif->tif_dir.td_refblackwhite))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION))
+                       {
+                               if (!TIFFWriteDirectoryTagTransferfunction(tif,&ndir,dir))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_INKNAMES))
+                       {
+                               if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames))
+                                       goto bad;
+                       }
+                       if (TIFFFieldSet(tif,FIELD_SUBIFD))
+                       {
+                               if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir))
+                                       goto bad;
+                       }
+                       {
+                               uint32 n;
+                               for (n=0; n<tif->tif_nfields; n++) {
+                                       const TIFFField* o;
+                                       o = tif->tif_fields[n];
+                                       if ((o->field_bit>=FIELD_CODEC)&&(TIFFFieldSet(tif,o->field_bit)))
+                                       {
+                                               switch (o->get_field_type)
+                                               {
+                                                       case TIFF_SETGET_ASCII:
+                                                               {
+                                                                       uint32 pa;
+                                                                       char* pb;
+                                                                       assert(o->field_type==TIFF_ASCII);
+                                                                       assert(o->field_readcount==TIFF_VARIABLE);
+                                                                       assert(o->field_passcount==0);
+                                                                       TIFFGetField(tif,o->field_tag,&pb);
+                                                                       pa=(uint32)(strlen(pb));
+                                                                       if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,o->field_tag,pa,pb))
+                                                                               goto bad;
+                                                               }
+                                                               break;
+                                                       case TIFF_SETGET_UINT16:
+                                                               {
+                                                                       uint16 p;
+                                                                       assert(o->field_type==TIFF_SHORT);
+                                                                       assert(o->field_readcount==1);
+                                                                       assert(o->field_passcount==0);
+                                                                       TIFFGetField(tif,o->field_tag,&p);
+                                                                       if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,o->field_tag,p))
+                                                                               goto bad;
+                                                               }
+                                                               break;
+                                                       case TIFF_SETGET_UINT32:
+                                                               {
+                                                                       uint32 p;
+                                                                       assert(o->field_type==TIFF_LONG);
+                                                                       assert(o->field_readcount==1);
+                                                                       assert(o->field_passcount==0);
+                                                                       TIFFGetField(tif,o->field_tag,&p);
+                                                                       if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,o->field_tag,p))
+                                                                               goto bad;
+                                                               }
+                                                               break;
+                                                       case TIFF_SETGET_C32_UINT8:
+                                                               {
+                                                                       uint32 pa;
+                                                                       void* pb;
+                                                                       assert(o->field_type==TIFF_UNDEFINED);
+                                                                       assert(o->field_readcount==TIFF_VARIABLE2);
+                                                                       assert(o->field_passcount==1);
+                                                                       TIFFGetField(tif,o->field_tag,&pa,&pb);
+                                                                       if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,o->field_tag,pa,pb))
+                                                                               goto bad;
+                                                               }
+                                                               break;
+                                                       default:
+                                                               assert(0);   /* we should never get here */
+                                                               break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               for (m=0; m<(uint32)(tif->tif_dir.td_customValueCount); m++)
+               {
+                       switch (tif->tif_dir.td_customValues[m].info->field_type)
+                       {
+                               case TIFF_ASCII:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_UNDEFINED:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_BYTE:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_SBYTE:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_SHORT:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_SSHORT:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_LONG:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_SLONG:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_LONG8:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_SLONG8:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_RATIONAL:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_SRATIONAL:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_FLOAT:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_DOUBLE:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_IFD:
+                                       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))
+                                               goto bad;
+                                       break;
+                               case TIFF_IFD8:
+                                       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))
+                                               goto bad;
+                                       break;
+                               default:
+                                       assert(0);   /* we should never get here */
+                                       break;
+                       }
+               }
+               if (dir!=NULL)
+                       break;
+               dir=_TIFFmalloc(ndir*sizeof(TIFFDirEntry));
+               if (dir==NULL)
+               {
+                       TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+                       goto bad;
+               }
+               if (isimage)
+               {
+                       if ((tif->tif_diroff==0)&&(!TIFFLinkDirectory(tif)))
+                               goto bad;
+               }
+               else
+                       tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~1);
+               if (pdiroff!=NULL)
+                       *pdiroff=tif->tif_diroff;
+               if (!(tif->tif_flags&TIFF_BIGTIFF))
+                       dirsize=2+ndir*12+4;
+               else
+                       dirsize=8+ndir*20+8;
+               tif->tif_dataoff=tif->tif_diroff+dirsize;
+               if (!(tif->tif_flags&TIFF_BIGTIFF))
+                       tif->tif_dataoff=(uint32)tif->tif_dataoff;
+               if ((tif->tif_dataoff<tif->tif_diroff)||(tif->tif_dataoff<(uint64)dirsize))
+               {
+                       TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
+                       goto bad;
+               }
+               if (tif->tif_dataoff&1)
+                       tif->tif_dataoff++;
+               if (isimage)
+                       tif->tif_curdir++;
+       }
+       if (isimage)
+       {
+               if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0))
+               {
+                       uint32 na;
+                       TIFFDirEntry* nb;
+                       for (na=0, nb=dir; ; na++, nb++)
+                       {
+                               assert(na<ndir);
+                               if (nb->tdir_tag==TIFFTAG_SUBIFD)
+                                       break;
+                       }
+                       if (!(tif->tif_flags&TIFF_BIGTIFF))
+                               tif->tif_subifdoff=tif->tif_diroff+2+na*12+8;
+                       else
+                               tif->tif_subifdoff=tif->tif_diroff+8+na*20+12;
+               }
+       }
+       dirmem=_TIFFmalloc(dirsize);
+       if (dirmem==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               goto bad;
+       }
+       if (!(tif->tif_flags&TIFF_BIGTIFF))
+       {
+               uint8* n;
+               uint32 nTmp;
+               TIFFDirEntry* o;
+               n=dirmem;
+               *(uint16*)n=ndir;
+               if (tif->tif_flags&TIFF_SWAB)
+                       TIFFSwabShort((uint16*)n);
+               n+=2;
+               o=dir;
+               for (m=0; m<ndir; m++)
+               {
+                       *(uint16*)n=o->tdir_tag;
+                       if (tif->tif_flags&TIFF_SWAB)
+                               TIFFSwabShort((uint16*)n);
+                       n+=2;
+                       *(uint16*)n=o->tdir_type;
+                       if (tif->tif_flags&TIFF_SWAB)
+                               TIFFSwabShort((uint16*)n);
+                       n+=2;
+                       nTmp = (uint32)o->tdir_count;
+                       _TIFFmemcpy(n,&nTmp,4);
+                       if (tif->tif_flags&TIFF_SWAB)
+                               TIFFSwabLong((uint32*)n);
+                       n+=4;
+                       /* This is correct. The data has been */
+                       /* swabbed previously in TIFFWriteDirectoryTagData */
+                       _TIFFmemcpy(n,&o->tdir_offset,4);
+                       n+=4;
+                       o++;
+               }
+               nTmp = (uint32)tif->tif_nextdiroff;
+               if (tif->tif_flags&TIFF_SWAB)
+                       TIFFSwabLong(&nTmp);
+               _TIFFmemcpy(n,&nTmp,4);
+       }
+       else
+       {
+               uint8* n;
+               TIFFDirEntry* o;
+               n=dirmem;
+               *(uint64*)n=ndir;
+               if (tif->tif_flags&TIFF_SWAB)
+                       TIFFSwabLong8((uint64*)n);
+               n+=8;
+               o=dir;
+               for (m=0; m<ndir; m++)
+               {
+                       *(uint16*)n=o->tdir_tag;
+                       if (tif->tif_flags&TIFF_SWAB)
+                               TIFFSwabShort((uint16*)n);
+                       n+=2;
+                       *(uint16*)n=o->tdir_type;
+                       if (tif->tif_flags&TIFF_SWAB)
+                               TIFFSwabShort((uint16*)n);
+                       n+=2;
+                       _TIFFmemcpy(n,&o->tdir_count,8);
+                       if (tif->tif_flags&TIFF_SWAB)
+                               TIFFSwabLong8((uint64*)n);
+                       n+=8;
+                       _TIFFmemcpy(n,&o->tdir_offset,8);
+                       n+=8;
+                       o++;
+               }
+               _TIFFmemcpy(n,&tif->tif_nextdiroff,8);
+               if (tif->tif_flags&TIFF_SWAB)
+                       TIFFSwabLong8((uint64*)n);
+       }
+       _TIFFfree(dir);
+       dir=NULL;
+       if (!SeekOK(tif,tif->tif_diroff))
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
+               goto bad;
+       }
+       if (!WriteOK(tif,dirmem,(tmsize_t)dirsize))
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
+               goto bad;
+       }
+       _TIFFfree(dirmem);
+       if (imagedone)
+       {
+               TIFFFreeDirectory(tif);
+               tif->tif_flags &= ~TIFF_DIRTYDIRECT;
+               tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+               (*tif->tif_cleanup)(tif);
+               /*
+               * Reset directory-related state for subsequent
+               * directories.
+               */
+               TIFFCreateDirectory(tif);
+       }
+       return(1);
+bad:
+       if (dir!=NULL)
+               _TIFFfree(dir);
+       if (dirmem!=NULL)
+               _TIFFfree(dirmem);
+       return(0);
+}
+
+static int
+TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
+       void* conv;
+       uint32 i;
+       int ok;
+       conv = _TIFFmalloc(count*sizeof(double));
+       if (conv == NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata, module, "Out of memory");
+               return (0);
+       }
+
+       switch (tif->tif_dir.td_sampleformat)
+       {
+               case SAMPLEFORMAT_IEEEFP:
+                       if (tif->tif_dir.td_bitspersample<=32)
+                       {
+                               for (i = 0; i < count; ++i)
+                                       ((float*)conv)[i] = (float)value[i];
+                               ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
+                       }
+                       else
+                       {
+                               ok = TIFFWriteDirectoryTagDoubleArray(tif,ndir,dir,tag,count,value);
+                       }
+                       break;
+               case SAMPLEFORMAT_INT:
+                       if (tif->tif_dir.td_bitspersample<=8)
+                       {
+                               for (i = 0; i < count; ++i)
+                                       ((int8*)conv)[i] = (int8)value[i];
+                               ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv);
+                       }
+                       else if (tif->tif_dir.td_bitspersample<=16)
+                       {
+                               for (i = 0; i < count; ++i)
+                                       ((int16*)conv)[i] = (int16)value[i];
+                               ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv);
+                       }
+                       else
+                       {
+                               for (i = 0; i < count; ++i)
+                                       ((int32*)conv)[i] = (int32)value[i];
+                               ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv);
+                       }
+                       break;
+               case SAMPLEFORMAT_UINT:
+                       if (tif->tif_dir.td_bitspersample<=8)
+                       {
+                               for (i = 0; i < count; ++i)
+                                       ((uint8*)conv)[i] = (uint8)value[i];
+                               ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv);
+                       }
+                       else if (tif->tif_dir.td_bitspersample<=16)
+                       {
+                               for (i = 0; i < count; ++i)
+                                       ((uint16*)conv)[i] = (uint16)value[i];
+                               ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv);
+                       }
+                       else
+                       {
+                               for (i = 0; i < count; ++i)
+                                       ((uint32*)conv)[i] = (uint32)value[i];
+                               ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv);
+                       }
+                       break;
+               default:
+                       ok = 0;
+       }
+
+       _TIFFfree(conv);
+       return (ok);
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+       switch (tif->tif_dir.td_sampleformat)
+       {
+               case SAMPLEFORMAT_IEEEFP:
+                       if (tif->tif_dir.td_bitspersample<=32)
+                               return(TIFFWriteDirectoryTagFloatPerSample(tif,ndir,dir,tag,(float)value));
+                       else
+                               return(TIFFWriteDirectoryTagDoublePerSample(tif,ndir,dir,tag,value));
+               case SAMPLEFORMAT_INT:
+                       if (tif->tif_dir.td_bitspersample<=8)
+                               return(TIFFWriteDirectoryTagSbytePerSample(tif,ndir,dir,tag,(int8)value));
+                       else if (tif->tif_dir.td_bitspersample<=16)
+                               return(TIFFWriteDirectoryTagSshortPerSample(tif,ndir,dir,tag,(int16)value));
+                       else
+                               return(TIFFWriteDirectoryTagSlongPerSample(tif,ndir,dir,tag,(int32)value));
+               case SAMPLEFORMAT_UINT:
+                       if (tif->tif_dir.td_bitspersample<=8)
+                               return(TIFFWriteDirectoryTagBytePerSample(tif,ndir,dir,tag,(uint8)value));
+                       else if (tif->tif_dir.td_bitspersample<=16)
+                               return(TIFFWriteDirectoryTagShortPerSample(tif,ndir,dir,tag,(uint16)value));
+                       else
+                               return(TIFFWriteDirectoryTagLongPerSample(tif,ndir,dir,tag,(uint32)value));
+               default:
+                       return(1);
+       }
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedAscii(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedUndefinedArray(tif,ndir,dir,tag,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedByte(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagBytePerSample";
+       uint8* m;
+       uint8* na;
+       uint16 nb;
+       int o;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint8));
+       if (m==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               return(0);
+       }
+       for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+               *na=value;
+       o=TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+       _TIFFfree(m);
+       return(o);
+}
+#endif
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedSbyte(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagSbytePerSample";
+       int8* m;
+       int8* na;
+       uint16 nb;
+       int o;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int8));
+       if (m==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               return(0);
+       }
+       for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+               *na=value;
+       o=TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+       _TIFFfree(m);
+       return(o);
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,value));
+}
+
+static int
+TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
+       uint16* m;
+       uint16* na;
+       uint16 nb;
+       int o;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint16));
+       if (m==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               return(0);
+       }
+       for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+               *na=value;
+       o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+       _TIFFfree(m);
+       return(o);
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedSshort(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagSshortPerSample";
+       int16* m;
+       int16* na;
+       uint16 nb;
+       int o;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int16));
+       if (m==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               return(0);
+       }
+       for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+               *na=value;
+       o=TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+       _TIFFfree(m);
+       return(o);
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
+}
+
+static int
+TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagLongPerSample";
+       uint32* m;
+       uint32* na;
+       uint16 nb;
+       int o;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint32));
+       if (m==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               return(0);
+       }
+       for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+               *na=value;
+       o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+       _TIFFfree(m);
+       return(o);
+}
+#endif
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedSlong(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagSlongPerSample";
+       int32* m;
+       int32* na;
+       uint16 nb;
+       int o;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int32));
+       if (m==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               return(0);
+       }
+       for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+               *na=value;
+       o=TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+       _TIFFfree(m);
+       return(o);
+}
+#endif
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedLong8(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedSlong8(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedSlong8Array(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedRational(tif,ndir,dir,tag,value));
+}
+
+static int
+TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedRationalArray(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value));
+}
+
+#ifdef notdef
+static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedFloat(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagFloatPerSample";
+       float* m;
+       float* na;
+       uint16 nb;
+       int o;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(float));
+       if (m==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               return(0);
+       }
+       for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+               *na=value;
+       o=TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+       _TIFFfree(m);
+       return(o);
+}
+#endif
+
+#ifdef notdef
+static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedDouble(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagDoublePerSample";
+       double* m;
+       double* na;
+       uint16 nb;
+       int o;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(double));
+       if (m==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               return(0);
+       }
+       for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+               *na=value;
+       o=TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+       _TIFFfree(m);
+       return(o);
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,tag,count,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
+{
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       if (value<=0xFFFF)
+               return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,(uint16)value));
+       else
+               return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
+}
+
+/************************************************************************/
+/*                TIFFWriteDirectoryTagLongLong8Array()                 */
+/*                                                                      */
+/*      Write out LONG8 array as LONG8 for BigTIFF or LONG for          */
+/*      Classic TIFF with some checking.                                */
+/************************************************************************/
+
+static int
+TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+    static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
+    uint64* ma;
+    uint32 mb;
+    uint32* p;
+    uint32* q;
+    int o;
+
+    /* is this just a counting pass? */
+    if (dir==NULL)
+    {
+        (*ndir)++;
+        return(1);
+    }
+
+    /* We always write LONG8 for BigTIFF, no checking needed. */
+    if( tif->tif_flags&TIFF_BIGTIFF )
+        return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,
+                                                      tag,count,value);
+
+    /*
+    ** For classic tiff we want to verify everything is in range for LONG
+    ** and convert to long format.
+    */
+
+    p = _TIFFmalloc(count*sizeof(uint32));
+    if (p==NULL)
+    {
+        TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+        return(0);
+    }
+
+    for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
+    {
+        if (*ma>0xFFFFFFFF)
+        {
+            TIFFErrorExt(tif->tif_clientdata,module,
+                         "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
+            _TIFFfree(p);
+            return(0);
+        }
+        *q= (uint32)(*ma);
+    }
+
+    o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
+    _TIFFfree(p);
+
+    return(o);
+}
+
+/************************************************************************/
+/*                 TIFFWriteDirectoryTagIfdIfd8Array()                  */
+/*                                                                      */
+/*      Write either IFD8 or IFD array depending on file type.          */
+/************************************************************************/
+
+static int
+TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+    static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
+    uint64* ma;
+    uint32 mb;
+    uint32* p;
+    uint32* q;
+    int o;
+
+    /* is this just a counting pass? */
+    if (dir==NULL)
+    {
+        (*ndir)++;
+        return(1);
+    }
+
+    /* We always write IFD8 for BigTIFF, no checking needed. */
+    if( tif->tif_flags&TIFF_BIGTIFF )
+        return TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,
+                                                     tag,count,value);
+
+    /*
+    ** For classic tiff we want to verify everything is in range for IFD
+    ** and convert to long format.
+    */
+
+    p = _TIFFmalloc(count*sizeof(uint32));
+    if (p==NULL)
+    {
+        TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+        return(0);
+    }
+
+    for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
+    {
+        if (*ma>0xFFFFFFFF)
+        {
+            TIFFErrorExt(tif->tif_clientdata,module,
+                         "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
+            _TIFFfree(p);
+            return(0);
+        }
+        *q= (uint32)(*ma);
+    }
+
+    o=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,p);
+    _TIFFfree(p);
+
+    return(o);
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagShortLongLong8Array";
+       uint64* ma;
+       uint32 mb;
+       uint8 n;
+       int o;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       n=0;
+       for (ma=value, mb=0; mb<count; ma++, mb++)
+       {
+               if ((n==0)&&(*ma>0xFFFF))
+                       n=1;
+               if ((n==1)&&(*ma>0xFFFFFFFF))
+               {
+                       n=2;
+                       break;
+               }
+       }
+       if (n==0)
+       {
+               uint16* p;
+               uint16* q;
+               p=_TIFFmalloc(count*sizeof(uint16));
+               if (p==NULL)
+               {
+                       TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+                       return(0);
+               }
+               for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
+                       *q=(uint16)(*ma);
+               o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p);
+               _TIFFfree(p);
+       }
+       else if (n==1)
+       {
+               uint32* p;
+               uint32* q;
+               p=_TIFFmalloc(count*sizeof(uint32));
+               if (p==NULL)
+               {
+                       TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+                       return(0);
+               }
+               for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
+                       *q=(uint32)(*ma);
+               o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
+               _TIFFfree(p);
+       }
+       else
+       {
+               assert(n==2);
+               o=TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value);
+       }
+       return(o);
+}
+#endif
+static int
+TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
+{
+       static const char module[] = "TIFFWriteDirectoryTagColormap";
+       uint32 m;
+       uint16* n;
+       int o;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       m=(1<<tif->tif_dir.td_bitspersample);
+       n=_TIFFmalloc(3*m*sizeof(uint16));
+       if (n==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               return(0);
+       }
+       _TIFFmemcpy(&n[0],tif->tif_dir.td_colormap[0],m*sizeof(uint16));
+       _TIFFmemcpy(&n[m],tif->tif_dir.td_colormap[1],m*sizeof(uint16));
+       _TIFFmemcpy(&n[2*m],tif->tif_dir.td_colormap[2],m*sizeof(uint16));
+       o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_COLORMAP,3*m,n);
+       _TIFFfree(n);
+       return(o);
+}
+
+static int
+TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
+{
+       static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
+       uint32 m;
+       uint16 n;
+       uint16* o;
+       int p;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       m=(1<<tif->tif_dir.td_bitspersample);
+       n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples;
+       /*
+        * Check if the table can be written as a single column,
+        * or if it must be written as 3 columns.  Note that we
+        * write a 3-column tag if there are 2 samples/pixel and
+        * a single column of data won't suffice--hmm.
+        */
+       if (n>3)
+               n=3;
+       if (n==3)
+       {
+               if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)))
+                       n=2;
+       }
+       if (n==2)
+       {
+               if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
+                       n=1;
+       }
+       if (n==0)
+               n=1;
+       o=_TIFFmalloc(n*m*sizeof(uint16));
+       if (o==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               return(0);
+       }
+       _TIFFmemcpy(&o[0],tif->tif_dir.td_transferfunction[0],m*sizeof(uint16));
+       if (n>1)
+               _TIFFmemcpy(&o[m],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16));
+       if (n>2)
+               _TIFFmemcpy(&o[2*m],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16));
+       p=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_TRANSFERFUNCTION,n*m,o);
+       _TIFFfree(o);
+       return(p);
+}
+
+static int
+TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
+{
+       static const char module[] = "TIFFWriteDirectoryTagSubifd";
+       uint64 m;
+       int n;
+       if (tif->tif_dir.td_nsubifd==0)
+               return(1);
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       m=tif->tif_dataoff;
+       if (!(tif->tif_flags&TIFF_BIGTIFF))
+       {
+               uint32* o;
+               uint64* pa;
+               uint32* pb;
+               uint16 p;
+               o=_TIFFmalloc(tif->tif_dir.td_nsubifd*sizeof(uint32));
+               if (o==NULL)
+               {
+                       TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+                       return(0);
+               }
+               pa=tif->tif_dir.td_subifd;
+               pb=o;
+               for (p=0; p < tif->tif_dir.td_nsubifd; p++)
+               {
+                        assert(pa != 0);
+                       assert(*pa <= 0xFFFFFFFFUL);
+                       *pb++=(uint32)(*pa++);
+               }
+               n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o);
+               _TIFFfree(o);
+       }
+       else
+               n=TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,tif->tif_dir.td_subifd);
+       if (!n)
+               return(0);
+       /*
+        * Total hack: if this directory includes a SubIFD
+        * tag then force the next <n> directories to be
+        * written as ``sub directories'' of this one.  This
+        * is used to write things like thumbnails and
+        * image masks that one wants to keep out of the
+        * normal directory linkage access mechanism.
+        */
+       tif->tif_flags|=TIFF_INSUBIFD;
+       tif->tif_nsubifd=tif->tif_dir.td_nsubifd;
+       if (tif->tif_dir.td_nsubifd==1)
+               tif->tif_subifdoff=0;
+       else
+               tif->tif_subifdoff=m;
+       return(1);
+}
+
+static int
+TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
+{
+       assert(sizeof(char)==1);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+       assert(sizeof(uint8)==1);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_UNDEFINED,count,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
+{
+       assert(sizeof(uint8)==1);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,1,1,&value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+       assert(sizeof(uint8)==1);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,count,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
+{
+       assert(sizeof(int8)==1);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,1,1,&value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
+{
+       assert(sizeof(int8)==1);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,count,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
+{
+       uint16 m;
+       assert(sizeof(uint16)==2);
+       m=value;
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabShort(&m);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,1,2,&m));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
+{
+       assert(count<0x80000000);
+       assert(sizeof(uint16)==2);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabArrayOfShort(value,count);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,count,count*2,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
+{
+       int16 m;
+       assert(sizeof(int16)==2);
+       m=value;
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabShort((uint16*)(&m));
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,1,2,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
+{
+       assert(count<0x80000000);
+       assert(sizeof(int16)==2);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabArrayOfShort((uint16*)value,count);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,count,count*2,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
+{
+       uint32 m;
+       assert(sizeof(uint32)==4);
+       m=value;
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabLong(&m);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,1,4,&m));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
+{
+       assert(count<0x40000000);
+       assert(sizeof(uint32)==4);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabArrayOfLong(value,count);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,count,count*4,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
+{
+       int32 m;
+       assert(sizeof(int32)==4);
+       m=value;
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabLong((uint32*)(&m));
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,1,4,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
+{
+       assert(count<0x40000000);
+       assert(sizeof(int32)==4);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabArrayOfLong((uint32*)value,count);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,count,count*4,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
+{
+       uint64 m;
+       assert(sizeof(uint64)==8);
+       assert(tif->tif_flags&TIFF_BIGTIFF);
+       m=value;
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabLong8(&m);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,1,8,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+       assert(count<0x20000000);
+       assert(sizeof(uint64)==8);
+       assert(tif->tif_flags&TIFF_BIGTIFF);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabArrayOfLong8(value,count);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
+{
+       int64 m;
+       assert(sizeof(int64)==8);
+       assert(tif->tif_flags&TIFF_BIGTIFF);
+       m=value;
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabLong8((uint64*)(&m));
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,1,8,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
+{
+       assert(count<0x20000000);
+       assert(sizeof(int64)==8);
+       assert(tif->tif_flags&TIFF_BIGTIFF);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabArrayOfLong8((uint64*)value,count);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+       uint32 m[2];
+       assert(value>=0.0);
+       assert(sizeof(uint32)==4);
+       if (value<=0.0)
+       {
+               m[0]=0;
+               m[1]=1;
+       }
+       else if (value==(double)(uint32)value)
+       {
+               m[0]=(uint32)value;
+               m[1]=1;
+       }
+       else if (value<1.0)
+       {
+               m[0]=(uint32)(value*0xFFFFFFFF);
+               m[1]=0xFFFFFFFF;
+       }
+       else
+       {
+               m[0]=0xFFFFFFFF;
+               m[1]=(uint32)(0xFFFFFFFF/value);
+       }
+       if (tif->tif_flags&TIFF_SWAB)
+       {
+               TIFFSwabLong(&m[0]);
+               TIFFSwabLong(&m[1]);
+       }
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,1,8,&m[0]));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
+       uint32* m;
+       float* na;
+       uint32* nb;
+       uint32 nc;
+       int o;
+       assert(sizeof(uint32)==4);
+       m=_TIFFmalloc(count*2*sizeof(uint32));
+       if (m==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               return(0);
+       }
+       for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
+       {
+               if (*na<=0.0)
+               {
+                       nb[0]=0;
+                       nb[1]=1;
+               }
+               else if (*na==(float)(uint32)(*na))
+               {
+                       nb[0]=(uint32)(*na);
+                       nb[1]=1;
+               }
+               else if (*na<1.0)
+               {
+                       nb[0]=(uint32)((*na)*0xFFFFFFFF);
+                       nb[1]=0xFFFFFFFF;
+               }
+               else
+               {
+                       nb[0]=0xFFFFFFFF;
+                       nb[1]=(uint32)(0xFFFFFFFF/(*na));
+               }
+       }
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabArrayOfLong(m,count*2);
+       o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]);
+       _TIFFfree(m);
+       return(o);
+}
+
+static int
+TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
+       int32* m;
+       float* na;
+       int32* nb;
+       uint32 nc;
+       int o;
+       assert(sizeof(int32)==4);
+       m=_TIFFmalloc(count*2*sizeof(int32));
+       if (m==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               return(0);
+       }
+       for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
+       {
+               if (*na<0.0)
+               {
+                       if (*na==(int32)(*na))
+                       {
+                               nb[0]=(int32)(*na);
+                               nb[1]=1;
+                       }
+                       else if (*na>-1.0)
+                       {
+                               nb[0]=-(int32)((-*na)*0x7FFFFFFF);
+                               nb[1]=0x7FFFFFFF;
+                       }
+                       else
+                       {
+                               nb[0]=-0x7FFFFFFF;
+                               nb[1]=(int32)(0x7FFFFFFF/(-*na));
+                       }
+               }
+               else
+               {
+                       if (*na==(int32)(*na))
+                       {
+                               nb[0]=(int32)(*na);
+                               nb[1]=1;
+                       }
+                       else if (*na<1.0)
+                       {
+                               nb[0]=(int32)((*na)*0x7FFFFFFF);
+                               nb[1]=0x7FFFFFFF;
+                       }
+                       else
+                       {
+                               nb[0]=0x7FFFFFFF;
+                               nb[1]=(int32)(0x7FFFFFFF/(*na));
+                       }
                }
        }
-       TIFFGetField(tif, tag, &v);
-       for (i = 0; i < samples; i++)
-               w[i] = v;
-       
-       dir->tdir_tag = (uint16) tag;
-       dir->tdir_type = (uint16) TIFF_SHORT;
-       dir->tdir_count = samples;
-       status = TIFFWriteShortArray(tif, dir, w);
-       if (w != buf)
-               _TIFFfree((char*) w);
-       return (status);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabArrayOfLong((uint32*)m,count*2);
+       o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]);
+       _TIFFfree(m);
+       return(o);
 }
 
-/*
- * Setup a directory entry that references a samples/pixel array of ``type''
- * values and (potentially) write the associated indirect values.  The source
- * data from TIFFGetField() for the specified tag must be returned as double.
- */
+#ifdef notdef
 static int
-TIFFWritePerSampleAnys(TIFF* tif,
-    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
+TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
 {
-       double buf[10], v;
-       double* w = buf;
-       uint16 i, samples = tif->tif_dir.td_samplesperpixel;
-       int status;
-
-       if (samples > NITEMS(buf)) {
-               w = (double*) _TIFFmalloc(samples * sizeof (double));
-               if (w == NULL) {
-                       TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                           "No space to write per-sample values");
-                       return (0);
-               }
-       }
-       TIFFGetField(tif, tag, &v);
-       for (i = 0; i < samples; i++)
-               w[i] = v;
-       status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
-       if (w != buf)
-               _TIFFfree(w);
-       return (status);
+       float m;
+       assert(sizeof(float)==4);
+       m=value;
+       TIFFCvtNativeToIEEEFloat(tif,1,&m);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabFloat(&m);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,1,4,&m));
 }
-#undef NITEMS
+#endif
 
-/*
- * Setup a pair of shorts that are returned by
- * value, rather than as a reference to an array.
- */
 static int
-TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
+TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
 {
-       uint16 v[2];
-
-       TIFFGetField(tif, tag, &v[0], &v[1]);
-
-       dir->tdir_tag = (uint16) tag;
-       dir->tdir_type = (uint16) TIFF_SHORT;
-       dir->tdir_count = 2;
-       return (TIFFWriteShortArray(tif, dir, v));
+       assert(count<0x40000000);
+       assert(sizeof(float)==4);
+       TIFFCvtNativeToIEEEFloat(tif,count,&value);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabArrayOfFloat(value,count);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,count,count*4,value));
 }
 
-/*
- * Setup a directory entry for an NxM table of shorts,
- * where M is known to be 2**bitspersample, and write
- * the associated indirect data.
- */
+#ifdef notdef
 static int
-TIFFWriteShortTable(TIFF* tif,
-    ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
+TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
 {
-       uint32 i, off;
-
-       dir->tdir_tag = (uint16) tag;
-       dir->tdir_type = (short) TIFF_SHORT;
-       /* XXX -- yech, fool TIFFWriteData */
-       dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
-       off = tif->tif_dataoff;
-       for (i = 0; i < n; i++)
-               if (!TIFFWriteData(tif, dir, (char *)table[i]))
-                       return (0);
-       dir->tdir_count *= n;
-       dir->tdir_offset = off;
-       return (1);
+       double m;
+       assert(sizeof(double)==8);
+       m=value;
+       TIFFCvtNativeToIEEEDouble(tif,1,&m);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabDouble(&m);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,1,8,&m));
 }
+#endif
 
-/*
- * Write/copy data associated with an ASCII or opaque tag value.
- */
 static int
-TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
+TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
 {
-       if (dir->tdir_count > 4) {
-               if (!TIFFWriteData(tif, dir, cp))
-                       return (0);
-       } else
-               _TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count);
-       return (1);
+       assert(count<0x20000000);
+       assert(sizeof(double)==8);
+       TIFFCvtNativeToIEEEDouble(tif,count,&value);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabArrayOfDouble(value,count);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,count,count*8,value));
 }
 
-/*
- * Setup a directory entry of an array of SHORT
- * or SSHORT and write the associated indirect values.
- */
 static int
-TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
-{
-       if (dir->tdir_count <= 2) {
-               if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
-                       dir->tdir_offset = (uint32) ((long) v[0] << 16);
-                       if (dir->tdir_count == 2)
-                               dir->tdir_offset |= v[1] & 0xffff;
-               } else {
-                       dir->tdir_offset = v[0] & 0xffff;
-                       if (dir->tdir_count == 2)
-                               dir->tdir_offset |= (long) v[1] << 16;
-               }
-               return (1);
-       } else
-               return (TIFFWriteData(tif, dir, (char*) v));
+TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
+{
+       assert(count<0x40000000);
+       assert(sizeof(uint32)==4);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabArrayOfLong(value,count);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD,count,count*4,value));
 }
 
-/*
- * Setup a directory entry of an array of LONG
- * or SLONG and write the associated indirect values.
- */
 static int
-TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
+TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
 {
-       if (dir->tdir_count == 1) {
-               dir->tdir_offset = v[0];
-               return (1);
-       } else
-               return (TIFFWriteData(tif, dir, (char*) v));
+       assert(count<0x20000000);
+       assert(sizeof(uint64)==8);
+       assert(tif->tif_flags&TIFF_BIGTIFF);
+       if (tif->tif_flags&TIFF_SWAB)
+               TIFFSwabArrayOfLong8(value,count);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD8,count,count*8,value));
 }
 
-/*
- * Setup a directory entry of an array of RATIONAL
- * or SRATIONAL and write the associated indirect values.
- */
 static int
-TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
+TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data)
 {
-       uint32 i;
-       uint32* t;
-       int status;
-
-       t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32));
-       if (t == NULL) {
-               TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                   "No space to write RATIONAL array");
-               return (0);
+       static const char module[] = "TIFFWriteDirectoryTagData";
+       uint32 m;
+       m=0;
+       while (m<(*ndir))
+       {
+               assert(dir[m].tdir_tag!=tag);
+               if (dir[m].tdir_tag>tag)
+                       break;
+               m++;
+       }
+       if (m<(*ndir))
+       {
+               uint32 n;
+               for (n=*ndir; n>m; n--)
+                       dir[n]=dir[n-1];
        }
-       for (i = 0; i < dir->tdir_count; i++) {
-               float fv = v[i];
-               int sign = 1;
-               uint32 den;
-
-               if (fv < 0) {
-                       if (dir->tdir_type == TIFF_RATIONAL) {
-                               TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-       "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
-                               _TIFFFieldWithTag(tif,dir->tdir_tag)->field_name,
-                               fv);
-                               fv = 0;
-                       } else
-                               fv = -fv, sign = -1;
+       dir[m].tdir_tag=tag;
+       dir[m].tdir_type=datatype;
+       dir[m].tdir_count=count;
+       dir[m].tdir_offset.toff_long8 = 0;
+       if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U))
+               _TIFFmemcpy(&dir[m].tdir_offset,data,datalength);
+       else
+       {
+               uint64 na,nb;
+               na=tif->tif_dataoff;
+               nb=na+datalength;
+               if (!(tif->tif_flags&TIFF_BIGTIFF))
+                       nb=(uint32)nb;
+               if ((nb<na)||(nb<datalength))
+               {
+                       TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
+                       return(0);
+               }
+               if (!SeekOK(tif,na))
+               {
+                       TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
+                       return(0);
+               }
+               assert(datalength<0x80000000UL);
+               if (!WriteOK(tif,data,(tmsize_t)datalength))
+               {
+                       TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
+                       return(0);
+               }
+               tif->tif_dataoff=nb;
+               if (tif->tif_dataoff&1)
+                       tif->tif_dataoff++;
+               if (!(tif->tif_flags&TIFF_BIGTIFF))
+               {
+                       uint32 o;
+                       o=(uint32)na;
+                       if (tif->tif_flags&TIFF_SWAB)
+                               TIFFSwabLong(&o);
+                       _TIFFmemcpy(&dir[m].tdir_offset,&o,4);
                }
-               den = 1L;
-               if (fv > 0) {
-                       while (fv < 1L<<(31-3) && den < 1L<<(31-3))
-                               fv *= 1<<3, den *= 1L<<3;
+               else
+               {
+                       dir[m].tdir_offset.toff_long8 = na;
+                       if (tif->tif_flags&TIFF_SWAB)
+                               TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
                }
-               t[2*i+0] = (uint32) (sign * (fv + 0.5));
-               t[2*i+1] = den;
        }
-       status = TIFFWriteData(tif, dir, (char *)t);
-       _TIFFfree((char*) t);
-       return (status);
-}
-
-static int
-TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
-{
-       TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v);
-       if (dir->tdir_count == 1) {
-               dir->tdir_offset = *(uint32*) &v[0];
-               return (1);
-       } else
-               return (TIFFWriteData(tif, dir, (char*) v));
-}
-
-static int
-TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
-{
-       TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v);
-       return (TIFFWriteData(tif, dir, (char*) v));
+       (*ndir)++;
+       return(1);
 }
 
 /*
- * Write an array of ``type'' values for a specified tag (i.e. this is a tag
- * which is allowed to have different types, e.g. SMaxSampleType).
- * Internally the data values are represented as double since a double can
- * hold any of the TIFF tag types (yes, this should really be an abstract
- * type tany_t for portability).  The data is converted into the specified
- * type in a temporary buffer and then handed off to the appropriate array
- * writer.
+ * Link the current directory into the directory chain for the file.
  */
 static int
-TIFFWriteAnyArray(TIFF* tif,
-    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
+TIFFLinkDirectory(TIFF* tif)
 {
-       char buf[10 * sizeof(double)];
-       char* w = buf;
-       int i, status = 0;
-
-       if (n * TIFFDataWidth(type) > sizeof buf) {
-               w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
-               if (w == NULL) {
-                       TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                           "No space to write array");
-                       return (0);
-               }
-       }
+       static const char module[] = "TIFFLinkDirectory";
 
-       dir->tdir_tag = (uint16) tag;
-       dir->tdir_type = (uint16) type;
-       dir->tdir_count = n;
+       tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) &~ 1;
 
-       switch (type) {
-       case TIFF_BYTE:
-               { 
-                       uint8* bp = (uint8*) w;
-                       for (i = 0; i < (int) n; i++)
-                               bp[i] = (uint8) v[i];
-                       if (!TIFFWriteByteArray(tif, dir, (char*) bp))
-                               goto out;
-               }
-               break;
-       case TIFF_SBYTE:
-               { 
-                       int8* bp = (int8*) w;
-                       for (i = 0; i < (int) n; i++)
-                               bp[i] = (int8) v[i];
-                       if (!TIFFWriteByteArray(tif, dir, (char*) bp))
-                               goto out;
+       /*
+        * Handle SubIFDs
+        */
+       if (tif->tif_flags & TIFF_INSUBIFD)
+       {
+               if (!(tif->tif_flags&TIFF_BIGTIFF))
+               {
+                       uint32 m;
+                       m = (uint32)tif->tif_diroff;
+                       if (tif->tif_flags & TIFF_SWAB)
+                               TIFFSwabLong(&m);
+                       (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
+                       if (!WriteOK(tif, &m, 4)) {
+                               TIFFErrorExt(tif->tif_clientdata, module,
+                                    "Error writing SubIFD directory link");
+                               return (0);
+                       }
+                       /*
+                        * Advance to the next SubIFD or, if this is
+                        * the last one configured, revert back to the
+                        * normal directory linkage.
+                        */
+                       if (--tif->tif_nsubifd)
+                               tif->tif_subifdoff += 4;
+                       else
+                               tif->tif_flags &= ~TIFF_INSUBIFD;
+                       return (1);
                }
-               break;
-       case TIFF_SHORT:
+               else
                {
-                       uint16* bp = (uint16*) w;
-                       for (i = 0; i < (int) n; i++)
-                               bp[i] = (uint16) v[i];
-                       if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
-                               goto out;
+                       uint64 m;
+                       m = tif->tif_diroff;
+                       if (tif->tif_flags & TIFF_SWAB)
+                               TIFFSwabLong8(&m);
+                       (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
+                       if (!WriteOK(tif, &m, 8)) {
+                               TIFFErrorExt(tif->tif_clientdata, module,
+                                    "Error writing SubIFD directory link");
+                               return (0);
+                       }
+                       /*
+                        * Advance to the next SubIFD or, if this is
+                        * the last one configured, revert back to the
+                        * normal directory linkage.
+                        */
+                       if (--tif->tif_nsubifd)
+                               tif->tif_subifdoff += 8;
+                       else
+                               tif->tif_flags &= ~TIFF_INSUBIFD;
+                       return (1);
                }
-               break;
-       case TIFF_SSHORT:
-               { 
-                       int16* bp = (int16*) w;
-                       for (i = 0; i < (int) n; i++)
-                               bp[i] = (int16) v[i];
-                       if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
-                               goto out;
+       }
+
+       if (!(tif->tif_flags&TIFF_BIGTIFF))
+       {
+               uint32 m;
+               uint32 nextdir;
+               m = (uint32)(tif->tif_diroff);
+               if (tif->tif_flags & TIFF_SWAB)
+                       TIFFSwabLong(&m);
+               if (tif->tif_header.classic.tiff_diroff == 0) {
+                       /*
+                        * First directory, overwrite offset in header.
+                        */
+                       tif->tif_header.classic.tiff_diroff = (uint32) tif->tif_diroff;
+                       (void) TIFFSeekFile(tif,4, SEEK_SET);
+                       if (!WriteOK(tif, &m, 4)) {
+                               TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+                                            "Error writing TIFF header");
+                               return (0);
+                       }
+                       return (1);
                }
-               break;
-       case TIFF_LONG:
-               {
-                       uint32* bp = (uint32*) w;
-                       for (i = 0; i < (int) n; i++)
-                               bp[i] = (uint32) v[i];
-                       if (!TIFFWriteLongArray(tif, dir, bp))
-                               goto out;
+               /*
+                * Not the first directory, search to the last and append.
+                */
+               nextdir = tif->tif_header.classic.tiff_diroff;
+               while(1) {
+                       uint16 dircount;
+                       uint32 nextnextdir;
+
+                       if (!SeekOK(tif, nextdir) ||
+                           !ReadOK(tif, &dircount, 2)) {
+                               TIFFErrorExt(tif->tif_clientdata, module,
+                                            "Error fetching directory count");
+                               return (0);
+                       }
+                       if (tif->tif_flags & TIFF_SWAB)
+                               TIFFSwabShort(&dircount);
+                       (void) TIFFSeekFile(tif,
+                           nextdir+2+dircount*12, SEEK_SET);
+                       if (!ReadOK(tif, &nextnextdir, 4)) {
+                               TIFFErrorExt(tif->tif_clientdata, module,
+                                            "Error fetching directory link");
+                               return (0);
+                       }
+                       if (tif->tif_flags & TIFF_SWAB)
+                               TIFFSwabLong(&nextnextdir);
+                       if (nextnextdir==0)
+                       {
+                               (void) TIFFSeekFile(tif,
+                                   nextdir+2+dircount*12, SEEK_SET);
+                               if (!WriteOK(tif, &m, 4)) {
+                                       TIFFErrorExt(tif->tif_clientdata, module,
+                                            "Error writing directory link");
+                                       return (0);
+                               }
+                               break;
+                       }
+                       nextdir=nextnextdir;
                }
-               break;
-       case TIFF_SLONG:
-               {
-                       int32* bp = (int32*) w;
-                       for (i = 0; i < (int) n; i++)
-                               bp[i] = (int32) v[i];
-                       if (!TIFFWriteLongArray(tif, dir, (uint32*) bp))
-                               goto out;
+       }
+       else
+       {
+               uint64 m;
+               uint64 nextdir;
+               m = tif->tif_diroff;
+               if (tif->tif_flags & TIFF_SWAB)
+                       TIFFSwabLong8(&m);
+               if (tif->tif_header.big.tiff_diroff == 0) {
+                       /*
+                        * First directory, overwrite offset in header.
+                        */
+                       tif->tif_header.big.tiff_diroff = tif->tif_diroff;
+                       (void) TIFFSeekFile(tif,8, SEEK_SET);
+                       if (!WriteOK(tif, &m, 8)) {
+                               TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+                                            "Error writing TIFF header");
+                               return (0);
+                       }
+                       return (1);
                }
-               break;
-       case TIFF_FLOAT:
-               { 
-                       float* bp = (float*) w;
-                       for (i = 0; i < (int) n; i++)
-                               bp[i] = (float) v[i];
-                       if (!TIFFWriteFloatArray(tif, dir, bp))
-                               goto out;
+               /*
+                * Not the first directory, search to the last and append.
+                */
+               nextdir = tif->tif_header.big.tiff_diroff;
+               while(1) {
+                       uint64 dircount64;
+                       uint16 dircount;
+                       uint64 nextnextdir;
+
+                       if (!SeekOK(tif, nextdir) ||
+                           !ReadOK(tif, &dircount64, 8)) {
+                               TIFFErrorExt(tif->tif_clientdata, module,
+                                            "Error fetching directory count");
+                               return (0);
+                       }
+                       if (tif->tif_flags & TIFF_SWAB)
+                               TIFFSwabLong8(&dircount64);
+                       if (dircount64>0xFFFF)
+                       {
+                               TIFFErrorExt(tif->tif_clientdata, module,
+                                            "Sanity check on tag count failed, likely corrupt TIFF");
+                               return (0);
+                       }
+                       dircount=(uint16)dircount64;
+                       (void) TIFFSeekFile(tif,
+                           nextdir+8+dircount*20, SEEK_SET);
+                       if (!ReadOK(tif, &nextnextdir, 8)) {
+                               TIFFErrorExt(tif->tif_clientdata, module,
+                                            "Error fetching directory link");
+                               return (0);
+                       }
+                       if (tif->tif_flags & TIFF_SWAB)
+                               TIFFSwabLong8(&nextnextdir);
+                       if (nextnextdir==0)
+                       {
+                               (void) TIFFSeekFile(tif,
+                                   nextdir+8+dircount*20, SEEK_SET);
+                               if (!WriteOK(tif, &m, 8)) {
+                                       TIFFErrorExt(tif->tif_clientdata, module,
+                                            "Error writing directory link");
+                                       return (0);
+                               }
+                               break;
+                       }
+                       nextdir=nextnextdir;
                }
-               break;
-       case TIFF_DOUBLE:
-               return (TIFFWriteDoubleArray(tif, dir, v));
-       default:
-               /* TIFF_NOTYPE */
-               /* TIFF_ASCII */
-               /* TIFF_UNDEFINED */
-               /* TIFF_RATIONAL */
-               /* TIFF_SRATIONAL */
-               goto out;
        }
-       status = 1;
- out:
-       if (w != buf)
-               _TIFFfree(w);
-       return (status);
+       return (1);
 }
 
-static int
-TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
+/************************************************************************/
+/*                          TIFFRewriteField()                          */
+/*                                                                      */
+/*      Rewrite a field in the directory on disk without regard to      */
+/*      updating the TIFF directory structure in memory.  Currently     */
+/*      only supported for field that already exist in the on-disk      */
+/*      directory.  Mainly used for updating stripoffset /              */
+/*      stripbytecount values after the directory is already on         */
+/*      disk.                                                           */
+/*                                                                      */
+/*      Returns zero on failure, and one on success.                    */
+/************************************************************************/
+
+int
+_TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype, 
+                  tmsize_t count, void* data)
 {
-       TIFFDirectory* td = &tif->tif_dir;
-       tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
-       uint16** tf = td->td_transferfunction;
-       int ncols;
+    static const char module[] = "TIFFResetField";
+    /* const TIFFField* fip = NULL; */
+    uint16 dircount;
+    tmsize_t dirsize;
+    uint8 direntry_raw[20];
+    uint16 entry_tag = 0;
+    uint16 entry_type = 0;
+    uint64 entry_count = 0;
+    uint64 entry_offset = 0;
+    int    value_in_entry = 0;
+    uint64 read_offset;
+    uint8 *buf_to_write = NULL;
+    TIFFDataType datatype;
+
+/* -------------------------------------------------------------------- */
+/*      Find field definition.                                          */
+/* -------------------------------------------------------------------- */
+    /*fip =*/ TIFFFindField(tif, tag, TIFF_ANY);
+
+/* -------------------------------------------------------------------- */
+/*      Do some checking this is a straight forward case.               */
+/* -------------------------------------------------------------------- */
+    if( isMapped(tif) )
+    {
+        TIFFErrorExt( tif->tif_clientdata, module, 
+                      "Memory mapped files not currently supported for this operation." );
+        return 0;
+    }
 
-       /*
-        * Check if the table can be written as a single column,
-        * or if it must be written as 3 columns.  Note that we
-        * write a 3-column tag if there are 2 samples/pixel and
-        * a single column of data won't suffice--hmm.
-        */
-       switch (td->td_samplesperpixel - td->td_extrasamples) {
-       default:        if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
-       case 2:         if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
-       case 1: case 0: ncols = 1;
-       }
-       return (TIFFWriteShortTable(tif,
-           TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
-}
+    if( tif->tif_diroff == 0 )
+    {
+        TIFFErrorExt( tif->tif_clientdata, module, 
+                      "Attempt to reset field on directory not already on disk." );
+        return 0;
+    }
 
-static int
-TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
-{
-       TIFFDirectory* td = &tif->tif_dir;
+/* -------------------------------------------------------------------- */
+/*      Read the directory entry count.                                 */
+/* -------------------------------------------------------------------- */
+    if (!SeekOK(tif, tif->tif_diroff)) {
+        TIFFErrorExt(tif->tif_clientdata, module,
+                     "%s: Seek error accessing TIFF directory",
+                     tif->tif_name);
+        return 0;
+    }
 
-       dir->tdir_tag = TIFFTAG_INKNAMES;
-       dir->tdir_type = (short) TIFF_ASCII;
-       dir->tdir_count = td->td_inknameslen;
-       return (TIFFWriteByteArray(tif, dir, td->td_inknames));
-}
+    read_offset = tif->tif_diroff;
 
-/*
- * Write a contiguous directory item.
- */
-static int
-TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
-{
-       tsize_t cc;
+    if (!(tif->tif_flags&TIFF_BIGTIFF))
+    {
+        if (!ReadOK(tif, &dircount, sizeof (uint16))) {
+            TIFFErrorExt(tif->tif_clientdata, module,
+                         "%s: Can not read TIFF directory count",
+                         tif->tif_name);
+            return 0;
+        }
+        if (tif->tif_flags & TIFF_SWAB)
+            TIFFSwabShort(&dircount);
+        dirsize = 12;
+        read_offset += 2;
+    } else {
+        uint64 dircount64;
+        if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
+            TIFFErrorExt(tif->tif_clientdata, module,
+                         "%s: Can not read TIFF directory count",
+                         tif->tif_name);
+            return 0;
+        }
+        if (tif->tif_flags & TIFF_SWAB)
+            TIFFSwabLong8(&dircount64);
+        dircount = (uint16)dircount64;
+        dirsize = 20;
+        read_offset += 8;
+    }
 
-       if (tif->tif_flags & TIFF_SWAB) {
-               switch (dir->tdir_type) {
-               case TIFF_SHORT:
-               case TIFF_SSHORT:
-                       TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
-                       break;
-               case TIFF_LONG:
-               case TIFF_SLONG:
-               case TIFF_FLOAT:
-                       TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
-                       break;
-               case TIFF_RATIONAL:
-               case TIFF_SRATIONAL:
-                       TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
-                       break;
-               case TIFF_DOUBLE:
-                       TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
-                       break;
-               }
-       }
-       dir->tdir_offset = tif->tif_dataoff;
-       cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type);
-       if (SeekOK(tif, dir->tdir_offset) &&
-           WriteOK(tif, cp, cc)) {
-               tif->tif_dataoff += (cc + 1) & ~1;
-               return (1);
-       }
-       TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing data for field \"%s\"",
-           _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
-       return (0);
-}
+/* -------------------------------------------------------------------- */
+/*      Read through directory to find target tag.                      */
+/* -------------------------------------------------------------------- */
+    while( dircount > 0 )
+    {
+        if (!ReadOK(tif, direntry_raw, dirsize)) {
+            TIFFErrorExt(tif->tif_clientdata, module,
+                         "%s: Can not read TIFF directory entry.",
+                         tif->tif_name);
+            return 0;
+        }
 
-/*
- * Similar to TIFFWriteDirectory(), but if the directory has already
- * been written once, it is relocated to the end of the file, in case it
- * has changed in size.  Note that this will result in the loss of the 
- * previously used directory space. 
- */ 
+        memcpy( &entry_tag, direntry_raw + 0, sizeof(uint16) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabShort( &entry_tag );
 
-int 
-TIFFRewriteDirectory( TIFF *tif )
-{
-    static const char module[] = "TIFFRewriteDirectory";
+        if( entry_tag == tag )
+            break;
 
-    /* We don't need to do anything special if it hasn't been written. */
-    if( tif->tif_diroff == 0 )
-        return TIFFWriteDirectory( tif );
+        read_offset += dirsize;
+    }
 
-    /*
-    ** Find and zero the pointer to this directory, so that TIFFLinkDirectory
-    ** will cause it to be added after this directories current pre-link.
-    */
-    
-    /* Is it the first directory in the file? */
-    if (tif->tif_header.tiff_diroff == tif->tif_diroff) 
+    if( entry_tag != tag )
+    {
+        TIFFErrorExt(tif->tif_clientdata, module,
+                     "%s: Could not find tag %d.",
+                     tif->tif_name, tag );
+        return 0;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Extract the type, count and offset for this entry.              */
+/* -------------------------------------------------------------------- */
+    memcpy( &entry_type, direntry_raw + 2, sizeof(uint16) );
+    if (tif->tif_flags&TIFF_SWAB)
+        TIFFSwabShort( &entry_type );
+
+    if (!(tif->tif_flags&TIFF_BIGTIFF))
+    {
+        uint32 value;
+        
+        memcpy( &value, direntry_raw + 4, sizeof(uint32) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong( &value );
+        entry_count = value;
+
+        memcpy( &value, direntry_raw + 8, sizeof(uint32) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong( &value );
+        entry_offset = value;
+    }
+    else
+    {
+        memcpy( &entry_count, direntry_raw + 4, sizeof(uint64) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong8( &entry_count );
+
+        memcpy( &entry_offset, direntry_raw + 12, sizeof(uint64) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong8( &entry_offset );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      What data type do we want to write this as?                     */
+/* -------------------------------------------------------------------- */
+    if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) )
+    {
+        if( in_datatype == TIFF_LONG8 )
+            datatype = TIFF_LONG;
+        else if( in_datatype == TIFF_SLONG8 )
+            datatype = TIFF_SLONG;
+        else if( in_datatype == TIFF_IFD8 )
+            datatype = TIFF_IFD;
+        else
+            datatype = in_datatype;
+    }
+    else 
+        datatype = in_datatype;
+
+/* -------------------------------------------------------------------- */
+/*      Prepare buffer of actual data to write.  This includes          */
+/*      swabbing as needed.                                             */
+/* -------------------------------------------------------------------- */
+    buf_to_write =
+           (uint8 *)_TIFFCheckMalloc(tif, count, TIFFDataWidth(datatype),
+                                     "for field buffer.");
+    if (!buf_to_write)
+        return 0;
+
+    if( datatype == in_datatype )
+        memcpy( buf_to_write, data, count * TIFFDataWidth(datatype) );
+    else if( datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8 )
     {
-        tif->tif_header.tiff_diroff = 0;
-        tif->tif_diroff = 0;
+       tmsize_t i;
 
-        TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
-                    SEEK_SET);
-        if (!WriteOK(tif, &(tif->tif_header.tiff_diroff), 
-                     sizeof (tif->tif_diroff))) 
+        for( i = 0; i < count; i++ )
         {
-                       TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error updating TIFF header");
-            return (0);
+            ((int32 *) buf_to_write)[i] = 
+                (int32) ((int64 *) data)[i];
+            if( (int64) ((int32 *) buf_to_write)[i] != ((int64 *) data)[i] )
+            {
+                _TIFFfree( buf_to_write );
+                TIFFErrorExt( tif->tif_clientdata, module, 
+                              "Value exceeds 32bit range of output type." );
+                return 0;
+            }
+        }
+    }
+    else if( (datatype == TIFF_LONG && in_datatype == TIFF_LONG8)
+             || (datatype == TIFF_IFD && in_datatype == TIFF_IFD8) )
+    {
+       tmsize_t i;
+
+        for( i = 0; i < count; i++ )
+        {
+            ((uint32 *) buf_to_write)[i] = 
+                (uint32) ((uint64 *) data)[i];
+            if( (uint64) ((uint32 *) buf_to_write)[i] != ((uint64 *) data)[i] )
+            {
+                _TIFFfree( buf_to_write );
+                TIFFErrorExt( tif->tif_clientdata, module, 
+                              "Value exceeds 32bit range of output type." );
+                return 0;
+            }
+        }
+    }
+
+    if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) )
+    {
+        if( TIFFDataWidth(datatype) == 2 )
+            TIFFSwabArrayOfShort( (uint16 *) buf_to_write, count );
+        else if( TIFFDataWidth(datatype) == 4 )
+            TIFFSwabArrayOfLong( (uint32 *) buf_to_write, count );
+        else if( TIFFDataWidth(datatype) == 8 )
+            TIFFSwabArrayOfLong8( (uint64 *) buf_to_write, count );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Is this a value that fits into the directory entry?             */
+/* -------------------------------------------------------------------- */
+    if (!(tif->tif_flags&TIFF_BIGTIFF))
+    {
+        if( TIFFDataWidth(datatype) * count <= 4 )
+        {
+            entry_offset = read_offset + 8;
+            value_in_entry = 1;
         }
     }
     else
     {
-        toff_t  nextdir, off;
+        if( TIFFDataWidth(datatype) * count <= 8 )
+        {
+            entry_offset = read_offset + 12;
+            value_in_entry = 1;
+        }
+    }
 
-       nextdir = tif->tif_header.tiff_diroff;
-       do {
-               uint16 dircount;
+/* -------------------------------------------------------------------- */
+/*      If the tag type, and count match, then we just write it out     */
+/*      over the old values without altering the directory entry at     */
+/*      all.                                                            */
+/* -------------------------------------------------------------------- */
+    if( entry_count == (uint64)count && entry_type == (uint16) datatype )
+    {
+        if (!SeekOK(tif, entry_offset)) {
+            _TIFFfree( buf_to_write );
+            TIFFErrorExt(tif->tif_clientdata, module,
+                         "%s: Seek error accessing TIFF directory",
+                         tif->tif_name);
+            return 0;
+        }
+        if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
+            _TIFFfree( buf_to_write );
+            TIFFErrorExt(tif->tif_clientdata, module,
+                         "Error writing directory link");
+            return (0);
+        }
 
-               if (!SeekOK(tif, nextdir) ||
-                   !ReadOK(tif, &dircount, sizeof (dircount))) {
-                       TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
-                       return (0);
-               }
-               if (tif->tif_flags & TIFF_SWAB)
-                       TIFFSwabShort(&dircount);
-               (void) TIFFSeekFile(tif,
-                   dircount * sizeof (TIFFDirEntry), SEEK_CUR);
-               if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
-                       TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory link");
-                       return (0);
-               }
-               if (tif->tif_flags & TIFF_SWAB)
-                       TIFFSwabLong(&nextdir);
-       } while (nextdir != tif->tif_diroff && nextdir != 0);
-        off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
-        (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
-        tif->tif_diroff = 0;
-       if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) {
-               TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
-               return (0);
-       }
+        _TIFFfree( buf_to_write );
+        return 1;
     }
 
-    /*
-    ** Now use TIFFWriteDirectory() normally.
-    */
+/* -------------------------------------------------------------------- */
+/*      Otherwise, we write the new tag data at the end of the file.    */
+/* -------------------------------------------------------------------- */
+    if( !value_in_entry )
+    {
+        entry_offset = TIFFSeekFile(tif,0,SEEK_END);
+        
+        if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
+            _TIFFfree( buf_to_write );
+            TIFFErrorExt(tif->tif_clientdata, module,
+                         "Error writing directory link");
+            return (0);
+        }
+        
+        _TIFFfree( buf_to_write );
+    }
+    else
+    {
+        memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
+    }
 
-    return TIFFWriteDirectory( tif );
-}
+/* -------------------------------------------------------------------- */
+/*      Adjust the directory entry.                                     */
+/* -------------------------------------------------------------------- */
+    entry_type = datatype;
+    memcpy( direntry_raw + 2, &entry_type, sizeof(uint16) );
+    if (tif->tif_flags&TIFF_SWAB)
+        TIFFSwabShort( (uint16 *) (direntry_raw + 2) );
 
+    if (!(tif->tif_flags&TIFF_BIGTIFF))
+    {
+        uint32 value;
 
-/*
- * Link the current directory into the
- * directory chain for the file.
- */
-static int
-TIFFLinkDirectory(TIFF* tif)
-{
-       static const char module[] = "TIFFLinkDirectory";
-       toff_t nextdir;
-       toff_t diroff, off;
+        value = (uint32) entry_count;
+        memcpy( direntry_raw + 4, &value, sizeof(uint32) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong( (uint32 *) (direntry_raw + 4) );
 
-       tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
-       diroff = tif->tif_diroff;
-       if (tif->tif_flags & TIFF_SWAB)
-               TIFFSwabLong(&diroff);
+        value = (uint32) entry_offset;
+        memcpy( direntry_raw + 8, &value, sizeof(uint32) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong( (uint32 *) (direntry_raw + 8) );
+    }
+    else
+    {
+        memcpy( direntry_raw + 4, &entry_count, sizeof(uint64) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong8( (uint64 *) (direntry_raw + 4) );
 
-       /*
-        * Handle SubIFDs
-        */
-        if (tif->tif_flags & TIFF_INSUBIFD) {
-               (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
-               if (!WriteOK(tif, &diroff, sizeof (diroff))) {
-                       TIFFErrorExt(tif->tif_clientdata, module,
-                           "%s: Error writing SubIFD directory link",
-                           tif->tif_name);
-                       return (0);
-               }
-               /*
-                * Advance to the next SubIFD or, if this is
-                * the last one configured, revert back to the
-                * normal directory linkage.
-                */
-               if (--tif->tif_nsubifd)
-                       tif->tif_subifdoff += sizeof (diroff);
-               else
-                       tif->tif_flags &= ~TIFF_INSUBIFD;
-               return (1);
-       }
+        memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong8( (uint64 *) (direntry_raw + 12) );
+    }
 
-       if (tif->tif_header.tiff_diroff == 0) {
-               /*
-                * First directory, overwrite offset in header.
-                */
-               tif->tif_header.tiff_diroff = tif->tif_diroff;
-               (void) TIFFSeekFile(tif,
-                                   (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
-                                    SEEK_SET);
-               if (!WriteOK(tif, &diroff, sizeof (diroff))) {
-                       TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing TIFF header");
-                       return (0);
-               }
-               return (1);
-       }
-       /*
-        * Not the first directory, search to the last and append.
-        */
-       nextdir = tif->tif_header.tiff_diroff;
-       do {
-               uint16 dircount;
+/* -------------------------------------------------------------------- */
+/*      Write the directory entry out to disk.                          */
+/* -------------------------------------------------------------------- */
+    if (!SeekOK(tif, read_offset )) {
+        TIFFErrorExt(tif->tif_clientdata, module,
+                     "%s: Seek error accessing TIFF directory",
+                     tif->tif_name);
+        return 0;
+    }
 
-               if (!SeekOK(tif, nextdir) ||
-                   !ReadOK(tif, &dircount, sizeof (dircount))) {
-                       TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
-                       return (0);
-               }
-               if (tif->tif_flags & TIFF_SWAB)
-                       TIFFSwabShort(&dircount);
-               (void) TIFFSeekFile(tif,
-                   dircount * sizeof (TIFFDirEntry), SEEK_CUR);
-               if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
-                       TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory link");
-                       return (0);
-               }
-               if (tif->tif_flags & TIFF_SWAB)
-                       TIFFSwabLong(&nextdir);
-       } while (nextdir != 0);
-        off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
-        (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
-       if (!WriteOK(tif, &diroff, sizeof (diroff))) {
-               TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
-               return (0);
-       }
-       return (1);
+    if (!WriteOK(tif, direntry_raw,dirsize))
+    {
+        TIFFErrorExt(tif->tif_clientdata, module,
+                     "%s: Can not write TIFF directory entry.",
+                     tif->tif_name);
+        return 0;
+    }
+    
+    return 1;
 }
-
 /* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */