From 0e11090ef6cd6cf68a7ee521feb126006a70e368 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Aug 2011 02:00:25 +0000 Subject: [PATCH] Fixed crash when saving as a monochrome TIFF image with incomplete options set. When setting only wxIMAGE_OPTION_TIFF_BITSPERSAMPLE to 1 the used samples per pixel (wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL) would still be set to 3. This is invalid and confuses libtiff, resulting in a crash ("possible heap corruption" during _TIFFfree using WinXP+MSVC8). Set the used samples per pixel to 1 explicitly in cases where only bits per sample is set to 1. Added a unit test to check for this problem (and verify the bits per sample from the saved image is indeed 1). git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68782 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/imagtiff.cpp | 8 ++++++++ tests/image/image.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index 3d8c102821..b3209d39f9 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -593,7 +593,15 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo int bps = image->GetOptionInt(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE); if ( !bps ) + { bps = 8; + } + else if (bps == 1) + { + // One bit per sample combined with 3 samples per pixel is + // not allowed and crashes libtiff. + spp = 1; + } int compression = image->GetOptionInt(wxIMAGE_OPTION_TIFF_COMPRESSION); if ( !compression ) diff --git a/tests/image/image.cpp b/tests/image/image.cpp index 22384f5e1f..010bc1d278 100644 --- a/tests/image/image.cpp +++ b/tests/image/image.cpp @@ -73,6 +73,7 @@ private: CPPUNIT_TEST( CompareLoadedImage ); CPPUNIT_TEST( CompareSavedImage ); CPPUNIT_TEST( SavePNG ); + CPPUNIT_TEST( SaveTIFF ); CPPUNIT_TEST( SaveAnimatedGIF ); CPPUNIT_TEST( ReadCorruptedTGA ); CPPUNIT_TEST( GIFComment ); @@ -87,6 +88,7 @@ private: void CompareLoadedImage(); void CompareSavedImage(); void SavePNG(); + void SaveTIFF(); void SaveAnimatedGIF(); void ReadCorruptedTGA(); void GIFComment(); @@ -1088,6 +1090,33 @@ void ImageTestCase::SavePNG() } +static void TestTIFFImage(const wxString& option, int value) +{ + wxImage image("horse.png"); + + wxMemoryOutputStream memOut; + image.SetOption(option, value); + + CPPUNIT_ASSERT(image.SaveFile(memOut, wxBITMAP_TYPE_TIF)); + + wxMemoryInputStream memIn(memOut); + CPPUNIT_ASSERT(memIn.IsOk()); + + wxImage savedImage(memIn); + CPPUNIT_ASSERT(savedImage.IsOk()); + + WX_ASSERT_EQUAL_MESSAGE(("While checking for option %s", option), + true, savedImage.HasOption(option)); + + WX_ASSERT_EQUAL_MESSAGE(("While testing for %s", option), + value, savedImage.GetOptionInt(option)); +} + +void ImageTestCase::SaveTIFF() +{ + TestTIFFImage(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, 1); +} + void ImageTestCase::SaveAnimatedGIF() { #if wxUSE_PALETTE -- 2.45.2