+ CompareImage(*handler, expected32, wxIMAGE_HAVE_ALPHA);
+ }
+}
+
+void ImageTestCase::SavePNG()
+{
+ wxImage expected24("horse.png");
+ CPPUNIT_ASSERT( expected24.IsOk() );
+#if wxUSE_PALETTE
+ CPPUNIT_ASSERT( !expected24.HasPalette() );
+#endif // #if wxUSE_PALETTE
+
+ wxImage expected8 = expected24.ConvertToGreyscale();
+
+ /*
+ horse.png converted to greyscale should be saved without a palette.
+ */
+ CompareImage(*wxImage::FindHandler(wxBITMAP_TYPE_PNG), expected8);
+
+ /*
+ But if we explicitly ask for trying to save with a palette, it should work.
+ */
+ expected8.SetOption(wxIMAGE_OPTION_PNG_FORMAT, wxPNG_TYPE_PALETTE);
+
+ CompareImage(*wxImage::FindHandler(wxBITMAP_TYPE_PNG),
+ expected8, wxIMAGE_HAVE_PALETTE);
+
+
+ CPPUNIT_ASSERT( expected8.LoadFile("horse.gif") );
+#if wxUSE_PALETTE
+ CPPUNIT_ASSERT( expected8.HasPalette() );
+#endif // #if wxUSE_PALETTE
+
+ CompareImage(*wxImage::FindHandler(wxBITMAP_TYPE_PNG),
+ expected8, wxIMAGE_HAVE_PALETTE);
+
+ /*
+ Add alpha to the image in such a way that there will still be a maximum
+ of 256 unique RGBA combinations. This should result in a saved
+ PNG image still being palettised and having alpha.
+ */
+ expected8.SetAlpha();
+
+ int x, y;
+ const int width = expected8.GetWidth();
+ const int height = expected8.GetHeight();
+ for (y = 0; y < height; ++y)
+ {
+ for (x = 0; x < width; ++x)
+ {
+ expected8.SetAlpha(x, y, expected8.GetRed(x, y));
+ }
+ }
+
+ CompareImage(*wxImage::FindHandler(wxBITMAP_TYPE_PNG),
+ expected8, wxIMAGE_HAVE_ALPHA|wxIMAGE_HAVE_PALETTE);
+
+ /*
+ Now change the alpha of the first pixel so that we can't save palettised
+ anymore because there will be 256+1 entries which is beyond PNGs limit
+ of 256 entries.
+ */
+ expected8.SetAlpha(0, 0, 1);
+
+ CompareImage(*wxImage::FindHandler(wxBITMAP_TYPE_PNG),
+ expected8, wxIMAGE_HAVE_ALPHA);
+
+ /*
+ Even if we explicitly ask for saving palettised it should not be done.
+ */
+ expected8.SetOption(wxIMAGE_OPTION_PNG_FORMAT, wxPNG_TYPE_PALETTE);
+ CompareImage(*wxImage::FindHandler(wxBITMAP_TYPE_PNG),
+ expected8, wxIMAGE_HAVE_ALPHA);
+
+}
+
+static void TestTIFFImage(const wxString& option, int value,
+ const wxImage *compareImage = NULL)
+{
+ wxImage image;
+ if (compareImage)
+ {
+ image = *compareImage;
+ }
+ else
+ {
+ (void) image.LoadFile("horse.png");
+ }
+ CPPUNIT_ASSERT( image.IsOk() );
+
+ wxMemoryOutputStream memOut;
+ image.SetOption(option, value);
+
+ CPPUNIT_ASSERT(image.SaveFile(memOut, wxBITMAP_TYPE_TIFF));
+
+ 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));
+
+ WX_ASSERT_EQUAL_MESSAGE(("HasAlpha() not equal"), image.HasAlpha(), savedImage.HasAlpha());
+}
+
+void ImageTestCase::SaveTIFF()
+{
+ TestTIFFImage(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, 1);
+ TestTIFFImage(wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, 1);
+ TestTIFFImage(wxIMAGE_OPTION_TIFF_PHOTOMETRIC, 0/*PHOTOMETRIC_MINISWHITE*/);
+ TestTIFFImage(wxIMAGE_OPTION_TIFF_PHOTOMETRIC, 1/*PHOTOMETRIC_MINISBLACK*/);
+
+ wxImage alphaImage("horse.png");
+ CPPUNIT_ASSERT( alphaImage.IsOk() );
+ SetAlpha(&alphaImage);
+
+ // RGB with alpha
+ TestTIFFImage(wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, 4, &alphaImage);
+
+ // Grey with alpha
+ TestTIFFImage(wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, 2, &alphaImage);
+
+ // B/W with alpha
+ alphaImage.SetOption(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, 1);
+ TestTIFFImage(wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, 2, &alphaImage);
+}
+
+void ImageTestCase::SaveAnimatedGIF()
+{
+#if wxUSE_PALETTE
+ wxImage image("horse.gif");
+ CPPUNIT_ASSERT( image.IsOk() );
+
+ wxImageArray images;
+ images.Add(image);
+ int i;
+ for (i = 0; i < 4-1; ++i)
+ {
+ images.Add( images[i].Rotate90() );
+
+ images[i+1].SetPalette(images[0].GetPalette());
+ }
+
+ wxMemoryOutputStream memOut;
+ CPPUNIT_ASSERT( wxGIFHandler().SaveAnimation(images, &memOut) );
+
+ wxGIFHandler handler;
+ wxMemoryInputStream memIn(memOut);
+ CPPUNIT_ASSERT(memIn.IsOk());
+ const int imageCount = handler.GetImageCount(memIn);
+ CPPUNIT_ASSERT_EQUAL(4, imageCount);
+
+ for (i = 0; i < imageCount; ++i)
+ {
+ wxFileOffset pos = memIn.TellI();
+ CPPUNIT_ASSERT( handler.LoadFile(&image, memIn, true, i) );
+ memIn.SeekI(pos);
+
+ WX_ASSERT_EQUAL_MESSAGE
+ (
+ ("Compare test for GIF frame number %d failed", i),
+ images[i],
+ image
+ );
+ }
+#endif // #if wxUSE_PALETTE
+}
+
+void ImageTestCase::ReadCorruptedTGA()
+{
+ static unsigned char corruptTGA[18+1+3] =
+ {
+ 0,
+ 0,
+ 10, // RLE compressed image.
+ 0, 0,
+ 0, 0,
+ 0,
+ 0, 0,
+ 0, 0,
+ 1, 0, // Width is 1.
+ 1, 0, // Height is 1.
+ 24, // Bits per pixel.
+ 0,
+
+ 0xff, // Run length (repeat next pixel 127+1 times).
+ 0xff, 0xff, 0xff // One 24-bit pixel.
+ };
+
+ wxMemoryInputStream memIn(corruptTGA, WXSIZEOF(corruptTGA));
+ CPPUNIT_ASSERT(memIn.IsOk());
+
+ wxImage tgaImage;
+ CPPUNIT_ASSERT( !tgaImage.LoadFile(memIn) );
+
+
+ /*
+ Instead of repeating a pixel 127+1 times, now tell it there will
+ follow 127+1 uncompressed pixels (while we only should have 1 in total).
+ */
+ corruptTGA[18] = 0x7f;
+ CPPUNIT_ASSERT( !tgaImage.LoadFile(memIn) );
+}
+
+static void TestGIFComment(const wxString& comment)
+{
+ wxImage image("horse.gif");
+
+ image.SetOption(wxIMAGE_OPTION_GIF_COMMENT, comment);
+ wxMemoryOutputStream memOut;
+ CPPUNIT_ASSERT(image.SaveFile(memOut, wxBITMAP_TYPE_GIF));
+
+ wxMemoryInputStream memIn(memOut);
+ CPPUNIT_ASSERT( image.LoadFile(memIn) );
+
+ CPPUNIT_ASSERT_EQUAL(comment,
+ image.GetOption(wxIMAGE_OPTION_GIF_COMMENT));
+}
+
+void ImageTestCase::GIFComment()
+{
+ // Test reading a comment.
+ wxImage image("horse.gif");
+ CPPUNIT_ASSERT_EQUAL(" Imported from GRADATION image: gray",
+ image.GetOption(wxIMAGE_OPTION_GIF_COMMENT));
+
+
+ // Test writing a comment and reading it back.
+ TestGIFComment("Giving the GIF a gifted giraffe as a gift");
+
+
+ // Test writing and reading a comment again but with a long comment.
+ TestGIFComment(wxString(wxT('a'), 256)
+ + wxString(wxT('b'), 256)
+ + wxString(wxT('c'), 256));
+
+
+ // Test writing comments in an animated GIF and reading them back.
+ CPPUNIT_ASSERT( image.LoadFile("horse.gif") );
+
+ wxImageArray images;
+ int i;
+ for (i = 0; i < 4; ++i)
+ {
+ if (i)
+ {
+ images.Add( images[i-1].Rotate90() );
+ images[i].SetPalette(images[0].GetPalette());
+ }
+ else
+ {
+ images.Add(image);
+ }
+
+ images[i].SetOption(wxIMAGE_OPTION_GIF_COMMENT,
+ wxString::Format("GIF comment for frame #%d", i+1));
+
+ }
+
+
+ wxMemoryOutputStream memOut;
+ CPPUNIT_ASSERT( wxGIFHandler().SaveAnimation(images, &memOut) );
+
+ wxGIFHandler handler;
+ wxMemoryInputStream memIn(memOut);
+ CPPUNIT_ASSERT(memIn.IsOk());
+ const int imageCount = handler.GetImageCount(memIn);
+ for (i = 0; i < imageCount; ++i)
+ {
+ wxFileOffset pos = memIn.TellI();
+ CPPUNIT_ASSERT( handler.LoadFile(&image, memIn, true /*verbose?*/, i) );
+
+ CPPUNIT_ASSERT_EQUAL(
+ wxString::Format("GIF comment for frame #%d", i+1),
+ image.GetOption(wxIMAGE_OPTION_GIF_COMMENT));
+ memIn.SeekI(pos);