/////////////////////////////////////////////////////////////////////////////// // Name: tests/image/image.cpp // Purpose: Test wxImage // Author: Francesco Montorsi // Created: 2009-05-31 // RCS-ID: $Id$ // Copyright: (c) 2009 Francesco Montorsi // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- #include "testprec.h" #if wxUSE_IMAGE #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #endif // WX_PRECOMP #include "wx/image.h" #include "wx/palette.h" #include "wx/url.h" #include "wx/log.h" #include "wx/mstream.h" #include "wx/zstream.h" #include "wx/wfstream.h" struct testData { const char* file; wxBitmapType type; unsigned bitDepth; } g_testfiles[] = { { "horse.ico", wxBITMAP_TYPE_ICO, 4 }, { "horse.xpm", wxBITMAP_TYPE_XPM, 8 }, { "horse.png", wxBITMAP_TYPE_PNG, 24 }, { "horse.ani", wxBITMAP_TYPE_ANI, 24 }, { "horse.bmp", wxBITMAP_TYPE_BMP, 8 }, { "horse.cur", wxBITMAP_TYPE_CUR, 1 }, { "horse.gif", wxBITMAP_TYPE_GIF, 8 }, { "horse.jpg", wxBITMAP_TYPE_JPEG, 24 }, { "horse.pcx", wxBITMAP_TYPE_PCX, 8 }, { "horse.pnm", wxBITMAP_TYPE_PNM, 24 }, { "horse.tga", wxBITMAP_TYPE_TGA, 8 }, { "horse.tif", wxBITMAP_TYPE_TIF, 8 } }; // ---------------------------------------------------------------------------- // test class // ---------------------------------------------------------------------------- class ImageTestCase : public CppUnit::TestCase { public: ImageTestCase(); ~ImageTestCase(); private: CPPUNIT_TEST_SUITE( ImageTestCase ); CPPUNIT_TEST( LoadFromSocketStream ); CPPUNIT_TEST( LoadFromZipStream ); CPPUNIT_TEST( LoadFromFile ); CPPUNIT_TEST( SizeImage ); CPPUNIT_TEST( CompareLoadedImage ); CPPUNIT_TEST( CompareSavedImage ); CPPUNIT_TEST_SUITE_END(); void LoadFromSocketStream(); void LoadFromZipStream(); void LoadFromFile(); void SizeImage(); void CompareLoadedImage(); void CompareSavedImage(); DECLARE_NO_COPY_CLASS(ImageTestCase) }; CPPUNIT_TEST_SUITE_REGISTRATION( ImageTestCase ); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ImageTestCase, "ImageTestCase" ); ImageTestCase::ImageTestCase() { wxSocketBase::Initialize(); // the formats we're going to test: wxImage::AddHandler(new wxICOHandler); wxImage::AddHandler(new wxXPMHandler); wxImage::AddHandler(new wxPNGHandler); wxImage::AddHandler(new wxANIHandler); wxImage::AddHandler(new wxBMPHandler); wxImage::AddHandler(new wxCURHandler); wxImage::AddHandler(new wxGIFHandler); wxImage::AddHandler(new wxJPEGHandler); wxImage::AddHandler(new wxPCXHandler); wxImage::AddHandler(new wxPNMHandler); wxImage::AddHandler(new wxTGAHandler); wxImage::AddHandler(new wxTIFFHandler); } ImageTestCase::~ImageTestCase() { wxSocketBase::Shutdown(); } void ImageTestCase::LoadFromFile() { wxImage img; for (unsigned int i=0; iIsOk() ); wxImage img; // NOTE: it's important to inform wxImage about the type of the image being // loaded otherwise it will try to autodetect the format, but that // requires a seekable stream! WX_ASSERT_MESSAGE ( ("Loading image from \"%s\" failed.", testData[i].url), img.LoadFile(*in_stream, testData[i].type) ); delete in_stream; } } void ImageTestCase::LoadFromZipStream() { for (unsigned int i=0; iGetSize() ); unsigned bitsPerPixel = testPalette ? 8 : (testAlpha ? 32 : 24); WX_ASSERT_MESSAGE ( ("Compare test '%s (%d-bit)' for saving failed", handler.GetExtension(), bitsPerPixel), memcmp(actual.GetData(), expected->GetData(), expected->GetWidth() * expected->GetHeight() * 3) == 0 ); #if wxUSE_PALETTE CPPUNIT_ASSERT(actual.HasPalette() == (testPalette || type == wxBITMAP_TYPE_XPM)); #endif CPPUNIT_ASSERT( actual.HasAlpha() == testAlpha); if (!testAlpha) { return; } WX_ASSERT_MESSAGE ( ("Compare alpha test '%s' for saving failed", handler.GetExtension()), memcmp(actual.GetAlpha(), expected->GetAlpha(), expected->GetWidth() * expected->GetHeight()) == 0 ); } void ImageTestCase::CompareSavedImage() { // FIXME-VC6: Pre-declare the loop variables for compatibility with // pre-standard compilers such as MSVC6 that don't implement proper scope // for the variables declared in the for loops. int i, x, y; wxImage expected24("horse.png"); CPPUNIT_ASSERT( expected24.IsOk() ); CPPUNIT_ASSERT( !expected24.HasAlpha() ); unsigned long numColours = expected24.CountColours(); wxImage expected8 = expected24.ConvertToGreyscale(); numColours = expected8.CountColours(); unsigned char greys[256]; for (i = 0; i < 256; ++i) { greys[i] = i; } wxPalette palette(256, greys, greys, greys); expected8.SetPalette(palette); expected8.SetOption(wxIMAGE_OPTION_BMP_FORMAT, wxBMP_8BPP_PALETTE); // Create an image with alpha based on the loaded image wxImage expected32(expected24); expected32.SetAlpha(); int width = expected32.GetWidth(); int height = expected32.GetHeight(); for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { expected32.SetAlpha(x, y, (x*y) & wxIMAGE_ALPHA_OPAQUE); } } const wxList& list = wxImage::GetHandlers(); for ( wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext() ) { wxImageHandler *handler = (wxImageHandler *) node->GetData(); #if wxUSE_PALETTE CompareImage(*handler, expected8, wxIMAGE_HAVE_PALETTE); #endif CompareImage(*handler, expected24); CompareImage(*handler, expected32, wxIMAGE_HAVE_ALPHA); } expected8.LoadFile("horse.gif"); CPPUNIT_ASSERT( expected8.IsOk() ); CPPUNIT_ASSERT( expected8.HasPalette() ); expected8.SetAlpha(); width = expected8.GetWidth(); height = expected8.GetHeight(); for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { expected8.SetAlpha(x, y, (x*y) & wxIMAGE_ALPHA_OPAQUE); } } /* The image contains 256 indexed colours and needs another palette entry for storing the transparency index. This results in wanting 257 palette entries but that amount is not supported by PNG, as such this image should not contain a palette (but still have alpha) and be stored as a true colour image instead. */ CompareImage(*wxImage::FindHandler(wxBITMAP_TYPE_PNG), expected8, wxIMAGE_HAVE_ALPHA); #if wxUSE_PALETTE /* Now do the same test again but remove one (random) palette entry. This should result in saving the PNG with a palette. */ unsigned char red[256], green[256], blue[256]; const wxPalette& pal = expected8.GetPalette(); const int paletteCount = pal.GetColoursCount(); for (i = 0; i < paletteCount; ++i) { expected8.GetPalette().GetRGB(i, &red[i], &green[i], &blue[i]); } wxPalette newPal(paletteCount - 1, red, green, blue); expected8.Replace( red[paletteCount-1], green[paletteCount-1], blue[paletteCount-1], red[paletteCount-2], green[paletteCount-2], blue[paletteCount-2]); expected8.SetPalette(newPal); /* Explicitly make known we want a palettised PNG. If we don't then this particular image gets saved as a true colour image because there's an alpha channel present and the PNG saver prefers to keep the alpha over saving as a palettised image that has alpha converted to a mask. */ expected8.SetOption(wxIMAGE_OPTION_PNG_FORMAT, wxPNG_TYPE_PALETTE); wxImage ref8 = expected8; /* Convert the alpha channel to a mask like the PNG saver does. Also convert the colour used for transparency from 1,0,0 to 2,0,0. The latter gets done by the PNG loader in search of an unused colour to use for transparency (this should be fixed). */ ref8.ConvertAlphaToMask(); ref8.Replace(1, 0, 0, 2, 0, 0); CompareImage(*wxImage::FindHandler(wxBITMAP_TYPE_PNG), expected8, wxIMAGE_HAVE_PALETTE, &ref8); #endif } #endif //wxUSE_IMAGE /* TODO: add lots of more tests to wxImage functions */