From 7ffc9affb41239c681e25ccccd6a2e55a6f0b81a Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Thu, 18 Aug 2011 13:15:43 +0000 Subject: [PATCH] Fixed saving TIFF images to wxMemoryOutputStream. Libtiff attempts to seek past the end of a stream and the behaviour for this can vary per stream implementation. Fixed failure to seek by filling the gap between the end of stream and new seek position with zeroes. Enabled a unit test which so far was disabled due to wxMemoryOutputStream failing to save a TIFF because of the seeking problem. Also closes #4089. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68772 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/imagtiff.cpp | 38 ++++++++++++++++++++++++++++++++++++-- tests/image/image.cpp | 9 +-------- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index 2501e91..59b7fb9 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -192,8 +192,42 @@ wxTIFFSeekOProc(thandle_t handle, toff_t off, int whence) { wxOutputStream *stream = (wxOutputStream*) handle; - return wxFileOffsetToTIFF(stream->SeekO((wxFileOffset)off, - wxSeekModeFromTIFF(whence))); + toff_t offset = wxFileOffsetToTIFF( + stream->SeekO((wxFileOffset)off, wxSeekModeFromTIFF(whence)) ); + + if (offset != (toff_t) -1 || whence != SEEK_SET) + { + return offset; + } + + + /* + Try to workaround problems with libtiff seeking past the end of streams. + + This occurs when libtiff is writing tag entries past the end of a + stream but hasn't written the directory yet (which will be placed + before the tags and contain offsets to the just written tags). + The behaviour for seeking past the end of a stream is not consistent + and doesn't work with for example wxMemoryOutputStream. When this type + of seeking fails (with SEEK_SET), fill in the gap with zeroes and try + again. + */ + + wxFileOffset streamLength = stream->GetLength(); + if (streamLength != wxInvalidOffset && (wxFileOffset) off > streamLength) + { + if (stream->SeekO(streamLength, wxFromStart) == wxInvalidOffset) + { + return (toff_t) -1; + } + + for (wxFileOffset i = 0; i < (wxFileOffset) off - streamLength; ++i) + { + stream->PutC(0); + } + } + + return wxFileOffsetToTIFF( stream->TellO() ); } int TIFFLINKAGEMODE diff --git a/tests/image/image.cpp b/tests/image/image.cpp index ae63591..22384f5 100644 --- a/tests/image/image.cpp +++ b/tests/image/image.cpp @@ -912,15 +912,8 @@ void CompareImage(const wxImageHandler& handler, const wxImage& image, return; } - if (type == wxBITMAP_TYPE_JPEG /* skip lossy JPEG */ - || type == wxBITMAP_TYPE_TIF) + if (type == wxBITMAP_TYPE_JPEG /* skip lossy JPEG */) { - /* - TIFF is skipped because the memory stream can't be loaded. Libtiff - looks for a TIFF directory at offset 120008 while the memory - stream size is only 120008 bytes (when saving as a file - the file size is 120280 bytes). - */ return; } -- 2.7.4