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
This commit is contained in:
Andrey Kiselev 2004-04-14 06:34:40 +00:00
parent 973a9b78d6
commit 1c37d7bf24

View File

@ -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 * Copyright (c) 1988-1997 Sam Leffler
@ -33,8 +33,6 @@
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#define REWRITE_HACK
#define STRIPINCR 20 /* expansion factor on strip array */ #define STRIPINCR 20 /* expansion factor on strip array */
#define WRITECHECKSTRIPS(tif, module) \ #define WRITECHECKSTRIPS(tif, module) \
@ -114,6 +112,19 @@ TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample)
return (-1); return (-1);
tif->tif_flags |= TIFF_CODERSETUP; 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)) if (!(*tif->tif_preencode)(tif, sample))
return (-1); return (-1);
tif->tif_flags |= TIFF_POSTENCODE; 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 * Encode the supplied data and write it to the
* specified strip. There must be space for the * specified strip.
* data; we don't check if strips overlap!
* *
* NB: Image length must be setup before writing. * 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; tif->tif_flags |= TIFF_CODERSETUP;
} }
#ifdef REWRITE_HACK
tif->tif_rawcc = 0; tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata; 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 */ /* this forces TIFFAppendToStrip() to do a seek */
tif->tif_curoff = 0; tif->tif_curoff = 0;
} }
#endif
tif->tif_flags &= ~TIFF_POSTENCODE; tif->tif_flags &= ~TIFF_POSTENCODE;
sample = (tsample_t)(strip / td->td_stripsperimage); 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. * 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. * 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); return ((tsize_t) -1);
tif->tif_curtile = tile; tif->tif_curtile = tile;
#ifdef REWRITE_HACK
tif->tif_rawcc = 0; tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata; 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 */ /* this forces TIFFAppendToStrip() to do a seek */
tif->tif_curoff = 0; tif->tif_curoff = 0;
} }
#endif
/* /*
* Compute tiles per row & per column to compute * Compute tiles per row & per column to compute
@ -497,23 +501,6 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
return (0); 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 * On the first write verify all the required information
* has been setup and initialize any data structures that * 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. * 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 static int
TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc) 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. * No current offset, set the current strip.
*/ */
if (td->td_stripoffset[strip] != 0) { 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])) { if (!SeekOK(tif, td->td_stripoffset[strip])) {
TIFFError(module, TIFFError(module,
"%s: Seek error at scanline %lu", "%s: Seek error at scanline %lu",
tif->tif_name, (u_long) tif->tif_row); tif->tif_name, (u_long)tif->tif_row);
return (0); return (0);
} }
} else } else
@ -644,6 +647,7 @@ TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc)
TIFFSeekFile(tif, (toff_t) 0, SEEK_END); TIFFSeekFile(tif, (toff_t) 0, SEEK_END);
tif->tif_curoff = td->td_stripoffset[strip]; tif->tif_curoff = td->td_stripoffset[strip];
} }
if (!WriteOK(tif, data, cc)) { if (!WriteOK(tif, data, cc)) {
TIFFError(module, "%s: Write error at scanline %lu", TIFFError(module, "%s: Write error at scanline %lu",
tif->tif_name, (u_long) tif->tif_row); tif->tif_name, (u_long) tif->tif_row);