AWARE [SYSTEMS] Imaging expertise for the Delphi developer
AWare Systems, Imaging expertise for the Delphi developer, Home TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

TIFF and LibTiff Mailing List Archive
April 2002

Previous Thread
Next Thread

Previous by Thread
Next by Thread

Previous by Date
Next by Date

Contact

The TIFF Mailing List Homepage
This list is run by Frank Warmerdam
Archive maintained by AWare Systems



Valid HTML 4.01!



Thread

2002.04.08 15:45 "writing tiff incrementally", by <myia@is.elta.co.il>
2002.04.08 15:48 "Re: writing tiff incrementally", by Daniel Mccoy
2002.04.08 16:02 "Re: writing tiff incrementally", by Sam Leffler
2002.04.08 16:11 "Re: writing tiff incrementally", by Daniel Mccoy
2002.04.08 19:50 "Re: writing tiff incrementally", by Daniel Mccoy

2002.04.08 19:50 "Re: writing tiff incrementally", by Daniel Mccoy

From: myia@is.elta.co.il
> I would like to write a tiff image incrementally: I have a program that
> writes a tiff file, and I would like to allow users to view the tiles I
> wrote so far (using standard tiff viewers). Does the library support
> something like this?
> I tried TIFFFlush, but it doesn't allow me to go on writing tiles to the
> image. If the library does not support it, is there some standard or
> easy wat to do it?
> 
> Any suggestions are welcome.

Here is a patch to the 3.5.7 tif_dirwrite to add TIFFCheckpointDirectory().
(You might want to also add an "extern" for it in tiffio.h,
right next to the one for TIFFWriteDirectory().)

Once this is in, you need only call TIFFCheckpointDirectory(tif)
to write out the current state of the tiff directory into the file
to make what is currently in the file readable.
Unlike TIFFWriteDirectory, TIFFCheckpointDirectory does not free
up the directory data structures in memory, so they can be updated
(as strips/tiles are written) and written again.

Reading such a partial file you will at worst get a tiff read error
for the first strip/tile encountered that is incomplete,
but you will at least get all the valid data in the file before that.

When the file is complete, just use TIFFWriteDirectory as usual
to finish it off cleanly.

(The changes are not really as extensive as it looks, a couple of sections
of code got pulled into conditionals so the indentation changed. 
Try a diff that ignores whitespace after the patch to see what really changed.)

Could someone else give this a try and merge it into the library?
(I've already spent more time on it than I'm supposed to at this point.)

Daniel McCoy    Pixar

*************Beginning of patch************************
--- tif_dirwrite.c	Mon Apr  8 12:29:59 2002
+++ tif_dirwrite.c.new	Mon Apr  8 12:30:06 2002
@@ -87,8 +87,8 @@
  * handle overwriting a directory with auxiliary
  * storage that's been changed.
  */
-int
-TIFFWriteDirectory(TIFF* tif)
+static int
+TIFFWriteDirectory1(TIFF* tif, int done)
 {
 	uint16 dircount;
 	toff_t diroff;
@@ -108,31 +108,34 @@
 	 * different characteristics get the right buffers
 	 * setup for them.
 	 */
-	if (tif->tif_flags & TIFF_POSTENCODE) {
-		tif->tif_flags &= ~TIFF_POSTENCODE;
-		if (!(*tif->tif_postencode)(tif)) {
-			TIFFError(tif->tif_name,
-			    "Error post-encoding before directory write");
-			return (0);
-		}
-	}
-	(*tif->tif_close)(tif);			/* shutdown encoder */
-	/*
-	 * Flush any data that might have been written
-	 * by the compression close+cleanup routines.
-	 */
-	if (tif->tif_rawcc > 0 && !TIFFFlushData1(tif)) {
-		TIFFError(tif->tif_name,
-		    "Error flushing data before directory write");
-		return (0);
-	}
-	if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
-		_TIFFfree(tif->tif_rawdata);
-		tif->tif_rawdata = NULL;
-		tif->tif_rawcc = 0;
-                tif->tif_rawdatasize = 0;
+	if (done)
+	{
+	    if (tif->tif_flags & TIFF_POSTENCODE) {
+		    tif->tif_flags &= ~TIFF_POSTENCODE;
+		    if (!(*tif->tif_postencode)(tif)) {
+			    TIFFError(tif->tif_name,
+				"Error post-encoding before directory write");
+			    return (0);
+		    }
+	    }
+	    (*tif->tif_close)(tif);		/* shutdown encoder */
+	    /*
+	     * Flush any data that might have been written
+	     * by the compression close+cleanup routines.
+	     */
+	    if (tif->tif_rawcc > 0 && !TIFFFlushData1(tif)) {
+		    TIFFError(tif->tif_name,
+			"Error flushing data before directory write");
+		    return (0);
+	    }
+	    if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
+		    _TIFFfree(tif->tif_rawdata);
+		    tif->tif_rawdata = NULL;
+		    tif->tif_rawcc = 0;
+		    tif->tif_rawdatasize = 0;
+	    }
+	    tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
 	}
-	tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
 
 	td = &tif->tif_dir;
 	/*
@@ -351,22 +354,48 @@
 		TIFFError(tif->tif_name, "Error writing directory link");
 		goto bad;
 	}
-	TIFFFreeDirectory(tif);
-	_TIFFfree(data);
-	tif->tif_flags &= ~TIFF_DIRTYDIRECT;
-	(*tif->tif_cleanup)(tif);
+	if (done) {
+		TIFFFreeDirectory(tif);
+		tif->tif_flags &= ~TIFF_DIRTYDIRECT;
+		(*tif->tif_cleanup)(tif);
 
-	/*
-	 * Reset directory-related state for subsequent
-	 * directories.
-	 */
-        TIFFCreateDirectory(tif);
+		/*
+		* Reset directory-related state for subsequent
+		* directories.
+		*/
+		TIFFCreateDirectory(tif);
+	}
+	_TIFFfree(data);
 	return (1);
 bad:
 	_TIFFfree(data);
 	return (0);
 }
 #undef WriteRationalPair
+
+int
+TIFFWriteDirectory(TIFF* tif)
+{
+	return TIFFWriteDirectory1(tif, 1);
+}
+
+/*
+ * Similar to TIFFWriteDirectory(), writes the directory out
+ * but leaves all data structures in memory so that it can be
+ * written again.  This will make a partially written TIFF file
+ * readable before it is successfully completed/closed.
+ */ 
+int
+TIFFCheckpointDirectory(TIFF* tif)
+{
+	int rc;
+	/* Setup the strips arrays, if they haven't already been. */
+	if (tif->tif_dir.td_stripoffset == NULL)
+	    (void) TIFFSetupStrips(tif);
+	rc = TIFFWriteDirectory1(tif, 0);
+	(void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
+	return rc;
+}
 
 /*
  * Process tags that are not special cased.
*************End of patch************************