2 Copyright 2005-2007 Adobe Systems Incorporated
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).
8 See http://opensource.adobe.com/gil for most recent version including documentation.
10 // pixel_iterator.cpp : Tests GIL iterators
14 #include <boost/gil/planar_pixel_reference.hpp>
15 #include <boost/gil/rgb.hpp>
16 #include <boost/gil/pixel_iterator.hpp>
17 #include <boost/gil/pixel_iterator_adaptor.hpp>
18 #include <boost/gil/planar_pixel_iterator.hpp>
19 #include <boost/gil/bit_aligned_pixel_iterator.hpp>
20 #include <boost/gil/packed_pixel.hpp>
21 #include <boost/gil/iterator_from_2d.hpp>
22 #include <boost/gil/step_iterator.hpp>
23 #include <boost/gil/typedefs.hpp>
24 #include <boost/gil/color_convert.hpp>
25 #include <boost/gil/image_view_factory.hpp>
26 #include <boost/mpl/vector.hpp>
28 using namespace boost::gil
;
31 void test_pixel_iterator() {
32 boost::function_requires
<Point2DConcept
<point2
<int> > >();
34 boost::function_requires
<MutablePixelIteratorConcept
<bgr8_ptr_t
> >();
35 boost::function_requires
<MutablePixelIteratorConcept
<cmyk8_planar_ptr_t
> >();
36 boost::function_requires
<PixelIteratorConcept
<rgb8c_planar_step_ptr_t
> >();
37 boost::function_requires
<MutableStepIteratorConcept
<rgb8_step_ptr_t
> >();
39 boost::function_requires
<MutablePixelLocatorConcept
<rgb8_step_loc_t
> >();
40 boost::function_requires
<PixelLocatorConcept
<rgb8c_planar_step_loc_t
> >();
42 boost::function_requires
<MutableStepIteratorConcept
<cmyk8_planar_step_ptr_t
> >();
43 boost::function_requires
<StepIteratorConcept
<gray8c_step_ptr_t
> >();
45 boost::function_requires
<MutablePixelLocatorConcept
<memory_based_2d_locator
<rgb8_step_ptr_t
> > >();
47 typedef const bit_aligned_pixel_reference
<boost::uint8_t, boost::mpl::vector3_c
<int,1,2,1>, bgr_layout_t
, true> bgr121_ref_t
;
48 typedef bit_aligned_pixel_iterator
<bgr121_ref_t
> bgr121_ptr_t
;
50 boost::function_requires
<MutablePixelIteratorConcept
<bgr121_ptr_t
> >();
51 boost::function_requires
<PixelBasedConcept
<bgr121_ptr_t
> >();
52 boost::function_requires
<MemoryBasedIteratorConcept
<bgr121_ptr_t
> >();
53 boost::function_requires
<HasDynamicXStepTypeConcept
<bgr121_ptr_t
> >();
55 // TEST dynamic_step_t
56 BOOST_STATIC_ASSERT(( boost::is_same
<cmyk16_step_ptr_t
,dynamic_x_step_type
<cmyk16_step_ptr_t
>::type
>::value
));
57 BOOST_STATIC_ASSERT(( boost::is_same
<cmyk16_planar_step_ptr_t
,dynamic_x_step_type
<cmyk16_planar_ptr_t
>::type
>::value
));
59 BOOST_STATIC_ASSERT(( boost::is_same
<iterator_type
<bits8
,gray_layout_t
,false,false,false>::type
,gray8c_ptr_t
>::value
));
61 // TEST iterator_is_step
62 BOOST_STATIC_ASSERT(iterator_is_step
< cmyk16_step_ptr_t
>::value
);
63 BOOST_STATIC_ASSERT(iterator_is_step
< cmyk16_planar_step_ptr_t
>::value
);
64 BOOST_STATIC_ASSERT(!iterator_is_step
< cmyk16_planar_ptr_t
>::value
);
66 typedef color_convert_deref_fn
<rgb8c_ref_t
, gray8_pixel_t
> ccv_rgb_g_fn
;
67 typedef color_convert_deref_fn
<gray8c_ref_t
, rgb8_pixel_t
> ccv_g_rgb_fn
;
68 gil_function_requires
<PixelDereferenceAdaptorConcept
<ccv_rgb_g_fn
> >();
69 gil_function_requires
<PixelDereferenceAdaptorConcept
<deref_compose
<ccv_rgb_g_fn
,ccv_g_rgb_fn
> > >();
71 typedef dereference_iterator_adaptor
<rgb8_ptr_t
, ccv_rgb_g_fn
> rgb2gray_ptr
;
72 BOOST_STATIC_ASSERT(!iterator_is_step
< rgb2gray_ptr
>::value
);
74 typedef dynamic_x_step_type
<rgb2gray_ptr
>::type rgb2gray_step_ptr
;
75 BOOST_STATIC_ASSERT(( boost::is_same
< rgb2gray_step_ptr
, dereference_iterator_adaptor
<rgb8_step_ptr_t
, ccv_rgb_g_fn
> >::value
));
78 make_step_iterator(rgb2gray_ptr(),2);
80 typedef dereference_iterator_adaptor
<rgb8_step_ptr_t
, ccv_rgb_g_fn
> rgb2gray_step_ptr1
;
81 BOOST_STATIC_ASSERT(iterator_is_step
< rgb2gray_step_ptr1
>::value
);
82 BOOST_STATIC_ASSERT(( boost::is_same
< rgb2gray_step_ptr1
, dynamic_x_step_type
<rgb2gray_step_ptr1
>::type
>::value
));
84 typedef memory_based_step_iterator
<dereference_iterator_adaptor
<rgb8_ptr_t
, ccv_rgb_g_fn
> > rgb2gray_step_ptr2
;
85 BOOST_STATIC_ASSERT(iterator_is_step
< rgb2gray_step_ptr2
>::value
);
86 BOOST_STATIC_ASSERT(( boost::is_same
< rgb2gray_step_ptr2
, dynamic_x_step_type
<rgb2gray_step_ptr2
>::type
>::value
));
87 make_step_iterator(rgb2gray_step_ptr2(),2);
89 // bit_aligned iterators test
91 // Mutable reference to a BGR232 pixel
92 typedef const bit_aligned_pixel_reference
<boost::uint8_t, boost::mpl::vector3_c
<unsigned,2,3,2>, bgr_layout_t
, true> bgr232_ref_t
;
94 // A mutable iterator over BGR232 pixels
95 typedef bit_aligned_pixel_iterator
<bgr232_ref_t
> bgr232_ptr_t
;
97 // BGR232 pixel value. It is a packed_pixel of size 1 byte. (The last bit is unused)
98 typedef std::iterator_traits
<bgr232_ptr_t
>::value_type bgr232_pixel_t
;
99 BOOST_STATIC_ASSERT((sizeof(bgr232_pixel_t
)==1));
101 bgr232_pixel_t
red(0,0,3); // = 0RRGGGBB, = 01100000
103 // a buffer of 7 bytes fits exactly 8 BGR232 pixels.
104 unsigned char pix_buffer
[7];
105 std::fill(pix_buffer
,pix_buffer
+7,0);
106 bgr232_ptr_t
pix_it(&pix_buffer
[0],0); // start at bit 0 of the first pixel
107 for (int i
=0; i
<8; ++i
) {
112 // TODO: Make better tests. Use some code from below.
115 template <typename Pixel>
116 void invert_pixel1(Pixel& pix) {
120 template <typename T> inline void ignore_unused_variable_warning(const T&){}
122 void test_pixel_iterator() {
124 rgb8_pixel_t rgb8(1,2,3);
127 rgb8_ptr_t ptr1=&rgb8;
128 memunit_advance(ptr1, 3);
129 const rgb8_ptr_t ptr2=memunit_advanced(ptr1,10);
131 memunit_distance(ptr1,ptr2);
132 const rgb8_pixel_t& ref=memunit_advanced_ref(ptr1,10); ignore_unused_variable_warning(ref);
134 rgb8_planar_ptr_t planarPtr1(&rgb8);
135 rgb8_planar_ptr_t planarPtr2(&rgb8);
136 memunit_advance(planarPtr1,10);
137 memunit_distance(planarPtr1,planarPtr2);
138 rgb8_planar_ptr_t planarPtr3=memunit_advanced(planarPtr1,10);
140 // planarPtr2=&rgba8;
142 planar_pixel_reference<bits8&,rgb_t> pxl=*(planarPtr1+5);
143 rgb8_pixel_t pv2=pxl;
144 rgb8_pixel_t pv3=*(planarPtr1+5);
145 rgb8_pixel_t pv=planarPtr1[5];
147 assert(*(planarPtr1+5)==planarPtr1[5]);
149 rgb8_planar_ref_t planarRef=memunit_advanced_ref(planarPtr1,10);
151 rgb8_step_ptr_t stepIt(&rgb8,5);
153 rgb8_step_ptr_t stepIt2=stepIt+10;
156 rgb8_step_ptr_t stepIt3(&rgb8,5);
158 rgb8_pixel_t& ref1=stepIt3[5];
159 // bool v=boost::is_POD<iterator_traits<memory_based_step_iterator<rgb8_ptr_t> >::value_type>::value;
160 // v=boost::is_POD<rgb8_pixel_t>::value;
161 // v=boost::is_POD<int>::value;
163 rgb8_step_ptr_t rgb8StepIt(ptr1, 10);
164 rgb8_step_ptr_t rgb8StepIt2=rgb8StepIt;
165 rgb8StepIt=rgb8StepIt2;
167 rgb8_ref_t reff=*rgb8StepIt; ignore_unused_variable_warning(reff);
169 ptrdiff_t dst=rgb8StepIt2-rgb8StepIt; ignore_unused_variable_warning(dst);
172 rgb8_pixel_t val1=ref1;
173 rgb8_ptr_t ptr=&ref1;
175 invert_pixel1(*planarPtr1);
176 // invert_pixel1(*ptr);
177 rgb8c_planar_ptr_t r8cpp;
178 // invert_pixel1(*r8cpp);
180 rgb8_pixel_t& val21=stepIt3[5];
181 rgb8_pixel_t val22=val21;
183 rgb8_pixel_t val2=stepIt3[5];
184 rgb8_ptr_t ptr11=&(stepIt3[5]); ignore_unused_variable_warning(ptr11);
185 rgb8_ptr_t ptr3=&*(stepIt3+5); ignore_unused_variable_warning(ptr3);
187 rgb8_step_ptr_t stepIt4(ptr,5);
190 rgb8_step_ptr_t stepIt5;
191 if (stepIt4==stepIt5) {
192 int st=0;ignore_unused_variable_warning(st);
195 iterator_from_2d<rgb8_loc_t> pix_img_it(rgb8_loc_t(ptr, 20), 5);
198 rgb8_pixel_t& refr=*pix_img_it;
199 refr=rgb8_pixel_t(1,2,3);
200 *pix_img_it=rgb8_pixel_t(1,2,3);
201 pix_img_it[3]=rgb8_pixel_t(1,2,3);
202 *(pix_img_it+3)=rgb8_pixel_t(1,2,3);
204 iterator_from_2d<rgb8c_loc_t> pix_img_it_c(rgb8c_loc_t(rgb8c_ptr_t(ptr),20), 5);
207 // *pix_img_it_c=rgb8_pixel_t(1,2,3); // error: assigning though const iterator
208 typedef iterator_from_2d<rgb8_loc_t>::difference_type dif_t;
210 ptrdiff_t tdt=dt; ignore_unused_variable_warning(tdt);
214 // memory_based_step_iterator<rgb8_pixel_t> stepIt3Err=stepIt+10; // error: non-const from const iterator
216 memory_based_2d_locator<rgb8_step_ptr_t> xy_locator(ptr,27);
219 // memory_based_step_iterator<rgb8_pixel_t>& yit=xy_locator.y();
221 xy_locator+=point2<std::ptrdiff_t>(3,4);
222 // *xy_locator=(xy_locator(-1,0)+xy_locator(0,1))/2;
223 rgb8_pixel_t& rf=*xy_locator; ignore_unused_variable_warning(rf);
225 make_step_iterator(rgb8_ptr_t(),3);
226 make_step_iterator(rgb8_planar_ptr_t(),3);
227 make_step_iterator(rgb8_planar_step_ptr_t(),3);
229 // Test operator-> on planar ptrs
231 rgb8c_planar_ptr_t cp(&rgb8);
232 rgb8_planar_ptr_t p(&rgb8);
233 // get_color(p,red_t()) = get_color(cp,green_t()); // does not compile - cannot assign a non-const pointer to a const pointer. Otherwise you will be able to modify the value through it.
238 // dimensions to explore
240 // values, references, pointers
241 // color spaces (rgb,cmyk,gray)
242 // channel ordering (bgr vs rgb)
243 // planar vs interleaved
246 // typedef const iterator_traits<rgb8_ptr_t>::pointer RGB8ConstPtr;
247 typedef const rgb8_ptr_t RGB8ConstPtr;
248 typedef const rgb8_planar_ptr_t RGB8ConstPlanarPtr;
249 // typedef const iterator_traits<rgb8_planar_ptr_t>::pointer RGB8ConstPlanarPtr;
251 // constructing from values, references and other pointers
252 RGB8ConstPtr rgb8_const_ptr=NULL; ignore_unused_variable_warning(rgb8_const_ptr);
253 rgb8_ptr_t rgb8ptr=&rgb8;
256 rgb8=bgr8_pixel_t(30,20,10);
257 rgb8_planar_ptr_t rgb8_pptr=&rgb8;
261 RGB8ConstPlanarPtr rgb8_const_planar_ptr=&rgb8;
263 rgb8c_planar_ptr_t r8c=&rgb8;
269 // rgb8_const_planar_ptr=&rgb16p; // error: incompatible bit depth
271 // iterator_traits<CMYK8>::pointer cmyk8_ptr_t=&rgb8; // error: incompatible pointer type
273 RGB8ConstPtr rgb8_const_ptr_err=rgb8ptr; // const pointer from non-regular pointer
274 ignore_unused_variable_warning(rgb8_const_ptr_err);
275 // dereferencing pointers to obtain references
276 rgb8_ref_t rgb8ref_2=*rgb8ptr; ignore_unused_variable_warning(rgb8ref_2);
277 assert(rgb8ref_2==rgb8);
278 // RGB8Ref rgb8ref_2_err=*rgb8_const_planar_ptr; // error: non-const reference from const pointer
280 rgb8_planar_ref_t rgb8planarref_3=*rgb8_pptr; // planar reference from planar pointer
281 assert(rgb8planarref_3==rgb8);
282 // RGB8Ref rgb8ref_3=*rgb8_planar_ptr_t; // error: non-planar reference from planar pointer
285 const rgb8_pixel_t crgb8=rgb8;
289 memunit_advance(rgb8_pptr,3);
290 memunit_advance(rgb8_pptr,-3);
294 int main(int argc
, char* argv
[]) {
295 test_pixel_iterator();