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