home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0040 - 0049 / ibm0040-0049 / ibm0040.tar / ibm0040 / IMGPROC.ZIP / C6TIFF.ZIP / DIR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-30  |  42.9 KB  |  1,484 lines

  1. /*
  2.  * Copyright (c) 1988 by Sam Leffler.
  3.  * All rights reserved.
  4.  *
  5.  * This file is provided for unrestricted use provided that this
  6.  * legend is included on all tape media and as a part of the
  7.  * software program in whole or part.  Users may copy, modify or
  8.  * distribute this file at will.
  9.  */
  10.  
  11. /*
  12. Directory Support Routines.
  13. */
  14.  
  15. #include "tiffio.h"
  16. #include <sys/stat.h>
  17. #include <io.h>
  18. #include <alloc.h>
  19. #include <mem.h>
  20. #include <stdarg.h>
  21. #include <process.h>
  22. #include <string.h>
  23. #include "tiffio.h"
  24.  
  25. #define ReadOK(fd, buf, size)   (read(fd, (char *)buf, size) == size)
  26. #define WriteOK(fd, buf, size)  (write(fd, (char *)buf, size) == size)
  27. #define SeekOK(fd, off)         (lseek(fd, (long)off, SEEK_SET) == (long)off)
  28.  
  29. #define howmany(x, y)   (((x)+((y)-1))/(y))
  30. #define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
  31.  
  32. #define FieldSet(fields, f)             (fields[f/32] & (1L<<(f&0x1f)))
  33. #define ResetFieldBit(fields, f)        (fields[f/32] &= ~(1L<<(f&0x1f)))
  34.  
  35. #define TIFFExtractData(tif, type, v) \
  36.     ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \
  37.         ((v) >> (tif)->tif_typeshift[type]) & (tif)->tif_typemask[type] : \
  38.         (v) & (tif)->tif_typemask[type])
  39. #define TIFFInsertData(tif, type, v) \
  40.     ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \
  41.         ((v) & (tif)->tif_typemask[type]) << (tif)->tif_typeshift[type] : \
  42.         (v) & (tif)->tif_typemask[type])
  43.  
  44.  
  45. /*
  46. This array is assumed to be sorted by tag.
  47. */
  48. static  TIFFFieldInfo FieldInfo[] =
  49. {
  50.     { TIFFTAG_SUBFILETYPE,       1, LONG,       FIELD_SUBFILETYPE,
  51.       "SubfileType" },
  52.     { TIFFTAG_OSUBFILETYPE,      1, SHORT,      FIELD_SUBFILETYPE,
  53.       "OldSubfileType" },
  54.     { TIFFTAG_IMAGEWIDTH,        1, LONG,       FIELD_IMAGEDIMENSIONS,
  55.       "ImageWidth" },
  56.     { TIFFTAG_IMAGEWIDTH,        1, SHORT,      FIELD_IMAGEDIMENSIONS,
  57.       "ImageWidth" },
  58.     { TIFFTAG_IMAGELENGTH,       1, LONG,       FIELD_IMAGEDIMENSIONS,
  59.       "ImageLength" },
  60.     { TIFFTAG_IMAGELENGTH,       1, SHORT,      FIELD_IMAGEDIMENSIONS,
  61.       "ImageLength" },
  62.     { TIFFTAG_BITSPERSAMPLE,    -1, SHORT,      FIELD_BITSPERSAMPLE,
  63.       "BitsPerSample" },
  64.     { TIFFTAG_COMPRESSION,       1, SHORT,      FIELD_COMPRESSION,
  65.       "Compression" },
  66.     { TIFFTAG_PHOTOMETRIC,       1, SHORT,      FIELD_PHOTOMETRIC,
  67.       "PhotometricInterpretation" },
  68.     { TIFFTAG_THRESHHOLDING,     1, SHORT,      FIELD_THRESHHOLDING,
  69.       "Threshholding" },
  70.     { TIFFTAG_CELLWIDTH,         1, SHORT,      0xffff,
  71.       "CellWidth" },
  72.     { TIFFTAG_CELLLENGTH,        1, SHORT,      0xffff,
  73.       "CellLength" },
  74.     { TIFFTAG_FILLORDER,         1, SHORT,      0xffff,
  75.       "FillOrder" },
  76.     { TIFFTAG_DOCUMENTNAME,     -1, ASCII,      FIELD_DOCUMENTNAME,
  77.       "DocumentName" },
  78.     { TIFFTAG_IMAGEDESCRIPTION, -1, ASCII,      FIELD_IMAGEDESCRIPTION,
  79.       "ImageDescription" },
  80.     { TIFFTAG_MAKE,             -1, ASCII,      FIELD_MAKE,
  81.       "Make" },
  82.     { TIFFTAG_MODEL,            -1, ASCII,      FIELD_MODEL,
  83.       "Model" },
  84.     { TIFFTAG_STRIPOFFSETS,     -1, LONG,       FIELD_STRIPOFFSETS,
  85.       "StripOffsets" },
  86.     { TIFFTAG_STRIPOFFSETS,     -1, SHORT,      FIELD_STRIPOFFSETS,
  87.       "StripOffsets" },
  88.     { TIFFTAG_ORIENTATION,       1, SHORT,      FIELD_ORIENTATION,
  89.       "Orientation" },
  90.     { TIFFTAG_SAMPLESPERPIXEL,   1, SHORT,      FIELD_SAMPLESPERPIXEL,
  91.       "SamplesPerPixel" },
  92.     { TIFFTAG_ROWSPERSTRIP,      1, LONG,       FIELD_ROWSPERSTRIP,
  93.       "RowsPerStrip" },
  94.     { TIFFTAG_ROWSPERSTRIP,      1, SHORT,      FIELD_ROWSPERSTRIP,
  95.       "RowsPerStrip" },
  96.     { TIFFTAG_STRIPBYTECOUNTS,  -1, LONG,       FIELD_STRIPBYTECOUNTS,
  97.       "StripByteCounts" },
  98.     { TIFFTAG_STRIPBYTECOUNTS,  -1, SHORT,      FIELD_STRIPBYTECOUNTS,
  99.       "StripByteCounts" },
  100.     { TIFFTAG_MINSAMPLEVALUE,   -1, SHORT,      FIELD_MINSAMPLEVALUE,
  101.       "MinSampleValue" },
  102.     { TIFFTAG_MAXSAMPLEVALUE,   -1, SHORT,      FIELD_MAXSAMPLEVALUE,
  103.       "MaxSampleValue" },
  104.     { TIFFTAG_XRESOLUTION,       1, RATIONAL,   FIELD_RESOLUTION,
  105.       "XResolution" },
  106.     { TIFFTAG_YRESOLUTION,       1, RATIONAL,   FIELD_RESOLUTION,
  107.       "YResolution" },
  108.     { TIFFTAG_PLANARCONFIG,      1, SHORT,      FIELD_PLANARCONFIG,
  109.       "PlanarConfiguration" },
  110.     { TIFFTAG_PAGENAME,         -1, ASCII,      FIELD_PAGENAME,
  111.       "PageName" },
  112.     { TIFFTAG_XPOSITION,         1, RATIONAL,   FIELD_POSITION,
  113.       "XPosition" },
  114.     { TIFFTAG_YPOSITION,         1, RATIONAL,   FIELD_POSITION,
  115.       "YPosition" },
  116.     { TIFFTAG_FREEOFFSETS,      -1, LONG,       0xffff,
  117.       "FreeOffsets" },
  118.     { TIFFTAG_FREEBYTECOUNTS,   -1, LONG,       0xffff,
  119.       "FreeByteCounts" },
  120.     { TIFFTAG_GRAYRESPONSEUNIT,  1, SHORT,      FIELD_GRAYRESPONSEUNIT,
  121.       "GrayResponseUnit" },
  122.     { TIFFTAG_GRAYRESPONSECURVE,-1, SHORT,      FIELD_GRAYRESPONSECURVE,
  123.       "GrayResponseCurve" },
  124.     { TIFFTAG_GROUP3OPTIONS,     1, LONG,       FIELD_GROUP3OPTIONS,
  125.       "Group3Options" },
  126.     { TIFFTAG_GROUP4OPTIONS,     1, LONG,       FIELD_GROUP4OPTIONS,
  127.       "Group4Options" },
  128.     { TIFFTAG_RESOLUTIONUNIT,    1, SHORT,      FIELD_RESOLUTIONUNIT,
  129.       "ResolutionUnit" },
  130.     { TIFFTAG_PAGENUMBER,        2, SHORT,      FIELD_PAGENUMBER,
  131.       "PageNumber" },
  132.     { TIFFTAG_COLORRESPONSEUNIT, 1, SHORT,      FIELD_COLORRESPONSEUNIT,
  133.       "ColorResponseUnit" },
  134.     { TIFFTAG_COLORRESPONSECURVE,-1,SHORT,      FIELD_COLORRESPONSECURVE,
  135.       "ColorResponseCurve" },
  136.     { TIFFTAG_SOFTWARE,         -1, ASCII,      FIELD_SOFTWARE,
  137.       "Software" },
  138.     { TIFFTAG_DATETIME,         -1, ASCII,      FIELD_DATETIME,
  139.       "DateTime" },
  140.     { TIFFTAG_ARTIST,           -1, ASCII,      FIELD_ARTIST,
  141.       "Artist" },
  142.     { TIFFTAG_HOSTCOMPUTER,     -1, ASCII,      FIELD_HOSTCOMPUTER,
  143.       "HostComputer" },
  144.     { TIFFTAG_PREDICTOR,         1, SHORT,      FIELD_PREDICTOR,
  145.       "Predictor" },
  146.     { TIFFTAG_COLORMAP,         -1, SHORT,      FIELD_COLORMAP,
  147.       "ColorMap" }
  148. };
  149. #define NFIELDINFO      (sizeof (FieldInfo) / sizeof (FieldInfo[0]))
  150.  
  151. #define IGNORE  0               /* tag placeholder used below */
  152.  
  153. static unsigned datawidth[] =
  154. {
  155.     1,  /* nothing */
  156.     1,  /* BYTE */
  157.     1,  /* ASCII */
  158.     2,  /* SHORT */
  159.     4,  /* LONG */
  160.     8,  /* RATIONAL */
  161. };
  162.  
  163.  
  164. static TIFFFieldInfo *
  165. FieldWithTag(unsigned tag)
  166. {
  167.    register TIFFFieldInfo *fip;
  168.  
  169.    for (fip = FieldInfo; fip < &FieldInfo[NFIELDINFO]; fip++)
  170.       if (fip->field_tag == tag)
  171.      return (fip);
  172.    TIFFError("FieldWithTag", "Internal error, unknown tag 0x%x", tag);
  173.    exit(-1);
  174.    return((TIFFFieldInfo *) 0);
  175. }
  176.  
  177. /*
  178. Record the value of a field in the
  179. internal directory structure.  The
  180. field will be written to the file
  181. when/if the directory structure is
  182. updated.
  183. */
  184.  
  185. CompletionCode TIFFSetField(TIFF *tif, unsigned tag, ...)
  186. {
  187.    static char module[] = "TIFFSetField";
  188.    TIFFDirectory *td = &tif->tif_dir;
  189.    va_list ap;
  190.    long v;
  191.    int field = -1;
  192.    int status = TRUE;
  193.  
  194.    if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING))
  195.    {
  196.       TIFFError(module,"%s: Cannot change TIFF directory while writing",
  197.         tif->tif_name);
  198.       return (FALSE);
  199.    }
  200.    va_start(ap,tag);
  201.    switch (tag)
  202.    {
  203.       case TIFFTAG_SUBFILETYPE:
  204.      td->td_subfiletype = va_arg(ap, unsigned long);
  205.      field = FIELD_SUBFILETYPE;
  206.      break;
  207.       case TIFFTAG_IMAGEWIDTH:
  208.      td->td_imagewidth = va_arg(ap, unsigned long);
  209.      field = FIELD_IMAGEDIMENSIONS;
  210.      break;
  211.       case TIFFTAG_IMAGELENGTH:
  212.      td->td_imagelength = va_arg(ap, unsigned long);
  213.      field = FIELD_IMAGEDIMENSIONS;
  214.      break;
  215.       case TIFFTAG_BITSPERSAMPLE:
  216.      td->td_bitspersample = va_arg(ap, unsigned);
  217.      field = FIELD_BITSPERSAMPLE;
  218.      break;
  219.       case TIFFTAG_COMPRESSION:
  220.      v = va_arg(ap, unsigned) & 0xffff;
  221.      /*
  222.      If we're changing the compression scheme,
  223.      then notify the previous module so that it
  224.      can cleanup any state it's setup.
  225.      */
  226.      if (TIFFFieldSet(tif, FIELD_COMPRESSION))
  227.      {
  228.         if (td->td_compression == v)
  229.            break;
  230.         if (tif->tif_cleanup)
  231.            (*tif->tif_cleanup)(tif);
  232.      }
  233.      /* Setup new compression routine state. */
  234.      if ((status = TIFFSetCompressionScheme(tif, (unsigned) v)) == TRUE)
  235.      {
  236.         td->td_compression = (unsigned) v;
  237.         field = FIELD_COMPRESSION;
  238.      }
  239.      break;
  240.       case TIFFTAG_PHOTOMETRIC:
  241.      td->td_photometric = va_arg(ap, unsigned);
  242.      field = FIELD_PHOTOMETRIC;
  243.      break;
  244.       case TIFFTAG_THRESHHOLDING:
  245.      td->td_threshholding = va_arg(ap, unsigned);
  246.      field = FIELD_THRESHHOLDING;
  247.      break;
  248.       case TIFFTAG_DOCUMENTNAME:
  249.      td->td_documentname = va_arg(ap, char *);
  250.      field = FIELD_DOCUMENTNAME;
  251.      break;
  252.       case TIFFTAG_ARTIST:
  253.      td->td_artist = va_arg(ap, char *);
  254.      field = FIELD_ARTIST;
  255.      break;
  256.       case TIFFTAG_DATETIME:
  257.      td->td_datetime = va_arg(ap, char *);
  258.      field = FIELD_DATETIME;
  259.      break;
  260.       case TIFFTAG_HOSTCOMPUTER:
  261.      td->td_hostcomputer = va_arg(ap, char *);
  262.      field = FIELD_HOSTCOMPUTER;
  263.      break;
  264.       case TIFFTAG_IMAGEDESCRIPTION:
  265.      td->td_imagedescription = va_arg(ap, char *);
  266.      field = FIELD_IMAGEDESCRIPTION;
  267.      break;
  268.       case TIFFTAG_MAKE:
  269.      td->td_make = va_arg(ap, char *);
  270.      field = FIELD_MAKE;
  271.      break;
  272.       case TIFFTAG_MODEL:
  273.      td->td_model = va_arg(ap, char *);
  274.      field = FIELD_MODEL;
  275.      break;
  276.       case TIFFTAG_SOFTWARE:
  277.      td->td_software = va_arg(ap, char *);
  278.      field = FIELD_SOFTWARE;
  279.      break;
  280.       case TIFFTAG_ORIENTATION:
  281.      td->td_orientation = va_arg(ap, unsigned);
  282.      field = FIELD_ORIENTATION;
  283.      break;
  284.       case TIFFTAG_SAMPLESPERPIXEL:
  285.      v = va_arg(ap, unsigned);
  286.      if (v == 0)
  287.         goto badvalue;
  288.      if (v > 4)
  289.      {
  290.         TIFFError(tif->tif_name,"Cannot handle %ld-channel data", v);
  291.         goto bad;
  292.      }
  293.      td->td_samplesperpixel = (unsigned) v;
  294.      field = FIELD_SAMPLESPERPIXEL;
  295.      break;
  296.       case TIFFTAG_ROWSPERSTRIP:
  297.      v = va_arg(ap, long);
  298.      if (v == 0)
  299.         goto badvalue;
  300.      td->td_rowsperstrip = v;
  301.      field = FIELD_ROWSPERSTRIP;
  302.      break;
  303.       case TIFFTAG_MINSAMPLEVALUE:
  304.      td->td_minsamplevalue = va_arg(ap, unsigned) & 0xffff;
  305.      field = FIELD_MINSAMPLEVALUE;
  306.      break;
  307.       case TIFFTAG_MAXSAMPLEVALUE:
  308.      td->td_maxsamplevalue = va_arg(ap, unsigned) & 0xffff;
  309.      field = FIELD_MAXSAMPLEVALUE;
  310.      break;
  311.       case TIFFTAG_XRESOLUTION:
  312.      td->td_xresolution = va_arg(ap, double);
  313.      field = FIELD_RESOLUTION;
  314.      break;
  315.       case TIFFTAG_YRESOLUTION:
  316.      td->td_yresolution = va_arg(ap, double);
  317.      field = FIELD_RESOLUTION;
  318.      break;
  319.       case TIFFTAG_PLANARCONFIG:
  320.      v = va_arg(ap, unsigned);
  321.      td->td_planarconfig = (unsigned) v;
  322.      field = FIELD_PLANARCONFIG;
  323.      break;
  324.       case TIFFTAG_PAGENAME:
  325.      td->td_pagename = va_arg(ap, char *);
  326.      field = FIELD_PAGENAME;
  327.      break;
  328.       case TIFFTAG_XPOSITION:
  329.      td->td_xposition = va_arg(ap, double);
  330.      field = FIELD_POSITION;
  331.      break;
  332.       case TIFFTAG_YPOSITION:
  333.      td->td_yposition = va_arg(ap, double);
  334.      field = FIELD_POSITION;
  335.      break;
  336.       case TIFFTAG_GRAYRESPONSEUNIT:
  337.      td->td_grayresponseunit = va_arg(ap, unsigned);
  338.      field = FIELD_GRAYRESPONSEUNIT;
  339.      break;
  340.       case TIFFTAG_GRAYRESPONSECURVE:
  341.      td->td_grayresponsecurve = va_arg(ap, unsigned *);
  342.      field = FIELD_GRAYRESPONSECURVE;
  343.      break;
  344.       case TIFFTAG_GROUP3OPTIONS:
  345.      td->td_group3options = va_arg(ap, long);
  346.      field = FIELD_GROUP3OPTIONS;
  347.      break;
  348.       case TIFFTAG_GROUP4OPTIONS:
  349.      td->td_group4options = va_arg(ap, long);
  350.      field = FIELD_GROUP4OPTIONS;
  351.      break;
  352.       case TIFFTAG_RESOLUTIONUNIT:
  353.      td->td_resolutionunit = va_arg(ap, unsigned);
  354.      field = FIELD_RESOLUTIONUNIT;
  355.      break;
  356.       case TIFFTAG_PAGENUMBER:
  357.      td->td_pagenumber = va_arg(ap, unsigned);
  358.      field = FIELD_PAGENUMBER;
  359.      break;
  360.       case TIFFTAG_COLORRESPONSEUNIT:
  361.      td->td_colorresponseunit = va_arg(ap, unsigned);
  362.      field = FIELD_COLORRESPONSEUNIT;
  363.      break;
  364.       case TIFFTAG_COLORRESPONSECURVE:
  365.      td->td_redresponsecurve   = va_arg(ap, unsigned *);
  366.      td->td_greenresponsecurve = va_arg(ap, unsigned *);
  367.      td->td_blueresponsecurve  = va_arg(ap, unsigned *);
  368.      field = FIELD_COLORRESPONSECURVE;
  369.      break;
  370.       case TIFFTAG_COLORMAP:
  371.      td->td_redcolormap   = va_arg(ap, unsigned *);
  372.      td->td_greencolormap = va_arg(ap, unsigned *);
  373.      td->td_bluecolormap  = va_arg(ap, unsigned *);
  374.      field = FIELD_COLORMAP;
  375.      break;
  376.       case TIFFTAG_PREDICTOR:
  377.      td->td_predictor = va_arg(ap, unsigned);
  378.      field = FIELD_PREDICTOR;
  379.      break;
  380.    }
  381.    if (field >= 0)
  382.    {
  383.       TIFFSetFieldBit(tif, field);
  384.       tif->tif_flags |= TIFF_DIRTYDIRECT;
  385.    }
  386.    va_end(ap);
  387.    return (status);
  388. badvalue:
  389.    TIFFError(tif->tif_name, "%d: Bad value for \"%s\"", v,
  390.          FieldWithTag(tag)->field_name);
  391. bad:
  392.    va_end(ap);
  393.    return (FALSE);
  394. }
  395.  
  396. static
  397. void MissingRequired(TIFF *tif, char *tagname)
  398. {
  399.    TIFFError(tif->tif_name,
  400.             "TIFF directory is missing required \"%s\" field", tagname);
  401. }
  402.  
  403.  
  404. /*
  405. Fetch a contiguous directory item.
  406. */
  407. static
  408. CompletionCode TIFFFetchData(TIFF *tif, TIFFDirEntry *dir, char *cp)
  409. {
  410.    unsigned cc, w;
  411.  
  412.    w = datawidth[dir->tdir_type];
  413.    cc = (unsigned)(dir->tdir_count * w);
  414.  
  415.    if (SeekOK(tif->tif_fd, dir->tdir_offset) && ReadOK(tif->tif_fd, cp, cc))
  416.    {
  417.       if (tif->tif_flags & TIFF_SWAB)
  418.       {
  419.      switch (dir->tdir_type)
  420.      {
  421.         case SHORT:
  422.            TIFFSwabArrayOfShort((unsigned *) cp, (unsigned) dir->tdir_count);
  423.            break;
  424.         case LONG:
  425.            TIFFSwabArrayOfLong((unsigned long *) cp, (unsigned)dir->tdir_count);
  426.            break;
  427.         case RATIONAL:
  428.            TIFFSwabArrayOfLong((unsigned long *) cp, (unsigned)(2*dir->tdir_count));
  429.            break;
  430.      }
  431.       }
  432.       return (cc);
  433.    }
  434.    TIFFError(tif->tif_name, "Error fetching data for field \"%s\"",
  435.          FieldWithTag(dir->tdir_tag)->field_name);
  436.    return (FALSE);
  437. }
  438.  
  439. /*
  440. Fetch a rational item from the file
  441. at offset off.  We return the value
  442. as floating point number.
  443. */
  444. static double
  445. TIFFFetchRational(TIFF *tif, TIFFDirEntry *dir)
  446. {
  447.    long l[2];
  448.  
  449.    if (!TIFFFetchData(tif, dir, (char *) l))
  450.       return (1.0);
  451.    if (l[1] == 0)
  452.    {
  453.       TIFFError(tif->tif_name, "%s: Rational with zero denominator",
  454.         FieldWithTag(dir->tdir_tag)->field_name);
  455.       return (1.0);
  456.    }
  457.    return ((double)l[0] / (double)l[1]);
  458. }
  459.  
  460. static
  461. CompletionCode TIFFFetchPerSampleShorts(TIFF *tif, TIFFDirEntry *dir, long *pl)
  462. {
  463.    unsigned v[4];
  464.    unsigned i;
  465.  
  466.    switch ((unsigned) dir->tdir_count)
  467.    {
  468.       case 1:
  469.      *pl = TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset);
  470.      return (TRUE);             /* should check samplesperpixel */
  471.       case 2:
  472.      if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN)
  473.      {
  474.         v[0] = (unsigned) (dir->tdir_offset >> 16);
  475.         v[1] = (unsigned) (dir->tdir_offset & 0xffff);
  476.      }
  477.      else
  478.      {
  479.         v[0] = (unsigned) (dir->tdir_offset & 0xffff);
  480.         v[1] = (unsigned) (dir->tdir_offset >> 16);
  481.      }
  482.      break;
  483.       default:
  484.      if (!TIFFFetchData(tif, dir, (char *) v))
  485.         return (FALSE);
  486.      break;
  487.    }
  488.    if (tif->tif_dir.td_samplesperpixel != dir->tdir_count)
  489.    {
  490.       TIFFError(tif->tif_name, "Incorrect count %d for field \"%s\"",
  491.         dir->tdir_count, FieldWithTag(dir->tdir_tag)->field_name);
  492.       return (FALSE);
  493.    }
  494.    for (i = 1; i < dir->tdir_count; i++)
  495.       if (v[i] != v[0])
  496.       {
  497.      TIFFError(tif->tif_name,"Cannot handle different per-sample values for field \"%s\"",
  498.            FieldWithTag(dir->tdir_tag)->field_name);
  499.      return (FALSE);
  500.       }
  501. ok:
  502.    *pl = v[0];
  503.    return (TRUE);
  504. }
  505.  
  506. static
  507. CompletionCode TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir,
  508.                    long nstrips, unsigned long **lpp)
  509. {
  510.    register unsigned long *lp;
  511.    int status;
  512.  
  513.    if (nstrips != dir->tdir_count)
  514.    {
  515.       TIFFError(tif->tif_name,
  516.            "Count mismatch for field \"%s\"; expecting %d, got %d",
  517.         FieldWithTag(dir->tdir_tag)->field_name, nstrips,
  518.         dir->tdir_count);
  519.       return (FALSE);
  520.    }
  521.    /* Allocate space for strip information. */
  522.    if (*lpp == NULL &&
  523.       (*lpp = (unsigned long *)malloc((unsigned) (nstrips *
  524.                       sizeof (unsigned long)))) == NULL)
  525.    {
  526.       TIFFError(tif->tif_name, "No space for \"%s\" array",
  527.         FieldWithTag(dir->tdir_tag)->field_name);
  528.       return (FALSE);
  529.    }
  530.    lp = *lpp;
  531.    status = 1;
  532.    if (dir->tdir_type == (unsigned) SHORT)
  533.    {
  534.       /* Handle short->long expansion. */
  535.       if (dir->tdir_count > 2)
  536.       {
  537.      char *dp = malloc((unsigned)(dir->tdir_count * datawidth[(unsigned)SHORT]));
  538.      if (dp == NULL)
  539.      {
  540.         TIFFError(tif->tif_name,"No memory to fetch field \"%s\"",
  541.               FieldWithTag(dir->tdir_tag)->field_name);
  542.         return (FALSE);
  543.      }
  544.      status = TIFFFetchData(tif, dir, dp);
  545.      if (status)
  546.      {
  547.         register unsigned *wp = (unsigned *)dp;
  548.         while (nstrips-- > 0)
  549.            *lp++ = *wp++;
  550.      }
  551.      free((char *) dp);
  552.       }
  553.       else
  554.       {
  555.      /* Extract data from offset field. */
  556.     if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN)
  557.     {
  558.        *lp++ = dir->tdir_offset >> 16;
  559.        *lp = dir->tdir_offset & 0xffff;
  560.     }
  561.     else
  562.     {
  563.        *lp++ = dir->tdir_offset & 0xffff;
  564.        *lp = dir->tdir_offset >> 16;
  565.     }
  566.       }
  567.    }
  568.    else
  569.    {
  570.       if (dir->tdir_count > 1)
  571.      status = TIFFFetchData(tif, dir, (char *) lp);
  572.       else
  573.      *lp = dir->tdir_offset;
  574.    }
  575.    return (status);
  576. }
  577.  
  578.  
  579. /*
  580. Read the next TIFF directory from a file
  581. and convert it to the internal format.
  582. We read directories sequentially.
  583. */
  584. CompletionCode TIFFReadDirectory(TIFF *tif)
  585. {
  586.    register TIFFDirEntry *dp;
  587.    register int n;
  588.    register TIFFDirectory *td = NULL;
  589.    TIFFDirEntry *dir = NULL;
  590.    long v;
  591.    TIFFFieldInfo *fip;
  592.    unsigned dircount;
  593.    char *cp;
  594.    unsigned bytestoread;
  595.  
  596.    tif->tif_diroff = tif->tif_nextdiroff;
  597.    if (tif->tif_diroff == 0)               /* no more directories */
  598.       return (FALSE);
  599.  
  600.    if (!SeekOK(tif->tif_fd, tif->tif_diroff))
  601.    {
  602.       TIFFError(tif->tif_name, "Seek error accessing TIFF directory");
  603.       return (FALSE);
  604.    }
  605.    if (!ReadOK(tif->tif_fd, &dircount, sizeof (unsigned)))
  606.    {
  607.       TIFFError(tif->tif_name, "Can not read TIFF directory count");
  608.       return (FALSE);
  609.    }
  610.    if (tif->tif_flags & TIFF_SWAB)
  611.       TIFFSwabShort((unsigned *) &dircount);
  612.  
  613.    bytestoread = dircount * sizeof (TIFFDirEntry);
  614.  
  615.    dir = (TIFFDirEntry *)malloc(bytestoread);
  616.    if (dir == NULL)
  617.    {
  618.       TIFFError(tif->tif_name, "No space to read TIFF directory");
  619.       return (FALSE);
  620.    }
  621.    if (!ReadOK(tif->tif_fd, dir, bytestoread))
  622.    {
  623.       TIFFError(tif->tif_name, "Can not read TIFF directory");
  624.       goto bad;
  625.    }
  626.    /* Read offset to next directory for sequential scans. */
  627.    if (!ReadOK(tif->tif_fd, &tif->tif_nextdiroff, sizeof (long)))
  628.       tif->tif_nextdiroff = 0;
  629.    if (tif->tif_flags & TIFF_SWAB)
  630.       TIFFSwabLong((unsigned long *) &tif->tif_nextdiroff);
  631.  
  632.    tif->tif_flags &= ~TIFF_BEENWRITING;    /* reset before new dir */
  633.    /*
  634.    Setup default value and then make a pass over
  635.    the fields to check type and tag information,
  636.    and to extract info required to size data
  637.    structures.  A second pass is made afterwards
  638.    to read in everthing not taken in the first pass.
  639.    */
  640.    td = &tif->tif_dir;
  641.    if (tif->tif_diroff != tif->tif_header.tiff_diroff)
  642.    {
  643.       /* free any old stuff and reinit */
  644.       TIFFFreeDirectory(tif);
  645.       memset((char *)td, 0, sizeof (*td));
  646.    }
  647.    TIFFDefaultDirectory(tif);
  648.    /*
  649.    Electronic Arts writes gray-scale TIFF files
  650.    without a PlanarConfiguration directory entry.
  651.    Thus we setup a default value here, even though
  652.    the TIFF spec says there is no default value.
  653.    */
  654.    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  655.    for (fip = FieldInfo, dp = dir, n = dircount; n > 0; n--, dp++)
  656.    {
  657.       if (tif->tif_flags & TIFF_SWAB)
  658.       {
  659.      TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
  660.      TIFFSwabArrayOfLong(&dp->tdir_count, 2);
  661.       }
  662.       /*
  663.       Find the field information entry for this tag.
  664.       */
  665.       while (fip < &FieldInfo[NFIELDINFO] && fip->field_tag < dp->tdir_tag)
  666.      fip++;
  667.       if (fip >= &FieldInfo[NFIELDINFO] || fip->field_tag != dp->tdir_tag)
  668.       {
  669.      /*
  670.      Unknown field, should this be fatal?
  671.      */
  672.      TIFFWarning(tif->tif_name,"Ignoring unknown field with tag %d (0x%x)",
  673.              dp->tdir_tag, dp->tdir_tag);
  674.      dp->tdir_tag = IGNORE;
  675.      continue;
  676.       }
  677.       /* Null out old tags that we ignore. */
  678.       if (fip->field_bit == 0xffff)
  679.       {
  680.      dp->tdir_tag = IGNORE;
  681.      continue;
  682.       }
  683.       /* Check data type. */
  684.       while ((TIFFDataType)dp->tdir_type != fip->field_type)
  685.       {
  686.      fip++;
  687.      if (fip >= &FieldInfo[NFIELDINFO] || fip->field_tag != dp->tdir_tag)
  688.      {
  689.         TIFFError(tif->tif_name,"Wrong data type %d for field \"%s\"",
  690.               dp->tdir_type, fip->field_name);
  691.         goto bad;
  692.      }
  693.       }
  694.       switch (dp->tdir_tag)
  695.       {
  696.      case TIFFTAG_STRIPOFFSETS:
  697.      case TIFFTAG_STRIPBYTECOUNTS:
  698.         TIFFSetFieldBit(tif, fip->field_bit);
  699.         break;
  700.      case TIFFTAG_IMAGELENGTH:
  701.      case TIFFTAG_PLANARCONFIG:
  702.      case TIFFTAG_ROWSPERSTRIP:
  703.      case TIFFTAG_SAMPLESPERPIXEL:
  704.         if (!TIFFSetField(tif, dp->tdir_tag,
  705.                           TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset)))
  706.            goto bad;
  707.         break;
  708.       }
  709.    }
  710.    /* Allocate directory structure and setup defaults. */
  711.    if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
  712.    {
  713.       MissingRequired(tif, "ImageLength");
  714.       goto bad;
  715.    }
  716.    if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
  717.    {
  718.       MissingRequired(tif, "PlanarConfiguration");
  719.       goto bad;
  720.    }
  721.    if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
  722.    {
  723.       MissingRequired(tif, "StripOffsets");
  724.       goto bad;
  725.    }
  726.    td->td_stripsperimage = (td->td_rowsperstrip == 0xffffffffL ?
  727.             1 : howmany(td->td_imagelength, td->td_rowsperstrip));
  728.    td->td_nstrips = td->td_stripsperimage;
  729.    if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  730.       td->td_nstrips *= td->td_samplesperpixel;
  731.  
  732.    /*
  733.    Second pass: extract other information.
  734.    Should do a better job of verifying values.
  735.    */
  736.  
  737.    for (dp = dir, n = dircount; n > 0; n--, dp++)
  738.    {
  739.       if (dp->tdir_tag == IGNORE)
  740.      continue;
  741.  
  742.       if (dp->tdir_type == ASCII)
  743.       {
  744.      if (dp->tdir_count > 0)
  745.      {
  746.         /* allocate space for string */
  747.         cp = (char *) malloc((unsigned)dp->tdir_count+1);
  748.         if (cp == NULL)
  749.            goto bad;
  750.         if (dp->tdir_count > 4)
  751.         {
  752.            /* get ASCII string located somewhere in file */
  753.            if (TIFFFetchData(tif, dp, cp) == FALSE)
  754.            goto bad;
  755.         }
  756.         else
  757.         {
  758.            /* ASCII is in offset field of tag */
  759.            strcpy(cp,(char *) &(dp->tdir_offset));
  760.         }
  761.         /* in either case */
  762.         if (!TIFFSetField(tif, dp->tdir_tag, cp))
  763.            goto bad;
  764.      }
  765.      continue;
  766.       }
  767.       if (dp->tdir_type == (unsigned) RATIONAL)
  768.       {
  769.      if (!TIFFSetField(tif, dp->tdir_tag,TIFFFetchRational(tif, dp)))
  770.         goto bad;
  771.      continue;
  772.       }
  773.       switch (dp->tdir_tag)
  774.       {
  775.      case TIFFTAG_COMPRESSION:
  776.         /*
  777.         The 5.0 spec says the compression tag has
  778.         one value, while earlier specs say it has
  779.         one value per sample.  Because of this, we
  780.         accept the tag if one value is supplied.
  781.         */
  782.         if (dp->tdir_count == 1)
  783.         {
  784.            v = TIFFExtractData(tif,dp->tdir_type, dp->tdir_offset);
  785.            if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, v))
  786.           goto bad;
  787.            break;
  788.         }
  789.         /* fall thru */
  790.         case TIFFTAG_MINSAMPLEVALUE:
  791.         case TIFFTAG_MAXSAMPLEVALUE:
  792.         case TIFFTAG_BITSPERSAMPLE:
  793.            if (!TIFFFetchPerSampleShorts(tif, dp, &v) ||
  794.            !TIFFSetField(tif, dp->tdir_tag, v))
  795.           goto bad;
  796.            break;
  797.         case TIFFTAG_STRIPOFFSETS:
  798.            if (!TIFFFetchStripThing(tif, dp,td->td_nstrips, &td->td_stripoffset))
  799.           goto bad;
  800.            TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
  801.            break;
  802.         case TIFFTAG_STRIPBYTECOUNTS:
  803.            if (!TIFFFetchStripThing(tif, dp,td->td_nstrips, &td->td_stripbytecount))
  804.           goto bad;
  805.            TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
  806.            break;
  807.         case TIFFTAG_IMAGELENGTH:
  808.         case TIFFTAG_ROWSPERSTRIP:
  809.         case TIFFTAG_SAMPLESPERPIXEL:
  810.         case TIFFTAG_PLANARCONFIG:
  811.            /* handled in first pass above */
  812.            break;
  813.         case TIFFTAG_GRAYRESPONSECURVE:
  814.         case TIFFTAG_COLORRESPONSECURVE:
  815.         case TIFFTAG_COLORMAP:
  816.            v = (1<< (td->td_bitspersample * td->td_samplesperpixel)) * sizeof (unsigned);
  817.            cp = malloc((unsigned) (dp->tdir_tag == TIFFTAG_GRAYRESPONSECURVE ?
  818.                 v : 3*v));
  819.            if (cp == NULL)
  820.           goto bad;
  821.            if (!TIFFSetField(tif, dp->tdir_tag, (unsigned *) cp,
  822.                (unsigned *)(cp+(unsigned) v),
  823.                (unsigned *)(cp+2*(unsigned) v)) ||
  824.                 !TIFFFetchData(tif, dp, cp))
  825.            goto bad;
  826.            break;
  827.  
  828.         /* BEGIN REV 4.0 COMPATIBILITY */
  829.  
  830.         case TIFFTAG_OSUBFILETYPE:
  831.            v = 0;
  832.            switch ((unsigned)TIFFExtractData(tif, dp->tdir_type,dp->tdir_offset))
  833.            {
  834.           case OFILETYPE_REDUCEDIMAGE:
  835.              v = FILETYPE_REDUCEDIMAGE;
  836.              break;
  837.           case OFILETYPE_PAGE:
  838.              v = FILETYPE_PAGE;
  839.              break;
  840.            }
  841.            if (!TIFFSetField(tif, dp->tdir_tag, v))
  842.           goto bad;
  843.            break;
  844.  
  845.            /* END REV 4.0 COMPATIBILITY */
  846.  
  847.         default:
  848.            if (!TIFFSetField(tif, dp->tdir_tag,
  849.             TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset)))
  850.           goto bad;
  851.            break;
  852.      }
  853.       }
  854.       if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS))
  855.       {
  856.      struct stat sb;
  857.      int space;
  858.      /*
  859.      Some manufacturers violate the spec by not giving
  860.      the size of the strips.  In this case, assume there
  861.      is one uncompressed strip of data.
  862.      */
  863.      if (td->td_nstrips > 1)
  864.      {
  865.         MissingRequired(tif, "StripByteCounts");
  866.         goto bad;
  867.      }
  868.      TIFFWarning(tif->tif_name,
  869. "TIFF directory missing \"%s\" field, calculating from imagelength",
  870.                     FieldWithTag(TIFFTAG_STRIPBYTECOUNTS)->field_name);
  871.      fstat(tif->tif_fd, &sb);
  872.      td->td_stripbytecount = (unsigned long *)malloc(sizeof (unsigned long));
  873.      space = sizeof (TIFFHeader) + sizeof (unsigned) +
  874.             (dircount * sizeof (TIFFDirEntry)) + sizeof (long);
  875.      /* calculate amount of space used by indirect values */
  876.      for (dp = dir, n = dircount; n > 0; n--, dp++)
  877.      {
  878.         unsigned cc = (unsigned) (dp->tdir_count *
  879.                       datawidth[dp->tdir_type]);
  880.         if (cc > sizeof (long))
  881.            space += cc;
  882.      }
  883.      td->td_stripbytecount[0] = sb.st_size - space;
  884.      TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
  885.      if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
  886.         td->td_rowsperstrip = td->td_imagelength;
  887.       }
  888.       if (dir)
  889.      free((char *) dir);
  890.       if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
  891.      td->td_maxsamplevalue = (1<<td->td_bitspersample)-1;
  892.       /* Setup default compression scheme. */
  893.       return (!TIFFFieldSet(tif, FIELD_COMPRESSION) ?
  894.             TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE) : 1);
  895. bad:
  896.    if (dir)
  897.       free((char *) dir);
  898.    return (FALSE);
  899. }
  900.  
  901.  
  902.  
  903.  
  904. void TIFFFreeDirectory(TIFF *tif)
  905. {
  906.    register TIFFDirectory *td = &tif->tif_dir;
  907.  
  908.    if  (td->td_stripoffset)
  909.       free((char *) td->td_stripoffset);
  910.    if  (td->td_stripbytecount)
  911.       free((char *) td->td_stripbytecount);
  912.  
  913.    /*
  914.    Only dealloc fields which were for sure allocated.
  915.    This conditional allows TIFF writing programs
  916.    to clean up after themselves, but TIFF reading
  917.    programs clean up automatically.
  918.    */
  919.    if (tif->tif_mode == O_RDONLY)
  920.    {
  921.       if (TIFFFieldSet(tif, FIELD_GRAYRESPONSECURVE))
  922.      free((char *) td->td_grayresponsecurve);
  923.       /*
  924.       Whole COLORRESPONSECURVE allocated at one time. It
  925.       must be freed in the same way.
  926.       */
  927.       if (TIFFFieldSet(tif, FIELD_COLORRESPONSECURVE))
  928.      free((char *) td->td_redresponsecurve);
  929.       /*
  930.       Whole COLORMAP allocated at one time. It
  931.       must be freed in the same way.
  932.       */
  933.       if (TIFFFieldSet(tif, FIELD_COLORMAP))
  934.      free((char *) td->td_redcolormap);
  935.    }
  936. }
  937.  
  938. /*
  939. Setup a default directory structure.
  940. */
  941. CompletionCode TIFFDefaultDirectory(TIFF *tif)
  942. {
  943.    register TIFFDirectory *td = &tif->tif_dir;
  944.  
  945.    td->td_bitspersample = 1;
  946.    td->td_threshholding = THRESHHOLD_BILEVEL;
  947.    td->td_orientation = ORIENTATION_TOPLEFT;
  948.    td->td_samplesperpixel = 1;
  949.    td->td_rowsperstrip = 0xfffffffL;
  950.    td->td_grayresponseunit = GRAYRESPONSEUNIT_100S;
  951.    td->td_resolutionunit = RESUNIT_INCH;
  952.    td->td_colorresponseunit = COLORRESPONSEUNIT_100S;
  953.    return (TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE));
  954. }
  955.  
  956. static
  957. void TIFFGetField1(TIFFDirectory *td, unsigned tag, va_list ap)
  958. {
  959.    switch (tag)
  960.    {
  961.       case TIFFTAG_SUBFILETYPE:
  962.      *va_arg(ap, unsigned long *) = td->td_subfiletype;
  963.      break;
  964.       case TIFFTAG_IMAGEWIDTH:
  965.      *va_arg(ap, unsigned long *) = td->td_imagewidth;
  966.      break;
  967.       case TIFFTAG_IMAGELENGTH:
  968.      *va_arg(ap, unsigned long *) = td->td_imagelength;
  969.      break;
  970.       case TIFFTAG_BITSPERSAMPLE:
  971.      *va_arg(ap, unsigned *) = td->td_bitspersample;
  972.      break;
  973.       case TIFFTAG_COMPRESSION:
  974.      *va_arg(ap, unsigned *) = td->td_compression;
  975.      break;
  976.       case TIFFTAG_PHOTOMETRIC:
  977.      *va_arg(ap, unsigned *) = td->td_photometric;
  978.      break;
  979.       case TIFFTAG_THRESHHOLDING:
  980.      *va_arg(ap, unsigned *) = td->td_threshholding;
  981.      break;
  982.       case TIFFTAG_DOCUMENTNAME:
  983.      *va_arg(ap, char **) = td->td_documentname;
  984.      break;
  985.       case TIFFTAG_ARTIST:
  986.      *va_arg(ap, char **) = td->td_artist;
  987.      break;
  988.       case TIFFTAG_DATETIME:
  989.      *va_arg(ap, char **) = td->td_datetime;
  990.      break;
  991.       case TIFFTAG_HOSTCOMPUTER:
  992.      *va_arg(ap, char **) = td->td_hostcomputer;
  993.      break;
  994.       case TIFFTAG_IMAGEDESCRIPTION:
  995.      *va_arg(ap, char **) = td->td_imagedescription;
  996.      break;
  997.       case TIFFTAG_MAKE:
  998.      *va_arg(ap, char **) = td->td_make;
  999.      break;
  1000.       case TIFFTAG_MODEL:
  1001.      *va_arg(ap, char **) = td->td_model;
  1002.      break;
  1003.       case TIFFTAG_SOFTWARE:
  1004.      *va_arg(ap, char **) = td->td_software;
  1005.      break;
  1006.       case TIFFTAG_ORIENTATION:
  1007.      *va_arg(ap, unsigned *) = td->td_orientation;
  1008.      break;
  1009.       case TIFFTAG_SAMPLESPERPIXEL:
  1010.      *va_arg(ap, unsigned *) = td->td_samplesperpixel;
  1011.      break;
  1012.       case TIFFTAG_ROWSPERSTRIP:
  1013.      *va_arg(ap, unsigned long *) = td->td_rowsperstrip;
  1014.      break;
  1015.       case TIFFTAG_MINSAMPLEVALUE:
  1016.      *va_arg(ap, unsigned *) = td->td_minsamplevalue;
  1017.      break;
  1018.       case TIFFTAG_MAXSAMPLEVALUE:
  1019.      *va_arg(ap, unsigned *) = td->td_maxsamplevalue;
  1020.      break;
  1021.       case TIFFTAG_XRESOLUTION:
  1022.      *va_arg(ap, float *) = td->td_xresolution;
  1023.      break;
  1024.       case TIFFTAG_YRESOLUTION:
  1025.      *va_arg(ap, float *) = td->td_yresolution;
  1026.      break;
  1027.       case TIFFTAG_PLANARCONFIG:
  1028.      *va_arg(ap, unsigned *) = td->td_planarconfig;
  1029.      break;
  1030.       case TIFFTAG_XPOSITION:
  1031.      *va_arg(ap, float *) = td->td_xposition;
  1032.      break;
  1033.       case TIFFTAG_YPOSITION:
  1034.      *va_arg(ap, float *) = td->td_yposition;
  1035.      break;
  1036.       case TIFFTAG_PAGENAME:
  1037.      *va_arg(ap, char **) = td->td_pagename;
  1038.      break;
  1039.       case TIFFTAG_GRAYRESPONSEUNIT:
  1040.      *va_arg(ap, unsigned *) = td->td_grayresponseunit;
  1041.      break;
  1042.       case TIFFTAG_GRAYRESPONSECURVE:
  1043.      *va_arg(ap, unsigned **) = td->td_grayresponsecurve;
  1044.      break;
  1045.       case TIFFTAG_GROUP3OPTIONS:
  1046.      *va_arg(ap, unsigned long *) = td->td_group3options;
  1047.      break;
  1048.       case TIFFTAG_GROUP4OPTIONS:
  1049.      *va_arg(ap, unsigned long *) = td->td_group4options;
  1050.      break;
  1051.       case TIFFTAG_RESOLUTIONUNIT:
  1052.      *va_arg(ap, unsigned *) = td->td_resolutionunit;
  1053.      break;
  1054.       case TIFFTAG_PAGENUMBER:
  1055.      *va_arg(ap, unsigned long *) = td->td_pagenumber;
  1056.      break;
  1057.       case TIFFTAG_COLORRESPONSEUNIT:
  1058.      *va_arg(ap, unsigned *) = td->td_colorresponseunit;
  1059.      break;
  1060.       case TIFFTAG_COLORRESPONSECURVE:
  1061.      *va_arg(ap, unsigned **) = td->td_redresponsecurve;
  1062.      *va_arg(ap, unsigned **) = td->td_greenresponsecurve;
  1063.      *va_arg(ap, unsigned **) = td->td_blueresponsecurve;
  1064.      break;
  1065.       case TIFFTAG_COLORMAP:
  1066.      *va_arg(ap, unsigned **) = td->td_redcolormap;
  1067.      *va_arg(ap, unsigned **) = td->td_greencolormap;
  1068.      *va_arg(ap, unsigned **) = td->td_bluecolormap;
  1069.      break;
  1070.       case TIFFTAG_PREDICTOR:
  1071.      *va_arg(ap, unsigned *) = td->td_predictor;
  1072.      break;
  1073.       case TIFFTAG_STRIPOFFSETS:
  1074.      *va_arg(ap, unsigned long **) = td->td_stripoffset;
  1075.      break;
  1076.       case TIFFTAG_STRIPBYTECOUNTS:
  1077.      *va_arg(ap, unsigned long **) = td->td_stripbytecount;
  1078.      break;
  1079.    }
  1080.    va_end(ap);
  1081. }
  1082.  
  1083.  
  1084. /*
  1085. Return the value of a field in the
  1086. internal directory structure.
  1087. */
  1088. CompletionCode TIFFGetField(TIFF *tif, unsigned tag, ...)
  1089. {
  1090.    register TIFFFieldInfo *fip;
  1091.    TIFFDirectory *td = &tif->tif_dir;
  1092.    va_list ap;
  1093.  
  1094.    for (fip = FieldInfo; fip < &FieldInfo[NFIELDINFO]; fip++)
  1095.       if (fip->field_tag == tag)
  1096.      break;
  1097.    if (fip >= &FieldInfo[NFIELDINFO])
  1098.    {
  1099.       TIFFError("TIFFGetField", "Unknown field, tag 0x%x", tag);
  1100.       return (FALSE);
  1101.    }
  1102.    if (TIFFFieldSet(tif, fip->field_bit))
  1103.    {
  1104.       va_start(ap,tag);
  1105.       TIFFGetField1(td, tag, ap);
  1106.       va_end(ap);
  1107.       return (TRUE);
  1108.    }
  1109.    return (FALSE);
  1110. }
  1111.  
  1112.  
  1113. /*
  1114. Internal interface to TIFFGetField...
  1115. */
  1116. static
  1117. void TIFFgetfield(TIFFDirectory *td, unsigned tag, ...)
  1118. {
  1119.    va_list ap;
  1120.  
  1121.    va_start(ap,tag);
  1122.    TIFFGetField1(td, tag, ap);
  1123.    va_end(ap);
  1124. }
  1125.  
  1126. /* shorthands for setting up and writing directory... */
  1127. #define MakeShortDirent(tag, v) \
  1128.         dir->tdir_tag = tag; \
  1129.         dir->tdir_type = (unsigned)SHORT; \
  1130.         dir->tdir_count = 1; \
  1131.     dir->tdir_offset = TIFFInsertData(tif, (unsigned) SHORT, v); \
  1132.         dir++
  1133. #define WriteRationalPair(tag1, v1, tag2, v2) \
  1134.         (TIFFWriteRational(tif, tag1, dir++, v1) && \
  1135.          TIFFWriteRational(tif, tag2, dir++, v2))
  1136.  
  1137. static  long dataoff;
  1138.  
  1139. /*
  1140. Link the current directory into the
  1141. directory chain for the file.
  1142. */
  1143. static
  1144. CompletionCode TIFFLinkDirectory(register TIFF *tif)
  1145. {
  1146.    static char module[] = "TIFFLinkDirectory";
  1147.    short dircount;
  1148.    long nextdir;
  1149.  
  1150.    tif->tif_diroff = (lseek(tif->tif_fd, 0L, SEEK_END)+1) &~ 1;
  1151.    if (tif->tif_header.tiff_diroff == 0)
  1152.    {
  1153.       /* First directory, overwrite header. */
  1154.       tif->tif_header.tiff_diroff = tif->tif_diroff;
  1155.       lseek(tif->tif_fd, 0L, SEEK_SET);
  1156.       if (!WriteOK(tif->tif_fd, &tif->tif_header,sizeof (tif->tif_header)))
  1157.       {
  1158.      TIFFError(tif->tif_name, "Error writing TIFF header");
  1159.      return (FALSE);
  1160.       }
  1161.       return (TRUE);
  1162.    }
  1163.    /* Not the first directory, search to the last and append. */
  1164.    nextdir = tif->tif_header.tiff_diroff;
  1165.    do
  1166.    {
  1167.       if (!SeekOK(tif->tif_fd, nextdir) ||
  1168.       !ReadOK(tif->tif_fd, &dircount, sizeof (dircount)))
  1169.       {
  1170.      TIFFError(module, "Error fetching directory count");
  1171.      return (FALSE);
  1172.       }
  1173.       lseek(tif->tif_fd, dircount * sizeof (TIFFDirEntry), SEEK_CUR);
  1174.       if (!ReadOK(tif->tif_fd, &nextdir, sizeof (nextdir)))
  1175.       {
  1176.      TIFFError(module, "Error fetching directory link");
  1177.      return (FALSE);
  1178.       }
  1179.    } while (nextdir != 0);
  1180.    lseek(tif->tif_fd, -sizeof (nextdir), SEEK_CUR);
  1181.    if (!WriteOK(tif->tif_fd, &tif->tif_diroff, sizeof (tif->tif_diroff)))
  1182.    {
  1183.       TIFFError(module, "Error writing directory link");
  1184.       return (FALSE);
  1185.    }
  1186.    return (TRUE);
  1187. }
  1188.  
  1189.  
  1190. /*
  1191. Write a contiguous directory item.
  1192. */
  1193. static
  1194. CompletionCode TIFFWriteData(TIFF *tif, TIFFDirEntry *dir, char *cp)
  1195. {
  1196.    unsigned cc;
  1197.  
  1198.    dir->tdir_offset = dataoff;
  1199.    cc = (unsigned)(dir->tdir_count * datawidth[dir->tdir_type]);
  1200.    if (SeekOK(tif->tif_fd, dir->tdir_offset) && WriteOK(tif->tif_fd, cp, cc))
  1201.    {
  1202.       dataoff += (cc + 1) & ~1;
  1203.       return (TRUE);
  1204.    }
  1205.    TIFFError(tif->tif_name, "Error writing data for field \"%s\"",
  1206.          FieldWithTag(dir->tdir_tag)->field_name);
  1207.    return (FALSE);
  1208. }
  1209.  
  1210.  
  1211. /*
  1212. Set the n-th directory as the current directory.
  1213. Directories are numbered starting at 0.
  1214. */
  1215. CompletionCode TIFFSetDirectory(register TIFF *tif, long n)
  1216. {
  1217.    static char module[] = "TIFFSetDirectory";
  1218.    short dircount;
  1219.    long nextdir;
  1220.  
  1221.    nextdir = tif->tif_header.tiff_diroff;
  1222.    while (n-- > 0 && nextdir != 0)
  1223.    {
  1224.       if (!SeekOK(tif->tif_fd, nextdir) ||
  1225.       !ReadOK(tif->tif_fd, &dircount, sizeof (dircount)))
  1226.       {
  1227.      TIFFError(module, "%s: Error fetching directory count",
  1228.            tif->tif_name);
  1229.      return (FALSE);
  1230.       }
  1231.       lseek(tif->tif_fd, dircount*sizeof (TIFFDirEntry), SEEK_CUR);
  1232.       if (!ReadOK(tif->tif_fd, &nextdir, sizeof (nextdir)))
  1233.       {
  1234.      TIFFError(module, "%s: Error fetching directory link",
  1235.            tif->tif_name);
  1236.      return (FALSE);
  1237.       }
  1238.    }
  1239.    tif->tif_nextdiroff = nextdir;
  1240.    return (TIFFReadDirectory(tif));
  1241. }
  1242.  
  1243. static
  1244. CompletionCode TIFFWriteStripThing(TIFF *tif, unsigned tag,
  1245.                    TIFFDirEntry *dir, unsigned long *lp)
  1246. {
  1247.    dir->tdir_tag = tag;
  1248.    dir->tdir_type = (unsigned)LONG;           /* XXX */
  1249.    dir->tdir_count = tif->tif_dir.td_nstrips;
  1250.    if (dir->tdir_count > 1)
  1251.       return (TIFFWriteData(tif, dir, (char *) lp));
  1252.    dir->tdir_offset = *lp;
  1253.    return (TRUE);
  1254. }
  1255.  
  1256.  
  1257.  
  1258. static
  1259. CompletionCode TIFFWriteRational(TIFF *tif, unsigned tag,
  1260.                  TIFFDirEntry *dir, float v)
  1261. {
  1262.    long t[2];
  1263.  
  1264.    dir->tdir_tag = tag;
  1265.    dir->tdir_type = (unsigned)RATIONAL;
  1266.    dir->tdir_count = 1;
  1267.    /* need algorithm to convert ... */
  1268.    t[0] = v * 10000.0;
  1269.    t[1] = 10000.0;
  1270.    return (TIFFWriteData(tif, dir, (char *) t));
  1271. }
  1272.  
  1273. static
  1274. CompletionCode TIFFWritePerSampleShorts(TIFF *tif, unsigned tag,
  1275.                     TIFFDirEntry *dir, short v)
  1276. {
  1277.    unsigned w[4];
  1278.    unsigned i;
  1279.    unsigned samplesperpixel = tif->tif_dir.td_samplesperpixel;
  1280.  
  1281.    dir->tdir_tag = tag;
  1282.    dir->tdir_type = (unsigned)SHORT;
  1283.    dir->tdir_count = samplesperpixel;
  1284.    if (samplesperpixel <= 2)
  1285.    {
  1286.       if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN)
  1287.       {
  1288.      dir->tdir_offset = v << 16;
  1289.      if (samplesperpixel == 2)
  1290.         dir->tdir_offset |= v & 0xffff;
  1291.       }
  1292.       else
  1293.       {
  1294.      dir->tdir_offset = v & 0xffff;
  1295.      if (samplesperpixel == 2)
  1296.         dir->tdir_offset |= v << 16;
  1297.       }
  1298.       return (TRUE);
  1299.    }
  1300.    for (i = 0; i < samplesperpixel; i++)
  1301.       w[i] = v;
  1302.    return (TIFFWriteData(tif, dir, (char *) w));
  1303. }
  1304.  
  1305.  
  1306.  
  1307.  
  1308. /*
  1309. Write the contents of the current directory
  1310. to the specified file.  This routine doesn't
  1311. handle overwriting a directory with auxiliary
  1312. storage that's been changed.
  1313. */
  1314.  
  1315. #define WRITE(x)        TIFFWriteData(tif, dir, x)
  1316.  
  1317.  
  1318. CompletionCode TIFFWriteDirectory(TIFF *tif)
  1319. {
  1320.    short dircount, v;
  1321.    unsigned b, nfields, dirsize;
  1322.    char *data, *cp;
  1323.    TIFFFieldInfo *fip;
  1324.    TIFFDirEntry *dir;
  1325.    TIFFDirectory *td;
  1326.    unsigned long off, fields[sizeof (td->td_fieldsset) / sizeof (unsigned long)];
  1327.  
  1328.    if (tif->tif_mode == O_RDONLY)
  1329.       return (1);
  1330.    td = &tif->tif_dir;
  1331.    /*
  1332.    Size the directory so that we can calculate
  1333.    offsets for the data items that aren't kept
  1334.    in-place in each field.
  1335.    */
  1336.    nfields = 0;
  1337.    for (b = 0; b <= FIELD_LAST; b++)
  1338.       if (TIFFFieldSet(tif, b))
  1339.      nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
  1340.    dirsize = nfields * sizeof (TIFFDirEntry);
  1341.    data = malloc(dirsize);
  1342.    if (data == NULL)
  1343.    {
  1344.       TIFFError(tif->tif_name,"Cannot write directory, out of space");
  1345.       return (FALSE);
  1346.    }
  1347.    /*
  1348.    Directory hasn't been placed yet, put
  1349.    it at the end of the file and link it
  1350.    into the existing directory structure.
  1351.    */
  1352.    if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
  1353.       return (FALSE);
  1354.    dataoff = tif->tif_diroff + sizeof (unsigned) + dirsize + sizeof (long);
  1355.    if (dataoff & 1)
  1356.       dataoff++;
  1357.    lseek(tif->tif_fd, dataoff, SEEK_SET);
  1358.    dir = (TIFFDirEntry *)data;
  1359.    /*
  1360.    Setup external form of directory
  1361.    entries and write data items.
  1362.    */
  1363.    movmem(td->td_fieldsset, fields, sizeof (fields));
  1364.    for (fip = FieldInfo; fip < &FieldInfo[NFIELDINFO]; fip++)
  1365.    {
  1366.       if (fip->field_bit == 0xffff || !FieldSet(fields, fip->field_bit))
  1367.      continue;
  1368.       if (fip->field_type == ASCII)
  1369.       {
  1370.      TIFFgetfield(td, fip->field_tag, &cp);
  1371.      dir->tdir_tag = fip->field_tag;
  1372.      dir->tdir_type = (unsigned) ASCII;
  1373.      dir->tdir_count = strlen(cp) + 1;
  1374.      if (!TIFFWriteData(tif, dir++, cp))
  1375.         goto bad;
  1376.      ResetFieldBit(fields, fip->field_bit);
  1377.      continue;
  1378.       }
  1379.       switch (fip->field_bit)
  1380.       {
  1381.      case FIELD_STRIPOFFSETS:
  1382.      case FIELD_STRIPBYTECOUNTS:
  1383.         if (!TIFFWriteStripThing(tif,fip->field_tag, dir++,
  1384.          fip->field_bit == FIELD_STRIPOFFSETS ?
  1385.          td->td_stripoffset : td->td_stripbytecount))
  1386.            goto bad;
  1387.         break;
  1388.      case FIELD_GRAYRESPONSECURVE:
  1389.         dir->tdir_tag = fip->field_tag;
  1390.         dir->tdir_type = (unsigned)SHORT;
  1391.         dir->tdir_count =
  1392.         1 << (td->td_bitspersample * td->td_samplesperpixel);
  1393.         if (!TIFFWriteData(tif, dir++,(char *) td->td_grayresponsecurve))
  1394.            goto bad;
  1395.         break;
  1396.      case FIELD_COLORRESPONSECURVE:
  1397.      case FIELD_COLORMAP:
  1398.         dir->tdir_tag = fip->field_tag;
  1399.         dir->tdir_type = (unsigned)SHORT;
  1400.         /* yech, fool TIFFWriteData */
  1401.         dir->tdir_count =
  1402.         1 << (td->td_bitspersample * td->td_samplesperpixel);
  1403.         off = dataoff;
  1404.         if (fip->field_tag == TIFFTAG_COLORMAP)
  1405.         {
  1406.            if (!WRITE((char *) td->td_redcolormap) ||
  1407.            !WRITE((char *) td->td_greencolormap) ||
  1408.            !WRITE((char *) td->td_bluecolormap))
  1409.           goto bad;
  1410.         }
  1411.         else
  1412.         {
  1413.            if (!WRITE((char *) td->td_redresponsecurve) ||
  1414.            !WRITE((char *) td->td_greenresponsecurve) ||
  1415.            !WRITE((char *) td->td_blueresponsecurve))
  1416.           goto bad;
  1417.         }
  1418. #undef WRITE
  1419.         dir->tdir_count *= 3;
  1420.         dir->tdir_offset = off;
  1421.         break;
  1422.      case FIELD_IMAGEDIMENSIONS:
  1423.         MakeShortDirent(TIFFTAG_IMAGEWIDTH, td->td_imagewidth);
  1424.         MakeShortDirent(TIFFTAG_IMAGELENGTH,td->td_imagelength);
  1425.         break;
  1426.      case FIELD_POSITION:
  1427.         if (!WriteRationalPair(TIFFTAG_XPOSITION, td->td_xposition,
  1428.                    TIFFTAG_YPOSITION, td->td_yposition))
  1429.            goto bad;
  1430.         break;
  1431.      case FIELD_RESOLUTION:
  1432.         if (!WriteRationalPair(TIFFTAG_XRESOLUTION, td->td_xresolution,
  1433.                    TIFFTAG_YRESOLUTION, td->td_yresolution))
  1434.            goto bad;
  1435.         break;
  1436.      case FIELD_BITSPERSAMPLE:
  1437.      case FIELD_MINSAMPLEVALUE:
  1438.      case FIELD_MAXSAMPLEVALUE:
  1439.         TIFFgetfield(td, fip->field_tag, &v);
  1440.         if (!TIFFWritePerSampleShorts(tif, fip->field_tag,dir++, v))
  1441.            goto bad;
  1442.         break;
  1443.      default:
  1444.         dir->tdir_tag = fip->field_tag;
  1445.         dir->tdir_type = (unsigned)fip->field_type;
  1446.         dir->tdir_count = fip->field_count;
  1447.         if (fip->field_type == SHORT)
  1448.         {
  1449.            TIFFgetfield(td, fip->field_tag, &v);
  1450.            dir->tdir_offset = TIFFInsertData(tif, dir->tdir_type, v);
  1451.         }
  1452.         else
  1453.            TIFFgetfield(td, fip->field_tag,&dir->tdir_offset);
  1454.         dir++;
  1455.         break;
  1456.       }
  1457.       ResetFieldBit(fields, fip->field_bit);
  1458.    }
  1459.    /* Write directory. */
  1460.    lseek(tif->tif_fd, tif->tif_diroff, SEEK_SET);
  1461.    dircount = nfields;
  1462.    if (!WriteOK(tif->tif_fd, &dircount, sizeof (unsigned)))
  1463.    {
  1464.       TIFFError(tif->tif_name, "Error writing directory count");
  1465.       goto bad;
  1466.    }
  1467.    if (!WriteOK(tif->tif_fd, data, dirsize))
  1468.    {
  1469.       TIFFError(tif->tif_name, "Error writing directory contents");
  1470.       goto bad;
  1471.    }
  1472.    if (!WriteOK(tif->tif_fd, &tif->tif_nextdiroff, sizeof (long)))
  1473.    {
  1474.       TIFFError(tif->tif_name, "Error writing directory link");
  1475.       goto bad;
  1476.    }
  1477.    free((char *) data);
  1478.    return (TRUE);
  1479. bad:
  1480.    free((char *) data);
  1481.    return (FALSE);
  1482. }
  1483.  
  1484.