+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);
+ }
+}
+
+void ImageTestCase::DibPadding()
+{
+ /*
+ There used to be an error with calculating the DWORD aligned scan line
+ pitch for a BMP/ICO resulting in buffer overwrites (with at least MSVC9
+ Debug this gave a heap corruption assertion when saving the mask of
+ an ICO). Test for it here.
+ */
+ wxImage image("horse.gif");
+ CPPUNIT_ASSERT( image.IsOk() );
+
+ image = image.Scale(99, 99);
+
+ wxMemoryOutputStream memOut;
+ CPPUNIT_ASSERT( image.SaveFile(memOut, wxBITMAP_TYPE_ICO) );
+}
+
+static void CompareBMPImage(const wxString& file1, const wxString& file2)
+{
+ wxImage image1(file1);
+ CPPUNIT_ASSERT( image1.IsOk() );
+
+ wxImage image2(file2);
+ CPPUNIT_ASSERT( image2.IsOk() );
+
+ CompareImage(*wxImage::FindHandler(wxBITMAP_TYPE_BMP), image1, 0, &image2);
+}
+
+void ImageTestCase::BMPFlippingAndRLECompression()
+{
+ CompareBMPImage("image/horse_grey.bmp", "image/horse_grey_flipped.bmp");
+
+ CompareBMPImage("image/horse_rle8.bmp", "image/horse_grey.bmp");
+ CompareBMPImage("image/horse_rle8.bmp", "image/horse_rle8_flipped.bmp");
+
+ CompareBMPImage("image/horse_rle4.bmp", "image/horse_rle4_flipped.bmp");
+}