home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / tiff / tif_dirwrite.c < prev    next >
C/C++ Source or Header  |  2002-11-10  |  29KB  |  1,024 lines

  1. /* $Header: /pack/cvsroots/wxwindows/wxWindows/src/tiff/tif_dirwrite.c,v 1.1.6.1 2002/11/10 13:13:55 JS Exp $ */
  2.  
  3. /*
  4.  * Copyright (c) 1988-1997 Sam Leffler
  5.  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26.  
  27. /*
  28.  * TIFF Library.
  29.  *
  30.  * Directory Write Support Routines.
  31.  */
  32. #include "tiffiop.h"
  33.  
  34. #if HAVE_IEEEFP
  35. #define    TIFFCvtNativeToIEEEFloat(tif, n, fp)
  36. #define    TIFFCvtNativeToIEEEDouble(tif, n, dp)
  37. #else
  38. extern    void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
  39. extern    void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
  40. #endif
  41.  
  42. static    int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
  43. static    void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
  44. static    int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
  45. static    int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
  46. static    int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
  47. static    int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
  48. static    int TIFFWriteShortArray(TIFF*,
  49.         TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint16*);
  50. static    int TIFFWriteLongArray(TIFF *,
  51.         TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint32*);
  52. static    int TIFFWriteRationalArray(TIFF *,
  53.         TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*);
  54. static    int TIFFWriteFloatArray(TIFF *,
  55.         TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*);
  56. static    int TIFFWriteDoubleArray(TIFF *,
  57.         TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
  58. static    int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
  59. static    int TIFFWriteAnyArray(TIFF*,
  60.         TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
  61. #ifdef COLORIMETRY_SUPPORT
  62. static    int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
  63. #endif
  64. #ifdef CMYK_SUPPORT
  65. static    int TIFFWriteInkNames(TIFF*, TIFFDirEntry*);
  66. #endif
  67. static    int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
  68. static    int TIFFLinkDirectory(TIFF*);
  69.  
  70. #define    WriteRationalPair(type, tag1, v1, tag2, v2) {        \
  71.     if (!TIFFWriteRational(tif, type, tag1, dir, v1))    \
  72.         goto bad;                    \
  73.     if (!TIFFWriteRational(tif, type, tag2, dir+1, v2))    \
  74.         goto bad;                    \
  75.     dir++;                            \
  76. }
  77. #define    TIFFWriteRational(tif, type, tag, dir, v) \
  78.     TIFFWriteRationalArray((tif), (type), (tag), (dir), 1, &(v))
  79. #ifndef TIFFWriteRational
  80. static    int TIFFWriteRational(TIFF*,
  81.         TIFFDataType, ttag_t, TIFFDirEntry*, float);
  82. #endif
  83.  
  84. /*
  85.  * Write the contents of the current directory
  86.  * to the specified file.  This routine doesn't
  87.  * handle overwriting a directory with auxiliary
  88.  * storage that's been changed.
  89.  */
  90. int
  91. TIFFWriteDirectory(TIFF* tif)
  92. {
  93.     uint16 dircount;
  94.     uint32 diroff;
  95.     ttag_t tag;
  96.     uint32 nfields;
  97.     tsize_t dirsize;
  98.     char* data;
  99.     TIFFDirEntry* dir;
  100.     TIFFDirectory* td;
  101.     u_long b, fields[FIELD_SETLONGS];
  102.     int fi, nfi;
  103.  
  104.     if (tif->tif_mode == O_RDONLY)
  105.         return (1);
  106.     /*
  107.      * Clear write state so that subsequent images with
  108.      * different characteristics get the right buffers
  109.      * setup for them.
  110.      */
  111.     if (tif->tif_flags & TIFF_POSTENCODE) {
  112.         tif->tif_flags &= ~TIFF_POSTENCODE;
  113.         if (!(*tif->tif_postencode)(tif)) {
  114.             TIFFError(tif->tif_name,
  115.                 "Error post-encoding before directory write");
  116.             return (0);
  117.         }
  118.     }
  119.     (*tif->tif_close)(tif);            /* shutdown encoder */
  120.     /*
  121.      * Flush any data that might have been written
  122.      * by the compression close+cleanup routines.
  123.      */
  124.     if (tif->tif_rawcc > 0 && !TIFFFlushData1(tif)) {
  125.         TIFFError(tif->tif_name,
  126.             "Error flushing data before directory write");
  127.         return (0);
  128.     }
  129.     if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
  130.         _TIFFfree(tif->tif_rawdata);
  131.         tif->tif_rawdata = NULL;
  132.         tif->tif_rawcc = 0;
  133.     }
  134.     tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
  135.  
  136.     td = &tif->tif_dir;
  137.     /*
  138.      * Size the directory so that we can calculate
  139.      * offsets for the data items that aren't kept
  140.      * in-place in each field.
  141.      */
  142.     nfields = 0;
  143.     for (b = 0; b <= FIELD_LAST; b++)
  144.         if (TIFFFieldSet(tif, b))
  145.             nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
  146.     dirsize = nfields * sizeof (TIFFDirEntry);
  147.     data = (char*) _TIFFmalloc(dirsize);
  148.     if (data == NULL) {
  149.         TIFFError(tif->tif_name,
  150.             "Cannot write directory, out of space");
  151.         return (0);
  152.     }
  153.     /*
  154.      * Directory hasn't been placed yet, put
  155.      * it at the end of the file and link it
  156.      * into the existing directory structure.
  157.      */
  158.     if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
  159.         goto bad;
  160.     tif->tif_dataoff = (toff_t)(
  161.         tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
  162.     if (tif->tif_dataoff & 1)
  163.         tif->tif_dataoff++;
  164.     (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
  165.     tif->tif_curdir++;
  166.     dir = (TIFFDirEntry*) data;
  167.     /*
  168.      * Setup external form of directory
  169.      * entries and write data items.
  170.      */
  171.     _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
  172.     /*
  173.      * Write out ExtraSamples tag only if
  174.      * extra samples are present in the data.
  175.      */
  176.     if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) {
  177.         ResetFieldBit(fields, FIELD_EXTRASAMPLES);
  178.         nfields--;
  179.         dirsize -= sizeof (TIFFDirEntry);
  180.     }                                /*XXX*/
  181.     for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
  182.         const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
  183.         if (!FieldSet(fields, fip->field_bit))
  184.             continue;
  185.         switch (fip->field_bit) {
  186.         case FIELD_STRIPOFFSETS:
  187.             /*
  188.              * We use one field bit for both strip and tile
  189.              * offsets, and so must be careful in selecting
  190.              * the appropriate field descriptor (so that tags
  191.              * are written in sorted order).
  192.              */
  193.             tag = isTiled(tif) ?
  194.                 TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
  195.             if (tag != fip->field_tag)
  196.                 continue;
  197.             if (!TIFFWriteLongArray(tif, TIFF_LONG, tag, dir,
  198.                 (uint32) td->td_nstrips, td->td_stripoffset))
  199.                 goto bad;
  200.             break;
  201.         case FIELD_STRIPBYTECOUNTS:
  202.             /*
  203.              * We use one field bit for both strip and tile
  204.              * byte counts, and so must be careful in selecting
  205.              * the appropriate field descriptor (so that tags
  206.              * are written in sorted order).
  207.              */
  208.             tag = isTiled(tif) ?
  209.                 TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
  210.             if (tag != fip->field_tag)
  211.                 continue;
  212.             if (!TIFFWriteLongArray(tif, TIFF_LONG, tag, dir,
  213.                 (uint32) td->td_nstrips, td->td_stripbytecount))
  214.                 goto bad;
  215.             break;
  216.         case FIELD_ROWSPERSTRIP:
  217.             TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
  218.                 dir, td->td_rowsperstrip);
  219.             break;
  220.         case FIELD_COLORMAP:
  221.             if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
  222.                 3, td->td_colormap))
  223.                 goto bad;
  224.             break;
  225.         case FIELD_IMAGEDIMENSIONS:
  226.             TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
  227.                 dir++, td->td_imagewidth);
  228.             TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
  229.                 dir, td->td_imagelength);
  230.             break;
  231.         case FIELD_TILEDIMENSIONS:
  232.             TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
  233.                 dir++, td->td_tilewidth);
  234.             TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
  235.                 dir, td->td_tilelength);
  236.             break;
  237.         case FIELD_POSITION:
  238.             WriteRationalPair(TIFF_RATIONAL,
  239.                 TIFFTAG_XPOSITION, td->td_xposition,
  240.                 TIFFTAG_YPOSITION, td->td_yposition);
  241.             break;
  242.         case FIELD_RESOLUTION:
  243.             WriteRationalPair(TIFF_RATIONAL,
  244.                 TIFFTAG_XRESOLUTION, td->td_xresolution,
  245.                 TIFFTAG_YRESOLUTION, td->td_yresolution);
  246.             break;
  247.         case FIELD_BITSPERSAMPLE:
  248.         case FIELD_MINSAMPLEVALUE:
  249.         case FIELD_MAXSAMPLEVALUE:
  250.         case FIELD_SAMPLEFORMAT:
  251.             if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
  252.                 goto bad;
  253.             break;
  254.         case FIELD_SMINSAMPLEVALUE:
  255.         case FIELD_SMAXSAMPLEVALUE:
  256.             if (!TIFFWritePerSampleAnys(tif,
  257.                 _TIFFSampleToTagType(tif), fip->field_tag, dir))
  258.                 goto bad;
  259.             break;
  260.         case FIELD_PAGENUMBER:
  261.         case FIELD_HALFTONEHINTS:
  262. #ifdef YCBCR_SUPPORT
  263.         case FIELD_YCBCRSUBSAMPLING:
  264. #endif
  265. #ifdef CMYK_SUPPORT
  266.         case FIELD_DOTRANGE:
  267. #endif
  268.             if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
  269.                 goto bad;
  270.             break;
  271. #ifdef CMYK_SUPPORT
  272.         case FIELD_INKNAMES:
  273.             if (!TIFFWriteInkNames(tif, dir))
  274.                 goto bad;
  275.             break;
  276. #endif
  277. #ifdef COLORIMETRY_SUPPORT
  278.         case FIELD_TRANSFERFUNCTION:
  279.             if (!TIFFWriteTransferFunction(tif, dir))
  280.                 goto bad;
  281.             break;
  282. #endif
  283. #if SUBIFD_SUPPORT
  284.         case FIELD_SUBIFD:
  285.             if (!TIFFWriteNormalTag(tif, dir, fip))
  286.                 goto bad;
  287.             /*
  288.              * Total hack: if this directory includes a SubIFD
  289.              * tag then force the next <n> directories to be
  290.              * written as ``sub directories'' of this one.  This
  291.              * is used to write things like thumbnails and
  292.              * image masks that one wants to keep out of the
  293.              * normal directory linkage access mechanism.
  294.              */
  295.             if (dir->tdir_count > 0) {
  296.                 tif->tif_flags |= TIFF_INSUBIFD;
  297.                 tif->tif_nsubifd = dir->tdir_count;
  298.                 if (dir->tdir_count > 1)
  299.                     tif->tif_subifdoff = dir->tdir_offset;
  300.                 else
  301.                     tif->tif_subifdoff = (uint32)(
  302.                           tif->tif_diroff
  303.                         + sizeof (uint16)
  304.                         + ((char*)&dir->tdir_offset-data));
  305.             }
  306.             break;
  307. #endif
  308.         default:
  309.             if (!TIFFWriteNormalTag(tif, dir, fip))
  310.                 goto bad;
  311.             break;
  312.         }
  313.         dir++;
  314.         ResetFieldBit(fields, fip->field_bit);
  315.     }
  316.     /*
  317.      * Write directory.
  318.      */
  319.     dircount = (uint16) nfields;
  320.     diroff = (uint32) tif->tif_nextdiroff;
  321.     if (tif->tif_flags & TIFF_SWAB) {
  322.         /*
  323.          * The file's byte order is opposite to the
  324.          * native machine architecture.  We overwrite
  325.          * the directory information with impunity
  326.          * because it'll be released below after we
  327.          * write it to the file.  Note that all the
  328.          * other tag construction routines assume that
  329.          * we do this byte-swapping; i.e. they only
  330.          * byte-swap indirect data.
  331.          */
  332.         for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
  333.             TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
  334.             TIFFSwabArrayOfLong(&dir->tdir_count, 2);
  335.         }
  336.         dircount = (uint16) nfields;
  337.         TIFFSwabShort(&dircount);
  338.         TIFFSwabLong(&diroff);
  339.     }
  340.     (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
  341.     if (!WriteOK(tif, &dircount, sizeof (dircount))) {
  342.         TIFFError(tif->tif_name, "Error writing directory count");
  343.         goto bad;
  344.     }
  345.     if (!WriteOK(tif, data, dirsize)) {
  346.         TIFFError(tif->tif_name, "Error writing directory contents");
  347.         goto bad;
  348.     }
  349.     if (!WriteOK(tif, &diroff, sizeof (diroff))) {
  350.         TIFFError(tif->tif_name, "Error writing directory link");
  351.         goto bad;
  352.     }
  353.     TIFFFreeDirectory(tif);
  354.     _TIFFfree(data);
  355.     tif->tif_flags &= ~TIFF_DIRTYDIRECT;
  356.     (*tif->tif_cleanup)(tif);
  357.  
  358.     /*
  359.      * Reset directory-related state for subsequent
  360.      * directories.
  361.      */
  362.     TIFFDefaultDirectory(tif);
  363.     tif->tif_diroff = 0;
  364.     tif->tif_curoff = 0;
  365.     tif->tif_row = (uint32) -1;
  366.     tif->tif_curstrip = (tstrip_t) -1;
  367.     return (1);
  368. bad:
  369.     _TIFFfree(data);
  370.     return (0);
  371. }
  372. #undef WriteRationalPair
  373.  
  374. /*
  375.  * Process tags that are not special cased.
  376.  */
  377. static int
  378. TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip)
  379. {
  380.     u_short wc = (u_short) fip->field_writecount;
  381.     uint32 wc2;
  382.  
  383.     dir->tdir_tag = fip->field_tag;
  384.     dir->tdir_type = (u_short) fip->field_type;
  385.     dir->tdir_count = wc;
  386. #define    WRITEF(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.             uint16* wp;
  392.             if (wc == (u_short) TIFF_VARIABLE)
  393.                 TIFFGetField(tif, fip->field_tag, &wc, &wp);
  394.             else
  395.                 TIFFGetField(tif, fip->field_tag, &wp);
  396.             if (!WRITEF(TIFFWriteShortArray, wp))
  397.                 return (0);
  398.         } else {
  399.             uint16 sv;
  400.             TIFFGetField(tif, fip->field_tag, &sv);
  401.             dir->tdir_offset =
  402.                 TIFFInsertData(tif, dir->tdir_type, sv);
  403.         }
  404.         break;
  405.     case TIFF_LONG:
  406.     case TIFF_SLONG:
  407.         if (wc > 1) {
  408.             uint32* lp;
  409.             if (wc == (u_short) TIFF_VARIABLE)
  410.                 TIFFGetField(tif, fip->field_tag, &wc, &lp);
  411.             else
  412.                 TIFFGetField(tif, fip->field_tag, &lp);
  413.             if (!WRITEF(TIFFWriteLongArray, lp))
  414.                 return (0);
  415.         } else {
  416.             /* XXX handle LONG->SHORT conversion */
  417.             TIFFGetField(tif, fip->field_tag, &dir->tdir_offset);
  418.         }
  419.         break;
  420.     case TIFF_RATIONAL:
  421.     case TIFF_SRATIONAL:
  422.         if (wc > 1) {
  423.             float* fp;
  424.             if (wc == (u_short) TIFF_VARIABLE)
  425.                 TIFFGetField(tif, fip->field_tag, &wc, &fp);
  426.             else
  427.                 TIFFGetField(tif, fip->field_tag, &fp);
  428.             if (!WRITEF(TIFFWriteRationalArray, fp))
  429.                 return (0);
  430.         } else {
  431.             float fv;
  432.             TIFFGetField(tif, fip->field_tag, &fv);
  433.             if (!WRITEF(TIFFWriteRationalArray, &fv))
  434.                 return (0);
  435.         }
  436.         break;
  437.     case TIFF_FLOAT:
  438.         if (wc > 1) {
  439.             float* fp;
  440.             if (wc == (u_short) TIFF_VARIABLE)
  441.                 TIFFGetField(tif, fip->field_tag, &wc, &fp);
  442.             else
  443.                 TIFFGetField(tif, fip->field_tag, &fp);
  444.             if (!WRITEF(TIFFWriteFloatArray, fp))
  445.                 return (0);
  446.         } else {
  447.             float fv;
  448.             TIFFGetField(tif, fip->field_tag, &fv);
  449.             if (!WRITEF(TIFFWriteFloatArray, &fv))
  450.                 return (0);
  451.         }
  452.         break;
  453.     case TIFF_DOUBLE:
  454.         if (wc > 1) {
  455.             double* dp;
  456.             if (wc == (u_short) TIFF_VARIABLE)
  457.                 TIFFGetField(tif, fip->field_tag, &wc, &dp);
  458.             else
  459.                 TIFFGetField(tif, fip->field_tag, &dp);
  460.             if (!WRITEF(TIFFWriteDoubleArray, dp))
  461.                 return (0);
  462.         } else {
  463.             double dv;
  464.             TIFFGetField(tif, fip->field_tag, &dv);
  465.             if (!WRITEF(TIFFWriteDoubleArray, &dv))
  466.                 return (0);
  467.         }
  468.         break;
  469.     case TIFF_ASCII:
  470.         { char* cp;
  471.           TIFFGetField(tif, fip->field_tag, &cp);
  472.           dir->tdir_count = (uint32) (strlen(cp) + 1);
  473.           if (!TIFFWriteByteArray(tif, dir, cp))
  474.             return (0);
  475.         }
  476.         break;
  477.  
  478.         /* added based on patch request from MARTIN.MCBRIDE.MM@agfa.co.uk,
  479.            correctness not verified (FW, 99/08) */
  480.         case TIFF_BYTE:
  481.         case TIFF_SBYTE:          
  482.                 if (wc > 1) {
  483.                     char* cp;
  484.                     if (wc == (u_short) TIFF_VARIABLE) {
  485.                         TIFFGetField(tif, fip->field_tag, &wc, &cp);
  486.                         dir->tdir_count = wc;
  487.                     } else
  488.                         TIFFGetField(tif, fip->field_tag, &cp);
  489.                     if (!TIFFWriteByteArray(tif, dir, cp))
  490.                         return (0);
  491.                 } else {
  492.                     char cv;
  493.                     TIFFGetField(tif, fip->field_tag, &cv);
  494.                     if (!TIFFWriteByteArray(tif, dir, &cv))
  495.                         return (0);
  496.                 }
  497.                 break;
  498.  
  499.     case TIFF_UNDEFINED:
  500.         { char* cp;
  501.           if (wc == (u_short) TIFF_VARIABLE) {
  502.             TIFFGetField(tif, fip->field_tag, &wc, &cp);
  503.             dir->tdir_count = wc;
  504.           } else if (wc == (u_short) TIFF_VARIABLE2) {
  505.             TIFFGetField(tif, fip->field_tag, &wc2, &cp);
  506.             dir->tdir_count = wc2;
  507.           } else 
  508.             TIFFGetField(tif, fip->field_tag, &cp);
  509.           if (!TIFFWriteByteArray(tif, dir, cp))
  510.             return (0);
  511.         }
  512.         break;
  513.  
  514.         case TIFF_NOTYPE:
  515.                 break;
  516.     }
  517.     return (1);
  518. }
  519. #undef WRITEF
  520.  
  521. /*
  522.  * Setup a directory entry with either a SHORT
  523.  * or LONG type according to the value.
  524.  */
  525. static void
  526. TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
  527. {
  528.     dir->tdir_tag = tag;
  529.     dir->tdir_count = 1;
  530.     if (v > 0xffffL) {
  531.         dir->tdir_type = (short) TIFF_LONG;
  532.         dir->tdir_offset = v;
  533.     } else {
  534.         dir->tdir_type = (short) TIFF_SHORT;
  535.         dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
  536.     }
  537. }
  538. #undef MakeShortDirent
  539.  
  540. #ifndef TIFFWriteRational
  541. /*
  542.  * Setup a RATIONAL directory entry and
  543.  * write the associated indirect value.
  544.  */
  545. static int
  546. TIFFWriteRational(TIFF* tif,
  547.     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, float v)
  548. {
  549.     return (TIFFWriteRationalArray(tif, type, tag, dir, 1, &v));
  550. }
  551. #endif
  552.  
  553. #define    NITEMS(x)    (sizeof (x) / sizeof (x[0]))
  554. /*
  555.  * Setup a directory entry that references a
  556.  * samples/pixel array of SHORT values and
  557.  * (potentially) write the associated indirect
  558.  * values.
  559.  */
  560. static int
  561. TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
  562. {
  563.     uint16 buf[10], v;
  564.     uint16* w = buf;
  565.     int i, status, samples = tif->tif_dir.td_samplesperpixel;
  566.  
  567.     if (samples > NITEMS(buf))
  568.         w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
  569.     TIFFGetField(tif, tag, &v);
  570.     for (i = 0; i < samples; i++)
  571.         w[i] = v;
  572.     status = TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, samples, w);
  573.     if (w != buf)
  574.         _TIFFfree((char*) w);
  575.     return (status);
  576. }
  577.  
  578. /*
  579.  * Setup a directory entry that references a samples/pixel array of ``type''
  580.  * values and (potentially) write the associated indirect values.  The source
  581.  * data from TIFFGetField() for the specified tag must be returned as double.
  582.  */
  583. static int
  584. TIFFWritePerSampleAnys(TIFF* tif,
  585.     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
  586. {
  587.     double buf[10], v;
  588.     double* w = buf;
  589.     int i, status;
  590.     int samples = (int) tif->tif_dir.td_samplesperpixel;
  591.  
  592.     if (samples > NITEMS(buf))
  593.         w = (double*) _TIFFmalloc(samples * sizeof (double));
  594.     TIFFGetField(tif, tag, &v);
  595.     for (i = 0; i < samples; i++)
  596.         w[i] = v;
  597.     status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
  598.     if (w != buf)
  599.         _TIFFfree(w);
  600.     return (status);
  601. }
  602. #undef NITEMS
  603.  
  604. /*
  605.  * Setup a pair of shorts that are returned by
  606.  * value, rather than as a reference to an array.
  607.  */
  608. static int
  609. TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
  610. {
  611.     uint16 v[2];
  612.  
  613.     TIFFGetField(tif, tag, &v[0], &v[1]);
  614.     return (TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, 2, v));
  615. }
  616.  
  617. /*
  618.  * Setup a directory entry for an NxM table of shorts,
  619.  * where M is known to be 2**bitspersample, and write
  620.  * the associated indirect data.
  621.  */
  622. static int
  623. TIFFWriteShortTable(TIFF* tif,
  624.     ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
  625. {
  626.     uint32 i, off;
  627.  
  628.     dir->tdir_tag = tag;
  629.     dir->tdir_type = (short) TIFF_SHORT;
  630.     /* XXX -- yech, fool TIFFWriteData */
  631.     dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
  632.     off = tif->tif_dataoff;
  633.     for (i = 0; i < n; i++)
  634.         if (!TIFFWriteData(tif, dir, (char *)table[i]))
  635.             return (0);
  636.     dir->tdir_count *= n;
  637.     dir->tdir_offset = off;
  638.     return (1);
  639. }
  640.  
  641. /*
  642.  * Write/copy data associated with an ASCII or opaque tag value.
  643.  */
  644. static int
  645. TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
  646. {
  647.     if (dir->tdir_count > 4) {
  648.         if (!TIFFWriteData(tif, dir, cp))
  649.             return (0);
  650.     } else
  651.         _TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count);
  652.     return (1);
  653. }
  654.  
  655. /*
  656.  * Setup a directory entry of an array of SHORT
  657.  * or SSHORT and write the associated indirect values.
  658.  */
  659. static int
  660. TIFFWriteShortArray(TIFF* tif,
  661.     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16* v)
  662. {
  663.     dir->tdir_tag = tag;
  664.     dir->tdir_type = (short) type;
  665.     dir->tdir_count = n;
  666.     if (n <= 2) {
  667.         if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
  668.             dir->tdir_offset = (uint32) ((long) v[0] << 16);
  669.             if (n == 2)
  670.                 dir->tdir_offset |= v[1] & 0xffff;
  671.         } else {
  672.             dir->tdir_offset = v[0] & 0xffff;
  673.             if (n == 2)
  674.                 dir->tdir_offset |= (long) v[1] << 16;
  675.         }
  676.         return (1);
  677.     } else
  678.         return (TIFFWriteData(tif, dir, (char*) v));
  679. }
  680.  
  681. /*
  682.  * Setup a directory entry of an array of LONG
  683.  * or SLONG and write the associated indirect values.
  684.  */
  685. static int
  686. TIFFWriteLongArray(TIFF* tif,
  687.     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint32* v)
  688. {
  689.     dir->tdir_tag = tag;
  690.     dir->tdir_type = (short) type;
  691.     dir->tdir_count = n;
  692.     if (n == 1) {
  693.         dir->tdir_offset = v[0];
  694.         return (1);
  695.     } else
  696.         return (TIFFWriteData(tif, dir, (char*) v));
  697. }
  698.  
  699. /*
  700.  * Setup a directory entry of an array of RATIONAL
  701.  * or SRATIONAL and write the associated indirect values.
  702.  */
  703. static int
  704. TIFFWriteRationalArray(TIFF* tif,
  705.     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v)
  706. {
  707.     uint32 i;
  708.     uint32* t;
  709.     int status;
  710.  
  711.     dir->tdir_tag = tag;
  712.     dir->tdir_type = (short) type;
  713.     dir->tdir_count = n;
  714.     t = (uint32*) _TIFFmalloc(2*n * sizeof (uint32));
  715.     for (i = 0; i < n; i++) {
  716.         float fv = v[i];
  717.         int sign = 1;
  718.         uint32 den;
  719.  
  720.         if (fv < 0) {
  721.             if (type == TIFF_RATIONAL) {
  722.                 TIFFWarning(tif->tif_name,
  723.     "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
  724.                 _TIFFFieldWithTag(tif,tag)->field_name, fv);
  725.                 fv = 0;
  726.             } else
  727.                 fv = -fv, sign = -1;
  728.         }
  729.         den = 1L;
  730.         if (fv > 0) {
  731.             while (fv < 1L<<(31-3) && den < 1L<<(31-3))
  732.                 fv *= 1<<3, den *= 1L<<3;
  733.         }
  734.         t[2*i+0] = sign * (fv + 0.5);
  735.         t[2*i+1] = den;
  736.     }
  737.     status = TIFFWriteData(tif, dir, (char *)t);
  738.     _TIFFfree((char*) t);
  739.     return (status);
  740. }
  741.  
  742. static int
  743. TIFFWriteFloatArray(TIFF* tif,
  744.     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v)
  745. {
  746.     dir->tdir_tag = tag;
  747.     dir->tdir_type = (short) type;
  748.     dir->tdir_count = n;
  749.     TIFFCvtNativeToIEEEFloat(tif, n, v);
  750.     if (n == 1) {
  751.         dir->tdir_offset = *(uint32*) &v[0];
  752.         return (1);
  753.     } else
  754.         return (TIFFWriteData(tif, dir, (char*) v));
  755. }
  756.  
  757. static int
  758. TIFFWriteDoubleArray(TIFF* tif,
  759.     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
  760. {
  761.     dir->tdir_tag = tag;
  762.     dir->tdir_type = (short) type;
  763.     dir->tdir_count = n;
  764.     TIFFCvtNativeToIEEEDouble(tif, n, v);
  765.     return (TIFFWriteData(tif, dir, (char*) v));
  766. }
  767.  
  768. /*
  769.  * Write an array of ``type'' values for a specified tag (i.e. this is a tag
  770.  * which is allowed to have different types, e.g. SMaxSampleType).
  771.  * Internally the data values are represented as double since a double can
  772.  * hold any of the TIFF tag types (yes, this should really be an abstract
  773.  * type tany_t for portability).  The data is converted into the specified
  774.  * type in a temporary buffer and then handed off to the appropriate array
  775.  * writer.
  776.  */
  777. static int
  778. TIFFWriteAnyArray(TIFF* tif,
  779.     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
  780. {
  781.     char buf[10 * sizeof(double)];
  782.     char* w = buf;
  783.     int i, status = 0;
  784.  
  785.     if (n * tiffDataWidth[type] > sizeof buf)
  786.         w = (char*) _TIFFmalloc(n * tiffDataWidth[type]);
  787.     switch (type) {
  788.     case TIFF_BYTE:
  789.         { uint8* bp = (uint8*) w;
  790.           for (i = 0; i < n; i++)
  791.             bp[i] = (uint8) v[i];
  792.           dir->tdir_tag = tag;
  793.           dir->tdir_type = (short) type;
  794.           dir->tdir_count = n;
  795.           if (!TIFFWriteByteArray(tif, dir, (char*) bp))
  796.             goto out;
  797.         }
  798.         break;
  799.     case TIFF_SBYTE:
  800.         { int8* bp = (int8*) w;
  801.           for (i = 0; i < n; i++)
  802.             bp[i] = (int8) v[i];
  803.           dir->tdir_tag = tag;
  804.           dir->tdir_type = (short) type;
  805.           dir->tdir_count = n;
  806.           if (!TIFFWriteByteArray(tif, dir, (char*) bp))
  807.             goto out;
  808.         }
  809.         break;
  810.     case TIFF_SHORT:
  811.         { uint16* bp = (uint16*) w;
  812.           for (i = 0; i < n; i++)
  813.             bp[i] = (uint16) v[i];
  814.           if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp))
  815.                 goto out;
  816.         }
  817.         break;
  818.     case TIFF_SSHORT:
  819.         { int16* bp = (int16*) w;
  820.           for (i = 0; i < n; i++)
  821.             bp[i] = (int16) v[i];
  822.           if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp))
  823.             goto out;
  824.         }
  825.         break;
  826.     case TIFF_LONG:
  827.         { uint32* bp = (uint32*) w;
  828.           for (i = 0; i < n; i++)
  829.             bp[i] = (uint32) v[i];
  830.           if (!TIFFWriteLongArray(tif, type, tag, dir, n, bp))
  831.             goto out;
  832.         }
  833.         break;
  834.     case TIFF_SLONG:
  835.         { int32* bp = (int32*) w;
  836.           for (i = 0; i < n; i++)
  837.             bp[i] = (int32) v[i];
  838.           if (!TIFFWriteLongArray(tif, type, tag, dir, n, (uint32*) bp))
  839.             goto out;
  840.         }
  841.         break;
  842.     case TIFF_FLOAT:
  843.         { float* bp = (float*) w;
  844.           for (i = 0; i < n; i++)
  845.             bp[i] = (float) v[i];
  846.           if (!TIFFWriteFloatArray(tif, type, tag, dir, n, bp))
  847.             goto out;
  848.         }
  849.         break;
  850.     case TIFF_DOUBLE:
  851.         return (TIFFWriteDoubleArray(tif, type, tag, dir, n, v));
  852.     default:
  853.         /* TIFF_NOTYPE */
  854.         /* TIFF_ASCII */
  855.         /* TIFF_UNDEFINED */
  856.         /* TIFF_RATIONAL */
  857.         /* TIFF_SRATIONAL */
  858.         goto out;
  859.     }
  860.     status = 1;
  861.  out:
  862.     if (w != buf)
  863.         _TIFFfree(w);
  864.     return (status);
  865. }
  866.  
  867. #ifdef COLORIMETRY_SUPPORT
  868. static int
  869. TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
  870. {
  871.     TIFFDirectory* td = &tif->tif_dir;
  872.     tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
  873.     uint16** tf = td->td_transferfunction;
  874.     int ncols;
  875.  
  876.     /*
  877.      * Check if the table can be written as a single column,
  878.      * or if it must be written as 3 columns.  Note that we
  879.      * write a 3-column tag if there are 2 samples/pixel and
  880.      * a single column of data won't suffice--hmm.
  881.      */
  882.     switch (td->td_samplesperpixel - td->td_extrasamples) {
  883.     default:    if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
  884.     case 2:        if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
  885.     case 1: case 0:    ncols = 1;
  886.     }
  887.     return (TIFFWriteShortTable(tif,
  888.         TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
  889. }
  890. #endif
  891.  
  892. #ifdef CMYK_SUPPORT
  893. static int
  894. TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
  895. {
  896.     TIFFDirectory* td = &tif->tif_dir;
  897.  
  898.     dir->tdir_tag = TIFFTAG_INKNAMES;
  899.     dir->tdir_type = (short) TIFF_ASCII;
  900.     dir->tdir_count = td->td_inknameslen;
  901.     return (TIFFWriteByteArray(tif, dir, td->td_inknames));
  902. }
  903. #endif
  904.  
  905. /*
  906.  * Write a contiguous directory item.
  907.  */
  908. static int
  909. TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
  910. {
  911.     tsize_t cc;
  912.  
  913.     if (tif->tif_flags & TIFF_SWAB) {
  914.         switch (dir->tdir_type) {
  915.         case TIFF_SHORT:
  916.         case TIFF_SSHORT:
  917.             TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
  918.             break;
  919.         case TIFF_LONG:
  920.         case TIFF_SLONG:
  921.         case TIFF_FLOAT:
  922.             TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
  923.             break;
  924.         case TIFF_RATIONAL:
  925.         case TIFF_SRATIONAL:
  926.             TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
  927.             break;
  928.         case TIFF_DOUBLE:
  929.             TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
  930.             break;
  931.         }
  932.     }
  933.     dir->tdir_offset = tif->tif_dataoff;
  934.     cc = dir->tdir_count * tiffDataWidth[dir->tdir_type];
  935.     if (SeekOK(tif, dir->tdir_offset) &&
  936.         WriteOK(tif, cp, cc)) {
  937.         tif->tif_dataoff += (cc + 1) & ~1;
  938.         return (1);
  939.     }
  940.     TIFFError(tif->tif_name, "Error writing data for field \"%s\"",
  941.         _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
  942.     return (0);
  943. }
  944.  
  945. /*
  946.  * Link the current directory into the
  947.  * directory chain for the file.
  948.  */
  949. static int
  950. TIFFLinkDirectory(TIFF* tif)
  951. {
  952.     static const char module[] = "TIFFLinkDirectory";
  953.     uint32 nextdir;
  954.     uint32 diroff;
  955.  
  956.     tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
  957.     diroff = (uint32) tif->tif_diroff;
  958.     if (tif->tif_flags & TIFF_SWAB)
  959.         TIFFSwabLong(&diroff);
  960. #if SUBIFD_SUPPORT
  961.     if (tif->tif_flags & TIFF_INSUBIFD) {
  962.         (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
  963.         if (!WriteOK(tif, &diroff, sizeof (diroff))) {
  964.             TIFFError(module,
  965.                 "%s: Error writing SubIFD directory link",
  966.                 tif->tif_name);
  967.             return (0);
  968.         }
  969.         /*
  970.          * Advance to the next SubIFD or, if this is
  971.          * the last one configured, revert back to the
  972.          * normal directory linkage.
  973.          */
  974.         if (--tif->tif_nsubifd)
  975.             tif->tif_subifdoff += sizeof (diroff);
  976.         else
  977.             tif->tif_flags &= ~TIFF_INSUBIFD;
  978.         return (1);
  979.     }
  980. #endif
  981.     if (tif->tif_header.tiff_diroff == 0) {
  982.         /*
  983.          * First directory, overwrite offset in header.
  984.          */
  985.         tif->tif_header.tiff_diroff = (uint32) tif->tif_diroff;
  986. #define    HDROFF(f)    ((toff_t) &(((TIFFHeader*) 0)->f))
  987.         (void) TIFFSeekFile(tif, HDROFF(tiff_diroff), SEEK_SET);
  988.         if (!WriteOK(tif, &diroff, sizeof (diroff))) {
  989.             TIFFError(tif->tif_name, "Error writing TIFF header");
  990.             return (0);
  991.         }
  992.         return (1);
  993.     }
  994.     /*
  995.      * Not the first directory, search to the last and append.
  996.      */
  997.     nextdir = tif->tif_header.tiff_diroff;
  998.     do {
  999.         uint16 dircount;
  1000.  
  1001.         if (!SeekOK(tif, nextdir) ||
  1002.             !ReadOK(tif, &dircount, sizeof (dircount))) {
  1003.             TIFFError(module, "Error fetching directory count");
  1004.             return (0);
  1005.         }
  1006.         if (tif->tif_flags & TIFF_SWAB)
  1007.             TIFFSwabShort(&dircount);
  1008.         (void) TIFFSeekFile(tif,
  1009.             dircount * sizeof (TIFFDirEntry), SEEK_CUR);
  1010.         if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
  1011.             TIFFError(module, "Error fetching directory link");
  1012.             return (0);
  1013.         }
  1014.         if (tif->tif_flags & TIFF_SWAB)
  1015.             TIFFSwabLong(&nextdir);
  1016.     } while (nextdir != 0);
  1017.     (void) TIFFSeekFile(tif, -(toff_t) sizeof (nextdir), SEEK_CUR);
  1018.     if (!WriteOK(tif, &diroff, sizeof (diroff))) {
  1019.         TIFFError(module, "Error writing directory link");
  1020.         return (0);
  1021.     }
  1022.     return (1);
  1023. }
  1024.