home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / xv221src / tiff / tif_dirw.c < prev    next >
C/C++ Source or Header  |  1992-04-01  |  23KB  |  806 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_dirwrite.c,v 1.16 92/03/18 09:36:15 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. /*
  30.  * TIFF Library.
  31.  *
  32.  * Directory Write Support Routines.
  33.  *
  34.  * NB: Beware of the varargs declarations for routines in
  35.  *     this file.  The names and types of variables has been
  36.  *     carefully chosen to make things work with compilers that
  37.  *     are busted in one way or another (e.g. SGI/MIPS).
  38.  */
  39. #include "tiffioP.h"
  40. #include "prototypes.h"
  41.  
  42. #if HAVE_IEEEFP
  43. #define    TIFFCvtNativeToIEEEFloat(tif, n, fp)
  44. #endif
  45.  
  46. #if USE_PROTOTYPES
  47. static    TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, TIFFFieldInfo*);
  48. static    TIFFSetupShortLong(TIFF *, u_short, TIFFDirEntry *, u_long);
  49. static    TIFFSetupShortPair(TIFF *, u_short, TIFFDirEntry *);
  50. static    TIFFWriteRational(TIFF *,
  51.         TIFFDataType, u_short, TIFFDirEntry *, float);
  52. static    TIFFWritePerSampleShorts(TIFF *, u_short, TIFFDirEntry *);
  53. static    TIFFWriteShortTable(TIFF *, u_short, TIFFDirEntry *, int, u_short **);
  54. static    TIFFWriteShortArray(TIFF *,
  55.         TIFFDataType, u_short, TIFFDirEntry *, int, u_short *);
  56. static    TIFFWriteLongArray(TIFF *,
  57.         TIFFDataType, u_short, TIFFDirEntry *, int, u_long *);
  58. static    TIFFWriteRationalArray(TIFF *,
  59.         TIFFDataType, u_short, TIFFDirEntry *, int, float *);
  60. static    TIFFWriteFloatArray(TIFF *,
  61.         TIFFDataType, u_short, TIFFDirEntry *, int, float *);
  62. static    TIFFWriteString(TIFF *, u_short, TIFFDirEntry *, char *);
  63. #ifdef JPEG_SUPPORT
  64. static    TIFFWriteJPEGQTables(TIFF *, TIFFDirEntry *);
  65. static    TIFFWriteJPEGCTables(TIFF *, u_short, TIFFDirEntry *, u_char **);
  66. #endif
  67. #ifdef COLORIMETRY_SUPPORT
  68. static    TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
  69. #endif
  70. static    TIFFWriteData(TIFF *, TIFFDirEntry *, char *);
  71. static    TIFFLinkDirectory(TIFF *);
  72. #else
  73. static    TIFFWriteNormalTag();
  74. static    TIFFSetupShortLong();
  75. static    TIFFSetupShortPair();
  76. static    TIFFWriteRational();
  77. static    TIFFWritePerSampleShorts();
  78. static    TIFFWriteShortTable();
  79. static    TIFFWriteShortArray();
  80. static    TIFFWriteLongArray();
  81. static    TIFFWriteRationalArray();
  82. static    TIFFWriteFloatArray();
  83. static    TIFFWriteString();
  84. #ifdef JPEG_SUPPORT
  85. static    TIFFWriteJPEGQTables();
  86. static    TIFFWriteJPEGCTables();
  87. #endif
  88. static    TIFFWriteData();
  89. static    TIFFLinkDirectory();
  90. #endif
  91.  
  92. #define    WriteRationalPair(type, tag1, v1, tag2, v2) {        \
  93.     if (!TIFFWriteRational(tif, type, tag1, dir, v1))    \
  94.         goto bad;                    \
  95.     if (!TIFFWriteRational(tif, type, tag2, dir+1, v2))    \
  96.         goto bad;                    \
  97.     dir++;                            \
  98. }
  99.  
  100. static    long dataoff;
  101. /*
  102.  * Write the contents of the current directory
  103.  * to the specified file.  This routine doesn't
  104.  * handle overwriting a directory with auxiliary
  105.  * storage that's been changed.
  106.  */
  107. TIFFWriteDirectory(tif)
  108.     TIFF *tif;
  109. {
  110.     short dircount, tag;
  111.     int nfields, dirsize;
  112.     char *data;
  113.     TIFFFieldInfo *fip;
  114.     TIFFDirEntry *dir;
  115.     TIFFDirectory *td;
  116.     u_long b, fields[sizeof (td->td_fieldsset) / sizeof (u_long)];
  117.  
  118.     if (tif->tif_mode == O_RDONLY)
  119.         return (1);
  120.     /*
  121.      * Clear write state so that subsequent images with
  122.      * different characteristics get the right buffers
  123.      * setup for them.
  124.      */
  125.     if (tif->tif_flags & TIFF_POSTENCODE) {
  126.         tif->tif_flags &= ~TIFF_POSTENCODE;
  127.         if (tif->tif_postencode && !(*tif->tif_postencode)(tif)) {
  128.             TIFFError(tif->tif_name,
  129.                 "Error post-encoding before directory write");
  130.             return (0);
  131.         }
  132.     }
  133.     if (tif->tif_close)
  134.         (*tif->tif_close)(tif);
  135.     if (tif->tif_cleanup)
  136.         (*tif->tif_cleanup)(tif);
  137.     /*
  138.      * Flush any data that might have been written
  139.      * by the compression close+cleanup routines.
  140.      */
  141.     if (tif->tif_rawcc > 0 && !TIFFFlushData1(tif)) {
  142.         TIFFError(tif->tif_name,
  143.             "Error flushing data before directory write");
  144.         return (0);
  145.     }
  146.     if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
  147.         free(tif->tif_rawdata);
  148.         tif->tif_rawdata = NULL;
  149.         tif->tif_rawcc = 0;
  150.     }
  151.     tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
  152.  
  153.     td = &tif->tif_dir;
  154.     /*
  155.      * Size the directory so that we can calculate
  156.      * offsets for the data items that aren't kept
  157.      * in-place in each field.
  158.      */
  159.     nfields = 0;
  160.     for (b = 0; b <= FIELD_LAST; b++)
  161.         if (TIFFFieldSet(tif, b))
  162.             nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
  163.     dirsize = nfields * sizeof (TIFFDirEntry);
  164.     data = malloc(dirsize);
  165.     if (data == NULL) {
  166.         TIFFError(tif->tif_name,
  167.             "Cannot write directory, out of space");
  168.         return (0);
  169.     }
  170.     /*
  171.      * Directory hasn't been placed yet, put
  172.      * it at the end of the file and link it
  173.      * into the existing directory structure.
  174.      */
  175.     if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
  176.         return (0);
  177.     dataoff = tif->tif_diroff + sizeof (short) + dirsize + sizeof (long);
  178.     if (dataoff & 1)
  179.         dataoff++;
  180.     (void) lseek(tif->tif_fd, dataoff, L_SET);
  181.     tif->tif_curdir++;
  182.     dir = (TIFFDirEntry *)data;
  183.     /*
  184.      * Setup external form of directory
  185.      * entries and write data items.
  186.      */
  187.     bcopy(td->td_fieldsset, fields, sizeof (fields));
  188. /*BEGIN XXX*/
  189.     /*
  190.      * Write out ExtraSamples tag only if Matteing would
  191.      * be set to 1 (i.e. Associated Alpha data is present).
  192.      */
  193.     if (FieldSet(fields, FIELD_MATTEING) && !td->td_matteing) {    /*XXX*/
  194.         ResetFieldBit(fields, FIELD_MATTEING);            /*XXX*/
  195.         nfields--;                        /*XXX*/
  196.         dirsize -= sizeof (TIFFDirEntry);            /*XXX*/
  197.     }                                /*XXX*/
  198. /*END XXX*/
  199.     for (fip = tiffFieldInfo; fip->field_tag; fip++) {
  200.         if (fip->field_bit == FIELD_IGNORE ||
  201.             !FieldSet(fields, fip->field_bit))
  202.             continue;
  203.         switch (fip->field_bit) {
  204.         case FIELD_STRIPOFFSETS:
  205.             /*
  206.              * We use one field bit for both strip and tile
  207.              * offsets, and so must be careful in selecting
  208.              * the appropriate field descriptor (so that tags
  209.              * are written in sorted order).
  210.              */
  211.             tag = isTiled(tif) ?
  212.                 TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
  213.             if (tag != fip->field_tag)
  214.                 continue;
  215.             if (!TIFFWriteLongArray(tif, TIFF_LONG, tag, dir,
  216.                 (int) td->td_nstrips, td->td_stripoffset))
  217.                 goto bad;
  218.             break;
  219.         case FIELD_STRIPBYTECOUNTS:
  220.             /*
  221.              * We use one field bit for both strip and tile
  222.              * byte counts, and so must be careful in selecting
  223.              * the appropriate field descriptor (so that tags
  224.              * are written in sorted order).
  225.              */
  226.             tag = isTiled(tif) ?
  227.                 TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
  228.             if (tag != fip->field_tag)
  229.                 continue;
  230.             if (!TIFFWriteLongArray(tif, TIFF_LONG, tag, dir,
  231.                 (int) td->td_nstrips, td->td_stripbytecount))
  232.                 goto bad;
  233.             break;
  234.         case FIELD_COLORMAP:
  235.             if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
  236.                 3, td->td_colormap))
  237.                 goto bad;
  238.             break;
  239.         case FIELD_IMAGEDIMENSIONS:
  240.             TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
  241.                 dir++, td->td_imagewidth);
  242.             TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
  243.                 dir, td->td_imagelength);
  244.             break;
  245.         case FIELD_TILEDIMENSIONS:
  246.             TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
  247.                 dir++, td->td_tilewidth);
  248.             TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
  249.                 dir, td->td_tilelength);
  250.             break;
  251.         case FIELD_POSITION:
  252.             WriteRationalPair(TIFF_RATIONAL,
  253.                 TIFFTAG_XPOSITION, td->td_xposition,
  254.                 TIFFTAG_YPOSITION, td->td_yposition);
  255.             break;
  256.         case FIELD_RESOLUTION:
  257.             WriteRationalPair(TIFF_RATIONAL,
  258.                 TIFFTAG_XRESOLUTION, td->td_xresolution,
  259.                 TIFFTAG_YRESOLUTION, td->td_yresolution);
  260.             break;
  261.         case FIELD_BITSPERSAMPLE:
  262.         case FIELD_MINSAMPLEVALUE:
  263.         case FIELD_MAXSAMPLEVALUE:
  264.         case FIELD_SAMPLEFORMAT:
  265.             if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
  266.                 goto bad;
  267.             break;
  268.         case FIELD_PAGENUMBER:
  269.         case FIELD_HALFTONEHINTS:
  270. #ifdef YCBCR_SUPPORT
  271.         case FIELD_YCBCRSUBSAMPLING:
  272. #endif
  273. #ifdef CMYK_SUPPORT
  274.         case FIELD_DOTRANGE:
  275. #endif
  276.             TIFFSetupShortPair(tif, fip->field_tag, dir);
  277.             break;
  278. #ifdef JPEG_SUPPORT
  279.         case FIELD_JPEGQTABLES:
  280.             if (!TIFFWriteJPEGQTables(tif, dir))
  281.                 goto bad;
  282.             break;
  283.         case FIELD_JPEGDCTABLES:
  284.             if (!TIFFWriteJPEGCTables(tif,
  285.                 TIFFTAG_JPEGDCTABLES, dir, td->td_dctab))
  286.                 goto bad;
  287.             break;
  288.         case FIELD_JPEGACTABLES:
  289.             if (!TIFFWriteJPEGCTables(tif,
  290.                 TIFFTAG_JPEGACTABLES, dir, td->td_actab))
  291.                 goto bad;
  292.             break;
  293. #endif
  294. #ifdef COLORIMETRY_SUPPORT
  295.         case FIELD_REFBLACKWHITE:
  296.             if (!TIFFWriteRationalArray(tif, TIFF_RATIONAL,
  297.                 TIFFTAG_REFERENCEBLACKWHITE, dir,
  298.                 2*td->td_samplesperpixel, td->td_refblackwhite))
  299.                 goto bad;
  300.             break;
  301.         case FIELD_TRANSFERFUNCTION:
  302.             if (!TIFFWriteTransferFunction(tif, dir))
  303.                 goto bad;
  304.             break;
  305. #endif
  306.         default:
  307.             if (!TIFFWriteNormalTag(tif, dir, fip))
  308.                 goto bad;
  309.             break;
  310.         }
  311.         dir++;
  312.         ResetFieldBit(fields, fip->field_bit);
  313.     }
  314.     /*
  315.      * Write directory.
  316.      */
  317.     (void) lseek(tif->tif_fd, tif->tif_diroff, L_SET);
  318.     dircount = nfields;
  319.     if (!WriteOK(tif->tif_fd, &dircount, sizeof (short))) {
  320.         TIFFError(tif->tif_name, "Error writing directory count");
  321.         goto bad;
  322.     }
  323.     if (!WriteOK(tif->tif_fd, data, dirsize)) {
  324.         TIFFError(tif->tif_name, "Error writing directory contents");
  325.         goto bad;
  326.     }
  327.     if (!WriteOK(tif->tif_fd, &tif->tif_nextdiroff, sizeof (long))) {
  328.         TIFFError(tif->tif_name, "Error writing directory link");
  329.         goto bad;
  330.     }
  331.     TIFFFreeDirectory(tif);
  332.     free(data);
  333.     tif->tif_flags &= ~TIFF_DIRTYDIRECT;
  334.  
  335.     /*
  336.      * Reset directory-related state for subsequent
  337.      * directories.
  338.      */
  339.     TIFFDefaultDirectory(tif);
  340.     tif->tif_diroff = 0;
  341.     tif->tif_curoff = 0;
  342.     tif->tif_row = -1;
  343.     tif->tif_curstrip = -1;
  344.     return (1);
  345. bad:
  346.     free(data);
  347.     return (0);
  348. }
  349. #undef WriteRationalPair
  350.  
  351. /*
  352.  * Process tags that are not special cased.
  353.  */
  354. static
  355. DECLARE3(TIFFWriteNormalTag,
  356.     TIFF*, tif, TIFFDirEntry*, dir, TIFFFieldInfo*, fip)
  357. {
  358.     TIFFDirectory* td = &tif->tif_dir;
  359.     u_short wc = (u_short) fip->field_writecount;
  360.  
  361.     dir->tdir_tag = fip->field_tag;
  362.     dir->tdir_type = (u_short)fip->field_type;
  363.     dir->tdir_count = wc;
  364. #define    WRITE(x,y)    x(tif, fip->field_type, fip->field_tag, dir, wc, y)
  365.     switch (fip->field_type) {
  366.     case TIFF_SHORT:
  367.     case TIFF_SSHORT:
  368.         if (wc > 1) {
  369.             u_short *wp;
  370.             if (wc == (u_short) TIFF_VARIABLE) {
  371.                 _TIFFgetfield(td, fip->field_tag, &wc, &wp);
  372.                 dir->tdir_count = wc;
  373.             } else
  374.                 _TIFFgetfield(td, fip->field_tag, &wp);
  375.             if (!WRITE(TIFFWriteShortArray, wp))
  376.                 return (0);
  377.         } else {
  378.             u_short sv;
  379.             _TIFFgetfield(td, fip->field_tag, &sv);
  380.             dir->tdir_offset =
  381.                 TIFFInsertData(tif, dir->tdir_type, sv);
  382.         }
  383.         break;
  384.     case TIFF_LONG:
  385.     case TIFF_SLONG:
  386.         if (wc > 1) {
  387.             u_long *lp;
  388.             if (wc == (u_short) TIFF_VARIABLE) {
  389.                 _TIFFgetfield(td, fip->field_tag, &wc, &lp);
  390.                 dir->tdir_count = wc;
  391.             } else
  392.                 _TIFFgetfield(td, fip->field_tag, &lp);
  393.             if (!WRITE(TIFFWriteLongArray, lp))
  394.                 return (0);
  395.         } else {
  396.             /* XXX handle LONG->SHORT conversion */
  397.             _TIFFgetfield(td, fip->field_tag, &dir->tdir_offset);
  398.         }
  399.         break;
  400.     case TIFF_RATIONAL:
  401.     case TIFF_SRATIONAL:
  402.         if (wc > 1) {
  403.             float *fp;
  404.             if (wc == (u_short) TIFF_VARIABLE) {
  405.                 _TIFFgetfield(td, fip->field_tag, &wc, &fp);
  406.                 dir->tdir_count = wc;
  407.             } else
  408.                 _TIFFgetfield(td, fip->field_tag, &fp);
  409.             if (!WRITE(TIFFWriteRationalArray, fp))
  410.                 return (0);
  411.         } else {
  412.             float fv;
  413.             _TIFFgetfield(td, fip->field_tag, &fv);
  414.             if (!TIFFWriteRational(tif, fip->field_type, fip->field_tag, dir, fv))
  415.                 return (0);
  416.         }
  417.         break;
  418.     case TIFF_FLOAT:
  419.         if (wc > 1) {
  420.             float *fp;
  421.             if (wc == (u_short) TIFF_VARIABLE) {
  422.                 _TIFFgetfield(td, fip->field_tag, &wc, &fp);
  423.                 dir->tdir_count = wc;
  424.             } else
  425.                 _TIFFgetfield(td, fip->field_tag, &fp);
  426.             if (!WRITE(TIFFWriteFloatArray, fp))
  427.                 return (0);
  428.         } else {
  429.             float fv;
  430.             _TIFFgetfield(td, fip->field_tag, &fv);
  431.             TIFFCvtNativeToIEEEFloat(tif, 1, &fv);
  432.             /* XXX assumes sizeof (long) == sizeof (float) */
  433.             dir->tdir_offset = *(u_long *)&fv;    /* XXX */
  434.         }
  435.         break;
  436.     case TIFF_ASCII: {
  437.         char *cp;
  438.         _TIFFgetfield(td, fip->field_tag, &cp);
  439.         if (!TIFFWriteString(tif, fip->field_tag, dir, cp))
  440.             return (0);
  441.         break;
  442.     }
  443.     }
  444.     return (1);
  445. }
  446. #undef WRITE
  447.  
  448. /*
  449.  * Setup a directory entry with either a SHORT
  450.  * or LONG type according to the value.
  451.  */
  452. static
  453. DECLARE4(TIFFSetupShortLong,
  454.     TIFF*, tif, u_short, tag, TIFFDirEntry*, dir, u_long, v)
  455. {
  456.     dir->tdir_tag = tag;
  457.     dir->tdir_count = 1;
  458.     if (v > 0xffffL) {
  459.         dir->tdir_type = (short)TIFF_LONG;
  460.         dir->tdir_offset = v;
  461.     } else {
  462.         dir->tdir_type = (short)TIFF_SHORT;
  463.         dir->tdir_offset = TIFFInsertData(tif, (int)TIFF_SHORT, v);
  464.     }
  465. }
  466. #undef MakeShortDirent
  467.  
  468. /*
  469.  * Setup a RATIONAL directory entry and
  470.  * write the associated indirect value.
  471.  */
  472. static
  473. DECLARE5(TIFFWriteRational,
  474.     TIFF*, tif, TIFFDataType, type, u_short, tag, TIFFDirEntry*, dir, float, v)
  475. {
  476.     u_long t[2];
  477.  
  478.     dir->tdir_tag = tag;
  479.     dir->tdir_type = (short)type;
  480.     dir->tdir_count = 1;
  481.     if (type == TIFF_RATIONAL && v < 0)
  482.         TIFFWarning(tif->tif_name,
  483.     "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
  484.             TIFFFieldWithTag(tag)->field_name, v);
  485.     /* need algorithm to convert ... XXX */
  486.     t[0] = v*10000.0 + 0.5;
  487.     t[1] = 10000;
  488.     return (TIFFWriteData(tif, dir, (char *)t));
  489. }
  490.  
  491. /*
  492.  * Setup a directory entry that references a
  493.  * samples/pixel array of SHORT values and
  494.  * (potentially) write the associated indirect
  495.  * values.
  496.  */
  497. static
  498. DECLARE3(TIFFWritePerSampleShorts,
  499.     TIFF*, tif, u_short, tag, TIFFDirEntry*, dir)
  500. {
  501.     u_short w[4], v;
  502.     int i, samplesperpixel = tif->tif_dir.td_samplesperpixel;
  503.  
  504.     _TIFFgetfield(&tif->tif_dir, tag, &v);
  505.     for (i = 0; i < samplesperpixel; i++)
  506.         w[i] = v;
  507.     return (TIFFWriteShortArray(
  508.         tif, TIFF_SHORT, tag, dir, samplesperpixel, w));
  509. }
  510.  
  511. /*
  512.  * Setup a pair of shorts that are returned by
  513.  * value, rather than as a reference to an array.
  514.  */
  515. static
  516. DECLARE3(TIFFSetupShortPair,
  517.     TIFF*, tif, u_short, tag, TIFFDirEntry*, dir)
  518. {
  519.     u_short v[2];
  520.  
  521.     _TIFFgetfield(&tif->tif_dir, tag, &v[0], &v[1]);
  522.     return (TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, 2, v));
  523. }
  524.  
  525. /*
  526.  * Setup a directory entry for an NxM table of shorts,
  527.  * where M is known to be 2**bitspersample, and write
  528.  * the associated indirect data.
  529.  */
  530. static
  531. DECLARE5(TIFFWriteShortTable,
  532.     TIFF*, tif, u_short, tag, TIFFDirEntry*, dir, int, n, u_short**, table)
  533. {
  534.     u_long off;
  535.     int i;
  536.  
  537.     dir->tdir_tag = tag;
  538.     dir->tdir_type = (short)TIFF_SHORT;
  539.     /* XXX -- yech, fool TIFFWriteData */
  540.     dir->tdir_count = 1L<<tif->tif_dir.td_bitspersample;
  541.     off = dataoff;
  542.     for (i = 0; i < n; i++)
  543.         if (!TIFFWriteData(tif, dir, (char *)table[i]))
  544.             return (0);
  545.     dir->tdir_count *= n;
  546.     dir->tdir_offset = off;
  547.     return (1);
  548. }
  549.  
  550. /*
  551.  * Setup a directory entry of an ASCII string
  552.  * and write any associated indirect value.
  553.  */
  554. static
  555. DECLARE4(TIFFWriteString,
  556.     TIFF*, tif, u_short, tag, TIFFDirEntry*, dir, char*, cp)
  557. {
  558.     dir->tdir_tag = tag;
  559.     dir->tdir_type = (short)TIFF_ASCII;
  560.     dir->tdir_count = strlen(cp) + 1;    /* includes \0 byte */
  561.     if (dir->tdir_count > 4) {
  562.         if (!TIFFWriteData(tif, dir, cp))
  563.             return (0);
  564.     } else
  565.         bcopy(cp, &dir->tdir_offset, dir->tdir_count);
  566.     return (1);
  567. }
  568.  
  569. /*
  570.  * Setup a directory entry of an array of SHORT
  571.  * or SSHORT and write the associated indirect values.
  572.  */
  573. static
  574. DECLARE6(TIFFWriteShortArray, TIFF*, tif,
  575.     TIFFDataType, type, u_short, tag, TIFFDirEntry*, dir, int, n, u_short*, v)
  576. {
  577.     dir->tdir_tag = tag;
  578.     dir->tdir_type = (short)type;
  579.     dir->tdir_count = n;
  580.     if (n <= 2) {
  581.         if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
  582.             dir->tdir_offset = (long)v[0] << 16;
  583.             if (n == 2)
  584.                 dir->tdir_offset |= v[1] & 0xffff;
  585.         } else {
  586.             dir->tdir_offset = v[0] & 0xffff;
  587.             if (n == 2)
  588.                 dir->tdir_offset |= (long)v[1] << 16;
  589.         }
  590.         return (1);
  591.     } else
  592.         return (TIFFWriteData(tif, dir, (char *)v));
  593. }
  594.  
  595. /*
  596.  * Setup a directory entry of an array of LONG
  597.  * or SLONG and write the associated indirect values.
  598.  */
  599. static
  600. DECLARE6(TIFFWriteLongArray, TIFF*, tif,
  601.     TIFFDataType, type, u_short, tag, TIFFDirEntry*, dir, int, n, u_long*, v)
  602. {
  603.     dir->tdir_tag = tag;
  604.     dir->tdir_type = (short)type;
  605.     dir->tdir_count = n;
  606.     if (n == 1) {
  607.         dir->tdir_offset = v[0];
  608.         return (1);
  609.     } else
  610.         return (TIFFWriteData(tif, dir, (char *)v));
  611. }
  612.  
  613. /*
  614.  * Setup a directory entry of an array of RATIONAL
  615.  * or SRATIONAL and write the associated indirect values.
  616.  */
  617. static
  618. DECLARE6(TIFFWriteRationalArray, TIFF*, tif,
  619.     TIFFDataType, type, u_short, tag, TIFFDirEntry*, dir, int, n, float*, v)
  620. {
  621.     int i, status;
  622.     u_long *t;
  623.  
  624.     dir->tdir_tag = tag;
  625.     dir->tdir_type = (short)type;
  626.     dir->tdir_count = n;
  627.     t = (u_long *)malloc(2*n * sizeof (long));
  628.     for (i = 0; i < n; i++) {
  629.         /* need algorithm to convert ... XXX */
  630.         t[2*i+0] = v[i]*10000.0 + 0.5;
  631.         t[2*i+1] = 10000;
  632.     }
  633.     status = TIFFWriteData(tif, dir, (char *)t);
  634.     free((char *)t);
  635.     return (status);
  636. }
  637.  
  638. static
  639. DECLARE6(TIFFWriteFloatArray, TIFF *, tif,
  640.     TIFFDataType, type, u_short, tag, TIFFDirEntry *, dir, int, n, float *, v)
  641. {
  642.     dir->tdir_tag = tag;
  643.     dir->tdir_type = (short)type;
  644.     dir->tdir_count = n;
  645.     TIFFCvtNativeToIEEEFloat(tif, n, v);
  646.     if (n == 1) {
  647.         dir->tdir_offset = *(u_long *)&v[0];
  648.         return (1);
  649.     } else
  650.         return (TIFFWriteData(tif, dir, (char *)v));
  651. }
  652.  
  653. #ifdef JPEG_SUPPORT
  654. /*
  655.  * Setup a directory entry for JPEG Quantization
  656.  * tables and write the associated indirect values.
  657.  */
  658. static
  659. DECLARE2(TIFFWriteJPEGQTables, TIFF*, tif, TIFFDirEntry*, dir)
  660. {
  661.     TIFFDirectory *td = &tif->tif_dir;
  662.     TIFFDirEntry tdir;
  663.     u_long off[4];
  664.     int i;
  665.  
  666.     tdir.tdir_tag = TIFFTAG_JPEGQTABLES;    /* for diagnostics */
  667.     tdir.tdir_type = (short)TIFF_BYTE;
  668.     tdir.tdir_count = 64;
  669.     for (i = 0; i < td->td_samplesperpixel; i++) {
  670.         if (!TIFFWriteData(tif, &tdir, (char *)td->td_qtab[i]))
  671.             return (0);
  672.         off[i] = tdir.tdir_offset;
  673.     }
  674.     return (TIFFWriteLongArray(tif, TIFF_LONG,
  675.         TIFFTAG_JPEGQTABLES, dir, td->td_samplesperpixel, off));
  676. }
  677.  
  678. /*
  679.  * Setup a directory entry for JPEG Coefficient
  680.  * tables and write the associated indirect values.
  681.  */
  682. static
  683. DECLARE4(TIFFWriteJPEGCTables,
  684.     TIFF*, tif, u_short, tag, TIFFDirEntry*, dir, u_char **, tab)
  685. {
  686.     TIFFDirectory *td = &tif->tif_dir;
  687.     TIFFDirEntry tdir;
  688.     u_long off[4];
  689.     int i, j, ncodes;
  690.  
  691.     tdir.tdir_tag = tag;        /* for diagnostics */
  692.     tdir.tdir_type = (short)TIFF_BYTE;
  693.     for (i = 0; i < td->td_samplesperpixel; i++) {
  694.         for (ncodes = 0, j = 0; j < 16; j++)
  695.             ncodes += tab[i][j];
  696.         tdir.tdir_count = 16+ncodes;
  697.         if (!TIFFWriteData(tif, &tdir, (char *)tab[i]))
  698.             return (0);
  699.         off[i] = tdir.tdir_offset;
  700.     }
  701.     return (TIFFWriteLongArray(tif,
  702.         TIFF_LONG, tag, dir, td->td_samplesperpixel, off));
  703. }
  704. #endif
  705.  
  706. #ifdef COLORIMETRY_SUPPORT
  707. static
  708. DECLARE2(TIFFWriteTransferFunction, TIFF*, tif, TIFFDirEntry*, dir)
  709. {
  710.     TIFFDirectory *td = &tif->tif_dir;
  711.     int j, ncols;
  712.     u_long n;
  713.     u_short **tf = td->td_transferfunction;
  714.  
  715.     /*
  716.      * Check if the table can be written as a single column.
  717.      */
  718.     n = (1L<<td->td_bitspersample) * sizeof (u_short);
  719.     ncols = 1;        /* assume only one column is needed */
  720.     for (j = 1; j < td->td_samplesperpixel; j++)
  721.         if (bcmp(tf[0], tf[j], n)) {
  722.             ncols = td->td_samplesperpixel;
  723.             break;
  724.         }
  725.     return (TIFFWriteShortTable(tif,
  726.         TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
  727. }
  728. #endif
  729.  
  730. /*
  731.  * Write a contiguous directory item.
  732.  */
  733. static
  734. TIFFWriteData(tif, dir, cp)
  735.     TIFF *tif;
  736.     TIFFDirEntry *dir;
  737.     char *cp;
  738. {
  739.     int cc;
  740.  
  741.     dir->tdir_offset = dataoff;
  742.     cc = dir->tdir_count * tiffDataWidth[dir->tdir_type];
  743.     if (SeekOK(tif->tif_fd, dir->tdir_offset) &&
  744.         WriteOK(tif->tif_fd, cp, cc)) {
  745.         dataoff += (cc + 1) & ~1;
  746.         return (1);
  747.     }
  748.     TIFFError(tif->tif_name, "Error writing data for field \"%s\"",
  749.         TIFFFieldWithTag(dir->tdir_tag)->field_name);
  750.     return (0);
  751. }
  752.  
  753. /*
  754.  * Link the current directory into the
  755.  * directory chain for the file.
  756.  */
  757. static
  758. TIFFLinkDirectory(tif)
  759.     register TIFF *tif;
  760. {
  761.     static char module[] = "TIFFLinkDirectory";
  762.     u_short dircount;
  763.     long nextdir;
  764.  
  765.     tif->tif_diroff = (lseek(tif->tif_fd, 0L, L_XTND)+1) &~ 1L;
  766.     if (tif->tif_header.tiff_diroff == 0) {
  767.         /*
  768.          * First directory, overwrite header.
  769.          */
  770.         tif->tif_header.tiff_diroff = tif->tif_diroff;
  771.         (void) lseek(tif->tif_fd, 0L, L_SET);
  772.         if (!WriteOK(tif->tif_fd, &tif->tif_header,
  773.             sizeof (tif->tif_header))) {
  774.             TIFFError(tif->tif_name, "Error writing TIFF header");
  775.             return (0);
  776.         }
  777.         return (1);
  778.     }
  779.     /*
  780.      * Not the first directory, search to the last and append.
  781.      */
  782.     nextdir = tif->tif_header.tiff_diroff;
  783.     do {
  784.         if (!SeekOK(tif->tif_fd, nextdir) ||
  785.             !ReadOK(tif->tif_fd, &dircount, sizeof (dircount))) {
  786.             TIFFError(module, "Error fetching directory count");
  787.             return (0);
  788.         }
  789.         if (tif->tif_flags & TIFF_SWAB)
  790.             TIFFSwabShort(&dircount);
  791.         lseek(tif->tif_fd, dircount * sizeof (TIFFDirEntry), L_INCR);
  792.         if (!ReadOK(tif->tif_fd, &nextdir, sizeof (nextdir))) {
  793.             TIFFError(module, "Error fetching directory link");
  794.             return (0);
  795.         }
  796.         if (tif->tif_flags & TIFF_SWAB)
  797.             TIFFSwabLong((u_long *)&nextdir);
  798.     } while (nextdir != 0);
  799.     (void) lseek(tif->tif_fd, -sizeof (nextdir), L_INCR);
  800.     if (!WriteOK(tif->tif_fd, &tif->tif_diroff, sizeof (tif->tif_diroff))) {
  801.         TIFFError(module, "Error writing directory link");
  802.         return (0);
  803.     }
  804.     return (1);
  805. }
  806.