summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2023-03-26 14:09:24 +0000
committerEven Rouault <even.rouault@spatialys.com>2023-03-26 14:09:24 +0000
commit214fe59954644efe69c4681587d0dee64575dd0c (patch)
tree6577627e956df2c7ced31bef7b243745610ee249
parentddd7f044822ce7eb1720dc6cdec8f84821463cd8 (diff)
parentada85f3663f907b04f80e036f6fd263fab4b3305 (diff)
downloadlibtiff-git-214fe59954644efe69c4681587d0dee64575dd0c.tar.gz
Merge branch 'even_faster_setdirectory_with_IFDlist' into 'master'
Even faster TIFFSetDirectory() using IFD list. See merge request libtiff/libtiff!477
-rw-r--r--libtiff/tif_dir.c89
-rw-r--r--libtiff/tif_dir.h4
-rw-r--r--libtiff/tif_dirread.c85
-rw-r--r--libtiff/tif_dirwrite.c5
-rw-r--r--test/test_directory.c310
-rw-r--r--test/test_open_options.c22
6 files changed, 469 insertions, 46 deletions
diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c
index 293d6fde..3d57341f 100644
--- a/libtiff/tif_dir.c
+++ b/libtiff/tif_dir.c
@@ -2030,44 +2030,69 @@ int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
uint64_t nextdiroff;
tdir_t nextdirnum = 0;
tdir_t n;
- /* Fast path when we just advance relative to the current directory:
- * start at the current dir offset and continue to seek from there.
- * Check special cases when relative is not allowed:
- * - jump back from SubIFD or custom directory
- * - right after TIFFWriteDirectory() jump back to that directory
- * using TIFFSetDirectory() */
- const int relative = (dirn >= tif->tif_curdir) && (tif->tif_diroff != 0) &&
- !tif->tif_setdirectory_force_absolute;
-
- if (relative)
+
+ if (tif->tif_setdirectory_force_absolute)
{
- nextdiroff = tif->tif_diroff;
- dirn -= tif->tif_curdir;
- nextdirnum = tif->tif_curdir;
+ /* tif_setdirectory_force_absolute=1 will force parsing the main IFD
+ * chain from the beginning, thus IFD directory list needs to be cleared
+ * from possible SubIFD offsets.
+ */
+ _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
+ }
+
+ /* Even faster path, if offset is available within IFD loop hash list. */
+ if (!tif->tif_setdirectory_force_absolute &&
+ _TIFFGetOffsetFromDirNumber(tif, dirn, &nextdiroff))
+ {
+ /* Set parameters for following TIFFReadDirectory() below. */
+ tif->tif_nextdiroff = nextdiroff;
+ tif->tif_curdir = dirn;
+ /* Reset to relative stepping */
+ tif->tif_setdirectory_force_absolute = FALSE;
}
- else if (!(tif->tif_flags & TIFF_BIGTIFF))
- nextdiroff = tif->tif_header.classic.tiff_diroff;
else
- nextdiroff = tif->tif_header.big.tiff_diroff;
+ {
- /* Reset to relative stepping */
- tif->tif_setdirectory_force_absolute = FALSE;
+ /* Fast path when we just advance relative to the current directory:
+ * start at the current dir offset and continue to seek from there.
+ * Check special cases when relative is not allowed:
+ * - jump back from SubIFD or custom directory
+ * - right after TIFFWriteDirectory() jump back to that directory
+ * using TIFFSetDirectory() */
+ const int relative = (dirn >= tif->tif_curdir) &&
+ (tif->tif_diroff != 0) &&
+ !tif->tif_setdirectory_force_absolute;
+
+ if (relative)
+ {
+ nextdiroff = tif->tif_diroff;
+ dirn -= tif->tif_curdir;
+ nextdirnum = tif->tif_curdir;
+ }
+ else if (!(tif->tif_flags & TIFF_BIGTIFF))
+ nextdiroff = tif->tif_header.classic.tiff_diroff;
+ else
+ nextdiroff = tif->tif_header.big.tiff_diroff;
- for (n = dirn; n > 0 && nextdiroff != 0; n--)
- if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
+ /* Reset to relative stepping */
+ tif->tif_setdirectory_force_absolute = FALSE;
+
+ for (n = dirn; n > 0 && nextdiroff != 0; n--)
+ if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
+ return (0);
+ /* If the n-th directory could not be reached (does not exist),
+ * return here without touching anything further. */
+ if (nextdiroff == 0 || n > 0)
return (0);
- /* If the n-th directory could not be reached (does not exist),
- * return here without touching anything further. */
- if (nextdiroff == 0 || n > 0)
- return (0);
- tif->tif_nextdiroff = nextdiroff;
+ tif->tif_nextdiroff = nextdiroff;
- /* Set curdir to the actual directory index. */
- if (relative)
- tif->tif_curdir += dirn - n;
- else
- tif->tif_curdir = dirn - n;
+ /* Set curdir to the actual directory index. */
+ if (relative)
+ tif->tif_curdir += dirn - n;
+ else
+ tif->tif_curdir = dirn - n;
+ }
/* The -1 decrement is because TIFFReadDirectory will increment
* tif_curdir after successfully reading the directory. */
@@ -2118,8 +2143,8 @@ int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
tif->tif_nextdiroff = diroff;
retval = TIFFReadDirectory(tif);
/* If failed, curdir was not incremented in TIFFReadDirectory(), so set it
- * back. */
- if (!retval)
+ * back, but leave it for diroff==0. */
+ if (!retval && diroff != 0)
{
if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
tif->tif_curdir = 0;
diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h
index fad1eb02..53473fb3 100644
--- a/libtiff/tif_dir.h
+++ b/libtiff/tif_dir.h
@@ -329,6 +329,10 @@ extern "C"
uint64_t diroff);
extern int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff,
tdir_t *dirn);
+ extern int _TIFFGetOffsetFromDirNumber(TIFF *tif, tdir_t dirn,
+ uint64_t *diroff);
+ extern int _TIFFRemoveEntryFromDirectoryListByOffset(TIFF *tif,
+ uint64_t diroff);
#if defined(__cplusplus)
}
diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
index d4cc11d0..8c7b4d83 100644
--- a/libtiff/tif_dirread.c
+++ b/libtiff/tif_dirread.c
@@ -4068,11 +4068,10 @@ int TIFFReadDirectory(TIFF *tif)
if (tif->tif_nextdiroff == 0)
{
/* In this special case, tif_diroff needs also to be set to 0.
- * Furthermore, TIFFSetDirectory() needs to be switched to
- * absolute stepping. */
+ * This is behind the last IFD, thus no checking or reading necessary.
+ */
tif->tif_diroff = tif->tif_nextdiroff;
- tif->tif_setdirectory_force_absolute = TRUE;
- return 0; /* last offset, thus no checking necessary */
+ return 0;
}
nextdiroff = tif->tif_nextdiroff;
@@ -5521,6 +5520,7 @@ int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, tdir_t *dirn)
return 1;
}
+ /* This updates the directory list for all main-IFDs in the file. */
TIFFNumberOfDirectories(tif);
foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
@@ -5535,6 +5535,83 @@ int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, tdir_t *dirn)
} /*--- _TIFFGetDirNumberFromOffset() ---*/
/*
+ * Retrieve the matching IFD directory offset of a given IFD number
+ * from the list of directories already seen.
+ * Returns 1 if the offset was in the list of already seen IFDs and the
+ * directory offset can be returned. The directory list is not updated.
+ * Otherwise returns 0 or if an error occurred.
+ */
+int _TIFFGetOffsetFromDirNumber(TIFF *tif, tdir_t dirn, uint64_t *diroff)
+{
+
+ if (tif->tif_map_dir_number_to_offset == NULL)
+ return 0;
+ TIFFOffsetAndDirNumber entry;
+ entry.offset = 0; /* not used */
+ entry.dirNumber = dirn;
+
+ TIFFOffsetAndDirNumber *foundEntry =
+ (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
+ tif->tif_map_dir_number_to_offset, &entry);
+ if (foundEntry)
+ {
+ *diroff = foundEntry->offset;
+ return 1;
+ }
+
+ return 0;
+} /*--- _TIFFGetOffsetFromDirNumber() ---*/
+
+/*
+ * Remove an entry from the directory list of already seen directories
+ * by directory offset.
+ * If an entry is to be removed from the list, it is also okay if the entry
+ * is not in the list or the list does not exist.
+ */
+int _TIFFRemoveEntryFromDirectoryListByOffset(TIFF *tif, uint64_t diroff)
+{
+ if (tif->tif_map_dir_offset_to_number == NULL)
+ return 1;
+
+ TIFFOffsetAndDirNumber entryOld;
+ entryOld.offset = diroff;
+ entryOld.dirNumber = 0;
+ /* We must remove first from tif_map_dir_number_to_offset as the
+ * entry is owned (and thus freed) by tif_map_dir_offset_to_number.
+ * However, we need firstly to find the directory number from offset. */
+
+ TIFFOffsetAndDirNumber *foundEntryOldOff =
+ (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
+ tif->tif_map_dir_offset_to_number, &entryOld);
+ if (foundEntryOldOff)
+ {
+ entryOld.dirNumber = foundEntryOldOff->dirNumber;
+ if (tif->tif_map_dir_number_to_offset != NULL)
+ {
+ TIFFOffsetAndDirNumber *foundEntryOldDir =
+ (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
+ tif->tif_map_dir_number_to_offset, &entryOld);
+ if (foundEntryOldDir)
+ {
+ TIFFHashSetRemove(tif->tif_map_dir_number_to_offset,
+ foundEntryOldDir);
+ TIFFHashSetRemove(tif->tif_map_dir_offset_to_number,
+ foundEntryOldOff);
+ return 1;
+ }
+ }
+ else
+ {
+ TIFFErrorExtR(tif, "_TIFFRemoveEntryFromDirectoryListByOffset",
+ "Unexpectedly tif_map_dir_number_to_offset is "
+ "missing but tif_map_dir_offset_to_number exists.");
+ return 0;
+ }
+ }
+ return 1;
+} /*--- _TIFFRemoveEntryFromDirectoryListByOffset() ---*/
+
+/*
* Check the count field of a directory entry against a known value. The
* caller is expected to skip/ignore the tag if there is a mismatch.
*/
diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c
index 717afbac..a6a485f8 100644
--- a/libtiff/tif_dirwrite.c
+++ b/libtiff/tif_dirwrite.c
@@ -320,6 +320,7 @@ int TIFFRewriteDirectory(TIFF *tif)
* Find and zero the pointer to this directory, so that TIFFLinkDirectory
* will cause it to be added after this directories current pre-link.
*/
+ uint64_t torewritediroff = tif->tif_diroff;
if (!(tif->tif_flags & TIFF_BIGTIFF))
{
@@ -387,6 +388,8 @@ int TIFFRewriteDirectory(TIFF *tif)
nextdir = nextnextdir;
}
}
+ /* Remove skipped offset from IFD loop directory list. */
+ _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
}
else
{
@@ -456,6 +459,8 @@ int TIFFRewriteDirectory(TIFF *tif)
nextdir = nextnextdir;
}
}
+ /* Remove skipped offset from IFD loop directory list. */
+ _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
}
/*
diff --git a/test/test_directory.c b/test/test_directory.c
index 1cd14274..6cc3baf8 100644
--- a/test/test_directory.c
+++ b/test/test_directory.c
@@ -381,6 +381,68 @@ int test_arbitrary_directrory_loading(bool is_big_tiff)
goto failure;
}
+ /* Test very fast TIFFSetDirectory() using IFD loop directory list.
+ * First populate IFD loop directory list and then go through directories in
+ * reverse order. Within between read after end of IFDs using
+ * TIFFReadDirectory() where IFD loop directory list should be kept. */
+ for (int i = 0; i < N_DIRECTORIES; i++)
+ {
+ if (!TIFFSetDirectory(tif, i))
+ {
+ fprintf(stderr, "Can't set %d.th directory from %s\n", i, filename);
+ goto failure;
+ }
+ }
+ TIFFReadDirectory(tif);
+ for (int i = N_DIRECTORIES - 1; i >= 0; i--)
+ {
+ if (!TIFFSetDirectory(tif, i))
+ {
+ fprintf(stderr, "Can't set %d.th directory from %s\n", i, filename);
+ goto failure;
+ }
+ if (!is_requested_directory(tif, i, filename))
+ {
+ goto failure;
+ }
+ }
+
+ /* Test not existing directory number */
+ if (TIFFSetDirectory(tif, N_DIRECTORIES))
+ {
+ fprintf(stderr,
+ "No expected fail for accessing not existant directory number "
+ "%d in file %s\n",
+ N_DIRECTORIES, filename);
+ goto failure;
+ }
+
+ /* Close and Reopen prepared testfile */
+ TIFFClose(tif);
+ tif = TIFFOpen(filename, "r+");
+ if (!tif)
+ {
+ fprintf(stderr, "Can't create %s\n", filename);
+ return 1;
+ }
+
+ /* Step through directories just using TIFFSetSubDirectory() */
+ for (int i = N_DIRECTORIES - 1; i >= 0; i--)
+ {
+ if (!TIFFSetSubDirectory(tif, offsets_base[i]))
+ {
+ fprintf(stderr, "Can't set %d.th directory from %s\n", i, filename);
+ goto failure;
+ }
+ if (!is_requested_directory(tif, i, filename))
+ {
+ goto failure;
+ }
+ }
+
+ /* More specialized test cases for relative seeking within TIFFSetDirectory.
+ * However, with using IFD loop directory list, most of this test cases will
+ * never be reached! */
if (!TIFFSetDirectory(tif, 2))
{
fprintf(stderr, "Can't set directory %d within %s\n", 2, filename);
@@ -614,6 +676,165 @@ failure:
return 1;
}
+/* Tests SubIFD writing and reading
+ *
+ *
+ */
+int test_SubIFD_directrory_handling(bool is_big_tiff)
+{
+ const char *filename = "test_SubIFD_directrory_handling.tif";
+
+/* Define the number of sub-IFDs you are going to write */
+#define NUMBER_OF_SUBIFDs 3
+ uint16_t number_of_sub_IFDs = NUMBER_OF_SUBIFDs;
+ toff_t sub_IFDs_offsets[NUMBER_OF_SUBIFDs] = {
+ 0UL}; /* array for SubIFD tag */
+ int blnWriteSubIFD = 0;
+ int i;
+ int iIFD = 0, iSubIFD = 0;
+ TIFF *tif;
+ int expected_original_dirnumber;
+
+ /* Create a file and write N_DIRECTORIES (10) directories to it */
+ tif = TIFFOpen(filename, is_big_tiff ? "w8" : "w");
+ if (!tif)
+ {
+ fprintf(stderr, "Can't create %s\n", filename);
+ return 1;
+ }
+ for (i = 0; i < N_DIRECTORIES; i++)
+ {
+ if (write_data_to_current_directory(
+ tif, blnWriteSubIFD ? 200 + iSubIFD++ : iIFD++))
+ {
+ fprintf(stderr, "Can't write data to current directory in %s\n",
+ filename);
+ goto failure;
+ }
+ if (blnWriteSubIFD)
+ {
+ /* SUBFILETYPE tag is not mandatory for SubIFD writing, but a
+ * good idea to indicate thumbnails */
+ if (!TIFFSetField(tif, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE))
+ goto failure;
+ }
+
+ /* For the second multi-page image, trigger TIFFWriteDirectory() to
+ * switch for the next number_of_sub_IFDs calls to add those as SubIFDs
+ * e.g. for thumbnails */
+ if (1 == i)
+ {
+ blnWriteSubIFD = 1;
+ /* Now here is the trick: the next n directories written
+ * will be sub-IFDs of the main-IFD (where n is number_of_sub_IFDs
+ * specified when you set the TIFFTAG_SUBIFD field.
+ * The SubIFD offset array sub_IFDs_offsets is filled automatically
+ * with the proper offset values by the following number_of_sub_IFDs
+ * TIFFWriteDirectory() calls and are updated in the related
+ * main-IFD with the last call.
+ */
+ if (!TIFFSetField(tif, TIFFTAG_SUBIFD, number_of_sub_IFDs,
+ sub_IFDs_offsets))
+ goto failure;
+ }
+
+ if (!TIFFWriteDirectory(tif))
+ {
+ fprintf(stderr, "Can't write directory to %s\n", filename);
+ goto failure;
+ }
+
+ if (iSubIFD >= number_of_sub_IFDs)
+ blnWriteSubIFD = 0;
+ }
+ TIFFClose(tif);
+
+ /* Reopen prepared testfile */
+ tif = TIFFOpen(filename, "r+");
+ if (!tif)
+ {
+ fprintf(stderr, "Can't create %s\n", filename);
+ goto failure;
+ }
+
+ tdir_t numberOfMainIFDs = TIFFNumberOfDirectories(tif);
+ if (numberOfMainIFDs != N_DIRECTORIES - number_of_sub_IFDs)
+ {
+ fprintf(stderr,
+ "Unexpected number of directories in %s. Expected %i, "
+ "found %i.\n",
+ filename, N_DIRECTORIES - number_of_sub_IFDs, numberOfMainIFDs);
+ goto failure;
+ }
+
+ tdir_t currentDirNumber = TIFFCurrentDirectory(tif);
+
+ /* The first directory is already read through TIFFOpen() */
+ int blnRead = 0;
+ expected_original_dirnumber = 1;
+ do
+ {
+ /* Check if there are SubIFD subfiles */
+ void *ptr;
+ if (TIFFGetField(tif, TIFFTAG_SUBIFD, &number_of_sub_IFDs, &ptr))
+ {
+ /* Copy SubIFD array from pointer */
+ memcpy(sub_IFDs_offsets, ptr,
+ number_of_sub_IFDs * sizeof(sub_IFDs_offsets[0]));
+
+ for (i = 0; i < number_of_sub_IFDs; i++)
+ {
+ /* Read first SubIFD directory */
+ if (!TIFFSetSubDirectory(tif, sub_IFDs_offsets[i]))
+ goto failure;
+ if (!is_requested_directory(tif, 200 + i, filename))
+ {
+ goto failure;
+ }
+ /* Check if there is a SubIFD chain behind the first one from
+ * the array, as specified by Adobe */
+ int n = 0;
+ while (TIFFReadDirectory(tif))
+ {
+ /* analyse subfile */
+ if (!is_requested_directory(tif, 201 + i + n++, filename))
+ goto failure;
+ }
+ }
+ /* Go back to main-IFD chain and re-read that main-IFD directory */
+ if (!TIFFSetDirectory(tif, currentDirNumber))
+ goto failure;
+ }
+ /* Read next main-IFD directory (subfile) */
+ blnRead = TIFFReadDirectory(tif);
+ currentDirNumber = TIFFCurrentDirectory(tif);
+ if (blnRead && !is_requested_directory(
+ tif, expected_original_dirnumber++, filename))
+ goto failure;
+ } while (blnRead);
+
+ /*--- Now test arbitrary directory loading with SubIFDs ---*/
+ if (!TIFFSetSubDirectory(tif, sub_IFDs_offsets[1]))
+ goto failure;
+ if (!is_requested_directory(tif, 201, filename))
+ {
+ goto failure;
+ }
+
+ TIFFClose(tif);
+ unlink(filename);
+ return 0;
+
+failure:
+ if (tif)
+ {
+ TIFFClose(tif);
+ tif = NULL;
+ }
+ unlink(filename);
+ return 1;
+} /*--- test_SubIFD_directrory_handling() ---*/
+
/* Checks that rewriting a directory does not break the directory linked
* list
*
@@ -623,6 +844,8 @@ failure:
* skipped, otherwise the linked list will be broken at the point where it
* connected to the rewritten directory, resulting in the loss of the
* directories that come after it.
+ * Rewriting the first directory requires an additional test, because it is
+ * treated differently from the directories that have a predecessor in the list.
*/
int test_rewrite_lastdir_offset(bool is_big_tiff)
{
@@ -652,17 +875,22 @@ int test_rewrite_lastdir_offset(bool is_big_tiff)
}
}
- /* Without closing it, go to the fifth directory */
+ /* Without closing the file, go to the fifth directory
+ * and check, if dirn is requested directory. */
TIFFSetDirectory(tif, 4);
-
- /* Check, if dirn is requested directory */
if (!is_requested_directory(tif, 4, filename))
{
TIFFClose(tif);
return 4;
}
- /* Rewrite the fifth directory by calling TIFFRewriteDirectory */
+ /* Rewrite the fifth directory by calling TIFFRewriteDirectory
+ * and check, if the offset of IFD loaded by TIFFSetDirectory() is
+ * different. Then, the IFD loop directory list is correctly maintained for
+ * speed up of TIFFSetDirectory() with directly getting the offset that
+ * list.
+ */
+ uint64_t off1 = TIFFCurrentDirOffset(tif);
if (write_data_to_current_directory(tif, 4))
{
fprintf(stderr, "Can't write data to fifth directory in %s\n",
@@ -674,6 +902,64 @@ int test_rewrite_lastdir_offset(bool is_big_tiff)
fprintf(stderr, "Can't rewrite fifth directory to %s\n", filename);
goto failure;
}
+ i = 4;
+ if (!TIFFSetDirectory(tif, i))
+ {
+ fprintf(stderr, "Can't set %d.th directory from %s\n", i, filename);
+ goto failure;
+ }
+ uint64_t off2 = TIFFCurrentDirOffset(tif);
+ if (!is_requested_directory(tif, i, filename))
+ {
+ goto failure;
+ }
+ if (off1 == off2)
+ {
+ fprintf(stderr,
+ "Rewritten directory %d was not correctly accessed by "
+ "TIFFSetDirectory() in file %s\n",
+ i, filename);
+ goto failure;
+ }
+
+ /* Now, perform the test for the first directory */
+ TIFFSetDirectory(tif, 0);
+ if (!is_requested_directory(tif, 0, filename))
+ {
+ TIFFClose(tif);
+ return 5;
+ }
+ off1 = TIFFCurrentDirOffset(tif);
+ if (write_data_to_current_directory(tif, 0))
+ {
+ fprintf(stderr, "Can't write data to first directory in %s\n",
+ filename);
+ goto failure;
+ }
+ if (!TIFFRewriteDirectory(tif))
+ {
+ fprintf(stderr, "Can't rewrite first directory to %s\n", filename);
+ goto failure;
+ }
+ i = 0;
+ if (!TIFFSetDirectory(tif, i))
+ {
+ fprintf(stderr, "Can't set %d.th directory from %s\n", i, filename);
+ goto failure;
+ }
+ off2 = TIFFCurrentDirOffset(tif);
+ if (!is_requested_directory(tif, i, filename))
+ {
+ goto failure;
+ }
+ if (off1 == off2)
+ {
+ fprintf(stderr,
+ "Rewritten directory %d was not correctly accessed by "
+ "TIFFSetDirectory() in file %s\n",
+ i, filename);
+ goto failure;
+ }
TIFFClose(tif);
tif = NULL;
@@ -866,7 +1152,7 @@ int main()
return 1;
}
- /* Finally test arbitrary directory loading */
+ /* Test arbitrary directory loading */
if (test_arbitrary_directrory_loading(false))
{
fprintf(stderr,
@@ -880,5 +1166,19 @@ int main()
return 1;
}
+ /* Test SubIFD writing and reading */
+ if (test_SubIFD_directrory_handling(false))
+ {
+ fprintf(stderr,
+ "Failed during non-BigTIFF SubIFD_directrory_handling test.\n");
+ return 1;
+ }
+ if (test_SubIFD_directrory_handling(true))
+ {
+ fprintf(stderr,
+ "Failed during BigTIFF SubIFD_directrory_handling test.\n");
+ return 1;
+ }
+
return 0;
}
diff --git a/test/test_open_options.c b/test/test_open_options.c
index 136adb37..e7608a19 100644
--- a/test/test_open_options.c
+++ b/test/test_open_options.c
@@ -158,13 +158,14 @@ static int test_error_handler()
static int test_TIFFOpenOptionsSetMaxSingleMemAlloc(
tmsize_t limit, int expected_to_fail_in_open,
- int expected_to_fail_in_write_directory)
+ int expected_to_fail_in_write_directory, bool is_big_tiff)
{
int ret = 0;
TIFFOpenOptions *opts = TIFFOpenOptionsAlloc();
assert(opts);
TIFFOpenOptionsSetMaxSingleMemAlloc(opts, limit);
- TIFF *tif = TIFFOpenExt("test_error_handler.tif", "w", opts);
+ TIFF *tif =
+ TIFFOpenExt("test_error_handler.tif", is_big_tiff ? "w8" : "w", opts);
TIFFOpenOptionsFree(opts);
if (expected_to_fail_in_open)
{
@@ -217,10 +218,21 @@ int main()
{
int ret = 0;
ret += test_error_handler();
- ret += test_TIFFOpenOptionsSetMaxSingleMemAlloc(1, TRUE, -1);
+ fprintf(stderr, "---- test_TIFFOpenOptionsSetMaxSingleMemAlloc "
+ "with non-BigTIFF ---- \n");
+ ret += test_TIFFOpenOptionsSetMaxSingleMemAlloc(1, TRUE, -1, FALSE);
+ ret += test_TIFFOpenOptionsSetMaxSingleMemAlloc(
+ sizeof(TIFF) + strlen("test_error_handler.tif") + 1, FALSE, TRUE,
+ FALSE);
+ ret += test_TIFFOpenOptionsSetMaxSingleMemAlloc(
+ VALUE_SAMPLESPERPIXEL * sizeof(short), FALSE, FALSE, FALSE);
+
+ fprintf(stderr, "\n---- test_TIFFOpenOptionsSetMaxSingleMemAlloc "
+ "with BigTIFF ---- \n");
+ ret += test_TIFFOpenOptionsSetMaxSingleMemAlloc(1, TRUE, -1, TRUE);
ret += test_TIFFOpenOptionsSetMaxSingleMemAlloc(
- sizeof(TIFF) + strlen("test_error_handler.tif") + 1, FALSE, TRUE);
+ sizeof(TIFF) + strlen("test_error_handler.tif") + 1, FALSE, TRUE, TRUE);
ret += test_TIFFOpenOptionsSetMaxSingleMemAlloc(
- VALUE_SAMPLESPERPIXEL * sizeof(short), FALSE, FALSE);
+ VALUE_SAMPLESPERPIXEL * sizeof(short), FALSE, FALSE, TRUE);
return ret;
}