diff options
author | Su Laus <sulau@freenet.de> | 2023-03-26 14:09:24 +0000 |
---|---|---|
committer | Even Rouault <even.rouault@spatialys.com> | 2023-03-26 14:09:24 +0000 |
commit | ada85f3663f907b04f80e036f6fd263fab4b3305 (patch) | |
tree | 6577627e956df2c7ced31bef7b243745610ee249 | |
parent | ddd7f044822ce7eb1720dc6cdec8f84821463cd8 (diff) | |
download | libtiff-git-ada85f3663f907b04f80e036f6fd263fab4b3305.tar.gz |
Even faster TIFFSetDirectory() using IFD list.
-rw-r--r-- | libtiff/tif_dir.c | 89 | ||||
-rw-r--r-- | libtiff/tif_dir.h | 4 | ||||
-rw-r--r-- | libtiff/tif_dirread.c | 85 | ||||
-rw-r--r-- | libtiff/tif_dirwrite.c | 5 | ||||
-rw-r--r-- | test/test_directory.c | 310 | ||||
-rw-r--r-- | test/test_open_options.c | 22 |
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; } |