1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/image/image.cpp
3 // Purpose: Test wxImage
4 // Author: Francesco Montorsi
7 // Copyright: (c) 2009 Francesco Montorsi
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ----------------------------------------------------------------------------
13 // ----------------------------------------------------------------------------
27 #include "wx/mstream.h"
28 #include "wx/zstream.h"
29 #include "wx/wfstream.h"
36 { "horse.ico", wxBITMAP_TYPE_ICO
},
37 { "horse.xpm", wxBITMAP_TYPE_XPM
},
38 { "horse.png", wxBITMAP_TYPE_PNG
},
39 { "horse.ani", wxBITMAP_TYPE_ANI
},
40 { "horse.bmp", wxBITMAP_TYPE_BMP
},
41 { "horse.cur", wxBITMAP_TYPE_CUR
},
42 { "horse.gif", wxBITMAP_TYPE_GIF
},
43 { "horse.jpg", wxBITMAP_TYPE_JPEG
},
44 { "horse.pcx", wxBITMAP_TYPE_PCX
},
45 { "horse.pnm", wxBITMAP_TYPE_PNM
},
46 { "horse.tga", wxBITMAP_TYPE_TGA
},
47 { "horse.tif", wxBITMAP_TYPE_TIF
}
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 class ImageTestCase
: public CppUnit::TestCase
62 CPPUNIT_TEST_SUITE( ImageTestCase
);
63 CPPUNIT_TEST( LoadFromSocketStream
);
64 CPPUNIT_TEST( LoadFromZipStream
);
65 CPPUNIT_TEST( LoadFromFile
);
66 CPPUNIT_TEST( SizeImage
);
67 CPPUNIT_TEST_SUITE_END();
69 void LoadFromSocketStream();
70 void LoadFromZipStream();
74 DECLARE_NO_COPY_CLASS(ImageTestCase
)
77 CPPUNIT_TEST_SUITE_REGISTRATION( ImageTestCase
);
78 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ImageTestCase
, "ImageTestCase" );
80 ImageTestCase::ImageTestCase()
82 wxSocketBase::Initialize();
84 // the formats we're going to test:
85 wxImage::AddHandler(new wxICOHandler
);
86 wxImage::AddHandler(new wxXPMHandler
);
87 wxImage::AddHandler(new wxPNGHandler
);
88 wxImage::AddHandler(new wxANIHandler
);
89 wxImage::AddHandler(new wxBMPHandler
);
90 wxImage::AddHandler(new wxCURHandler
);
91 wxImage::AddHandler(new wxGIFHandler
);
92 wxImage::AddHandler(new wxJPEGHandler
);
93 wxImage::AddHandler(new wxPCXHandler
);
94 wxImage::AddHandler(new wxPNMHandler
);
95 wxImage::AddHandler(new wxTGAHandler
);
96 wxImage::AddHandler(new wxTIFFHandler
);
99 ImageTestCase::~ImageTestCase()
101 wxSocketBase::Shutdown();
104 void ImageTestCase::LoadFromFile()
107 for (unsigned int i
=0; i
<WXSIZEOF(g_testfiles
); i
++)
108 CPPUNIT_ASSERT(img
.LoadFile(g_testfiles
[i
].file
));
111 void ImageTestCase::LoadFromSocketStream()
113 // Skip this test when running on a build slave because it just keeps
114 // failing erratically and sends build failure notifications when it does.
116 // Of course, it would be even better to understand why does it fail but so
117 // far we didn't manage to do it so disable until someone can find the
119 if ( wxGetUserId().Lower().Matches("buildslave*") )
122 if (!IsNetworkAvailable()) // implemented in test.cpp
124 wxLogWarning("No network connectivity; skipping the "
125 "ImageTestCase::LoadFromSocketStream test unit.");
134 { "http://wxwidgets.org/logo9.jpg", wxBITMAP_TYPE_JPEG
},
135 { "http://wxwidgets.org/favicon.ico", wxBITMAP_TYPE_ICO
}
138 for (unsigned int i
=0; i
<WXSIZEOF(testData
); i
++)
140 wxURL
url(testData
[i
].url
);
141 CPPUNIT_ASSERT(url
.GetError() == wxURL_NOERR
);
143 wxInputStream
*in_stream
= url
.GetInputStream();
144 CPPUNIT_ASSERT(in_stream
&& in_stream
->IsOk());
148 // NOTE: it's important to inform wxImage about the type of the image being
149 // loaded otherwise it will try to autodetect the format, but that
150 // requires a seekable stream!
151 CPPUNIT_ASSERT(img
.LoadFile(*in_stream
, testData
[i
].type
));
157 void ImageTestCase::LoadFromZipStream()
159 for (unsigned int i
=0; i
<WXSIZEOF(g_testfiles
); i
++)
161 switch (g_testfiles
[i
].type
)
163 case wxBITMAP_TYPE_XPM
:
164 case wxBITMAP_TYPE_GIF
:
165 case wxBITMAP_TYPE_PCX
:
166 case wxBITMAP_TYPE_TGA
:
167 case wxBITMAP_TYPE_TIF
:
168 continue; // skip testing those wxImageHandlers which cannot
169 // load data from non-seekable streams
175 // compress the test file on the fly:
176 wxMemoryOutputStream memOut
;
178 wxFileInputStream
file(g_testfiles
[i
].file
);
179 CPPUNIT_ASSERT(file
.IsOk());
181 wxZlibOutputStream
compressFilter(memOut
, 5, wxZLIB_GZIP
);
182 CPPUNIT_ASSERT(compressFilter
.IsOk());
184 file
.Read(compressFilter
);
185 CPPUNIT_ASSERT(file
.GetLastError() == wxSTREAM_EOF
);
188 // now fetch the compressed memory to wxImage, decompressing it on the fly; this
189 // allows us to test loading images from non-seekable streams other than socket streams
190 wxMemoryInputStream
memIn(memOut
);
191 CPPUNIT_ASSERT(memIn
.IsOk());
192 wxZlibInputStream
decompressFilter(memIn
, wxZLIB_GZIP
);
193 CPPUNIT_ASSERT(decompressFilter
.IsOk());
197 // NOTE: it's important to inform wxImage about the type of the image being
198 // loaded otherwise it will try to autodetect the format, but that
199 // requires a seekable stream!
200 WX_ASSERT_MESSAGE(("Could not load file type '%d' after it was zipped", g_testfiles
[i
].type
),
201 img
.LoadFile(decompressFilter
, g_testfiles
[i
].type
));
205 void ImageTestCase::SizeImage()
207 // Test the wxImage::Size() function which takes a rectangle from source and
208 // places it in a new image at a given position. This test checks, if the
209 // correct areas are chosen, and clipping is done correctly.
212 static const char * xpm_orig
[] = {
213 "10 10 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
225 // the expected results for all tests:
226 static const char * xpm_l_t
[] = {
227 "10 10 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
239 static const char * xpm_t
[] = {
240 "10 10 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
252 static const char * xpm_r_t
[] = {
253 "10 10 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
265 static const char * xpm_l
[] = {
266 "10 10 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
278 static const char * xpm_r
[] = {
279 "10 10 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
291 static const char * xpm_l_b
[] = {
292 "10 10 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
304 static const char * xpm_b
[] = {
305 "10 10 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
317 static const char * xpm_r_b
[] = {
318 "10 10 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
330 static const char * xpm_sm
[] = {
331 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
341 static const char * xpm_gt
[] = {
342 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
356 static const char * xpm_gt_l_t
[] = {
357 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
371 static const char * xpm_gt_l
[] = {
372 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
386 static const char * xpm_gt_l_b
[] = {
387 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
401 static const char * xpm_gt_l_bb
[] = {
402 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
416 static const char * xpm_gt_t
[] = {
417 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
431 static const char * xpm_gt_b
[] = {
432 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
446 static const char * xpm_gt_bb
[] = {
447 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
461 static const char * xpm_gt_r_t
[] = {
462 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
476 static const char * xpm_gt_r
[] = {
477 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
491 static const char * xpm_gt_r_b
[] = {
492 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
506 static const char * xpm_gt_r_bb
[] = {
507 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
521 static const char * xpm_gt_rr_t
[] = {
522 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
536 static const char * xpm_gt_rr
[] = {
537 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
551 static const char * xpm_gt_rr_b
[] = {
552 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
566 static const char * xpm_gt_rr_bb
[] = {
567 "12 12 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
581 static const char * xpm_sm_ll_tt
[] = {
582 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
592 static const char * xpm_sm_ll_t
[] = {
593 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
603 static const char * xpm_sm_ll
[] = {
604 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
614 static const char * xpm_sm_ll_b
[] = {
615 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
625 static const char * xpm_sm_l_tt
[] = {
626 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
636 static const char * xpm_sm_l_t
[] = {
637 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
647 static const char * xpm_sm_l
[] = {
648 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
658 static const char * xpm_sm_l_b
[] = {
659 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
669 static const char * xpm_sm_tt
[] = {
670 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
680 static const char * xpm_sm_t
[] = {
681 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
691 static const char * xpm_sm_b
[] = {
692 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
702 static const char * xpm_sm_r_tt
[] = {
703 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
713 static const char * xpm_sm_r_t
[] = {
714 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
724 static const char * xpm_sm_r
[] = {
725 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
735 static const char * xpm_sm_r_b
[] = {
736 "8 8 5 1", "B c Black", " c #00ff00", ". c #0000ff", "+ c #7f7f7f", "@ c #FF0000",
747 // this table defines all tests
750 int w
, h
, dx
, dy
; // first parameters for Size()
751 const char **ref_xpm
; // expected result
754 { 10, 10, 0, 0, xpm_orig
}, // same size, same position
755 { 12, 12, 0, 0, xpm_gt
}, // target larger, same position
756 { 8, 8, 0, 0, xpm_sm
}, // target smaller, same position
757 { 10, 10, -2, -2, xpm_l_t
}, // same size, move left up
758 { 10, 10, -2, 0, xpm_l
}, // same size, move left
759 { 10, 10, -2, 2, xpm_l_b
}, // same size, move left down
760 { 10, 10, 0, -2, xpm_t
}, // same size, move up
761 { 10, 10, 0, 2, xpm_b
}, // same size, move down
762 { 10, 10, 2, -2, xpm_r_t
}, // same size, move right up
763 { 10, 10, 2, 0, xpm_r
}, // same size, move right
764 { 10, 10, 2, 2, xpm_r_b
}, // same size, move right down
765 { 12, 12, -2, -2, xpm_gt_l_t
}, // target larger, move left up
766 { 12, 12, -2, 0, xpm_gt_l
}, // target larger, move left
767 { 12, 12, -2, 2, xpm_gt_l_b
}, // target larger, move left down
768 { 12, 12, -2, 4, xpm_gt_l_bb
}, // target larger, move left down
769 { 12, 12, 0, -2, xpm_gt_t
}, // target larger, move up
770 { 12, 12, 0, 2, xpm_gt_b
}, // target larger, move down
771 { 12, 12, 0, 4, xpm_gt_bb
}, // target larger, move down
772 { 12, 12, 2, -2, xpm_gt_r_t
}, // target larger, move right up
773 { 12, 12, 2, 0, xpm_gt_r
}, // target larger, move right
774 { 12, 12, 2, 2, xpm_gt_r_b
}, // target larger, move right down
775 { 12, 12, 2, 4, xpm_gt_r_bb
}, // target larger, move right down
776 { 12, 12, 4, -2, xpm_gt_rr_t
}, // target larger, move right up
777 { 12, 12, 4, 0, xpm_gt_rr
}, // target larger, move right
778 { 12, 12, 4, 2, xpm_gt_rr_b
}, // target larger, move right down
779 { 12, 12, 4, 4, xpm_gt_rr_bb
}, // target larger, move right down
780 { 8, 8, -4, -4, xpm_sm_ll_tt
}, // target smaller, move left up
781 { 8, 8, -4, -2, xpm_sm_ll_t
}, // target smaller, move left up
782 { 8, 8, -4, 0, xpm_sm_ll
}, // target smaller, move left
783 { 8, 8, -4, 2, xpm_sm_ll_b
}, // target smaller, move left down
784 { 8, 8, -2, -4, xpm_sm_l_tt
}, // target smaller, move left up
785 { 8, 8, -2, -2, xpm_sm_l_t
}, // target smaller, move left up
786 { 8, 8, -2, 0, xpm_sm_l
}, // target smaller, move left
787 { 8, 8, -2, 2, xpm_sm_l_b
}, // target smaller, move left down
788 { 8, 8, 0, -4, xpm_sm_tt
}, // target smaller, move up
789 { 8, 8, 0, -2, xpm_sm_t
}, // target smaller, move up
790 { 8, 8, 0, 2, xpm_sm_b
}, // target smaller, move down
791 { 8, 8, 2, -4, xpm_sm_r_tt
}, // target smaller, move right up
792 { 8, 8, 2, -2, xpm_sm_r_t
}, // target smaller, move right up
793 { 8, 8, 2, 0, xpm_sm_r
}, // target smaller, move right
794 { 8, 8, 2, 2, xpm_sm_r_b
}, // target smaller, move right down
797 const wxImage
src_img(xpm_orig
);
798 for ( unsigned i
= 0; i
< WXSIZEOF(sizeTestData
); i
++ )
800 SizeTestData
& st
= sizeTestData
[i
];
802 actual(src_img
.Size(wxSize(st
.w
, st
.h
), wxPoint(st
.dx
, st
.dy
), 0, 0, 0)),
803 expected(st
.ref_xpm
);
805 // to check results with an image viewer uncomment this:
806 //actual.SaveFile(wxString::Format("imagetest-%02d-actual.png", i), wxBITMAP_TYPE_PNG);
807 //expected.SaveFile(wxString::Format("imagetest-%02d-exp.png", i), wxBITMAP_TYPE_PNG);
809 CPPUNIT_ASSERT_EQUAL( actual
.GetSize().x
, expected
.GetSize().x
);
810 CPPUNIT_ASSERT_EQUAL( actual
.GetSize().y
, expected
.GetSize().y
);
812 const unsigned data_len
= 3 * expected
.GetHeight() * expected
.GetWidth();
816 ("Resize test #%u: (%d, %d), (%d, %d)", i
, st
.w
, st
.h
, st
.dx
, st
.dy
),
817 memcmp(actual
.GetData(), expected
.GetData(), data_len
) == 0
824 TODO: add lots of more tests to wxImage functions