home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0040 - 0049 / ibm0040-0049 / ibm0040.tar / ibm0040 / IMGPROC.ZIP / C6TIFF.ZIP / IO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-30  |  19.9 KB  |  693 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. #include <io.h>
  12. #include <alloc.h>
  13. #include <mem.h>
  14. #include <assert.h>
  15. #include <string.h>
  16. #include "tiffio.h"
  17.  
  18. #define ord(e)          ((unsigned) e)
  19. #define howmany(x, y)   (((x)+((y)-1))/(y))
  20. #define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
  21. #define ReadOK(fd, buf, size)  (read(fd, (char *)buf, size) == size)
  22. #define WriteOK(fd, buf, size) (write(fd, (char *)buf, size) == size)
  23. #define SeekOK(fd, off)        (lseek(fd, (long)off, SEEK_SET) == (long)off)
  24. #define STRIPINCR       20     /* expansion factor on strip array */
  25.  
  26. /*
  27. Initialize shift & mask tables and byte
  28. swapping state according to the file
  29. byte order.
  30. */
  31.  
  32. static
  33. void TIFFInitByteOrder(TIFF *tif, unsigned magic, unsigned bigendian)
  34. {
  35.  
  36.    tif->tif_typemask[0] = 0;
  37.    tif->tif_typemask[ord(ABYTE)] = 0xff;
  38.    tif->tif_typemask[ord(SHORT)] = 0xffff;
  39.    tif->tif_typemask[ord(LONG)] = 0xffffffffL;
  40.    tif->tif_typemask[ord(RATIONAL)] = 0xffffffffL;
  41.    tif->tif_typeshift[0] = 0;
  42.    tif->tif_typeshift[ord(LONG)] = 0;
  43.    tif->tif_typeshift[ord(RATIONAL)] = 0;
  44.    if (magic == TIFF_BIGENDIAN)
  45.    {
  46.       tif->tif_typeshift[ord(ABYTE)] = 24;
  47.       tif->tif_typeshift[ord(SHORT)] = 16;
  48.       if (!bigendian)
  49.          tif->tif_flags |= TIFF_SWAB;
  50.    }
  51.    else
  52.    {
  53.       tif->tif_typeshift[ord(ABYTE)] = 0;
  54.       tif->tif_typeshift[ord(SHORT)] = 0;
  55.       if (bigendian)
  56.          tif->tif_flags |= TIFF_SWAB;
  57.    }
  58. }
  59.  
  60. /*
  61. Calculate how many bytes make up a single scan line.
  62. */
  63.  
  64. long TIFFScanlineSize(TIFF *tif)
  65. {
  66.    TIFFDirectory *td = &tif->tif_dir;
  67.    long scanline;
  68.  
  69.    scanline = td->td_bitspersample * td->td_imagewidth;
  70.    if (td->td_planarconfig == PLANARCONFIG_CONTIG)
  71.       scanline *= td->td_samplesperpixel;
  72.    return (howmany(scanline, 8));
  73. }
  74.  
  75. /*
  76. Flush raw data to the file.
  77. */
  78. CompletionCode TIFFFlushData(TIFF *tif)
  79. {
  80.    if ((tif->tif_flags & TIFF_BEENWRITING) == 0)
  81.       return (FALSE);
  82.    if (tif->tif_encodestrip && !(*tif->tif_encodestrip)(tif))
  83.       return (FALSE);
  84.    return (TIFFFlushData1(tif));
  85. }
  86.  
  87.  
  88. /*
  89. Flush a file to disk. Used before closing a written
  90. tiff file.
  91. */
  92. CompletionCode TIFFFlush(TIFF *tif)
  93. {
  94.  
  95.    if (tif->tif_mode != O_RDONLY)
  96.    {
  97.       if (tif->tif_rawcc > 0 && !TIFFFlushData(tif))
  98.          return (FALSE);
  99.       if ((tif->tif_flags & TIFF_DIRTYDIRECT) && !TIFFWriteDirectory(tif))
  100.          return (FALSE);
  101.    }
  102.    return (TRUE);
  103. }
  104.  
  105.  
  106. /*
  107. Close a TIFF file after use.
  108. */
  109. CompletionCode TIFFClose(TIFF *tif)
  110. {
  111.    if (tif->tif_mode != O_RDONLY)
  112.       /* Flush buffered data and directory (if dirty). */
  113.       TIFFFlush(tif);
  114.    if (tif->tif_cleanup)
  115.       (*tif->tif_cleanup)(tif);
  116.    TIFFFreeDirectory(tif);
  117.    if (tif->tif_rawdata)
  118.       free((char *) tif->tif_rawdata);
  119.    close(tif->tif_fd);
  120.    free((char *) tif);
  121.    return (TRUE);
  122. }
  123.  
  124. /*
  125. Open a TIFF file for read/writing.
  126. */
  127.  
  128. TIFF *TIFFOpen(char *name, char *mode)
  129. {
  130.    static char module[] = "TIFFOpen";
  131.    TIFF *tif;
  132.    int  fd;
  133.    unsigned m, bigendian, one;
  134.    char string[80];
  135.  
  136.    switch (mode[0])
  137.    {
  138.       case 'r':
  139.          m = O_RDONLY|O_BINARY;
  140.          break;
  141.       case 'w':
  142.          m = O_WRONLY|O_CREAT|O_TRUNC|O_BINARY;
  143.          break;
  144.       default:
  145.          TIFFError(module, "\"%s\": Bad mode", mode);
  146.          return ((TIFF *)0);
  147.    }
  148.  
  149.    /* Append a .tif file extension is necessary */
  150.  
  151.    if (!strchr(name,'.'))              /* is there an ext ? */
  152.    {
  153.       strcpy(string,name);             /* copy filename to buffer */
  154.       name = string;                   /* FileName now pts at buffer */
  155.       strcat(name,".tif");             /* if not add .tif ext */
  156.    }
  157.  
  158.    fd = open(name, m);
  159.    if (fd < 0)
  160.    {
  161.       TIFFError(module, "%s: Cannot open", name);
  162.       return ((TIFF *)0);
  163.    }
  164.    tif = (TIFF *) malloc(sizeof (TIFF) + strlen(name) + 1);
  165.    if (tif == NULL)
  166.    {
  167.       TIFFError(module, "%s: Out of memory (TIFF structure)", name);
  168.       close(fd);
  169.       return ((TIFF *)0);
  170.    }
  171.    memset((char *)tif,0,sizeof (*tif));
  172.    tif->tif_name = (char *)tif + sizeof (TIFF);
  173.    strcpy(tif->tif_name, name);
  174.    tif->tif_fd = fd;
  175.    tif->tif_mode = m &~ (O_CREAT|O_TRUNC|O_BINARY);
  176.    tif->tif_curoff = 0;
  177.    tif->tif_curstrip = -1;         /* invalid strip */
  178.    tif->tif_row = -1;              /* read/write pre-increment */
  179.  
  180.    /*
  181.    Determine byte order of machine running this code
  182.    */
  183.    one = 1;
  184.    bigendian = (*(char *)&one == 0);
  185.  
  186.    /* Read in TIFF header */
  187.    if (!ReadOK(fd, &tif->tif_header, sizeof (TIFFHeader)))
  188.    {
  189.       if (tif->tif_mode == O_RDONLY)
  190.       {
  191.          TIFFError(name, "Cannot read TIFF header");
  192.          goto bad;
  193.       }
  194.       /* Setup header and write */
  195.       tif->tif_header.tiff_magic =  bigendian ?
  196.                     TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
  197.       tif->tif_header.tiff_version = TIFF_VERSION;
  198.       tif->tif_header.tiff_diroff = 0;        /* filled in later */
  199.       if (!WriteOK(fd, &tif->tif_header, sizeof (TIFFHeader)))
  200.       {
  201.          TIFFError(name, "Error writing TIFF header");
  202.          goto bad;
  203.       }
  204.       /* Setup the byte order handling */
  205.       TIFFInitByteOrder(tif, tif->tif_header.tiff_magic, bigendian);
  206.       /* Setup default directory */
  207.       if (!TIFFDefaultDirectory(tif))
  208.         goto bad;
  209.       tif->tif_diroff = 0;
  210.       return (tif);
  211.    }
  212.    /* Setup the byte order handling */
  213.    if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
  214.        tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN)
  215.    {
  216.       TIFFError(name,  "Not a TIFF file, bad magic number %d (0x%x)",
  217.                         tif->tif_header.tiff_magic,
  218.                         tif->tif_header.tiff_magic);
  219.       goto bad;
  220.    }
  221.    TIFFInitByteOrder(tif, tif->tif_header.tiff_magic, bigendian);
  222.    /* Swap header if required */
  223.    if (tif->tif_flags & TIFF_SWAB)
  224.    {
  225.       TIFFSwabShort(&tif->tif_header.tiff_version);
  226.       TIFFSwabLong(&tif->tif_header.tiff_diroff);
  227.    }
  228.    /*
  229.    Now check version (if needed, it's been byte-swapped). Note
  230.    that this isn't actually a version number, it's a magic
  231.    number that doesn't change.
  232.    */
  233.    if (tif->tif_header.tiff_version != TIFF_VERSION)
  234.    {
  235.       TIFFError(name,"Not a TIFF file, bad version number %d",
  236.                      tif->tif_header.tiff_version);
  237.       goto bad;
  238.    }
  239.    /* Setup initial directory */
  240.    switch (mode[0])
  241.    {
  242.       case 'r':
  243.         tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
  244.         if (TIFFReadDirectory(tif))
  245.         {
  246.        tif->tif_scanlinesize = TIFFScanlineSize(tif);
  247.        tif->tif_rawcc = -1;
  248.            tif->tif_flags |= TIFF_BUFFERSETUP;
  249.            return (tif);
  250.         }
  251.         break;
  252.    }
  253. bad:
  254.    tif->tif_mode = O_RDONLY;       /* avoid flush */
  255.    TIFFClose(tif);
  256.    return ((TIFF *)0);
  257. }
  258.  
  259.  
  260.  
  261. /*
  262. The following functions are used to read tiff files.
  263. */
  264.  
  265. /*
  266. Set state to appear as if a strip has just been read in.
  267.  */
  268. static
  269. CompletionCode TIFFStartStrip(TIFF *tif, long strip)
  270. {
  271.    TIFFDirectory *td = &tif->tif_dir;
  272.  
  273.    tif->tif_curstrip = strip;
  274.    tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  275.    tif->tif_rawcp = tif->tif_rawdata;
  276.    tif->tif_rawcc = td->td_stripbytecount[(unsigned)strip];
  277.    return (tif->tif_stripdecode == NULL || (*tif->tif_stripdecode)(tif));
  278. }
  279.  
  280.  
  281. /*
  282. Read a strip of data from the file.
  283. */
  284. static
  285. CompletionCode TIFFReadStrip(TIFF *tif, long strip)
  286. {
  287.    static char module[] = "TIFFReadStrip";
  288.    TIFFDirectory *td = &tif->tif_dir;
  289.    long bytecount;
  290.  
  291.    if (!SeekOK(tif->tif_fd, td->td_stripoffset[(unsigned) strip]))
  292.    {
  293.       TIFFError(module, "%s: Seek error at scanline %d, strip %d",
  294.                 tif->tif_name, tif->tif_row, strip);
  295.       return (FALSE);
  296.    }
  297.    /*
  298.    Expand raw data buffer, if needed, to hold data strip
  299.    coming from file (perhaps should set upper bound on
  300.    the size of a buffer we'll use?).
  301.    */
  302.    bytecount = td->td_stripbytecount[(unsigned) strip];
  303.  
  304.    if (bytecount > tif->tif_rawdatasize)
  305.    {
  306.       tif->tif_curstrip = -1;         /* unknown state */
  307.       if (tif->tif_rawdata)
  308.       {
  309.          free((char *) tif->tif_rawdata);
  310.          tif->tif_rawdata = NULL;
  311.       }
  312.  
  313.       tif->tif_rawdatasize = bytecount; /* bug CAL */
  314.  
  315.       tif->tif_rawdata = malloc((unsigned)tif->tif_rawdatasize);
  316.       if (tif->tif_rawdata == NULL)
  317.       {
  318.          TIFFError(module,"%s: No space for data buffer at scanline %d",
  319.                    tif->tif_name, tif->tif_row);
  320.          tif->tif_rawdatasize = 0;
  321.          return (FALSE);
  322.       }
  323.    }
  324.    if (!ReadOK(tif->tif_fd, tif->tif_rawdata, (unsigned) bytecount))
  325.    {
  326.       TIFFError(module, "%s: Read error at scanline %d",
  327.                 tif->tif_name, tif->tif_row);
  328.       return (FALSE);
  329.    }
  330.    return (TIFFStartStrip(tif, strip));
  331. }
  332.  
  333. /*
  334. Seek to a random row+sample in a file.
  335. */
  336.  
  337. static
  338. CompletionCode TIFFSeek(TIFF *tif, long row, unsigned sample)
  339. {
  340.    register TIFFDirectory *td = &tif->tif_dir;
  341.    unsigned long strip;
  342.  
  343.    if (row >= td->td_imagelength)
  344.    {
  345.       /* out of range */
  346.       TIFFError(tif->tif_name, "%d: Row out of range, max %d",
  347.                 row, td->td_imagelength);
  348.       return (FALSE);
  349.    }
  350.    if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  351.    {
  352.       if (sample >= td->td_samplesperpixel)
  353.       {
  354.          TIFFError(tif->tif_name,"%d: Sample out of range, max %d",
  355.                    sample, td->td_samplesperpixel);
  356.          return (FALSE);
  357.       }
  358.       strip = (sample*td->td_stripsperimage+row/td->td_rowsperstrip);
  359.    }
  360.    else
  361.       strip = row / td->td_rowsperstrip;
  362.  
  363.    if (strip != tif->tif_curstrip)
  364.    {
  365.       /* different strip, refill */
  366.       if (!TIFFReadStrip(tif, strip))
  367.          return (FALSE);
  368.    }
  369.    else
  370.    {
  371.       if (row < tif->tif_row)
  372.       {
  373.          /*
  374.          Moving backwards within the same strip: backup
  375.          to the start and then decode forward (below). If
  376.          you're planning on lots of random access within a
  377.          strip, it's better to just read and decode the entire
  378.          strip, and then access the decoded data in a random fashion.
  379.          */
  380.          if (!TIFFStartStrip(tif, strip))
  381.             return (FALSE);
  382.       }
  383.       if (row != tif->tif_row)
  384.       {
  385.          if (tif->tif_seek)
  386.          {
  387.             /* Seek forward to the desired row */
  388.             if (!(*tif->tif_seek)(tif, row - tif->tif_row))
  389.                return (FALSE);
  390.             tif->tif_row = row;
  391.          }
  392.          else
  393.          {
  394.             TIFFError(tif->tif_name,
  395.                      "Compression algorithm does not support random access");
  396.             return (FALSE);
  397.          }
  398.       }
  399.    }
  400.    return (TRUE);
  401. }
  402.  
  403. /*
  404. Read a tiff scan line.
  405. */
  406. CompletionCode TIFFReadScanline(TIFF *tif, char *buf,
  407.                 long row, unsigned sample)
  408. {
  409.    CompletionCode e;
  410.  
  411.    if (tif->tif_mode == O_WRONLY)
  412.    {
  413.       TIFFError(tif->tif_name, "File not open for reading");
  414.       return (FALSE);
  415.    }
  416.    if ((e = TIFFSeek(tif, row, sample)) == TRUE)
  417.    {
  418.       /* Decompress desired row into user buffer */
  419.       e = (*tif->tif_decoderow)(tif, buf, tif->tif_scanlinesize);
  420.       tif->tif_row++;
  421.    }
  422.    return (e);
  423. }
  424.  
  425. /*
  426. The following functions are used to write tiff files.
  427. */
  428.  
  429. static  char module[] = "TIFFWriteScanline";
  430.  
  431. static
  432. CompletionCode TIFFGrowStrips(TIFF *tif, short delta)
  433. {
  434.    TIFFDirectory *td = &tif->tif_dir;
  435.  
  436.    assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
  437.    td->td_stripoffset = (unsigned long *)realloc(td->td_stripoffset,
  438.      (unsigned)((td->td_nstrips + delta) * sizeof (unsigned long)));
  439.    td->td_stripbytecount = (unsigned long *)realloc(td->td_stripbytecount,
  440.      (unsigned)((td->td_nstrips + delta) * sizeof (unsigned long)));
  441.    if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
  442.    {
  443.       td->td_nstrips = 0;
  444.       TIFFError(module, "%s: No space to expand strip arrays",tif->tif_name);
  445.       return (FALSE);
  446.    }
  447.    memset(td->td_stripoffset + (unsigned) td->td_nstrips,0,
  448.      (unsigned)(delta*sizeof (unsigned long)));
  449.    memset(td->td_stripbytecount + (unsigned) td->td_nstrips,0,
  450.      (unsigned)(delta*sizeof (unsigned long)));
  451.    td->td_nstrips += delta;
  452.    return (TRUE);
  453. }
  454.  
  455.  
  456. CompletionCode TIFFWriteScanline(TIFF *tif, char *buf,
  457.                  long row, unsigned sample)
  458. {
  459.    register TIFFDirectory *td;
  460.    CompletionCode status;
  461.    long strip;
  462.  
  463.    if (tif->tif_mode == O_RDONLY)
  464.    {
  465.       TIFFError(module, "%s: File not open for writing",tif->tif_name);
  466.       return (-1);
  467.    }
  468.    td = &tif->tif_dir;
  469.    /*
  470.    On the first write verify all the required information
  471.    has been setup and initialize any data structures that
  472.    had to wait until directory information was set.
  473.    Note that a lot of our work is assumed to remain valid
  474.    because we disallow any of the important parameters
  475.    from changing after we start writing (i.e. once
  476.    TIFF_BEENWRITING is set, TIFFSetField will only allow
  477.    the image's length to be changed).
  478.    */
  479.    if ((tif->tif_flags & TIFF_BEENWRITING) == 0)
  480.    {
  481.       if (!TIFFWriteSetup(tif))
  482.          return (-1);
  483.       tif->tif_flags |= TIFF_BEENWRITING;
  484.    }
  485.    /*
  486.    Handle delayed allocation of data buffer.  This
  487.    permits it to be sized more intelligently (using
  488.    directory information).
  489.    */
  490.    if ((tif->tif_flags & TIFF_BUFFERSETUP) == 0)
  491.    {
  492.       if (!TIFFBufferSetup(tif))
  493.          return (-1);
  494.       tif->tif_flags |= TIFF_BUFFERSETUP;
  495.    }
  496.    /*
  497.    Extend image length if needed (but only for PlanarConfig=1).
  498.    */
  499.    if (row >= td->td_imagelength)
  500.    {
  501.       /* extend image */
  502.       if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  503.       {
  504.          TIFFError(tif->tif_name,
  505.                   "Can not change \"ImageLength\" when using separate planes");
  506.         return (-1);
  507.       }
  508.       td->td_imagelength = row;
  509.    }
  510.    /*
  511.    Calculate strip and check for crossings. */
  512.    if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  513.    {
  514.       if (sample >= td->td_samplesperpixel)
  515.       {
  516.          TIFFError(tif->tif_name,"%d: Sample out of range, max %d",
  517.                    sample, td->td_samplesperpixel);
  518.          return (-1);
  519.       }
  520.       strip = (long)(sample*td->td_stripsperimage + row/td->td_rowsperstrip);
  521.    }
  522.    else
  523.       strip = (long)(row / td->td_rowsperstrip);
  524.    if (strip != tif->tif_curstrip)
  525.    {
  526.       /* Changing strips -- flush any data present. */
  527.       if (tif->tif_rawcc > 0 && !TIFFFlushData(tif))
  528.          return (-1);
  529.       tif->tif_curstrip = strip;
  530.       tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  531.       if (tif->tif_stripencode && !(*tif->tif_stripencode)(tif))
  532.          return (-1);
  533.    }
  534.    /*
  535.    Check strip array to make sure there's space. We don't
  536.    support dynamically growing files that have data organized
  537.    in separate bitplanes because it's too painful.  In that
  538.    case we require that the imagelength be set properly
  539.    before the first write (so that the strips array will
  540.    be fully allocated above).
  541.    */
  542.    if (strip > td->td_nstrips && !TIFFGrowStrips(tif, STRIPINCR))
  543.       return (-1);
  544.    /*
  545.    Ensure the write is either sequential or at the
  546.    beginning of a strip (or that we can randomly
  547.    access the data -- i.e. no encoding).
  548.    */
  549.    if (row != tif->tif_row)
  550.    {
  551.       if (tif->tif_seek)
  552.       {
  553.          if (row < tif->tif_row)
  554.          {
  555.             /*
  556.             Moving backwards within the same strip:
  557.             backup to the start and then decode
  558.             forward (below).
  559.             */
  560.             tif->tif_row = (strip % td->td_stripsperimage) *
  561.                                     td->td_rowsperstrip;
  562.             tif->tif_rawcp = tif->tif_rawdata;
  563.          }
  564.          /* Seek forward to the desired row. */
  565.          if (!(*tif->tif_seek)(tif, row - tif->tif_row))
  566.             return (-1);
  567.          tif->tif_row = row;
  568.       }
  569.       else
  570.       {
  571.          TIFFError(tif->tif_name,
  572.                   "Compression algorithm does not support random access");
  573.          return (-1);
  574.       }
  575.    }
  576.    status = (*tif->tif_encoderow)(tif, buf, tif->tif_scanlinesize);
  577.    tif->tif_row++;
  578.    return (status);
  579. }
  580.  
  581. /*
  582. Verify and setup state on first write.
  583. */
  584. static
  585. CompletionCode TIFFWriteSetup(TIFF *tif)
  586. {
  587.  
  588.    if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
  589.    {
  590.       TIFFError(module,"%s: Must set \"ImageWidth\" before writing data",
  591.                 tif->tif_name);
  592.       return (FALSE);
  593.    }
  594.    if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
  595.    {
  596.       TIFFError(module,
  597.                 "%s: Must set \"PlanarConfiguration\" before writing data",
  598.                 tif->tif_name);
  599.       return (FALSE);
  600.    }
  601.    if (tif->tif_dir.td_stripoffset == NULL)
  602.    {
  603.       register TIFFDirectory *td = &tif->tif_dir;
  604.  
  605.       td->td_stripsperimage =
  606.      (td->td_rowsperstrip == 0xffffffffL ||
  607.          td->td_imagelength == 0) ?
  608.          1 : howmany(td->td_imagelength, td->td_rowsperstrip);
  609.       td->td_nstrips = td->td_stripsperimage;
  610.       if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  611.          td->td_nstrips *= td->td_samplesperpixel;
  612.       td->td_stripoffset = (unsigned long *)
  613.       malloc((unsigned)(td->td_nstrips * sizeof (unsigned long)));
  614.       td->td_stripbytecount = (unsigned long *)
  615.       malloc((unsigned)(td->td_nstrips * sizeof (unsigned long)));
  616.       if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
  617.       {
  618.          td->td_nstrips = 0;
  619.          TIFFError(module, "%s: No space for strip arrays",tif->tif_name);
  620.          return (FALSE);
  621.       }
  622.       /*
  623.       Place data at the end-of-file (by setting offsets to zero). */
  624.       memset((char *)td->td_stripoffset,0,(unsigned)(
  625.     td->td_nstrips * sizeof (unsigned long)));
  626.       memset((char *)td->td_stripbytecount,0,(unsigned)(
  627.     td->td_nstrips * sizeof (unsigned long)));
  628.       TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
  629.       TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
  630.    }
  631.    return (TRUE);
  632. }
  633.  
  634. static
  635. CompletionCode TIFFBufferSetup(TIFF *tif)
  636. {
  637.    long scanline;
  638.  
  639.    tif->tif_scanlinesize = scanline = TIFFScanlineSize(tif);
  640.    /* Make raw data buffer at least 8K */
  641.    if (scanline < 8*1024)
  642.       scanline = 8*1024;
  643.    tif->tif_rawdata = malloc((unsigned) scanline);
  644.    if (tif->tif_rawdata == NULL)
  645.    {
  646.       TIFFError(module, "%s: No space for output buffer",tif->tif_name);
  647.       return (FALSE);
  648.    }
  649.    tif->tif_rawdatasize = scanline;
  650.    tif->tif_rawcc = 0;
  651.    tif->tif_rawcp = tif->tif_rawdata;
  652.    return (TRUE);
  653. }
  654.  
  655. /*
  656. Internal version of TIFFFlushData that can be
  657. called by ``encodestrip routines'' w/o concern
  658. for infinite recursion.
  659. */
  660. CompletionCode TIFFFlushData1(TIFF *tif)
  661. {
  662.    TIFFDirectory *td = &tif->tif_dir;
  663.    long strip = tif->tif_curstrip;
  664.  
  665.    if (td->td_stripoffset[(unsigned) strip] == 0 || tif->tif_curoff == 0)
  666.    {
  667.       /* No current offset, set the current strip. */
  668.       if (td->td_stripoffset[(unsigned) strip] != 0)
  669.       {
  670.          if (!SeekOK(tif->tif_fd, td->td_stripoffset[(unsigned) strip]))
  671.          {
  672.             TIFFError(module,"%s: Seek error at scanline %d",
  673.                       tif->tif_name, tif->tif_row);
  674.             return (FALSE);
  675.          }
  676.       }
  677.       else
  678.          td->td_stripoffset[(unsigned) strip] = lseek(tif->tif_fd, 0L, SEEK_END);
  679.          tif->tif_curoff = td->td_stripoffset[(unsigned) strip];
  680.    }
  681.    if (!WriteOK(tif->tif_fd, tif->tif_rawdata, (int) tif->tif_rawcc))
  682.    {
  683.       TIFFError(module, "%s: Write error at scanline %d",
  684.                 tif->tif_name, tif->tif_row);
  685.       return (FALSE);
  686.    }
  687.    tif->tif_curoff += tif->tif_rawcc;
  688.    td->td_stripbytecount[(unsigned) strip] += tif->tif_rawcc;
  689.    tif->tif_rawcc = 0;
  690.    tif->tif_rawcp = tif->tif_rawdata;
  691.    return (TRUE);
  692. }
  693.