summaryrefslogtreecommitdiff
path: root/libtiff
diff options
context:
space:
mode:
authorFrank Warmerdam <warmerdam@pobox.com>2011-02-18 20:53:04 +0000
committerFrank Warmerdam <warmerdam@pobox.com>2011-02-18 20:53:04 +0000
commit82361dfa04e1be95c02bd3a81c8ec4815410f92a (patch)
tree620745233e685fd22e6cfa7a4426916ea14af497 /libtiff
parent29beec44d2483599f1a8cf5d8db18c3218b8ddba (diff)
downloadlibtiff-git-82361dfa04e1be95c02bd3a81c8ec4815410f92a.tar.gz
implement optional support for deferred strip/tile offset/size loading
Diffstat (limited to 'libtiff')
-rw-r--r--libtiff/tif_config.h.in3
-rw-r--r--libtiff/tif_dir.c9
-rw-r--r--libtiff/tif_dir.h30
-rw-r--r--libtiff/tif_dirread.c76
-rw-r--r--libtiff/tif_dirwrite.c5
-rw-r--r--libtiff/tif_jpeg.c9
-rw-r--r--libtiff/tif_print.c7
-rw-r--r--libtiff/tif_read.c16
-rw-r--r--libtiff/tif_write.c4
-rw-r--r--libtiff/tiffiop.h25
10 files changed, 151 insertions, 33 deletions
diff --git a/libtiff/tif_config.h.in b/libtiff/tif_config.h.in
index 53673c14..09a427cb 100644
--- a/libtiff/tif_config.h.in
+++ b/libtiff/tif_config.h.in
@@ -18,6 +18,9 @@
packages produce RGBA files but don't mark the alpha properly. */
#undef DEFAULT_EXTRASAMPLE_AS_ALPHA
+/* enable deferred strip/tile offset/size loading (experimental) */
+#undef DEFER_STRILE_LOAD
+
/* Define to 1 if you have the <assert.h> header file. */
#undef HAVE_ASSERT_H
diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c
index 8494b305..90d258ff 100644
--- a/libtiff/tif_dir.c
+++ b/libtiff/tif_dir.c
@@ -1,4 +1,4 @@
-/* $Id: tif_dir.c,v 1.106 2011-01-24 21:06:31 olivier Exp $ */
+/* $Id: tif_dir.c,v 1.107 2011-02-18 20:53:04 fwarmerdam Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -889,10 +889,12 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
break;
case TIFFTAG_STRIPOFFSETS:
case TIFFTAG_TILEOFFSETS:
+ _TIFFFillStriles( tif );
*va_arg(ap, uint64**) = td->td_stripoffset;
break;
case TIFFTAG_STRIPBYTECOUNTS:
case TIFFTAG_TILEBYTECOUNTS:
+ _TIFFFillStriles( tif );
*va_arg(ap, uint64**) = td->td_stripbytecount;
break;
case TIFFTAG_MATTEING:
@@ -1163,6 +1165,11 @@ 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
diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h
index e906fefa..6af5f3dc 100644
--- a/libtiff/tif_dir.h
+++ b/libtiff/tif_dir.h
@@ -1,4 +1,4 @@
-/* $Id: tif_dir.h,v 1.53 2011-01-24 21:06:31 olivier Exp $ */
+/* $Id: tif_dir.h,v 1.54 2011-02-18 20:53:05 fwarmerdam Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -37,6 +37,28 @@ typedef struct {
} TIFFTagValue;
/*
+ * TIFF Image File Directories are comprised of a table of field
+ * descriptors of the form shown below. The table is sorted in
+ * ascending order by tag. The values associated with each entry are
+ * disjoint and may appear anywhere in the file (so long as they are
+ * placed on a word boundary).
+ *
+ * If the value is 4 bytes or less, in ClassicTIFF, or 8 bytes or less in
+ * BigTIFF, then it is placed in the offset field to save space. If so,
+ * it is left-justified in the offset field.
+ */
+typedef struct {
+ uint16 tdir_tag; /* see below */
+ uint16 tdir_type; /* data type; see below */
+ uint64 tdir_count; /* number of items; length in spec */
+ union {
+ uint16 toff_short;
+ uint32 toff_long;
+ uint64 toff_long8;
+ } tdir_offset; /* either offset or the data itself if fits */
+} TIFFDirEntry;
+
+/*
* Internal format of a TIFF directory entry.
*/
typedef struct {
@@ -76,6 +98,10 @@ typedef struct {
uint64* td_stripoffset;
uint64* td_stripbytecount;
int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
+#if defined(DEFER_STRILE_LOAD)
+ TIFFDirEntry td_stripoffset_entry; /* for deferred loading */
+ TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */
+#endif
uint16 td_nsubifd;
uint64* td_subifd;
/* YCbCr parameters */
@@ -232,6 +258,8 @@ extern const TIFFFieldArray* _TIFFGetExifFields(void);
extern void _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* infoarray);
extern void _TIFFPrintFieldInfo(TIFF*, FILE*);
+extern int _TIFFFillStriles(TIFF*);
+
typedef enum {
tfiatImage,
tfiatExif,
diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
index c92efdeb..6f96ec04 100644
--- a/libtiff/tif_dirread.c
+++ b/libtiff/tif_dirread.c
@@ -1,4 +1,4 @@
-/* $Id: tif_dirread.c,v 1.166 2011-01-24 21:06:31 olivier Exp $ */
+/* $Id: tif_dirread.c,v 1.167 2011-02-18 20:53:04 fwarmerdam Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -3592,6 +3592,7 @@ TIFFReadDirectory(TIFF* tif)
if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG)&&
(tif->tif_dir.td_planarconfig==PLANARCONFIG_SEPARATE))
{
+ _TIFFFillStriles(tif);
dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_STRIPOFFSETS);
if ((dp!=0)&&(dp->tdir_count==1))
{
@@ -3722,13 +3723,23 @@ 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 (!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 (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount))
goto bad;
+#endif
break;
case TIFFTAG_COLORMAP:
case TIFFTAG_TRANSFERFUNCTION:
@@ -3920,6 +3931,7 @@ TIFFReadDirectory(TIFF* tif)
tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) )
} else if (tif->tif_dir.td_nstrips == 1
+ && _TIFFFillStriles(tif)
&& tif->tif_dir.td_stripoffset[0] != 0
&& BYTECOUNTLOOKSBAD) {
/*
@@ -3933,6 +3945,8 @@ TIFFReadDirectory(TIFF* tif)
TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
if(EstimateStripByteCounts(tif, dir, dircount) < 0)
goto bad;
+
+#if !defined(DEFER_STRILE_LOAD)
} else if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG
&& tif->tif_dir.td_nstrips > 2
&& tif->tif_dir.td_compression == COMPRESSION_NONE
@@ -3944,12 +3958,17 @@ TIFFReadDirectory(TIFF* tif)
* absolutely wrong values (it can be equal to
* StripOffset array, for example). Catch this case
* here.
+ *
+ * We avoid this check if deferring strile loading
+ * as it would always force us to load the strip/tile
+ * information.
*/
TIFFWarningExt(tif->tif_clientdata, module,
"Wrong \"%s\" field, ignoring and calculating from imagelength",
TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
if (EstimateStripByteCounts(tif, dir, dircount) < 0)
goto bad;
+#endif /* !defined(DEFER_STRILE_LOAD) */
}
}
if (dir)
@@ -3969,6 +3988,7 @@ TIFFReadDirectory(TIFF* tif)
* bytecounts array. See also comments for TIFFAppendToStrip()
* function in tif_write.c.
*/
+#if !defined(DEFER_STRILE_LOAD)
if (tif->tif_dir.td_nstrips > 1) {
uint32 strip;
@@ -3981,6 +4001,8 @@ TIFFReadDirectory(TIFF* tif)
}
}
}
+#endif /* !defined(DEFER_STRILE_LOAD) */
+
/*
* An opportunity for compression mode dependent tag fixup
*/
@@ -4238,6 +4260,8 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
TIFFDirectory *td = &tif->tif_dir;
uint32 strip;
+ _TIFFFillStriles( tif );
+
if (td->td_stripbytecount)
_TIFFfree(td->td_stripbytecount);
td->td_stripbytecount = (uint64*)
@@ -5419,6 +5443,8 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
uint64* newcounts;
uint64* newoffsets;
+ _TIFFFillStriles(tif);
+
bytecount = td->td_stripbytecount[0];
offset = td->td_stripoffset[0];
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
@@ -5494,6 +5520,54 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
td->td_stripbytecountsorted = 1;
}
+int _TIFFFillStriles( TIFF *tif )
+{
+#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 )
+ return 0;
+
+ if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry),
+ td->td_nstrips,&td->td_stripoffset))
+ {
+ return_value = 0;
+ }
+
+ if (!TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
+ td->td_nstrips,&td->td_stripbytecount))
+ {
+ return_value = 0;
+ }
+
+ _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
+ _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+
+ 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[strip - 1] >
+ tif->tif_dir.td_stripoffset[strip]) {
+ tif->tif_dir.td_stripbytecountsorted = 0;
+ break;
+ }
+ }
+ }
+
+ return return_value;
+#else /* !defined(DEFER_STRILE_LOAD) */
+ (void) tif;
+ return 1;
+#endif
+}
+
+
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c
index fad091e3..11738cfe 100644
--- a/libtiff/tif_dirwrite.c
+++ b/libtiff/tif_dirwrite.c
@@ -1,4 +1,4 @@
-/* $Id: tif_dirwrite.c,v 1.75 2011-01-24 21:06:31 olivier Exp $ */
+/* $Id: tif_dirwrite.c,v 1.76 2011-02-18 20:53:04 fwarmerdam Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -370,6 +370,9 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
uint32 m;
if (tif->tif_mode == O_RDONLY)
return (1);
+
+ _TIFFFillStriles( tif );
+
/*
* Clear write state so that subsequent images with
* different characteristics get the right buffers
diff --git a/libtiff/tif_jpeg.c b/libtiff/tif_jpeg.c
index 6ae6c834..05aae9cd 100644
--- a/libtiff/tif_jpeg.c
+++ b/libtiff/tif_jpeg.c
@@ -1,4 +1,4 @@
-/* $Id: tif_jpeg.c,v 1.99 2011-01-06 05:51:13 fwarmerdam Exp $ */
+/* $Id: tif_jpeg.c,v 1.100 2011-02-18 20:53:04 fwarmerdam Exp $ */
/*
* Copyright (c) 1994-1997 Sam Leffler
@@ -688,12 +688,13 @@ static void JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* da
static int
JPEGFixupTags(TIFF* tif)
{
- #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
+#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&&
(tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
(tif->tif_dir.td_samplesperpixel==3))
JPEGFixupTagsSubsampling(tif);
- #endif
+#endif
+
return(1);
}
@@ -725,6 +726,8 @@ JPEGFixupTagsSubsampling(TIFF* tif)
static const char module[] = "JPEGFixupTagsSubsampling";
struct JPEGFixupTagsSubsamplingData m;
+ _TIFFFillStriles( tif );
+
if( tif->tif_dir.td_stripbytecount == NULL
|| tif->tif_dir.td_stripbytecount[0] == 0 )
{
diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c
index bcddbf26..a98c6d65 100644
--- a/libtiff/tif_print.c
+++ b/libtiff/tif_print.c
@@ -1,4 +1,4 @@
-/* $Id: tif_print.c,v 1.52 2011-02-11 19:21:03 fwarmerdam Exp $ */
+/* $Id: tif_print.c,v 1.53 2011-02-18 20:53:04 fwarmerdam Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -138,6 +138,8 @@ static int
_TIFFPrettyPrintField(TIFF* tif, FILE* fd, uint32 tag,
uint32 value_count, void *raw_data)
{
+ (void) tif;
+
switch (tag)
{
case TIFFTAG_INKSET:
@@ -618,6 +620,9 @@ 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;
diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c
index 95377629..10e5a247 100644
--- a/libtiff/tif_read.c
+++ b/libtiff/tif_read.c
@@ -1,4 +1,4 @@
-/* $Id: tif_read.c,v 1.33 2011-01-06 05:51:13 fwarmerdam Exp $ */
+/* $Id: tif_read.c,v 1.34 2011-02-18 20:53:04 fwarmerdam Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -50,6 +50,8 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
uint64 unused_data;
uint64 read_offset;
tmsize_t cc, to_read;
+
+ _TIFFFillStriles( tif );
/*
* Expand raw data buffer, if needed, to hold data
@@ -357,6 +359,8 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
{
TIFFDirectory *td = &tif->tif_dir;
+ _TIFFFillStriles( tif );
+
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!isMapped(tif)) {
tmsize_t cc;
@@ -480,6 +484,8 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
static const char module[] = "TIFFFillStrip";
TIFFDirectory *td = &tif->tif_dir;
+ _TIFFFillStriles( tif );
+
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{
uint64 bytecount = td->td_stripbytecount[strip];
@@ -647,6 +653,8 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m
{
TIFFDirectory *td = &tif->tif_dir;
+ _TIFFFillStriles( tif );
+
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!isMapped(tif)) {
tmsize_t cc;
@@ -761,6 +769,8 @@ TIFFFillTile(TIFF* tif, uint32 tile)
static const char module[] = "TIFFFillTile";
TIFFDirectory *td = &tif->tif_dir;
+ _TIFFFillStriles( tif );
+
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{
uint64 bytecount = td->td_stripbytecount[tile];
@@ -904,6 +914,8 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
{
TIFFDirectory *td = &tif->tif_dir;
+ _TIFFFillStriles( tif );
+
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupdecode)(tif))
return (0);
@@ -936,6 +948,8 @@ TIFFStartTile(TIFF* tif, uint32 tile)
{
TIFFDirectory *td = &tif->tif_dir;
+ _TIFFFillStriles( tif );
+
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupdecode)(tif))
return (0);
diff --git a/libtiff/tif_write.c b/libtiff/tif_write.c
index 585973e0..eaa1f814 100644
--- a/libtiff/tif_write.c
+++ b/libtiff/tif_write.c
@@ -1,4 +1,4 @@
-/* $Id: tif_write.c,v 1.35 2010-03-10 18:56:49 bfriesen Exp $ */
+/* $Id: tif_write.c,v 1.36 2011-02-18 20:53:04 fwarmerdam Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -498,6 +498,8 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
"Can not write scanlines to a tiled image");
return (0);
}
+
+ _TIFFFillStriles( tif );
/*
* On the first write verify all the required information
diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h
index cadbeeec..7bed4abd 100644
--- a/libtiff/tiffiop.h
+++ b/libtiff/tiffiop.h
@@ -1,4 +1,4 @@
-/* $Id: tiffiop.h,v 1.81 2011-01-24 21:06:32 olivier Exp $ */
+/* $Id: tiffiop.h,v 1.82 2011-02-18 20:53:05 fwarmerdam Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -58,6 +58,7 @@ extern void *lfind(const void *, const void *, size_t *, size_t,
#endif
#include "tiffio.h"
+
#include "tif_dir.h"
#ifndef STRIP_SIZE_DEFAULT
@@ -71,28 +72,6 @@ extern void *lfind(const void *, const void *, size_t *, size_t,
#define FALSE 0
#endif
-/*
- * TIFF Image File Directories are comprised of a table of field
- * descriptors of the form shown below. The table is sorted in
- * ascending order by tag. The values associated with each entry are
- * disjoint and may appear anywhere in the file (so long as they are
- * placed on a word boundary).
- *
- * If the value is 4 bytes or less, in ClassicTIFF, or 8 bytes or less in
- * BigTIFF, then it is placed in the offset field to save space. If so,
- * it is left-justified in the offset field.
- */
-typedef struct {
- uint16 tdir_tag; /* see below */
- uint16 tdir_type; /* data type; see below */
- uint64 tdir_count; /* number of items; length in spec */
- union {
- uint16 toff_short;
- uint32 toff_long;
- uint64 toff_long8;
- } tdir_offset; /* either offset or the data itself if fits */
-} TIFFDirEntry;
-
typedef struct client_info {
struct client_info *next;
void *data;