Update to 2.0.0 tree from current Fremantle build
[opencv] / otherlibs / _graphics / src / libtiff / tif_dirwrite.c
diff --git a/otherlibs/_graphics/src/libtiff/tif_dirwrite.c b/otherlibs/_graphics/src/libtiff/tif_dirwrite.c
deleted file mode 100644 (file)
index 9d4de53..0000000
+++ /dev/null
@@ -1,1238 +0,0 @@
-/* $Id: tif_dirwrite.c,v 1.1 2005/06/17 13:54:52 vp153 Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * 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.  
- * 
- * 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 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Directory Write Support Routines.
- */
-#include "tiffiop.h"
-
-#if HAVE_IEEEFP
-#define        TIFFCvtNativeToIEEEFloat(tif, n, fp)
-#define        TIFFCvtNativeToIEEEDouble(tif, n, dp)
-#else
-extern void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
-extern void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
-#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;
-
-/*
- * Write the contents of the current directory
- * to the specified file.  This routine doesn't
- * 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)) {
-                           TIFFError(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)) {
-                   TIFFError(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) {
-               TIFFError(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:
-               case FIELD_DOTRANGE:
-                       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:
-                       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))) {
-               TIFFError(tif->tif_name, "Error writing directory count");
-               goto bad;
-       }
-       if (!WriteOK(tif, data, dirsize)) {
-               TIFFError(tif->tif_name, "Error writing directory contents");
-               goto bad;
-       }
-       if (!WriteOK(tif, &diroff, sizeof (diroff))) {
-               TIFFError(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);
-}
-
-/*
- * Similar to TIFFWriteDirectory(), writes the directory out
- * 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)
-{
-       int rc;
-       /* Setup the strips arrays, if they haven't already been. */
-       if (tif->tif_dir.td_stripoffset == NULL)
-           (void) TIFFSetupStrips(tif);
-       rc = _TIFFWriteDirectory(tif, FALSE);
-       (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
-       return rc;
-}
-
-/*
- * 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;
-                       }
-               }
-               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;
-                       }
-               }
-               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;
-                       }
-               }
-               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;
-                       }
-               }
-                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);
-       }
-}
-
-/*
- * 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);
-}
-#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)
-{
-       uint16 buf[10], v;
-       uint16* w = buf;
-       int i, status, samples = tif->tif_dir.td_samplesperpixel;
-
-       if (samples > NITEMS(buf)) {
-               w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
-               if (w == NULL) {
-                       TIFFError(tif->tif_name,
-                           "No space to write per-sample shorts");
-                       return (0);
-               }
-       }
-       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);
-}
-
-/*
- * 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.
- */
-static int
-TIFFWritePerSampleAnys(TIFF* tif,
-    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
-{
-       double buf[10], v;
-       double* w = buf;
-       int i, status;
-       int samples = (int) tif->tif_dir.td_samplesperpixel;
-
-       if (samples > NITEMS(buf)) {
-               w = (double*) _TIFFmalloc(samples * sizeof (double));
-               if (w == NULL) {
-                       TIFFError(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);
-}
-#undef NITEMS
-
-/*
- * 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)
-{
-       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));
-}
-
-/*
- * Setup a directory entry for an NxM table of shorts,
- * where M is known to be 2**bitspersample, and write
- * the associated indirect data.
- */
-static int
-TIFFWriteShortTable(TIFF* tif,
-    ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
-{
-       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);
-}
-
-/*
- * Write/copy data associated with an ASCII or opaque tag value.
- */
-static int
-TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
-{
-       if (dir->tdir_count > 4) {
-               if (!TIFFWriteData(tif, dir, cp))
-                       return (0);
-       } else
-               _TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count);
-       return (1);
-}
-
-/*
- * 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));
-}
-
-/*
- * 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)
-{
-       if (dir->tdir_count == 1) {
-               dir->tdir_offset = v[0];
-               return (1);
-       } else
-               return (TIFFWriteData(tif, dir, (char*) v));
-}
-
-/*
- * 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)
-{
-       uint32 i;
-       uint32* t;
-       int status;
-
-       t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32));
-       if (t == NULL) {
-               TIFFError(tif->tif_name,
-                   "No space to write RATIONAL array");
-               return (0);
-       }
-       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) {
-                               TIFFWarning(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;
-               }
-               den = 1L;
-               if (fv > 0) {
-                       while (fv < 1L<<(31-3) && den < 1L<<(31-3))
-                               fv *= 1<<3, den *= 1L<<3;
-               }
-               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, n, v);
-       return (TIFFWriteData(tif, dir, (char*) v));
-}
-
-/*
- * 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.
- */
-static int
-TIFFWriteAnyArray(TIFF* tif,
-    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
-{
-       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) {
-                       TIFFError(tif->tif_name,
-                           "No space to write array");
-                       return (0);
-               }
-       }
-
-       dir->tdir_tag = (uint16) tag;
-       dir->tdir_type = (uint16) type;
-       dir->tdir_count = n;
-
-       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;
-               }
-               break;
-       case TIFF_SHORT:
-               {
-                       uint16* bp = (uint16*) w;
-                       for (i = 0; i < (int) n; i++)
-                               bp[i] = (uint16) v[i];
-                       if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
-                               goto out;
-               }
-               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;
-               }
-               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;
-               }
-               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;
-               }
-               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;
-               }
-               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);
-}
-
-static int
-TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
-{
-       TIFFDirectory* td = &tif->tif_dir;
-       tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
-       uint16** tf = td->td_transferfunction;
-       int ncols;
-
-       /*
-        * 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));
-}
-
-static int
-TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
-{
-       TIFFDirectory* td = &tif->tif_dir;
-
-       dir->tdir_tag = TIFFTAG_INKNAMES;
-       dir->tdir_type = (short) TIFF_ASCII;
-       dir->tdir_count = td->td_inknameslen;
-       return (TIFFWriteByteArray(tif, dir, td->td_inknames));
-}
-
-/*
- * Write a contiguous directory item.
- */
-static int
-TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
-{
-       tsize_t cc;
-
-       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);
-       }
-       TIFFError(tif->tif_name, "Error writing data for field \"%s\"",
-           _TIFFFieldWithTag(tif, dir->tdir_tag)->field_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. 
- */ 
-
-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.
-    */
-    
-    /* Is it the first directory in the file? */
-    if (tif->tif_header.tiff_diroff == tif->tif_diroff) 
-    {
-        tif->tif_header.tiff_diroff = 0;
-        tif->tif_diroff = 0;
-
-        TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
-                    SEEK_SET);
-        if (!WriteOK(tif, &(tif->tif_header.tiff_diroff), 
-                     sizeof (tif->tif_diroff))) 
-        {
-            TIFFError(tif->tif_name, "Error updating TIFF header");
-            return (0);
-        }
-    }
-    else
-    {
-        toff_t  nextdir, off;
-
-       nextdir = tif->tif_header.tiff_diroff;
-       do {
-               uint16 dircount;
-
-               if (!SeekOK(tif, nextdir) ||
-                   !ReadOK(tif, &dircount, sizeof (dircount))) {
-                       TIFFError(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))) {
-                       TIFFError(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))) {
-               TIFFError(module, "Error writing directory link");
-               return (0);
-       }
-    }
-
-    /*
-    ** Now use TIFFWriteDirectory() normally.
-    */
-
-    return TIFFWriteDirectory( tif );
-}
-
-
-/*
- * 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;
-
-       tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
-       diroff = tif->tif_diroff;
-       if (tif->tif_flags & TIFF_SWAB)
-               TIFFSwabLong(&diroff);
-
-       /*
-        * Handle SubIFDs
-        */
-        if (tif->tif_flags & TIFF_INSUBIFD) {
-               (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
-               if (!WriteOK(tif, &diroff, sizeof (diroff))) {
-                       TIFFError(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);
-       }
-
-       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))) {
-                       TIFFError(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;
-
-               if (!SeekOK(tif, nextdir) ||
-                   !ReadOK(tif, &dircount, sizeof (dircount))) {
-                       TIFFError(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))) {
-                       TIFFError(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))) {
-               TIFFError(module, "Error writing directory link");
-               return (0);
-       }
-       return (1);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */