From 1c37d7bf24b2dbbcdb7b558bcadb08a241d88771 Mon Sep 17 00:00:00 2001 From: Andrey Kiselev Date: Wed, 14 Apr 2004 06:34:40 +0000 Subject: [PATCH] Allow in-place updating of the compressed images (don't work properly with all codecs). For details see GDAL bug http://bugzilla.remotesensing.org/show_bug.cgi?id=534 --- libtiff/tif_write.c | 70 ++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/libtiff/tif_write.c b/libtiff/tif_write.c index 19c0c3d1..39bacafb 100644 --- a/libtiff/tif_write.c +++ b/libtiff/tif_write.c @@ -1,4 +1,4 @@ -/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_write.c,v 1.10 2004-01-20 19:28:05 dron Exp $ */ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_write.c,v 1.11 2004-04-14 06:34:40 dron Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -33,8 +33,6 @@ #include #include -#define REWRITE_HACK - #define STRIPINCR 20 /* expansion factor on strip array */ #define WRITECHECKSTRIPS(tif, module) \ @@ -114,6 +112,19 @@ TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) return (-1); tif->tif_flags |= TIFF_CODERSETUP; } + + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + + if( td->td_stripbytecount[strip] > 0 ) + { + /* if we are writing over existing tiles, zero length */ + td->td_stripbytecount[strip] = 0; + + /* this forces TIFFAppendToStrip() to do a seek */ + tif->tif_curoff = 0; + } + if (!(*tif->tif_preencode)(tif, sample)) return (-1); tif->tif_flags |= TIFF_POSTENCODE; @@ -166,8 +177,7 @@ TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) /* * Encode the supplied data and write it to the - * specified strip. There must be space for the - * data; we don't check if strips overlap! + * specified strip. * * NB: Image length must be setup before writing. */ @@ -215,7 +225,6 @@ TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc) tif->tif_flags |= TIFF_CODERSETUP; } -#ifdef REWRITE_HACK tif->tif_rawcc = 0; tif->tif_rawcp = tif->tif_rawdata; @@ -227,7 +236,6 @@ TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc) /* this forces TIFFAppendToStrip() to do a seek */ tif->tif_curoff = 0; } -#endif tif->tif_flags &= ~TIFF_POSTENCODE; sample = (tsample_t)(strip / td->td_stripsperimage); @@ -254,8 +262,6 @@ TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc) /* * Write the supplied data to the specified strip. - * There must be space for the data; we don't check - * if strips overlap! * * NB: Image length must be setup before writing. */ @@ -355,7 +361,6 @@ TIFFWriteEncodedTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc) return ((tsize_t) -1); tif->tif_curtile = tile; -#ifdef REWRITE_HACK tif->tif_rawcc = 0; tif->tif_rawcp = tif->tif_rawdata; @@ -367,7 +372,6 @@ TIFFWriteEncodedTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc) /* this forces TIFFAppendToStrip() to do a seek */ tif->tif_curoff = 0; } -#endif /* * Compute tiles per row & per column to compute @@ -497,23 +501,6 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module) return (0); } - /* - * While we allow compressed TIFF files to be opened in update mode, - * we don't allow writing any image blocks in an existing compressed - * image. Eventually we could do so, by moving blocks that grow - * to the end of the file, but we don't for now. - */ - if (tif->tif_dir.td_stripoffset != NULL - && tif->tif_dir.td_compression != COMPRESSION_NONE ) - { - TIFFError( module, - "%s:\n" - "In place update to compressed TIFF images not " - "supported.", - tif->tif_name ); - return (0); - } - /* * On the first write verify all the required information * has been setup and initialize any data structures that @@ -618,9 +605,6 @@ TIFFGrowStrips(TIFF* tif, int delta, const char* module) /* * Append the data to the specified strip. - * - * NB: We don't check that there's space in the - * file (i.e. that strips do not overlap). */ static int TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc) @@ -633,10 +617,29 @@ TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc) * No current offset, set the current strip. */ if (td->td_stripoffset[strip] != 0) { + /* + * Prevent overlapping of the data chunks. We need + * this to enable in place updating of the compressed + * images. Larger blocks will be moved at the end of + * the file without any optimization of the spare + * space, so such scheme is not too much effective. + */ + tstrip_t i; + for (i = 0; i < td->td_stripsperimage; i++) { + if (td->td_stripoffset[i] > + td->td_stripoffset[strip] + && td->td_stripoffset[i] < + td->td_stripoffset[strip] + cc) { + td->td_stripoffset[strip] = + TIFFSeekFile(tif, (toff_t) 0, + SEEK_END); + } + } + if (!SeekOK(tif, td->td_stripoffset[strip])) { TIFFError(module, - "%s: Seek error at scanline %lu", - tif->tif_name, (u_long) tif->tif_row); + "%s: Seek error at scanline %lu", + tif->tif_name, (u_long)tif->tif_row); return (0); } } else @@ -644,6 +647,7 @@ TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc) TIFFSeekFile(tif, (toff_t) 0, SEEK_END); tif->tif_curoff = td->td_stripoffset[strip]; } + if (!WriteOK(tif, data, cc)) { TIFFError(module, "%s: Write error at scanline %lu", tif->tif_name, (u_long) tif->tif_row);