From ee50a3aebd06e182602b8a757af7eb95022207cc Mon Sep 17 00:00:00 2001 From: Dieter De Baets Date: Wed, 6 Jan 2021 18:00:41 +0100 Subject: [PATCH] fixed libtiff handling of file IO by providing the proper sharing flag so the file can be deleted while open for reading --- src/libOpenImageIO/imagebuf_test.cpp | 2 +- src/tiff.imageio/tiffinput.cpp | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/libOpenImageIO/imagebuf_test.cpp b/src/libOpenImageIO/imagebuf_test.cpp index f60279cfb8..d4cdbeb563 100644 --- a/src/libOpenImageIO/imagebuf_test.cpp +++ b/src/libOpenImageIO/imagebuf_test.cpp @@ -417,7 +417,7 @@ test_write_over() OIIO_CHECK_ASSERT(pixel[0] == 0 && pixel[1] == 1 && pixel[2] == 0); // Replace the green image with red, under the nose of the ImageBuf. - Filesystem::remove("tmp-green.tif"); + OIIO_CHECK_ASSERT(Filesystem::remove("tmp-green.tif") == true); Filesystem::copy("tmp-red.tif", "tmp-green.tif"); // Read the image again -- different ImageBuf. diff --git a/src/tiff.imageio/tiffinput.cpp b/src/tiff.imageio/tiffinput.cpp index 2eadc31545..78f18ee6e7 100644 --- a/src/tiff.imageio/tiffinput.cpp +++ b/src/tiff.imageio/tiffinput.cpp @@ -630,6 +630,10 @@ TIFFInput::open(const std::string& name, ImageSpec& newspec, return open(name, newspec); } +#define WIN_SHARE_DELETE_WORKAROUND 1 +#if defined(_WIN32) && WIN_SHARE_DELETE_WORKAROUND +#include +#endif bool @@ -661,7 +665,25 @@ TIFFInput::seek_subimage(int subimage, int miplevel) if (!m_tif) { #ifdef _WIN32 std::wstring wfilename = Strutil::utf8_to_utf16(m_filename); + + // workaround for libtiff not passing FILE_SHARE_DELETE attribute + // Without this flag, a process cannot delete files that it has opened (for reading). + #if !WIN_SHARE_DELETE_WORKAROUND m_tif = TIFFOpenW(wfilename.c_str(), "rm"); + #else + int m = O_RDONLY; /*_TIFFgetMode(mode, module);*/ + int dwMode = OPEN_EXISTING /*case O_RDONLY: dwMode = OPEN_EXISTING; break;*/; + HANDLE fd = CreateFileW(wfilename.c_str(), + (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE), + FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE , NULL, dwMode, + (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL, + NULL); + if (fd != INVALID_HANDLE_VALUE) + { + m_tif = TIFFFdOpen((int)fd, "","rm"); /* FIXME: WIN64 cast from pointer to int warning */ + if (!m_tif) CloseHandle(fd); + } + #endif #else m_tif = TIFFOpen(m_filename.c_str(), "rm"); #endif