1 | /* |
2 | Copyright 2005-2007 Adobe Systems Incorporated |
3 | |
4 | Use, modification and distribution are subject to the Boost Software License, |
5 | Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
6 | http://www.boost.org/LICENSE_1_0.txt). |
7 | |
8 | See http://opensource.adobe.com/gil for most recent version including documentation. |
9 | */ |
10 | // image_test.cpp : |
11 | // |
12 | |
13 | #ifdef _MSC_VER |
14 | //#pragma warning(disable : 4244) // conversion from 'gil::image<V,Alloc>::coord_t' to 'int', possible loss of data (visual studio compiler doesn't realize that the two types are the same) |
15 | #pragma warning(disable : 4503) // decorated name length exceeded, name was truncated |
16 | #endif |
17 | |
18 | #include <string> |
19 | #include <vector> |
20 | #include <ios> |
21 | #include <iostream> |
22 | #include <fstream> |
23 | #include <map> |
24 | #include <boost/lambda/lambda.hpp> |
25 | #include <boost/lambda/bind.hpp> |
26 | #include <boost/mpl/vector.hpp> |
27 | #include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp> |
28 | #include <boost/crc.hpp> |
29 | |
30 | using namespace boost::gil; |
31 | using namespace std; |
32 | using namespace boost; |
33 | |
34 | extern rgb8c_planar_view_t sample_view; |
35 | void error_if(bool condition); |
36 | |
37 | |
38 | // When BOOST_GIL_GENERATE_REFERENCE_DATA is defined, the reference data is generated and saved. |
39 | // When it is undefined, regression tests are checked against it |
40 | //#define BOOST_GIL_GENERATE_REFERENCE_DATA |
41 | |
42 | //////////////////////////////////////////////////// |
43 | /// |
44 | /// Some algorithms to use in testing |
45 | /// |
46 | //////////////////////////////////////////////////// |
47 | |
48 | template <typename GrayView, typename R> |
49 | void gray_image_hist(const GrayView& img_view, R& hist) { |
50 | // for_each_pixel(img_view,++lambda::var(hist)[lambda::_1]); |
51 | for (typename GrayView::iterator it=img_view.begin(); it!=img_view.end(); ++it) |
52 | ++hist[*it]; |
53 | } |
54 | |
55 | template <typename V, typename R> |
56 | void get_hist(const V& img_view, R& hist) { |
57 | gray_image_hist(color_converted_view<gray8_pixel_t>(img_view), hist); |
58 | } |
59 | |
60 | // testing custom color conversion |
61 | template <typename C1, typename C2> |
62 | struct my_color_converter_impl : public default_color_converter_impl<C1,C2> {}; |
63 | template <typename C1> |
64 | struct my_color_converter_impl<C1,gray_t> { |
65 | template <typename P1, typename P2> |
66 | void operator()(const P1& src, P2& dst) const { |
67 | default_color_converter_impl<C1,gray_t>()(src,dst); |
68 | get_color(dst,gray_color_t())=channel_invert(get_color(dst,gray_color_t())); |
69 | } |
70 | }; |
71 | |
72 | struct my_color_converter { |
73 | template <typename SrcP,typename DstP> |
74 | void operator()(const SrcP& src,DstP& dst) const { |
75 | typedef typename color_space_type<SrcP>::type src_cs_t; |
76 | typedef typename color_space_type<DstP>::type dst_cs_t; |
77 | my_color_converter_impl<src_cs_t,dst_cs_t>()(src,dst); |
78 | } |
79 | }; |
80 | |
81 | // Models a Unary Function |
82 | template <typename P> // Models PixelValueConcept |
83 | struct mandelbrot_fn { |
84 | typedef point2<std::ptrdiff_t> point_t; |
85 | |
86 | typedef mandelbrot_fn const_t; |
87 | typedef P value_type; |
88 | typedef value_type reference; |
89 | typedef value_type const_reference; |
90 | typedef point_t argument_type; |
91 | typedef reference result_type; |
92 | BOOST_STATIC_CONSTANT(bool, is_mutable=false); |
93 | |
94 | value_type _in_color,_out_color; |
95 | point_t _img_size; |
96 | static const int MAX_ITER=100; // max number of iterations |
97 | |
98 | mandelbrot_fn() {} |
99 | mandelbrot_fn(const point_t& sz, const value_type& in_color, const value_type& out_color) : _in_color(in_color), _out_color(out_color), _img_size(sz) {} |
100 | |
101 | result_type operator()(const point_t& p) const { |
102 | // normalize the coords to (-2..1, -1.5..1.5) |
103 | // (actually make y -1.0..2 so it is asymmetric, so we can verify some view factory methods) |
104 | double t=get_num_iter(p: point2<double>(p.x/(double)_img_size.x*3-2, p.y/(double)_img_size.y*3-1.0f));//1.5f)); |
105 | t=pow(x: t,y: 0.2); |
106 | |
107 | value_type ret; |
108 | for (int k=0; k<num_channels<P>::value; ++k) |
109 | ret[k]=(typename channel_type<value_type>::type)(_in_color[k]*t + _out_color[k]*(1-t)); |
110 | return ret; |
111 | } |
112 | |
113 | private: |
114 | double get_num_iter(const point2<double>& p) const { |
115 | point2<double> Z(0,0); |
116 | for (int i=0; i<MAX_ITER; ++i) { |
117 | Z = point2<double>(Z.x*Z.x - Z.y*Z.y + p.x, 2*Z.x*Z.y + p.y); |
118 | if (Z.x*Z.x + Z.y*Z.y > 4) |
119 | return i/(double)MAX_ITER; |
120 | } |
121 | return 0; |
122 | } |
123 | }; |
124 | |
125 | template <typename T> |
126 | void x_gradient(const T& src, const gray8s_view_t& dst) { |
127 | for (int y=0; y<src.height(); ++y) { |
128 | typename T::x_iterator src_it = src.row_begin(y); |
129 | gray8s_view_t::x_iterator dst_it = dst.row_begin(y); |
130 | |
131 | for (int x=1; x<src.width()-1; ++x) |
132 | dst_it[x] = (src_it[x+1] - src_it[x-1]) / 2; |
133 | } |
134 | } |
135 | |
136 | // A quick test whether a view is homogeneous |
137 | |
138 | template <typename Pixel> |
139 | struct pixel_is_homogeneous : public mpl::true_ {}; |
140 | |
141 | template <typename P, typename C, typename L> |
142 | struct pixel_is_homogeneous<packed_pixel<P,C,L> > : public mpl::false_ {}; |
143 | |
144 | template <typename View> |
145 | struct view_is_homogeneous : public pixel_is_homogeneous<typename View::value_type> {}; |
146 | |
147 | |
148 | //////////////////////////////////////////////////// |
149 | /// |
150 | /// Tests image view transformations and algorithms |
151 | /// |
152 | //////////////////////////////////////////////////// |
153 | class image_test { |
154 | public: |
155 | virtual void initialize() {} |
156 | virtual void finalize() {} |
157 | virtual ~image_test() {} |
158 | |
159 | void run(); |
160 | protected: |
161 | virtual void check_view_impl(const rgb8c_view_t& view, const string& name)=0; |
162 | template <typename View> |
163 | void check_view(const View& img_view, const string& name) { |
164 | rgb8_image_t rgb_img(img_view.dimensions()); |
165 | copy_and_convert_pixels(img_view,view(img&: rgb_img)); |
166 | check_view_impl(view: const_view(img: rgb_img), name); |
167 | } |
168 | private: |
169 | template <typename Img> void basic_test(const string& prefix); |
170 | template <typename View> void view_transformations_test(const View& img_view, const string& prefix); |
171 | template <typename View> void homogeneous_view_transformations_test(const View& img_view, const string& prefix, mpl::true_); |
172 | template <typename View> void homogeneous_view_transformations_test(const View& img_view, const string& prefix, mpl::false_) {} |
173 | template <typename View> void histogram_test(const View& img_view, const string& prefix); |
174 | void virtual_view_test(); |
175 | void packed_image_test(); |
176 | void dynamic_image_test(); |
177 | template <typename Img> void image_all_test(const string& prefix); |
178 | }; |
179 | |
180 | |
181 | // testing image iterators, clone, fill, locators, color convert |
182 | template <typename Img> |
183 | void image_test::basic_test(const string& prefix) { |
184 | typedef typename Img::view_t View; |
185 | |
186 | // make a 20x20 image |
187 | Img img(typename View::point_t(20,20)); |
188 | const View& img_view=view(img); |
189 | |
190 | // fill it with red |
191 | rgb8_pixel_t red8(255,0,0), green8(0,255,0), blue8(0,0,255), white8(255,255,255); |
192 | typename View::value_type red,green,blue,white; |
193 | color_convert(red8,red); |
194 | default_color_converter()(red8,red); |
195 | red=color_convert_deref_fn<rgb8_ref_t,typename Img::view_t::value_type>()(red8); |
196 | |
197 | color_convert(green8,green); |
198 | color_convert(blue8,blue); |
199 | color_convert(white8,white); |
200 | fill(img_view.begin(),img_view.end(),red); |
201 | |
202 | color_convert(red8,img_view[0]); |
203 | |
204 | // pointer to first pixel of second row |
205 | typename View::reference rt=img_view.at(0,0)[img_view.width()]; |
206 | typename View::x_iterator ptr=&rt; |
207 | typename View::reference rt2=*(img_view.at(0,0)+img_view.width()); |
208 | typename View::x_iterator ptr2=&rt2; |
209 | error_if(ptr!=ptr2); |
210 | error_if(img_view.x_at(0,0)+10!=10+img_view.x_at(0,0)); |
211 | |
212 | // draw a blue line along the diagonal |
213 | typename View::xy_locator loc=img_view.xy_at(0,img_view.height()-1); |
214 | for (int y=0; y<img_view.height(); ++y) { |
215 | *loc=blue; |
216 | ++loc.x(); |
217 | loc.y()--; |
218 | } |
219 | |
220 | // draw a green dotted line along the main diagonal with step of 3 |
221 | loc=img_view.xy_at(img_view.width()-1,img_view.height()-1); |
222 | while (loc.x()>=img_view.x_at(0,0)) { |
223 | *loc=green; |
224 | loc-=typename View::point_t(3,3); |
225 | } |
226 | |
227 | // Clone and make every red pixel white |
228 | Img imgWhite(img); |
229 | for (typename View::iterator it=view(imgWhite).end(); (it-1)!=view(imgWhite).begin(); --it) { |
230 | if (*(it-1)==red) |
231 | *(it-1)=white; |
232 | } |
233 | |
234 | check_view(img_view,prefix+"red_x" ); |
235 | check_view(view(imgWhite),prefix+"white_x" ); |
236 | } |
237 | |
238 | template <typename View> |
239 | void image_test::histogram_test(const View& img_view, const string& prefix) { |
240 | // vector<int> histogram(255,0); |
241 | // get_hist(cropped,histogram.begin()); |
242 | unsigned char histogram[256]; |
243 | fill(first: histogram,last: histogram+256,value: 0); |
244 | get_hist(img_view,histogram); |
245 | gray8c_view_t hist_view=interleaved_view(width: 256,height: 1,pixels: (const gray8_pixel_t*)histogram,rowsize_in_bytes: 256); |
246 | check_view(img_view: hist_view,name: prefix+"histogram" ); |
247 | } |
248 | |
249 | |
250 | template <typename View> |
251 | void image_test::view_transformations_test(const View& img_view, const string& prefix) { |
252 | check_view(img_view,prefix+"original" ); |
253 | |
254 | check_view(subimage_view(img_view, iround(img_view.dimensions()/4), iround(img_view.dimensions()/2)),prefix+"cropped" ); |
255 | check_view(color_converted_view<gray8_pixel_t>(img_view),prefix+"gray8" ); |
256 | check_view(color_converted_view<gray8_pixel_t>(img_view,my_color_converter()),prefix+"my_gray8" ); |
257 | check_view(transposed_view(img_view),prefix+"transpose" ); |
258 | check_view(rotated180_view(img_view),prefix+"rot180" ); |
259 | check_view(rotated90cw_view(img_view),prefix+"90cw" ); |
260 | check_view(rotated90ccw_view(img_view),prefix+"90ccw" ); |
261 | check_view(flipped_up_down_view(img_view),prefix+"flipped_ud" ); |
262 | check_view(flipped_left_right_view(img_view),prefix+"flipped_lr" ); |
263 | check_view(subsampled_view(img_view,typename View::point_t(2,1)),prefix+"subsampled" ); |
264 | check_view(kth_channel_view<0>(img_view),prefix+"0th_k_channel" ); |
265 | homogeneous_view_transformations_test(img_view, prefix, view_is_homogeneous<View>()); |
266 | } |
267 | |
268 | template <typename View> |
269 | void image_test::homogeneous_view_transformations_test(const View& img_view, const string& prefix, mpl::true_) { |
270 | check_view(nth_channel_view(img_view,0),prefix+"0th_n_channel" ); |
271 | } |
272 | |
273 | |
274 | void image_test::virtual_view_test() { |
275 | typedef mandelbrot_fn<rgb8_pixel_t> deref_t; |
276 | typedef deref_t::point_t point_t; |
277 | typedef virtual_2d_locator<deref_t,false> locator_t; |
278 | typedef image_view<locator_t> my_virt_view_t; |
279 | |
280 | boost::function_requires<PixelLocatorConcept<locator_t> >(); |
281 | gil_function_requires<StepIteratorConcept<locator_t::x_iterator> >(); |
282 | |
283 | point_t dims(200,200); |
284 | my_virt_view_t mandel(dims, locator_t(point_t(0,0), point_t(1,1), deref_t(dims, rgb8_pixel_t(255,0,255), rgb8_pixel_t(0,255,0)))); |
285 | |
286 | gray8s_image_t img(dims); |
287 | fill_pixels(img_view: view(img),val: 0); // our x_gradient algorithm doesn't change the first & last column, so make sure they are 0 |
288 | x_gradient(src: color_converted_view<gray8_pixel_t>(src: mandel), dst: view(img)); |
289 | check_view(img_view: color_converted_view<gray8_pixel_t>(src: const_view(img)), name: "mandelLuminosityGradient" ); |
290 | |
291 | view_transformations_test(img_view: mandel,prefix: "virtual_" ); |
292 | histogram_test(img_view: mandel,prefix: "virtual_" ); |
293 | } |
294 | |
295 | // Test alignment and packed images |
296 | void image_test::packed_image_test() { |
297 | typedef bit_aligned_image3_type<1,3,1, bgr_layout_t>::type bgr131_image_t; |
298 | typedef bgr131_image_t::value_type bgr131_pixel_t; |
299 | bgr131_pixel_t fill_val(1,3,1); |
300 | |
301 | bgr131_image_t bgr131_img(3,10); |
302 | fill_pixels(img_view: view(img&: bgr131_img), val: fill_val); |
303 | |
304 | bgr131_image_t bgr131a_img(3,10,1); |
305 | copy_pixels(src: const_view(img: bgr131_img), dst: view(img&: bgr131a_img)); |
306 | |
307 | bgr131_image_t bgr131b_img(3,10,4); |
308 | copy_pixels(src: const_view(img: bgr131_img), dst: view(img&: bgr131b_img)); |
309 | |
310 | error_if(condition: bgr131_img!=bgr131a_img || bgr131a_img!=bgr131b_img); |
311 | } |
312 | |
313 | void image_test::dynamic_image_test() { |
314 | typedef any_image<mpl::vector<gray8_image_t, bgr8_image_t, argb8_image_t, |
315 | rgb8_image_t, rgb8_planar_image_t> > any_image_t; |
316 | rgb8_planar_image_t img(sample_view.dimensions()); |
317 | copy_pixels(src: sample_view, dst: view(img)); |
318 | any_image_t any_img=any_image_t(img); |
319 | |
320 | check_view(img_view: view(anyImage&: any_img), name: "dynamic_" ); |
321 | check_view(img_view: flipped_left_right_view(src: view(anyImage&: any_img)), name: "dynamic_fliplr" ); |
322 | check_view(img_view: flipped_up_down_view(src: view(anyImage&: any_img)), name: "dynamic_flipud" ); |
323 | |
324 | any_image_t::view_t subimageView=subimage_view(src: view(anyImage&: any_img),xMin: 0,yMin: 0,width: 10,height: 15); |
325 | |
326 | check_view(img_view: subimageView, name: "dynamic_subimage" ); |
327 | check_view(img_view: subsampled_view(src: rotated180_view(src: view(anyImage&: any_img)), xStep: 2,yStep: 1), name: "dynamic_subimage_subsampled180rot" ); |
328 | } |
329 | |
330 | template <typename Img> |
331 | void image_test::image_all_test(const string& prefix) { |
332 | basic_test<Img>(prefix+"basic_" ); |
333 | |
334 | Img img; |
335 | img.recreate(sample_view.dimensions()); |
336 | copy_and_convert_pixels(sample_view,view(img)); |
337 | |
338 | view_transformations_test(view(img), prefix+"views_" ); |
339 | |
340 | histogram_test(const_view(img),prefix+"histogram_" ); |
341 | } |
342 | |
343 | void image_test::run() { |
344 | initialize(); |
345 | |
346 | image_all_test<bgr8_image_t>(prefix: "bgr8_" ); |
347 | image_all_test<rgb8_image_t>(prefix: "rgb8_" ); |
348 | image_all_test<rgb8_planar_image_t>(prefix: "planarrgb8_" ); |
349 | image_all_test<gray8_image_t>(prefix: "gray8_" ); |
350 | |
351 | typedef const bit_aligned_pixel_reference<boost::uint8_t, mpl::vector3_c<int,1,2,1>, bgr_layout_t, true> bgr121_ref_t; |
352 | typedef image<bgr121_ref_t,false> bgr121_image_t; |
353 | image_all_test<bgr121_image_t>(prefix: "bgr121_" ); |
354 | |
355 | // TODO: Remove? |
356 | view_transformations_test(img_view: subsampled_view(src: sample_view,step: point2<ptrdiff_t>(1,2)),prefix: "subsampled_" ); |
357 | view_transformations_test(img_view: color_converted_view<gray8_pixel_t>(src: sample_view),prefix: "color_converted_" ); |
358 | |
359 | virtual_view_test(); |
360 | packed_image_test(); |
361 | dynamic_image_test(); |
362 | |
363 | finalize(); |
364 | } |
365 | |
366 | |
367 | |
368 | //////////////////////////////////////////////////// |
369 | /// |
370 | /// Performs or generates image tests using checksums |
371 | /// |
372 | //////////////////////////////////////////////////// |
373 | |
374 | class checksum_image_mgr : public image_test { |
375 | protected: |
376 | typedef map<string,boost::crc_32_type::value_type> crc_map_t; |
377 | crc_map_t _crc_map; |
378 | }; |
379 | |
380 | //////////////////////////////////////////////////// |
381 | /// |
382 | /// Performs image tests by comparing image pixel checksums against a reference |
383 | /// |
384 | //////////////////////////////////////////////////// |
385 | |
386 | class checksum_image_test : public checksum_image_mgr { |
387 | public: |
388 | checksum_image_test(const char* filename) : _filename(filename) {} |
389 | private: |
390 | const char* _filename; |
391 | virtual void initialize(); |
392 | virtual void check_view_impl(const rgb8c_view_t& v, const string& name); |
393 | }; |
394 | |
395 | // Load the checksums from the reference file and create the start image |
396 | void checksum_image_test::initialize() { |
397 | string crc_name; |
398 | boost::crc_32_type::value_type crc_result; |
399 | fstream checksum_ref(_filename,ios::in); |
400 | while (true) { |
401 | checksum_ref >> crc_name >> std::hex >> crc_result; |
402 | if(checksum_ref.fail()) break; |
403 | _crc_map[crc_name]=crc_result; |
404 | } |
405 | checksum_ref.close(); |
406 | } |
407 | |
408 | // Create a checksum for the given view and compare it with the reference checksum. Throw exception if different |
409 | void checksum_image_test::check_view_impl(const rgb8c_view_t& img_view, const string& name) { |
410 | boost::crc_32_type checksum_acumulator; |
411 | checksum_acumulator.process_bytes(buffer: img_view.row_begin(y: 0),byte_count: img_view.size()*3); |
412 | |
413 | cerr << "Checking checksum for " << name << endl; |
414 | if (checksum_acumulator.checksum()!=_crc_map[name]) { |
415 | cerr << "Checksum error in " <<name<<"\n" ; |
416 | error_if(condition: true); |
417 | } |
418 | } |
419 | |
420 | //////////////////////////////////////////////////// |
421 | /// |
422 | /// Generates a set of reference checksums to compare against |
423 | /// |
424 | //////////////////////////////////////////////////// |
425 | |
426 | class checksum_image_generate : public checksum_image_mgr { |
427 | public: |
428 | checksum_image_generate(const char* filename) : _filename(filename) {} |
429 | private: |
430 | const char* _filename; |
431 | virtual void check_view_impl(const rgb8c_view_t& img_view, const string& name); |
432 | virtual void finalize(); |
433 | }; |
434 | |
435 | // Add the checksum of the given view to the map of checksums |
436 | void checksum_image_generate::check_view_impl(const rgb8c_view_t& img_view, const string& name) { |
437 | boost::crc_32_type result; |
438 | result.process_bytes(buffer: img_view.row_begin(y: 0),byte_count: img_view.size()*3); |
439 | cerr << "Generating checksum for " << name << endl; |
440 | _crc_map[name] = result.checksum(); |
441 | } |
442 | |
443 | // Save the checksums into the reference file |
444 | void checksum_image_generate::finalize() { |
445 | fstream checksum_ref(_filename,ios::out); |
446 | for (crc_map_t::const_iterator it=_crc_map.begin(); it!=_crc_map.end(); ++it) { |
447 | checksum_ref << it->first << " " << std::hex << it->second << "\r\n" ; |
448 | } |
449 | checksum_ref.close(); |
450 | } |
451 | |
452 | |
453 | //////////////////////////////////////////////////// |
454 | /// |
455 | /// Performs or generates image tests using image I/O |
456 | /// |
457 | //////////////////////////////////////////////////// |
458 | |
459 | extern const string in_dir; |
460 | extern const string out_dir; |
461 | extern const string ref_dir; |
462 | |
463 | const string in_dir="" ; // directory of source images |
464 | const string out_dir=in_dir+"image-out/" ; // directory where to write output |
465 | const string ref_dir=in_dir+"image-ref/" ; // reference directory to compare written with actual output |
466 | |
467 | #ifndef BOOST_GIL_NO_IO |
468 | |
469 | #include <boost/gil/extension/io/jpeg_io.hpp> |
470 | |
471 | class file_image_mgr : public image_test {}; |
472 | |
473 | class file_image_test : public file_image_mgr { |
474 | public: |
475 | file_image_test(const char*) {} |
476 | protected: |
477 | void check_view_impl(const boost::gil::rgb8c_view_t& img_view,const string& name) { |
478 | jpeg_write_view(out_dir+name+".jpg" ,img_view); |
479 | rgb8_image_t img1, img2; |
480 | jpeg_read_and_convert_image(out_dir+name+".jpg" ,img1); |
481 | cerr << "Testing " <<name<<"\n" ; |
482 | |
483 | jpeg_read_and_convert_image(ref_dir+name+".jpg" ,img2); |
484 | if (img1!=img2) { |
485 | cerr << "Error with " <<name<<"\n" ; |
486 | error_if(true); |
487 | } |
488 | } |
489 | }; |
490 | |
491 | class file_image_generate : public file_image_mgr { |
492 | public: |
493 | file_image_generate(const char*) {} |
494 | protected: |
495 | void check_view_impl(const boost::gil::rgb8c_view_t& img_view,const string& name) { |
496 | jpeg_write_view(ref_dir+name+".jpg" ,img_view); |
497 | cerr << "Writing " <<name<<"\n" ; |
498 | } |
499 | }; |
500 | #endif |
501 | |
502 | |
503 | |
504 | |
505 | |
506 | |
507 | |
508 | |
509 | void static_checks() { |
510 | gil_function_requires<ImageConcept<rgb8_image_t> >(); |
511 | |
512 | BOOST_STATIC_ASSERT(view_is_basic<rgb8_step_view_t>::value); |
513 | BOOST_STATIC_ASSERT(view_is_basic<cmyk8c_planar_step_view_t>::value); |
514 | BOOST_STATIC_ASSERT(view_is_basic<rgb8_planar_view_t>::value); |
515 | |
516 | BOOST_STATIC_ASSERT(view_is_step_in_x<rgb8_step_view_t>::value); |
517 | BOOST_STATIC_ASSERT(view_is_step_in_x<cmyk8c_planar_step_view_t>::value); |
518 | BOOST_STATIC_ASSERT(!view_is_step_in_x<rgb8_planar_view_t>::value); |
519 | |
520 | BOOST_STATIC_ASSERT(!is_planar<rgb8_step_view_t>::value); |
521 | BOOST_STATIC_ASSERT(is_planar<cmyk8c_planar_step_view_t>::value); |
522 | BOOST_STATIC_ASSERT(is_planar<rgb8_planar_view_t>::value); |
523 | |
524 | BOOST_STATIC_ASSERT(view_is_mutable<rgb8_step_view_t>::value); |
525 | BOOST_STATIC_ASSERT(!view_is_mutable<cmyk8c_planar_step_view_t>::value); |
526 | BOOST_STATIC_ASSERT(view_is_mutable<rgb8_planar_view_t>::value); |
527 | |
528 | BOOST_STATIC_ASSERT((boost::is_same<derived_view_type<cmyk8c_planar_step_view_t>::type, cmyk8c_planar_step_view_t>::value)); |
529 | BOOST_STATIC_ASSERT((boost::is_same<derived_view_type<cmyk8c_planar_step_view_t, bits16, rgb_layout_t>::type, rgb16c_planar_step_view_t>::value)); |
530 | BOOST_STATIC_ASSERT((boost::is_same<derived_view_type<cmyk8c_planar_step_view_t, use_default, rgb_layout_t, mpl::false_, use_default, mpl::false_>::type, rgb8c_step_view_t>::value)); |
531 | |
532 | // test view get raw data (mostly compile-time test) |
533 | { |
534 | rgb8_image_t rgb8(100,100); |
535 | unsigned char* data=interleaved_view_get_raw_data(view: view(img&: rgb8)); |
536 | const unsigned char* cdata=interleaved_view_get_raw_data(view: const_view(img: rgb8)); |
537 | error_if(condition: data!=cdata); |
538 | } |
539 | |
540 | { |
541 | rgb16s_planar_image_t rgb8(100,100); |
542 | short* data=planar_view_get_raw_data(view: view(img&: rgb8),plane_index: 1); |
543 | const short* cdata=planar_view_get_raw_data(view: const_view(img: rgb8),plane_index: 1); |
544 | error_if(condition: data!=cdata); |
545 | } |
546 | } |
547 | |
548 | #ifdef BOOST_GIL_NO_IO |
549 | typedef checksum_image_test image_test_t; |
550 | typedef checksum_image_generate image_generate_t; |
551 | #else |
552 | typedef file_image_test image_test_t; |
553 | typedef file_image_generate image_generate_t; |
554 | #endif |
555 | |
556 | #ifdef BOOST_GIL_GENERATE_REFERENCE_DATA |
557 | typedef image_generate_t image_mgr_t; |
558 | #else |
559 | typedef image_test_t image_mgr_t; |
560 | #endif |
561 | |
562 | |
563 | void test_image(const char* ref_checksum) { |
564 | image_mgr_t mgr(ref_checksum); |
565 | |
566 | mgr.run(); |
567 | static_checks(); |
568 | } |
569 | |
570 | int main(int argc, char* argv[]) { |
571 | |
572 | const char* local_name = "gil_reference_checksums.txt" ; |
573 | const char* name_from_status = "../libs/gil/test/gil_reference_checksums.txt" ; |
574 | |
575 | std::ifstream file_is_there(local_name); |
576 | if (file_is_there) { |
577 | test_image(ref_checksum: local_name); |
578 | } else { |
579 | std::ifstream file_is_there(name_from_status); |
580 | if (file_is_there) |
581 | test_image(ref_checksum: name_from_status); |
582 | else { |
583 | std::cerr << "Unable to open gil_reference_checksums.txt" <<std::endl; |
584 | return 1; |
585 | } |
586 | } |
587 | |
588 | return 0; |
589 | } |
590 | |
591 | |