diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index 2501e91f3e..59b7fb9b43 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 ae63591d8e..22384f5e1f 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; }