diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | configure.ac | 16 | ||||
-rw-r--r-- | libtiff/tif_config.h.in | 3 | ||||
-rw-r--r-- | libtiff/tif_dir.c | 9 | ||||
-rw-r--r-- | libtiff/tif_dir.h | 30 | ||||
-rw-r--r-- | libtiff/tif_dirread.c | 76 | ||||
-rw-r--r-- | libtiff/tif_dirwrite.c | 5 | ||||
-rw-r--r-- | libtiff/tif_jpeg.c | 9 | ||||
-rw-r--r-- | libtiff/tif_print.c | 7 | ||||
-rw-r--r-- | libtiff/tif_read.c | 16 | ||||
-rw-r--r-- | libtiff/tif_write.c | 4 | ||||
-rw-r--r-- | libtiff/tiffiop.h | 25 |
12 files changed, 176 insertions, 33 deletions
@@ -1,3 +1,12 @@ +2011-02-18 Frank Warmerdam <warmerdam@pobox.com> + + * configure.ac, tif_read.c, tif_readdir.c, tif_dir.h, tiffiop.h, + tif_write.c, tif_print.c, tif_jpeg.c, tif_dirwrite.c, tif_write.c: + Implement optional support for deferring the load of strip/tile + offset and size tags for optimized scanning of directories. Enabled + with the --enable-defer-strile-load configure option (DEFER_STRILE_LOAD + #define in tif_config.h). + 2011-02-11 Frank Warmerdam <warmerdam@pobox.com> * libtiff/tif_print.c: remove unused variable. diff --git a/configure.ac b/configure.ac index fd4fcb4e..ed398a56 100644 --- a/configure.ac +++ b/configure.ac @@ -839,6 +839,22 @@ if test "$HAVE_STRIPCHOP" = "yes" \ fi dnl --------------------------------------------------------------------------- +dnl Should we try to defer loading of strip/tile offsets and sizes to +dnl optimize directory scanning? These is an experimental feature for +dnl libtiff 4.0. +dnl --------------------------------------------------------------------------- + +AC_ARG_ENABLE(defer-strile-load, + AS_HELP_STRING([--enable-defer-strile-load], + [enable deferred strip/tile offset/size loading (experimental)]), + [HAVE_DEFER_STRILE_LOAD=$enableval], [HAVE_DEFER_STRILE_LOAD=no]) + +if test "$HAVE_DEFER_STRILE_LOAD" = "yes" ; then + AC_DEFINE(DEFER_STRILE_LOAD,1,[enable deferred strip/tile offset/size loading (experimental)]) + +fi + +dnl --------------------------------------------------------------------------- dnl Default subifd support. dnl --------------------------------------------------------------------------- AC_DEFINE(SUBIFD_SUPPORT,1,[Enable SubIFD tag (330) support]) 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; |