summaryrefslogtreecommitdiff
path: root/libtiff
diff options
context:
space:
mode:
Diffstat (limited to 'libtiff')
-rw-r--r--libtiff/tif_dir.c13
-rw-r--r--libtiff/tif_dir.h9
-rw-r--r--libtiff/tif_dirread.c591
-rw-r--r--libtiff/tif_dirwrite.c14
-rw-r--r--libtiff/tif_jpeg.c11
-rw-r--r--libtiff/tif_ojpeg.c17
-rw-r--r--libtiff/tif_open.c17
-rw-r--r--libtiff/tif_print.c10
-rw-r--r--libtiff/tif_read.c87
-rw-r--r--libtiff/tif_strip.c3
-rw-r--r--libtiff/tif_write.c54
-rw-r--r--libtiff/tiffio.h5
-rw-r--r--libtiff/tiffiop.h2
13 files changed, 575 insertions, 258 deletions
diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c
index b4ecd44f..4a3fcd55 100644
--- a/libtiff/tif_dir.c
+++ b/libtiff/tif_dir.c
@@ -1018,12 +1018,12 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
case TIFFTAG_STRIPOFFSETS:
case TIFFTAG_TILEOFFSETS:
_TIFFFillStriles( tif );
- *va_arg(ap, uint64**) = td->td_stripoffset;
+ *va_arg(ap, uint64**) = td->td_stripoffset_p;
break;
case TIFFTAG_STRIPBYTECOUNTS:
case TIFFTAG_TILEBYTECOUNTS:
_TIFFFillStriles( tif );
- *va_arg(ap, uint64**) = td->td_stripbytecount;
+ *va_arg(ap, uint64**) = td->td_stripbytecount_p;
break;
case TIFFTAG_MATTEING:
*va_arg(ap, uint16*) =
@@ -1282,8 +1282,9 @@ TIFFFreeDirectory(TIFF* tif)
CleanupField(td_transferfunction[0]);
CleanupField(td_transferfunction[1]);
CleanupField(td_transferfunction[2]);
- CleanupField(td_stripoffset);
- CleanupField(td_stripbytecount);
+ CleanupField(td_stripoffset_p);
+ CleanupField(td_stripbytecount_p);
+ td->td_stripoffsetbyteallocsize = 0;
TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
@@ -1296,10 +1297,8 @@ TIFFFreeDirectory(TIFF* tif)
td->td_customValueCount = 0;
CleanupField(td_customValues);
-#if defined(DEFER_STRILE_LOAD)
_TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
_TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
-#endif
}
#undef CleanupField
@@ -1387,7 +1386,9 @@ TIFFDefaultDirectory(TIFF* tif)
td->td_tilewidth = 0;
td->td_tilelength = 0;
td->td_tiledepth = 1;
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
+#endif
td->td_resolutionunit = RESUNIT_INCH;
td->td_sampleformat = SAMPLEFORMAT_UINT;
td->td_imagedepth = 1;
diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h
index b2f5e694..76f3eaf7 100644
--- a/libtiff/tif_dir.h
+++ b/libtiff/tif_dir.h
@@ -97,13 +97,14 @@ typedef struct {
* number of striles */
uint32 td_stripsperimage;
uint32 td_nstrips; /* size of offset & bytecount arrays */
- uint64* td_stripoffset;
- uint64* td_stripbytecount;
+ uint64* td_stripoffset_p; /* should be accessed with TIFFGetStrileOffset */
+ uint64* td_stripbytecount_p; /* should be accessed with TIFFGetStrileByteCount */
+ uint32 td_stripoffsetbyteallocsize; /* number of elements currently allocated for td_stripoffset/td_stripbytecount. Only used if TIFF_LAZYSTRILELOAD is set */
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
-#if defined(DEFER_STRILE_LOAD)
+#endif
TIFFDirEntry td_stripoffset_entry; /* for deferred loading */
TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */
-#endif
uint16 td_nsubifd;
uint64* td_subifd;
/* YCbCr parameters */
diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
index 65675d0f..023c4c9b 100644
--- a/libtiff/tif_dirread.c
+++ b/libtiff/tif_dirread.c
@@ -3536,6 +3536,41 @@ static int _TIFFGetMaxColorChannels( uint16 photometric )
}
}
+static int ByteCountLooksBad(TIFF* tif)
+{
+ /*
+ * Assume we have wrong StripByteCount value (in case
+ * of single strip) in following cases:
+ * - it is equal to zero along with StripOffset;
+ * - it is larger than file itself (in case of uncompressed
+ * image);
+ * - it is smaller than the size of the bytes per row
+ * multiplied on the number of rows. The last case should
+ * not be checked in the case of writing new image,
+ * because we may do not know the exact strip size
+ * until the whole image will be written and directory
+ * dumped out.
+ */
+ uint64 bytecount = TIFFGetStrileByteCount(tif, 0);
+ uint64 offset = TIFFGetStrileOffset(tif, 0);
+ uint64 filesize;
+
+ if( offset == 0 )
+ return 0;
+ if (bytecount == 0)
+ return 1;
+ if ( tif->tif_dir.td_compression != COMPRESSION_NONE )
+ return 0;
+ filesize = TIFFGetFileSize(tif);
+ if( offset <= filesize && bytecount > filesize - offset )
+ return 1;
+ if( tif->tif_mode == O_RDONLY &&
+ bytecount < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength)
+ return 1;
+ return 0;
+}
+
+
/*
* Read the next TIFF directory from a file and convert it to the internal
* format. We read directories sequentially.
@@ -3870,39 +3905,39 @@ TIFFReadDirectory(TIFF* tif)
break;
case TIFFTAG_STRIPOFFSETS:
case TIFFTAG_TILEOFFSETS:
-#if defined(DEFER_STRILE_LOAD)
_TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry),
dp, sizeof(TIFFDirEntry) );
-#else
- if( tif->tif_dir.td_stripoffset != NULL )
+ if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
{
- TIFFErrorExt(tif->tif_clientdata, module,
- "tif->tif_dir.td_stripoffset is "
- "already allocated. Likely duplicated "
- "StripOffsets/TileOffsets tag");
- goto bad;
+ if( tif->tif_dir.td_stripoffset_p != NULL )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "tif->tif_dir.td_stripoffset is "
+ "already allocated. Likely duplicated "
+ "StripOffsets/TileOffsets tag");
+ goto bad;
+ }
+ if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset_p))
+ goto bad;
}
- if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset))
- goto bad;
-#endif
break;
case TIFFTAG_STRIPBYTECOUNTS:
case TIFFTAG_TILEBYTECOUNTS:
-#if defined(DEFER_STRILE_LOAD)
_TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry),
dp, sizeof(TIFFDirEntry) );
-#else
- if( tif->tif_dir.td_stripbytecount != NULL )
+ if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
{
- TIFFErrorExt(tif->tif_clientdata, module,
- "tif->tif_dir.td_stripbytecount is "
- "already allocated. Likely duplicated "
- "StripByteCounts/TileByteCounts tag");
- goto bad;
+ if( tif->tif_dir.td_stripbytecount_p != NULL )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "tif->tif_dir.td_stripbytecount is "
+ "already allocated. Likely duplicated "
+ "StripByteCounts/TileByteCounts tag");
+ goto bad;
+ }
+ if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount_p))
+ goto bad;
}
- if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount))
- goto bad;
-#endif
break;
case TIFFTAG_COLORMAP:
case TIFFTAG_TRANSFERFUNCTION:
@@ -4130,33 +4165,10 @@ TIFFReadDirectory(TIFF* tif)
"\"StripByteCounts\" field, calculating from imagelength");
if (EstimateStripByteCounts(tif, dir, dircount) < 0)
goto bad;
- /*
- * Assume we have wrong StripByteCount value (in case
- * of single strip) in following cases:
- * - it is equal to zero along with StripOffset;
- * - it is larger than file itself (in case of uncompressed
- * image);
- * - it is smaller than the size of the bytes per row
- * multiplied on the number of rows. The last case should
- * not be checked in the case of writing new image,
- * because we may do not know the exact strip size
- * until the whole image will be written and directory
- * dumped out.
- */
- #define BYTECOUNTLOOKSBAD \
- ( (tif->tif_dir.td_stripbytecount[0] == 0 && tif->tif_dir.td_stripoffset[0] != 0) || \
- (tif->tif_dir.td_compression == COMPRESSION_NONE && \
- (tif->tif_dir.td_stripoffset[0] <= TIFFGetFileSize(tif) && \
- tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0])) || \
- (tif->tif_mode == O_RDONLY && \
- tif->tif_dir.td_compression == COMPRESSION_NONE && \
- tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) )
} else if (tif->tif_dir.td_nstrips == 1
&& !(tif->tif_flags&TIFF_ISTILED)
- && _TIFFFillStriles(tif)
- && tif->tif_dir.td_stripoffset[0] != 0
- && BYTECOUNTLOOKSBAD) {
+ && ByteCountLooksBad(tif)) {
/*
* XXX: Plexus (and others) sometimes give a value of
* zero for a tag when they don't know what the
@@ -4168,13 +4180,13 @@ TIFFReadDirectory(TIFF* tif)
if(EstimateStripByteCounts(tif, dir, dircount) < 0)
goto bad;
-#if !defined(DEFER_STRILE_LOAD)
- } else if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG
+ } else if (!(tif->tif_flags&TIFF_DEFERSTRILELOAD)
+ && tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG
&& tif->tif_dir.td_nstrips > 2
&& tif->tif_dir.td_compression == COMPRESSION_NONE
- && tif->tif_dir.td_stripbytecount[0] != tif->tif_dir.td_stripbytecount[1]
- && tif->tif_dir.td_stripbytecount[0] != 0
- && tif->tif_dir.td_stripbytecount[1] != 0 ) {
+ && TIFFGetStrileByteCount(tif, 0) != TIFFGetStrileByteCount(tif, 1)
+ && TIFFGetStrileByteCount(tif, 0) != 0
+ && TIFFGetStrileByteCount(tif, 1) != 0 ) {
/*
* XXX: Some vendors fill StripByteCount array with
* absolutely wrong values (it can be equal to
@@ -4189,7 +4201,6 @@ TIFFReadDirectory(TIFF* tif)
"Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength");
if (EstimateStripByteCounts(tif, dir, dircount) < 0)
goto bad;
-#endif /* !defined(DEFER_STRILE_LOAD) */
}
}
if (dir)
@@ -4204,26 +4215,27 @@ TIFFReadDirectory(TIFF* tif)
else
tif->tif_dir.td_maxsamplevalue = (uint16)((1L<<tif->tif_dir.td_bitspersample)-1);
}
+
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
/*
* XXX: We can optimize checking for the strip bounds using the sorted
* bytecounts array. See also comments for TIFFAppendToStrip()
* function in tif_write.c.
*/
-#if !defined(DEFER_STRILE_LOAD)
- if (tif->tif_dir.td_nstrips > 1) {
+ if (!(tif->tif_flags&TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips > 1) {
uint32 strip;
tif->tif_dir.td_stripbytecountsorted = 1;
for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
- if (tif->tif_dir.td_stripoffset[strip - 1] >
- tif->tif_dir.td_stripoffset[strip]) {
+ if (TIFFGetStrileOffset(tif, strip - 1) >
+ TIFFGetStrileOffset(tif, strip)) {
tif->tif_dir.td_stripbytecountsorted = 0;
break;
}
}
}
-#endif /* !defined(DEFER_STRILE_LOAD) */
-
+#endif
+
/*
* An opportunity for compression mode dependent tag fixup
*/
@@ -4242,11 +4254,9 @@ TIFFReadDirectory(TIFF* tif)
(tif->tif_dir.td_nstrips==1)&&
(tif->tif_dir.td_compression==COMPRESSION_NONE)&&
((tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED))==TIFF_STRIPCHOP))
- {
- if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount )
- return 0;
- ChopUpSingleUncompressedStrip(tif);
- }
+ {
+ ChopUpSingleUncompressedStrip(tif);
+ }
/* There are also uncompressed stripped files with strips larger than */
/* 2 GB, which make them unfriendly with a lot of code. If possible, */
@@ -4256,8 +4266,6 @@ TIFFReadDirectory(TIFF* tif)
(tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP &&
TIFFStripSize64(tif) > 0x7FFFFFFFUL )
{
- if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount )
- return 0;
TryChopUpUncompressedBigTiff(tif);
}
@@ -4502,12 +4510,12 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
if( !_TIFFFillStrilesInternal( tif, 0 ) )
return -1;
- if (td->td_stripbytecount)
- _TIFFfree(td->td_stripbytecount);
- td->td_stripbytecount = (uint64*)
+ if (td->td_stripbytecount_p)
+ _TIFFfree(td->td_stripbytecount_p);
+ td->td_stripbytecount_p = (uint64*)
_TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
"for \"StripByteCounts\" array");
- if( td->td_stripbytecount == NULL )
+ if( td->td_stripbytecount_p == NULL )
return -1;
if (td->td_compression != COMPRESSION_NONE) {
@@ -4552,7 +4560,7 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
space /= td->td_samplesperpixel;
for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = space;
+ td->td_stripbytecount_p[strip] = space;
/*
* This gross hack handles the case were the offset to
* the last strip is past the place where we think the strip
@@ -4561,18 +4569,18 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
* of data in the strip and trim this number back accordingly.
*/
strip--;
- if (td->td_stripoffset[strip]+td->td_stripbytecount[strip] > filesize)
- td->td_stripbytecount[strip] = filesize - td->td_stripoffset[strip];
+ if (td->td_stripoffset_p[strip]+td->td_stripbytecount_p[strip] > filesize)
+ td->td_stripbytecount_p[strip] = filesize - td->td_stripoffset_p[strip];
} else if (isTiled(tif)) {
uint64 bytespertile = TIFFTileSize64(tif);
for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = bytespertile;
+ td->td_stripbytecount_p[strip] = bytespertile;
} else {
uint64 rowbytes = TIFFScanlineSize64(tif);
uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = rowbytes * rowsperstrip;
+ td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip;
}
TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
@@ -5744,9 +5752,9 @@ static void allocChoppedUpStripArrays(TIFF* tif, uint32 nstrips,
* Fill the strip information arrays with new bytecounts and offsets
* that reflect the broken-up format.
*/
- offset = td->td_stripoffset[0];
- bytecount = td->td_stripoffset[td->td_nstrips-1] +
- td->td_stripbytecount[td->td_nstrips-1] - offset;
+ offset = TIFFGetStrileOffset(tif, 0);
+ bytecount = TIFFGetStrileOffset(tif, td->td_nstrips-1) +
+ TIFFGetStrileByteCount(tif, td->td_nstrips-1) - offset;
for (i = 0; i < nstrips; i++)
{
if (stripbytes > bytecount)
@@ -5763,11 +5771,14 @@ static void allocChoppedUpStripArrays(TIFF* tif, uint32 nstrips,
td->td_stripsperimage = td->td_nstrips = nstrips;
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
- _TIFFfree(td->td_stripbytecount);
- _TIFFfree(td->td_stripoffset);
- td->td_stripbytecount = newcounts;
- td->td_stripoffset = newoffsets;
+ _TIFFfree(td->td_stripbytecount_p);
+ _TIFFfree(td->td_stripoffset_p);
+ td->td_stripbytecount_p = newcounts;
+ td->td_stripoffset_p = newoffsets;
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
td->td_stripbytecountsorted = 1;
+#endif
+ tif->tif_flags &= ~TIFF_DEFERSTRILELOAD;
}
@@ -5789,13 +5800,13 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
uint32 nstrips;
uint32 rowsperstrip;
- bytecount = td->td_stripbytecount[0];
+ bytecount = TIFFGetStrileByteCount(tif, 0);
/* On a newly created file, just re-opened to be filled, we */
/* don't want strip chop to trigger as it is going to cause issues */
/* later ( StripOffsets and StripByteCounts improperly filled) . */
if( bytecount == 0 && tif->tif_mode != O_RDONLY )
return;
- offset = td->td_stripoffset[0];
+ offset = TIFFGetStrileByteCount(tif, 0);
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
(!isUpSampled(tif)))
@@ -5870,7 +5881,7 @@ static void TryChopUpUncompressedBigTiff( TIFF* tif )
/* On a newly created file, just re-opened to be filled, we */
/* don't want strip chop to trigger as it is going to cause issues */
/* later ( StripOffsets and StripByteCounts improperly filled) . */
- if( td->td_stripbytecount[0] == 0 && tif->tif_mode != O_RDONLY )
+ if( TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY )
return;
if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
@@ -5890,7 +5901,7 @@ static void TryChopUpUncompressedBigTiff( TIFF* tif )
{
if( i == td->td_nstrips - 1 )
{
- if( td->td_stripbytecount[i] < TIFFVStripSize64(
+ if( TIFFGetStrileByteCount(tif, i) < TIFFVStripSize64(
tif, td->td_imagelength - i * td->td_rowsperstrip ) )
{
return;
@@ -5898,12 +5909,12 @@ static void TryChopUpUncompressedBigTiff( TIFF* tif )
}
else
{
- if( td->td_stripbytecount[i] != stripsize )
+ if( TIFFGetStrileByteCount(tif, i) != stripsize )
{
return;
}
- if( i > 0 && td->td_stripoffset[i] !=
- td->td_stripoffset[i-1] + td->td_stripbytecount[i - 1] )
+ if( i > 0 && TIFFGetStrileOffset(tif, i) !=
+ TIFFGetStrileOffset(tif, i-1) + TIFFGetStrileByteCount(tif, i-1) )
{
return;
}
@@ -5926,9 +5937,9 @@ static void TryChopUpUncompressedBigTiff( TIFF* tif )
/* file is as big as needed */
if( tif->tif_mode == O_RDONLY &&
nstrips > 1000000 &&
- (td->td_stripoffset[td->td_nstrips-1] > TIFFGetFileSize(tif) ||
- td->td_stripoffset[td->td_nstrips-1] +
- td->td_stripbytecount[td->td_nstrips-1] > TIFFGetFileSize(tif)) )
+ (TIFFGetStrileOffset(tif, td->td_nstrips-1) > TIFFGetFileSize(tif) ||
+ TIFFGetStrileOffset(tif, td->td_nstrips-1) +
+ TIFFGetStrileByteCount(tif, td->td_nstrips-1) > TIFFGetFileSize(tif)) )
{
return;
}
@@ -5936,60 +5947,384 @@ static void TryChopUpUncompressedBigTiff( TIFF* tif )
allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
}
+/* Read the value of [Strip|Tile]Offset or [Strip|Tile]ByteCount around
+ * strip/tile of number strile. Also fetch the neighbouring values using a
+ * 4096 byte page size.
+ */
+static
+int _TIFFPartialReadStripArray( TIFF* tif, TIFFDirEntry* dirent,
+ int strile, uint64* panVals )
+{
+ static const char module[] = "_TIFFPartialReadStripArray";
+#define IO_CACHE_PAGE_SIZE 4096
+
+ size_t sizeofval;
+ const int bSwab = (tif->tif_flags & TIFF_SWAB) != 0;
+ int sizeofvalint;
+ uint64 nBaseOffset;
+ uint64 nOffset;
+ uint64 nOffsetStartPage;
+ uint64 nOffsetEndPage;
+ tmsize_t nToRead;
+ tmsize_t nRead;
+ uint64 nLastStripOffset;
+ int iStartBefore;
+ int i;
+ const uint32 arraySize = tif->tif_dir.td_stripoffsetbyteallocsize;
+ unsigned char buffer[2 * IO_CACHE_PAGE_SIZE];
+
+ assert( dirent->tdir_count > 4 );
+
+ if( dirent->tdir_type == TIFF_SHORT )
+ {
+ sizeofval = sizeof(uint16);
+ }
+ else if( dirent->tdir_type == TIFF_LONG )
+ {
+ sizeofval = sizeof(uint32);
+ }
+ else if( dirent->tdir_type == TIFF_LONG8 )
+ {
+ sizeofval = sizeof(uint64);
+ }
+ else
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Invalid type for [Strip|Tile][Offset/ByteCounnt] tag");
+ panVals[strile] = 0;
+ return 0;
+ }
+ sizeofvalint = (int)(sizeofval);
+ if( tif->tif_flags&TIFF_BIGTIFF )
+ {
+ uint64 offset = dirent->tdir_offset.toff_long8;
+ if( bSwab )
+ TIFFSwabLong8(&offset);
+ nBaseOffset = offset;
+ }
+ else
+ {
+ uint32 offset = dirent->tdir_offset.toff_long;
+ if( bSwab )
+ TIFFSwabLong(&offset);
+ nBaseOffset = offset;
+ }
+ nOffset = nBaseOffset + sizeofval * strile;
+ nOffsetStartPage =
+ (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE;
+ nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE;
+
+ if( nOffset + sizeofval > nOffsetEndPage )
+ nOffsetEndPage += IO_CACHE_PAGE_SIZE;
+#undef IO_CACHE_PAGE_SIZE
+
+ nLastStripOffset = nBaseOffset + arraySize * sizeofval;
+ if( nLastStripOffset < nOffsetEndPage )
+ nOffsetEndPage = nLastStripOffset;
+ if( nOffsetStartPage >= nOffsetEndPage )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot read offset/size for strile %d", strile);
+ panVals[strile] = 0;
+ return 0;
+ }
+ if (!SeekOK(tif,nOffsetStartPage))
+ {
+ panVals[strile] = 0;
+ return 0;
+ }
-int _TIFFFillStriles( TIFF *tif )
-{
- return _TIFFFillStrilesInternal( tif, 1 );
+ nToRead = (tmsize_t)(nOffsetEndPage - nOffsetStartPage);
+ nRead = TIFFReadFile(tif, buffer, nToRead);
+ if( nRead < nToRead )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot read offset/size for strile around ~%d", strile);
+ return 0;
+ }
+ iStartBefore = -(int)((nOffset - nOffsetStartPage) / sizeofval);
+ if( strile + iStartBefore < 0 )
+ iStartBefore = -strile;
+ for( i = iStartBefore;
+ (uint32)(strile + i) < arraySize &&
+ (uint64)(nOffset) + (i + 1) * sizeofvalint <= nOffsetEndPage;
+ ++i )
+ {
+ if( sizeofval == sizeof(uint16) )
+ {
+ uint16 val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if( bSwab )
+ TIFFSwabShort(&val);
+ panVals[strile + i] = val;
+ }
+ else if( sizeofval == sizeof(uint32) )
+ {
+ uint32 val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if( bSwab )
+ TIFFSwabLong(&val);
+ panVals[strile + i] = val;
+ }
+ else
+ {
+ uint64 val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if( bSwab )
+ TIFFSwabLong8(&val);
+ panVals[strile + i] = val;
+ }
+ }
+ return 1;
}
-static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount )
+static int _TIFFFetchStrileValue(TIFF* tif,
+ uint32 strile,
+ TIFFDirEntry* dirent,
+ uint64** parray)
{
-#if defined(DEFER_STRILE_LOAD)
- register TIFFDirectory *td = &tif->tif_dir;
- int return_value = 1;
-
- if( td->td_stripoffset != NULL )
- return 1;
-
- if( td->td_stripoffset_entry.tdir_count == 0 )
+ static const char module[] = "_TIFFFetchStrileValue";
+ TIFFDirectory *td = &tif->tif_dir;
+ if( strile >= dirent->tdir_count )
+ {
+ return 0;
+ }
+ if( strile >= td->td_stripoffsetbyteallocsize )
+ {
+ uint32 nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize;
+ uint32 nStripArrayAllocNew;
+ uint64 nArraySize64;
+ size_t nArraySize;
+ uint64* offsetArray;
+ uint64* bytecountArray;
+
+ if( strile > 1000000 )
+ {
+ uint64 filesize = TIFFGetFileSize(tif);
+ /* Avoid excessive memory allocation attempt */
+ /* For such a big blockid we need at least a TIFF_LONG per strile */
+ /* for the offset array. */
+ if( strile > filesize / sizeof(uint32) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "File too short");
return 0;
+ }
+ }
+
+ if( td->td_stripoffsetbyteallocsize == 0 &&
+ td->td_nstrips < 1024 * 1024 )
+ {
+ nStripArrayAllocNew = td->td_nstrips;
+ }
+ else
+ {
+#define TIFF_MAX(a,b) (((a)>(b)) ? (a) : (b))
+#define TIFF_MIN(a,b) (((a)<(b)) ? (a) : (b))
+ nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U );
+ if( nStripArrayAllocNew < 0xFFFFFFFFU / 2 )
+ nStripArrayAllocNew *= 2;
+ nStripArrayAllocNew = TIFF_MIN(nStripArrayAllocNew, td->td_nstrips);
+ }
+ assert( strile < nStripArrayAllocNew );
+ nArraySize64 = (uint64)sizeof(uint64) * nStripArrayAllocNew;
+ nArraySize = (size_t)(nArraySize64);
+#if SIZEOF_SIZE_T == 4
+ if( nArraySize != nArraySize64 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot allocate strip offset and bytecount arrays");
+ return 0;
+ }
+#endif
+ offsetArray = (uint64*)(
+ _TIFFrealloc( td->td_stripoffset_p, nArraySize ) );
+ bytecountArray = (uint64*)(
+ _TIFFrealloc( td->td_stripbytecount_p, nArraySize ) );
+ if( offsetArray )
+ td->td_stripoffset_p = offsetArray;
+ if( bytecountArray )
+ td->td_stripbytecount_p = bytecountArray;
+ if( offsetArray && bytecountArray )
+ {
+ td->td_stripoffsetbyteallocsize = nStripArrayAllocNew;
+ /* Initialize new entries to ~0 / -1 */
+ memset(td->td_stripoffset_p + nStripArrayAllocBefore,
+ 0xFF,
+ (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * sizeof(uint64) );
+ memset(td->td_stripbytecount_p + nStripArrayAllocBefore,
+ 0xFF,
+ (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * sizeof(uint64) );
+ }
+ else
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot allocate strip offset and bytecount arrays");
+ _TIFFfree(td->td_stripoffset_p);
+ td->td_stripoffset_p = NULL;
+ _TIFFfree(td->td_stripbytecount_p);
+ td->td_stripbytecount_p = NULL;
+ td->td_stripoffsetbyteallocsize = 0;
+ }
+ }
+ if( *parray == NULL || strile >= td->td_stripoffsetbyteallocsize )
+ return 0;
- if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry),
- td->td_nstrips,&td->td_stripoffset))
+ if( ~((*parray)[strile]) == 0 )
+ {
+ if( !_TIFFPartialReadStripArray( tif, dirent, strile, *parray ) )
{
- return_value = 0;
+ (*parray)[strile] = 0;
+ return 0;
}
+ }
+
+ return 1;
+}
- if (loadStripByteCount &&
- !TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
- td->td_nstrips,&td->td_stripbytecount))
+static uint64 _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32 strile,
+ TIFFDirEntry* dirent,
+ uint64** parray,
+ int *pbErr)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ if( pbErr )
+ *pbErr = 0;
+ if( tif->tif_flags&TIFF_DEFERSTRILELOAD )
+ {
+ if( !(tif->tif_flags&TIFF_LAZYSTRILELOAD) ||
+ /* If the values may fit in the toff_long/toff_long8 member */
+ /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */
+ dirent->tdir_count <= 4 )
{
- return_value = 0;
+ if( !_TIFFFillStriles(tif) )
+ {
+ if( pbErr )
+ *pbErr = 1;
+ return 0;
+ }
}
+ else
+ {
+ if( !_TIFFFetchStrileValue(tif, strile, dirent, parray) )
+ {
+ if( pbErr )
+ *pbErr = 1;
+ return 0;
+ }
+ }
+ }
+ if( *parray == NULL || strile >= td->td_nstrips )
+ {
+ if( pbErr )
+ *pbErr = 1;
+ return 0;
+ }
+ return (*parray)[strile];
+}
- _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
- _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+/* Return the value of the TileOffsets/StripOffsets array for the specified tile/strile */
+uint64 TIFFGetStrileOffset(TIFF *tif, uint32 strile)
+{
+ return TIFFGetStrileOffsetWithErr(tif, strile, NULL);
+}
- if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) {
- uint32 strip;
+/* Return the value of the TileOffsets/StripOffsets array for the specified tile/strile */
+uint64 TIFFGetStrileOffsetWithErr(TIFF *tif, uint32 strile, int *pbErr)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ return _TIFFGetStrileOffsetOrByteCountValue(tif, strile,
+ &(td->td_stripoffset_entry),
+ &(td->td_stripoffset_p), pbErr);
+}
- tif->tif_dir.td_stripbytecountsorted = 1;
- for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
- if (tif->tif_dir.td_stripoffset[strip - 1] >
- tif->tif_dir.td_stripoffset[strip]) {
- tif->tif_dir.td_stripbytecountsorted = 0;
- break;
- }
- }
- }
+/* Return the value of the TileByteCounts/StripByteCounts array for the specified tile/strile */
+uint64 TIFFGetStrileByteCount(TIFF *tif, uint32 strile)
+{
+ return TIFFGetStrileByteCountWithErr(tif, strile, NULL);
+}
+
+/* Return the value of the TileByteCounts/StripByteCounts array for the specified tile/strile */
+uint64 TIFFGetStrileByteCountWithErr(TIFF *tif, uint32 strile, int *pbErr)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ return _TIFFGetStrileOffsetOrByteCountValue(tif, strile,
+ &(td->td_stripbytecount_entry),
+ &(td->td_stripbytecount_p), pbErr);
+}
- return return_value;
-#else /* !defined(DEFER_STRILE_LOAD) */
- (void) tif;
- (void) loadStripByteCount;
+
+int _TIFFFillStriles( TIFF *tif )
+{
+ return _TIFFFillStrilesInternal( tif, 1 );
+}
+
+static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount )
+{
+ register TIFFDirectory *td = &tif->tif_dir;
+ int return_value = 1;
+
+ /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */
+ if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
return 1;
-#endif
+
+ if( tif->tif_flags&TIFF_LAZYSTRILELOAD )
+ {
+ /* In case of lazy loading, reload completely the arrays */
+ _TIFFfree(td->td_stripoffset_p);
+ _TIFFfree(td->td_stripbytecount_p);
+ td->td_stripoffset_p = NULL;
+ td->td_stripbytecount_p = NULL;
+ td->td_stripoffsetbyteallocsize = 0;
+ tif->tif_flags &= ~TIFF_LAZYSTRILELOAD;
+ }
+
+ /* If stripoffset array is already loaded, exit with success */
+ if( td->td_stripoffset_p != NULL )
+ return 1;
+
+ /* If tdir_count was cancelled, then we already got there, but in error */
+ if( td->td_stripoffset_entry.tdir_count == 0 )
+ return 0;
+
+ if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry),
+ td->td_nstrips,&td->td_stripoffset_p))
+ {
+ return_value = 0;
+ }
+
+ if (loadStripByteCount &&
+ !TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
+ td->td_nstrips,&td->td_stripbytecount_p))
+ {
+ return_value = 0;
+ }
+
+ _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
+ _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
+ if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) {
+ uint32 strip;
+
+ tif->tif_dir.td_stripbytecountsorted = 1;
+ for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
+ if (tif->tif_dir.td_stripoffset_p[strip - 1] >
+ tif->tif_dir.td_stripoffset_p[strip]) {
+ tif->tif_dir.td_stripbytecountsorted = 0;
+ break;
+ }
+ }
+ }
+#endif
+
+ return return_value;
}
diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c
index 83c01b24..cc0e6217 100644
--- a/libtiff/tif_dirwrite.c
+++ b/libtiff/tif_dirwrite.c
@@ -192,7 +192,7 @@ TIFFCheckpointDirectory(TIFF* tif)
{
int rc;
/* Setup the strips arrays, if they haven't already been. */
- if (tif->tif_dir.td_stripoffset == NULL)
+ if (tif->tif_dir.td_stripoffset_p == NULL)
(void) TIFFSetupStrips(tif);
rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL);
(void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
@@ -527,12 +527,12 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
{
if (!isTiled(tif))
{
- if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
+ if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount_p))
goto bad;
}
else
{
- if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
+ if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount_p))
goto bad;
}
}
@@ -540,7 +540,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
{
if (!isTiled(tif))
{
- /* td_stripoffset might be NULL in an odd OJPEG case. See
+ /* td_stripoffset_p might be NULL in an odd OJPEG case. See
* tif_dirread.c around line 3634.
* XXX: OJPEG hack.
* If a) compression is OJPEG, b) it's not a tiled TIFF,
@@ -551,13 +551,13 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
* We can get here when using tiffset on such a file.
* See http://bugzilla.maptools.org/show_bug.cgi?id=2500
*/
- if (tif->tif_dir.td_stripoffset != NULL &&
- !TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
+ if (tif->tif_dir.td_stripoffset_p != NULL &&
+ !TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset_p))
goto bad;
}
else
{
- if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
+ if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset_p))
goto bad;
}
}
diff --git a/libtiff/tif_jpeg.c b/libtiff/tif_jpeg.c
index f2ddc331..8606f623 100644
--- a/libtiff/tif_jpeg.c
+++ b/libtiff/tif_jpeg.c
@@ -780,12 +780,9 @@ JPEGFixupTagsSubsampling(TIFF* tif)
*/
static const char module[] = "JPEGFixupTagsSubsampling";
struct JPEGFixupTagsSubsamplingData m;
+ uint64 fileoffset = TIFFGetStrileOffset(tif, 0);
- _TIFFFillStriles( tif );
-
- if( tif->tif_dir.td_stripbytecount == NULL
- || tif->tif_dir.td_stripoffset == NULL
- || tif->tif_dir.td_stripbytecount[0] == 0 )
+ if( fileoffset == 0 )
{
/* Do not even try to check if the first strip/tile does not
yet exist, as occurs when GDAL has created a new NULL file
@@ -804,9 +801,9 @@ JPEGFixupTagsSubsampling(TIFF* tif)
}
m.buffercurrentbyte=NULL;
m.bufferbytesleft=0;
- m.fileoffset=tif->tif_dir.td_stripoffset[0];
+ m.fileoffset=fileoffset;
m.filepositioned=0;
- m.filebytesleft=tif->tif_dir.td_stripbytecount[0];
+ m.filebytesleft=TIFFGetStrileByteCount(tif, 0);
if (!JPEGFixupTagsSubsamplingSec(&m))
TIFFWarningExt(tif->tif_clientdata,module,
"Unable to auto-correct subsampling values, likely corrupt JPEG compressed data in first strip/tile; auto-correcting skipped");
diff --git a/libtiff/tif_ojpeg.c b/libtiff/tif_ojpeg.c
index 27385d8c..c01d71a2 100644
--- a/libtiff/tif_ojpeg.c
+++ b/libtiff/tif_ojpeg.c
@@ -990,7 +990,6 @@ OJPEGSubsamplingCorrect(TIFF* tif)
OJPEGState* sp=(OJPEGState*)tif->tif_data;
uint8 mh;
uint8 mv;
- _TIFFFillStriles( tif );
assert(sp->subsamplingcorrect_done==0);
if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) &&
@@ -1989,29 +1988,21 @@ OJPEGReadBufferFill(OJPEGState* sp)
sp->in_buffer_source=osibsStrile;
break;
case osibsStrile:
- if (!_TIFFFillStriles( sp->tif )
- || sp->tif->tif_dir.td_stripoffset == NULL
- || sp->tif->tif_dir.td_stripbytecount == NULL)
- return 0;
-
if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)
sp->in_buffer_source=osibsEof;
else
{
- sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile];
+ sp->in_buffer_file_pos=TIFFGetStrileOffset(sp->tif, sp->in_buffer_next_strile);
if (sp->in_buffer_file_pos!=0)
{
+ uint64 bytecount = TIFFGetStrileByteCount(sp->tif, sp->in_buffer_next_strile);
if (sp->in_buffer_file_pos>=sp->file_size)
sp->in_buffer_file_pos=0;
- else if (sp->tif->tif_dir.td_stripbytecount==NULL)
+ else if (bytecount==0)
sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
else
{
- if (sp->tif->tif_dir.td_stripbytecount == 0) {
- TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing");
- return(0);
- }
- sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];
+ sp->in_buffer_file_togo=bytecount;
if (sp->in_buffer_file_togo==0)
sp->in_buffer_file_pos=0;
else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
diff --git a/libtiff/tif_open.c b/libtiff/tif_open.c
index c574c452..f7b7e0f8 100644
--- a/libtiff/tif_open.c
+++ b/libtiff/tif_open.c
@@ -181,6 +181,8 @@ TIFFClientOpen(
* 'h' read TIFF header only, do not load the first IFD
* '4' ClassicTIFF for creating a file (default)
* '8' BigTIFF for creating a file
+ * 'D' enable use of deferred strip/tile offset/bytecount array loading.
+ * 'O' on-demand loading of values instead of whole array loading (implies D)
*
* The use of the 'l' and 'b' flags is strongly discouraged.
* These flags are provided solely because numerous vendors,
@@ -262,7 +264,22 @@ TIFFClientOpen(
if (m&O_CREAT)
tif->tif_flags |= TIFF_BIGTIFF;
break;
+ case 'D':
+ tif->tif_flags |= TIFF_DEFERSTRILELOAD;
+ break;
+ case 'O':
+ if( m == O_RDONLY )
+ tif->tif_flags |= (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD);
+ break;
}
+
+#ifdef DEFER_STRILE_LOAD
+ /* Compatibility with old DEFER_STRILE_LOAD compilation flag */
+ /* Probably unneeded, since to the best of my knowledge (E. Rouault) */
+ /* GDAL was the only user of this, and will now use the new 'D' flag */
+ tif->tif_flags |= TIFF_DEFERSTRILELOAD;
+#endif
+
/*
* Read in TIFF header.
*/
diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c
index 1d86adbf..a0737941 100644
--- a/libtiff/tif_print.c
+++ b/libtiff/tif_print.c
@@ -652,8 +652,6 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
if (tif->tif_tagmethods.printdir)
(*tif->tif_tagmethods.printdir)(tif, fd, flags);
- _TIFFFillStriles( tif );
-
if ((flags & TIFFPRINT_STRIPS) &&
TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
uint32 s;
@@ -665,13 +663,13 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
fprintf(fd, " %3lu: [%8I64u, %8I64u]\n",
(unsigned long) s,
- td->td_stripoffset ? (unsigned __int64) td->td_stripoffset[s] : 0,
- td->td_stripbytecount ? (unsigned __int64) td->td_stripbytecount[s] : 0);
+ (unsigned __int64) TIFFGetStrileOffset(tif, s),
+ (unsigned __int64) TIFFGetStrileByteCount(tif, s));
#else
fprintf(fd, " %3lu: [%8llu, %8llu]\n",
(unsigned long) s,
- td->td_stripoffset ? (unsigned long long) td->td_stripoffset[s] : 0,
- td->td_stripbytecount ? (unsigned long long) td->td_stripbytecount[s] : 0);
+ (unsigned long long) TIFFGetStrileOffset(tif, s),
+ (unsigned long long) TIFFGetStrileByteCount(tif, s));
#endif
}
}
diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c
index 79c470cb..c65abcea 100644
--- a/libtiff/tif_read.c
+++ b/libtiff/tif_read.c
@@ -175,17 +175,14 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
tmsize_t to_read;
tmsize_t read_ahead_mod;
/* tmsize_t bytecountm; */
-
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
+
/*
* Expand raw data buffer, if needed, to hold data
* strip coming from file (perhaps should set upper
* bound on the size of a buffer we'll use?).
*/
- /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */
+ /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */
/* Not completely sure where the * 2 comes from, but probably for */
/* an exponentional growth strategy of tif_rawdatasize */
@@ -229,7 +226,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
/*
** Seek to the point in the file where more data should be read.
*/
- read_offset = td->td_stripoffset[strip]
+ read_offset = TIFFGetStrileOffset(tif, strip)
+ tif->tif_rawdataoff + tif->tif_rawdataloaded;
if (!SeekOK(tif, read_offset)) {
@@ -246,10 +243,10 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
to_read = read_ahead_mod - unused_data;
else
to_read = tif->tif_rawdatasize - unused_data;
- if( (uint64) to_read > td->td_stripbytecount[strip]
+ if( (uint64) to_read > TIFFGetStrileByteCount(tif, strip)
- tif->tif_rawdataoff - tif->tif_rawdataloaded )
{
- to_read = (tmsize_t) td->td_stripbytecount[strip]
+ to_read = (tmsize_t) TIFFGetStrileByteCount(tif, strip)
- tif->tif_rawdataoff - tif->tif_rawdataloaded;
}
@@ -288,7 +285,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
/* For JPEG, if there are multiple scans (can generally be known */
/* with the read_ahead used), we need to read the whole strip */
if( tif->tif_dir.td_compression==COMPRESSION_JPEG &&
- (uint64)tif->tif_rawcc < td->td_stripbytecount[strip] )
+ (uint64)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip) )
{
if( TIFFJPEGIsFullStripRequired(tif) )
{
@@ -347,9 +344,7 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
* read it a few lines at a time?
*/
#if defined(CHUNKY_STRIP_READ_SUPPORT)
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
- whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10
+ whole_strip = TIFFGetStrileByteCount(tif, strip) < 10
|| isMapped(tif);
if( td->td_compression == COMPRESSION_LERC ||
td->td_compression == COMPRESSION_JBIG )
@@ -402,7 +397,7 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
else if( !whole_strip )
{
if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < read_ahead
- && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < td->td_stripbytecount[strip] )
+ && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < TIFFGetStrileByteCount(tif, strip) )
{
if( !TIFFFillStripPartial(tif,strip,read_ahead,0) )
return 0;
@@ -599,16 +594,11 @@ static tmsize_t
TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
const char* module)
{
- TIFFDirectory *td = &tif->tif_dir;
-
- if (!_TIFFFillStriles( tif ))
- return ((tmsize_t)(-1));
-
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!isMapped(tif)) {
tmsize_t cc;
- if (!SeekOK(tif, td->td_stripoffset[strip])) {
+ if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip))) {
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at scanline %lu, strip %lu",
(unsigned long) tif->tif_row, (unsigned long) strip);
@@ -634,8 +624,8 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
} else {
tmsize_t ma = 0;
tmsize_t n;
- if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)||
- ((ma=(tmsize_t)td->td_stripoffset[strip])>tif->tif_size))
+ if ((TIFFGetStrileOffset(tif, strip) > (uint64)TIFF_TMSIZE_T_MAX)||
+ ((ma=(tmsize_t)TIFFGetStrileOffset(tif, strip))>tif->tif_size))
{
n=0;
}
@@ -679,12 +669,10 @@ static tmsize_t
TIFFReadRawStripOrTile2(TIFF* tif, uint32 strip_or_tile, int is_strip,
tmsize_t size, const char* module)
{
- TIFFDirectory *td = &tif->tif_dir;
-
assert( !isMapped(tif) );
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
- if (!SeekOK(tif, td->td_stripoffset[strip_or_tile])) {
+ if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile))) {
if( is_strip )
{
TIFFErrorExt(tif->tif_clientdata, module,
@@ -738,7 +726,7 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
"Compression scheme does not support access to raw uncompressed data");
return ((tmsize_t)(-1));
}
- bytecount = td->td_stripbytecount[strip];
+ bytecount = TIFFGetStrileByteCount(tif, strip);
if ((int64)bytecount <= 0) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
@@ -773,12 +761,9 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
static const char module[] = "TIFFFillStrip";
TIFFDirectory *td = &tif->tif_dir;
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{
- uint64 bytecount = td->td_stripbytecount[strip];
+ uint64 bytecount = TIFFGetStrileByteCount(tif, strip);
if ((int64)bytecount <= 0) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
@@ -831,13 +816,13 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
* We must check for overflow, potentially causing
* an OOB read. Instead of simple
*
- * td->td_stripoffset[strip]+bytecount > tif->tif_size
+ * TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size
*
* comparison (which can overflow) we do the following
* two comparisons:
*/
if (bytecount > (uint64)tif->tif_size ||
- td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) {
+ TIFFGetStrileOffset(tif, strip) > (uint64)tif->tif_size - bytecount) {
/*
* This error message might seem strange, but
* it's what would happen if a read were done
@@ -849,7 +834,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
"Read error on strip %lu; "
"got %I64u bytes, expected %I64u",
(unsigned long) strip,
- (unsigned __int64) tif->tif_size - td->td_stripoffset[strip],
+ (unsigned __int64) tif->tif_size - TIFFGetStrileOffset(tif, strip),
(unsigned __int64) bytecount);
#else
TIFFErrorExt(tif->tif_clientdata, module,
@@ -857,7 +842,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
"Read error on strip %lu; "
"got %llu bytes, expected %llu",
(unsigned long) strip,
- (unsigned long long) tif->tif_size - td->td_stripoffset[strip],
+ (unsigned long long) tif->tif_size - TIFFGetStrileOffset(tif, strip),
(unsigned long long) bytecount);
#endif
tif->tif_curstrip = NOSTRIP;
@@ -886,7 +871,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
}
tif->tif_flags &= ~TIFF_MYBUFFER;
tif->tif_rawdatasize = (tmsize_t)bytecount;
- tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
+ tif->tif_rawdata = tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip);
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = (tmsize_t) bytecount;
@@ -1101,16 +1086,11 @@ _TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile,
static tmsize_t
TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
{
- TIFFDirectory *td = &tif->tif_dir;
-
- if (!_TIFFFillStriles( tif ))
- return ((tmsize_t)(-1));
-
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!isMapped(tif)) {
tmsize_t cc;
- if (!SeekOK(tif, td->td_stripoffset[tile])) {
+ if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile))) {
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at row %lu, col %lu, tile %lu",
(unsigned long) tif->tif_row,
@@ -1140,9 +1120,9 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m
} else {
tmsize_t ma,mb;
tmsize_t n;
- ma=(tmsize_t)td->td_stripoffset[tile];
+ ma=(tmsize_t)TIFFGetStrileOffset(tif, tile);
mb=ma+size;
- if ((td->td_stripoffset[tile] > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size))
+ if ((TIFFGetStrileOffset(tif, tile) > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size))
n=0;
else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
n=tif->tif_size-ma;
@@ -1198,7 +1178,7 @@ TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
"Compression scheme does not support access to raw uncompressed data");
return ((tmsize_t)(-1));
}
- bytecount64 = td->td_stripbytecount[tile];
+ bytecount64 = TIFFGetStrileByteCount(tif, tile);
if (size != (tmsize_t)(-1) && (uint64)size < bytecount64)
bytecount64 = (uint64)size;
bytecountm = (tmsize_t)bytecount64;
@@ -1220,12 +1200,9 @@ TIFFFillTile(TIFF* tif, uint32 tile)
static const char module[] = "TIFFFillTile";
TIFFDirectory *td = &tif->tif_dir;
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{
- uint64 bytecount = td->td_stripbytecount[tile];
+ uint64 bytecount = TIFFGetStrileByteCount(tif, tile);
if ((int64)bytecount <= 0) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
@@ -1278,13 +1255,13 @@ TIFFFillTile(TIFF* tif, uint32 tile)
* We must check for overflow, potentially causing
* an OOB read. Instead of simple
*
- * td->td_stripoffset[tile]+bytecount > tif->tif_size
+ * TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size
*
* comparison (which can overflow) we do the following
* two comparisons:
*/
if (bytecount > (uint64)tif->tif_size ||
- td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
+ TIFFGetStrileOffset(tif, tile) > (uint64)tif->tif_size - bytecount) {
tif->tif_curtile = NOTILE;
return (0);
}
@@ -1313,7 +1290,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
tif->tif_rawdatasize = (tmsize_t)bytecount;
tif->tif_rawdata =
- tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
+ tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile);
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = (tmsize_t) bytecount;
tif->tif_flags |= TIFF_BUFFERMMAP;
@@ -1440,9 +1417,6 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
{
TIFFDirectory *td = &tif->tif_dir;
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupdecode)(tif))
return (0);
@@ -1463,7 +1437,7 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
if( tif->tif_rawdataloaded > 0 )
tif->tif_rawcc = tif->tif_rawdataloaded;
else
- tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
+ tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip);
}
return ((*tif->tif_predecode)(tif,
(uint16)(strip / td->td_stripsperimage)));
@@ -1480,9 +1454,6 @@ TIFFStartTile(TIFF* tif, uint32 tile)
TIFFDirectory *td = &tif->tif_dir;
uint32 howmany32;
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupdecode)(tif))
return (0);
@@ -1513,7 +1484,7 @@ TIFFStartTile(TIFF* tif, uint32 tile)
if( tif->tif_rawdataloaded > 0 )
tif->tif_rawcc = tif->tif_rawdataloaded;
else
- tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
+ tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile);
}
return ((*tif->tif_predecode)(tif,
(uint16)(tile/td->td_stripsperimage)));
diff --git a/libtiff/tif_strip.c b/libtiff/tif_strip.c
index 5b76fba5..2f3cd883 100644
--- a/libtiff/tif_strip.c
+++ b/libtiff/tif_strip.c
@@ -147,8 +147,7 @@ uint64
TIFFRawStripSize64(TIFF* tif, uint32 strip)
{
static const char module[] = "TIFFRawStripSize64";
- TIFFDirectory* td = &tif->tif_dir;
- uint64 bytecount = td->td_stripbytecount[strip];
+ uint64 bytecount = TIFFGetStrileByteCount(tif, strip);
if (bytecount == 0)
{
diff --git a/libtiff/tif_write.c b/libtiff/tif_write.c
index 4e5d8175..b79fd945 100644
--- a/libtiff/tif_write.c
+++ b/libtiff/tif_write.c
@@ -128,10 +128,10 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
- if( td->td_stripbytecount[strip] > 0 )
+ if( td->td_stripbytecount_p[strip] > 0 )
{
/* if we are writing over existing tiles, zero length */
- td->td_stripbytecount[strip] = 0;
+ td->td_stripbytecount_p[strip] = 0;
/* this forces TIFFAppendToStrip() to do a seek */
tif->tif_curoff = 0;
@@ -183,11 +183,11 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32 strip_or_tile)
{
TIFFDirectory *td = &tif->tif_dir;
- if( td->td_stripbytecount[strip_or_tile] > 0 )
+ if( td->td_stripbytecount_p[strip_or_tile] > 0 )
{
/* The +1 is to ensure at least one extra bytes */
/* The +4 is because the LZW encoder flushes 4 bytes before the limit */
- uint64 safe_buffer_size = (uint64)(td->td_stripbytecount[strip_or_tile] + 1 + 4);
+ uint64 safe_buffer_size = (uint64)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4);
if( tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size )
{
if( !(TIFFWriteBufferSetup(tif, NULL,
@@ -535,20 +535,20 @@ TIFFSetupStrips(TIFF* tif)
td->td_nstrips = td->td_stripsperimage;
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
td->td_stripsperimage /= td->td_samplesperpixel;
- td->td_stripoffset = (uint64 *)
+ td->td_stripoffset_p = (uint64 *)
_TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
"for \"StripOffsets\" array");
- td->td_stripbytecount = (uint64 *)
+ td->td_stripbytecount_p = (uint64 *)
_TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
"for \"StripByteCounts\" array");
- if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
+ if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
return (0);
/*
* Place data at the end-of-file
* (by setting offsets to zero).
*/
- _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64));
- _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64));
+ _TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips*sizeof (uint64));
+ _TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips*sizeof (uint64));
TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
return (1);
@@ -608,7 +608,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
return (0);
}
}
- if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
+ if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif)) {
tif->tif_dir.td_nstrips = 0;
TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays",
isTiled(tif) ? "tile" : "strip");
@@ -682,9 +682,9 @@ TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
uint64* new_stripbytecount;
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
- new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset,
+ new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset_p,
(td->td_nstrips + delta) * sizeof (uint64));
- new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount,
+ new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount_p,
(td->td_nstrips + delta) * sizeof (uint64));
if (new_stripoffset == NULL || new_stripbytecount == NULL) {
if (new_stripoffset)
@@ -695,11 +695,11 @@ TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
return (0);
}
- td->td_stripoffset = new_stripoffset;
- td->td_stripbytecount = new_stripbytecount;
- _TIFFmemset(td->td_stripoffset + td->td_nstrips,
+ td->td_stripoffset_p = new_stripoffset;
+ td->td_stripbytecount_p = new_stripbytecount;
+ _TIFFmemset(td->td_stripoffset_p + td->td_nstrips,
0, delta*sizeof (uint64));
- _TIFFmemset(td->td_stripbytecount + td->td_nstrips,
+ _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips,
0, delta*sizeof (uint64));
td->td_nstrips += delta;
tif->tif_flags |= TIFF_DIRTYDIRECT;
@@ -718,12 +718,12 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
uint64 m;
int64 old_byte_count = -1;
- if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
+ if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) {
assert(td->td_nstrips > 0);
- if( td->td_stripbytecount[strip] != 0
- && td->td_stripoffset[strip] != 0
- && td->td_stripbytecount[strip] >= (uint64) cc )
+ if( td->td_stripbytecount_p[strip] != 0
+ && td->td_stripoffset_p[strip] != 0
+ && td->td_stripbytecount_p[strip] >= (uint64) cc )
{
/*
* There is already tile data on disk, and the new tile
@@ -732,7 +732,7 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
* more data to append to this strip before we are done
* depending on how we are getting called.
*/
- if (!SeekOK(tif, td->td_stripoffset[strip])) {
+ if (!SeekOK(tif, td->td_stripoffset_p[strip])) {
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at scanline %lu",
(unsigned long)tif->tif_row);
@@ -745,17 +745,17 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
* Seek to end of file, and set that as our location to
* write this strip.
*/
- td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
+ td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
tif->tif_flags |= TIFF_DIRTYSTRIP;
}
- tif->tif_curoff = td->td_stripoffset[strip];
+ tif->tif_curoff = td->td_stripoffset_p[strip];
/*
* We are starting a fresh strip/tile, so set the size to zero.
*/
- old_byte_count = td->td_stripbytecount[strip];
- td->td_stripbytecount[strip] = 0;
+ old_byte_count = td->td_stripbytecount_p[strip];
+ td->td_stripbytecount_p[strip] = 0;
}
m = tif->tif_curoff+cc;
@@ -772,9 +772,9 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
return (0);
}
tif->tif_curoff = m;
- td->td_stripbytecount[strip] += cc;
+ td->td_stripbytecount_p[strip] += cc;
- if( (int64) td->td_stripbytecount[strip] != old_byte_count )
+ if( (int64) td->td_stripbytecount_p[strip] != old_byte_count )
tif->tif_flags |= TIFF_DIRTYSTRIP;
return (1);
diff --git a/libtiff/tiffio.h b/libtiff/tiffio.h
index 31c2e676..7193fbcf 100644
--- a/libtiff/tiffio.h
+++ b/libtiff/tiffio.h
@@ -488,6 +488,11 @@ extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n);
extern void TIFFReverseBits(uint8* cp, tmsize_t n);
extern const unsigned char* TIFFGetBitRevTable(int);
+extern uint64 TIFFGetStrileOffset(TIFF *tif, uint32 strile);
+extern uint64 TIFFGetStrileByteCount(TIFF *tif, uint32 strile);
+extern uint64 TIFFGetStrileOffsetWithErr(TIFF *tif, uint32 strile, int *pbErr);
+extern uint64 TIFFGetStrileByteCountWithErr(TIFF *tif, uint32 strile, int *pbErr);
+
#ifdef LOGLUV_PUBLIC
#define U_NEU 0.210526316
#define V_NEU 0.473684211
diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h
index 47a553aa..ef63de53 100644
--- a/libtiff/tiffiop.h
+++ b/libtiff/tiffiop.h
@@ -127,6 +127,8 @@ struct tiff {
#define TIFF_DIRTYSTRIP 0x200000U /* stripoffsets/stripbytecount dirty*/
#define TIFF_PERSAMPLE 0x400000U /* get/set per sample tags as arrays */
#define TIFF_BUFFERMMAP 0x800000U /* read buffer (tif_rawdata) points into mmap() memory */
+ #define TIFF_DEFERSTRILELOAD 0x1000000U /* defer strip/tile offset/bytecount array loading. */
+ #define TIFF_LAZYSTRILELOAD 0x2000000U /* lazy/ondemand loading of strip/tile offset/bytecount values. Only used if TIFF_DEFERSTRILELOAD is set and in read-only mode */
uint64 tif_diroff; /* file offset of current directory */
uint64 tif_nextdiroff; /* file offset of following directory */
uint64* tif_dirlist; /* list of offsets to already seen directories to prevent IFD looping */