]> git.saurik.com Git - wxWidgets.git/commitdiff
Fixed saving TIFF images to wxMemoryOutputStream.
authorDimitri Schoolwerth <dimitri.schoolwerth@gmail.com>
Thu, 18 Aug 2011 13:15:43 +0000 (13:15 +0000)
committerDimitri Schoolwerth <dimitri.schoolwerth@gmail.com>
Thu, 18 Aug 2011 13:15:43 +0000 (13:15 +0000)
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
tests/image/image.cpp

index 2501e91f3e50cfa57547589bf862b801b5dbb405..59b7fb9b432ca4ffaed6ca5d5dff34d266ffa613 100644 (file)
@@ -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
index ae63591d8e5a9441485956fc9ef790b0aba160b0..22384f5e1f313afed15f2b13040c2a04bdad4673 100644 (file)
@@ -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;
     }