From 7e74848639e4ff89b1ed615d4f00077d1131e29e Mon Sep 17 00:00:00 2001 From: Joachim Reichel <43646584+jreichel-nvidia@users.noreply.github.com> Date: Mon, 17 Jun 2024 17:27:21 +0200 Subject: [PATCH 1/2] Fix TIFF export with EXIF data and I/O proxy. TIFFSetDirectory() requires to read some of the previously written data. Change writer_readproc() to forward the call to the I/O proxy. Modify IOFile to also support reading after writing (in write mode). Modify IOVecOutput to also support reading (implicitly after writing, since the vector starts always empty). Signed-off-by: Joachim Reichel <43646584+jreichel-nvidia@users.noreply.github.com> --- src/include/OpenImageIO/filesystem.h | 4 +++- src/libutil/filesystem.cpp | 23 +++++++++++++++++++---- src/tiff.imageio/tiffoutput.cpp | 5 +++-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/include/OpenImageIO/filesystem.h b/src/include/OpenImageIO/filesystem.h index dbaec7c6a3..e29df72f9f 100644 --- a/src/include/OpenImageIO/filesystem.h +++ b/src/include/OpenImageIO/filesystem.h @@ -471,7 +471,7 @@ class OIIO_UTIL_API IOProxy { }; -/// IOProxy subclass for reading or writing (but not both) that wraps C +/// IOProxy subclass for reading or writing (plus re-reading) that wraps C /// stdio 'FILE'. class OIIO_UTIL_API IOFile : public IOProxy { public: @@ -521,7 +521,9 @@ class OIIO_UTIL_API IOVecOutput : public IOProxy { { } const char* proxytype() const override { return "vecoutput"; } + size_t read(void* buf, size_t size) override; size_t write(const void* buf, size_t size) override; + size_t pread(void* buf, size_t size, int64_t offset) override; size_t pwrite(const void* buf, size_t size, int64_t offset) override; size_t size() const override { return m_buf.size(); } diff --git a/src/libutil/filesystem.cpp b/src/libutil/filesystem.cpp index 81c6cb69a2..faef635f56 100644 --- a/src/libutil/filesystem.cpp +++ b/src/libutil/filesystem.cpp @@ -1178,7 +1178,7 @@ Filesystem::IOFile::IOFile(string_view filename, Mode mode) { // Call Filesystem::fopen since it handles UTF-8 file paths on Windows, // which std fopen does not. - m_file = Filesystem::fopen(m_filename, m_mode == Write ? "wb" : "rb"); + m_file = Filesystem::fopen(m_filename, m_mode == Write ? "w+b" : "rb"); if (!m_file) { m_mode = Closed; int e = errno; @@ -1230,7 +1230,7 @@ Filesystem::IOFile::seek(int64_t offset) size_t Filesystem::IOFile::read(void* buf, size_t size) { - if (!m_file || !size || m_mode != Read) + if (!m_file || !size || m_mode == Closed) return 0; size_t r = fread(buf, 1, size, m_file); m_pos += r; @@ -1249,7 +1249,7 @@ Filesystem::IOFile::read(void* buf, size_t size) size_t Filesystem::IOFile::pread(void* buf, size_t size, int64_t offset) { - if (!m_file || !size || offset < 0 || m_mode != Read) + if (!m_file || !size || offset < 0 || m_mode == Closed) return 0; #ifdef _WIN32 std::lock_guard lock(m_mutex); @@ -1317,6 +1317,14 @@ Filesystem::IOFile::flush() const +size_t +Filesystem::IOVecOutput::read(void* buf, size_t size) +{ + size = pread(buf, size, m_pos); + m_pos += size; + return size; +} + size_t Filesystem::IOVecOutput::write(const void* buf, size_t size) { @@ -1325,7 +1333,14 @@ Filesystem::IOVecOutput::write(const void* buf, size_t size) return size; } - +size_t +Filesystem::IOVecOutput::pread(void* buf, size_t size, int64_t offset) +{ + std::lock_guard lock(m_mutex); + size = std::min(size, m_buf.size() - offset); + memcpy(buf, &m_buf[offset], size); + return size; +} size_t Filesystem::IOVecOutput::pwrite(const void* buf, size_t size, int64_t offset) diff --git a/src/tiff.imageio/tiffoutput.cpp b/src/tiff.imageio/tiffoutput.cpp index 7bec7eaeec..e095039ece 100644 --- a/src/tiff.imageio/tiffoutput.cpp +++ b/src/tiff.imageio/tiffoutput.cpp @@ -400,9 +400,10 @@ allval(const std::vector& d, T v = T(0)) static tsize_t -writer_readproc(thandle_t, tdata_t, tsize_t) +writer_readproc(thandle_t handle, tdata_t data, tsize_t size) { - return 0; + auto io = static_cast(handle); + return io->read(data, size); } static tsize_t From 7dea4831ee60c5371fe6c72ac3f9b3d3464c5b82 Mon Sep 17 00:00:00 2001 From: Joachim Reichel <43646584+jreichel-nvidia@users.noreply.github.com> Date: Tue, 18 Jun 2024 15:51:35 +0200 Subject: [PATCH 2/2] Fix build error on MacOS. Signed-off-by: Joachim Reichel <43646584+jreichel-nvidia@users.noreply.github.com> --- src/libutil/filesystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libutil/filesystem.cpp b/src/libutil/filesystem.cpp index faef635f56..43381806a5 100644 --- a/src/libutil/filesystem.cpp +++ b/src/libutil/filesystem.cpp @@ -1337,7 +1337,7 @@ size_t Filesystem::IOVecOutput::pread(void* buf, size_t size, int64_t offset) { std::lock_guard lock(m_mutex); - size = std::min(size, m_buf.size() - offset); + size = std::min(size, size_t(m_buf.size() - offset)); memcpy(buf, &m_buf[offset], size); return size; }