Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / gil / test / legacy / pixel_iterator.cpp
1 //
2 // Copyright 2005-2007 Adobe Systems Incorporated
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 #ifdef _MSC_VER
9 #pragma warning(disable : 4244) // 'argument': conversion from 'int' to 'unsigned char', possible loss of data
10 #endif
11
12 #include <boost/gil.hpp>
13
14 #include <boost/assert.hpp>
15 #include <boost/mp11.hpp>
16
17 #include <exception>
18 #include <iostream>
19 #include <type_traits>
20 #include <vector>
21
22 using namespace boost::gil;
23 using namespace std;
24
25 void test_pixel_iterator()
26 {
27     boost::function_requires<Point2DConcept<point<int>>>();
28
29     boost::function_requires<MutablePixelIteratorConcept<bgr8_ptr_t> >();
30     boost::function_requires<MutablePixelIteratorConcept<cmyk8_planar_ptr_t> >();
31     boost::function_requires<PixelIteratorConcept<rgb8c_planar_step_ptr_t> >();
32     boost::function_requires<MutableStepIteratorConcept<rgb8_step_ptr_t> >();
33
34     boost::function_requires<MutablePixelLocatorConcept<rgb8_step_loc_t> >();
35     boost::function_requires<PixelLocatorConcept<rgb8c_planar_step_loc_t> >();
36
37     boost::function_requires<MutableStepIteratorConcept<cmyk8_planar_step_ptr_t> >();
38     boost::function_requires<StepIteratorConcept<gray8c_step_ptr_t> >();
39
40     boost::function_requires<MutablePixelLocatorConcept<memory_based_2d_locator<rgb8_step_ptr_t> > >();
41
42     using bgr121_ref_t = bit_aligned_pixel_reference
43         <
44             std::uint8_t,
45             boost::mp11::mp_list_c<int,1,2,1>,
46             bgr_layout_t,
47             true
48         > const;
49     using bgr121_ptr_t = bit_aligned_pixel_iterator<bgr121_ref_t>;
50
51     boost::function_requires<MutablePixelIteratorConcept<bgr121_ptr_t> >();
52     boost::function_requires<PixelBasedConcept<bgr121_ptr_t> >();
53     boost::function_requires<MemoryBasedIteratorConcept<bgr121_ptr_t> >();
54     boost::function_requires<HasDynamicXStepTypeConcept<bgr121_ptr_t> >();
55
56 // TEST dynamic_step_t
57     static_assert(std::is_same<cmyk16_step_ptr_t, dynamic_x_step_type<cmyk16_step_ptr_t>::type>::value, "");
58     static_assert(std::is_same<cmyk16_planar_step_ptr_t, dynamic_x_step_type<cmyk16_planar_ptr_t>::type>::value, "");
59
60     static_assert(std::is_same<iterator_type<uint8_t,gray_layout_t,false,false,false>::type,gray8c_ptr_t>::value, "");
61
62 // TEST iterator_is_step
63     static_assert(iterator_is_step<cmyk16_step_ptr_t>::value, "");
64     static_assert(iterator_is_step<cmyk16_planar_step_ptr_t>::value, "");
65     static_assert(!iterator_is_step<cmyk16_planar_ptr_t>::value, "");
66
67     using ccv_rgb_g_fn = color_convert_deref_fn<rgb8c_ref_t, gray8_pixel_t>;
68     using ccv_g_rgb_fn = color_convert_deref_fn<gray8c_ref_t, rgb8_pixel_t>;
69     gil_function_requires<PixelDereferenceAdaptorConcept<ccv_rgb_g_fn> >();
70     gil_function_requires<PixelDereferenceAdaptorConcept<deref_compose<ccv_rgb_g_fn,ccv_g_rgb_fn> > >();
71
72     using rgb2gray_ptr = dereference_iterator_adaptor<rgb8_ptr_t, ccv_rgb_g_fn>;
73     static_assert(!iterator_is_step<rgb2gray_ptr>::value, "");
74
75     using rgb2gray_step_ptr = dynamic_x_step_type<rgb2gray_ptr>::type;
76     static_assert(std::is_same<rgb2gray_step_ptr, dereference_iterator_adaptor<rgb8_step_ptr_t, ccv_rgb_g_fn>>::value, "");
77
78     make_step_iterator(rgb2gray_ptr(),2);
79
80     using rgb2gray_step_ptr1 = dereference_iterator_adaptor<rgb8_step_ptr_t, ccv_rgb_g_fn>;
81     static_assert(iterator_is_step<rgb2gray_step_ptr1>::value, "");
82     static_assert(std::is_same<rgb2gray_step_ptr1, dynamic_x_step_type<rgb2gray_step_ptr1>::type>::value, "");
83
84     using rgb2gray_step_ptr2 = memory_based_step_iterator<dereference_iterator_adaptor<rgb8_ptr_t, ccv_rgb_g_fn>>;
85     static_assert(iterator_is_step<rgb2gray_step_ptr2 >::value, "");
86     static_assert(std::is_same<rgb2gray_step_ptr2, dynamic_x_step_type<rgb2gray_step_ptr2>::type>::value, "");
87     make_step_iterator(rgb2gray_step_ptr2(),2);
88
89 // bit_aligned iterators test
90
91     // Mutable reference to a BGR232 pixel
92     using bgr232_ref_t = bit_aligned_pixel_reference
93         <
94             std::uint8_t,
95             boost::mp11::mp_list_c<unsigned, 2, 3, 2>,
96             bgr_layout_t,
97             true
98         > const;
99
100     // A mutable iterator over BGR232 pixels
101     using bgr232_ptr_t = bit_aligned_pixel_iterator<bgr232_ref_t>;
102
103     // BGR232 pixel value. It is a packed_pixel of size 1 byte. (The last bit is unused)
104     using bgr232_pixel_t = std::iterator_traits<bgr232_ptr_t>::value_type;
105     static_assert(sizeof(bgr232_pixel_t) == 1, "");
106
107     bgr232_pixel_t red(0,0,3); // = 0RRGGGBB, = 01100000
108
109     // a buffer of 7 bytes fits exactly 8 BGR232 pixels.
110     unsigned char pix_buffer[7];
111     std::fill(pix_buffer,pix_buffer+7,0);
112     bgr232_ptr_t pix_it(&pix_buffer[0],0);  // start at bit 0 of the first pixel
113     for (int i=0; i<8; ++i) {
114         *pix_it++ = red;
115     }
116
117         // test cross byte pixel values - meaning when a pixel value is stretched over two bytes
118         using gray3_image_t = bit_aligned_image1_type<3, gray_layout_t>::type;
119     using image_t = gray3_image_t;
120
121     using view_t = image_t::view_t;
122     using ref_t = view_t::reference;
123
124     using iterator_t = bit_aligned_pixel_iterator<ref_t>;
125
126         std::vector< unsigned char > buf( 4 );
127         // bit pattern is: 1011 0110  0110 1101  1101 1011
128         // each byte is read right to left
129         buf[0] = 182;
130     buf[1] = 109;
131     buf[2] = 219;
132
133     iterator_t it( &buf[0], 0 );
134
135     ref_t p1 = *it; it++;
136     ref_t p2 = *it; it++;
137     ref_t p3 = *it; it++;
138     ref_t p4 = *it; it++;
139     ref_t p5 = *it; it++;
140     ref_t p6 = *it; it++;
141     ref_t p7 = *it; it++;
142     ref_t p8 = *it; it++;
143
144     unsigned char v1 = get_color( p1, gray_color_t() );
145     unsigned char v2 = get_color( p2, gray_color_t() );
146     unsigned char v3 = get_color( p3, gray_color_t() );
147     unsigned char v4 = get_color( p4, gray_color_t() );
148     unsigned char v5 = get_color( p5, gray_color_t() );
149     unsigned char v6 = get_color( p6, gray_color_t() );
150     unsigned char v7 = get_color( p7, gray_color_t() );
151     unsigned char v8 = get_color( p8, gray_color_t() );
152
153         // all values should be 110b ( 6 );
154     BOOST_ASSERT(v1 == 6);
155     BOOST_ASSERT(v2 == 6);
156     BOOST_ASSERT(v3 == 6);
157     BOOST_ASSERT(v4 == 6);
158     BOOST_ASSERT(v5 == 6);
159     BOOST_ASSERT(v6 == 6);
160     BOOST_ASSERT(v7 == 6);
161     BOOST_ASSERT(v8 == 6);
162 }
163
164 // TODO: Make better tests. Use some code from below.
165
166 /*
167 template <typename Pixel>
168 void invert_pixel1(Pixel& pix) {
169     at_c<0>(pix)=0;
170 }
171
172 template <typename T> inline void ignore_unused_variable_warning(const T&){}
173
174 void test_pixel_iterator() {
175     rgb8_pixel_t rgb8(1,2,3);
176     rgba8_pixel_t rgba8;
177
178     rgb8_ptr_t ptr1=&rgb8;
179     memunit_advance(ptr1, 3);
180     const rgb8_ptr_t ptr2=memunit_advanced(ptr1,10);
181
182     memunit_distance(ptr1,ptr2);
183     const rgb8_pixel_t& ref=memunit_advanced_ref(ptr1,10); ignore_unused_variable_warning(ref);
184
185     rgb8_planar_ptr_t planarPtr1(&rgb8);
186     rgb8_planar_ptr_t planarPtr2(&rgb8);
187     memunit_advance(planarPtr1,10);
188     memunit_distance(planarPtr1,planarPtr2);
189     rgb8_planar_ptr_t planarPtr3=memunit_advanced(planarPtr1,10);
190
191 //    planarPtr2=&rgba8;
192
193     planar_pixel_reference<uint8_t&,rgb_t> pxl=*(planarPtr1+5);
194   rgb8_pixel_t pv2=pxl;
195   rgb8_pixel_t pv3=*(planarPtr1+5);
196      rgb8_pixel_t pv=planarPtr1[5];
197
198     assert(*(planarPtr1+5)==planarPtr1[5]);
199
200     rgb8_planar_ref_t planarRef=memunit_advanced_ref(planarPtr1,10);
201
202     rgb8_step_ptr_t stepIt(&rgb8,5);
203     stepIt++;
204     rgb8_step_ptr_t stepIt2=stepIt+10;
205     stepIt2=stepIt;
206
207     rgb8_step_ptr_t stepIt3(&rgb8,5);
208
209     rgb8_pixel_t& ref1=stepIt3[5];
210 //  bool v=std::is_pod<iterator_traits<memory_based_step_iterator<rgb8_ptr_t> >::value_type>::value;
211 //  v=std::is_pod<rgb8_pixel_t>::value;
212 //  v=std::is_pod<int>::value;
213
214     rgb8_step_ptr_t rgb8StepIt(ptr1, 10);
215     rgb8_step_ptr_t rgb8StepIt2=rgb8StepIt;
216     rgb8StepIt=rgb8StepIt2;
217     ++rgb8StepIt;
218     rgb8_ref_t reff=*rgb8StepIt; ignore_unused_variable_warning(reff);
219     rgb8StepIt+=10;
220     std::ptrdiff_t dst=rgb8StepIt2-rgb8StepIt; ignore_unused_variable_warning(dst);
221
222     rgb8_pixel_t val1=ref1;
223     rgb8_ptr_t ptr=&ref1;
224
225     invert_pixel1(*planarPtr1);
226 //    invert_pixel1(*ptr);
227     rgb8c_planar_ptr_t r8cpp;
228 //    invert_pixel1(*r8cpp);
229
230     rgb8_pixel_t& val21=stepIt3[5];
231     rgb8_pixel_t val22=val21;
232
233     rgb8_pixel_t val2=stepIt3[5];
234     rgb8_ptr_t ptr11=&(stepIt3[5]); ignore_unused_variable_warning(ptr11);
235     rgb8_ptr_t ptr3=&*(stepIt3+5); ignore_unused_variable_warning(ptr3);
236
237     rgb8_step_ptr_t stepIt4(ptr,5);
238     ++stepIt4;
239
240     rgb8_step_ptr_t stepIt5;
241     if (stepIt4==stepIt5) {
242         int st=0;ignore_unused_variable_warning(st);
243     }
244
245     iterator_from_2d<rgb8_loc_t> pix_img_it(rgb8_loc_t(ptr, 20), 5);
246     ++pix_img_it;
247     pix_img_it+=10;
248     rgb8_pixel_t& refr=*pix_img_it;
249     refr=rgb8_pixel_t(1,2,3);
250     *pix_img_it=rgb8_pixel_t(1,2,3);
251     pix_img_it[3]=rgb8_pixel_t(1,2,3);
252     *(pix_img_it+3)=rgb8_pixel_t(1,2,3);
253
254     iterator_from_2d<rgb8c_loc_t> pix_img_it_c(rgb8c_loc_t(rgb8c_ptr_t(ptr),20), 5);
255     ++pix_img_it_c;
256     pix_img_it_c+=10;
257     //  *pix_img_it_c=rgb8_pixel_t(1,2,3);        // error: assigning though const iterator
258     using dif_t = iterator_from_2d<rgb8_loc_t>::difference_type;
259     dif_t dt=0;
260     std::ptrdiff_t tdt=dt; ignore_unused_variable_warning(tdt);
261
262     //  memory_based_step_iterator<rgb8_pixel_t> stepIt3Err=stepIt+10;       // error: non-const from const iterator
263
264     memory_based_2d_locator<rgb8_step_ptr_t> xy_locator(ptr,27);
265
266     xy_locator.x()++;
267 //  memory_based_step_iterator<rgb8_pixel_t>& yit=xy_locator.y();
268     xy_locator.y()++;
269     xy_locator+=point<std::ptrdiff_t>(3,4);
270     // *xy_locator=(xy_locator(-1,0)+xy_locator(0,1))/2;
271     rgb8_pixel_t& rf=*xy_locator; ignore_unused_variable_warning(rf);
272
273     make_step_iterator(rgb8_ptr_t(),3);
274     make_step_iterator(rgb8_planar_ptr_t(),3);
275     make_step_iterator(rgb8_planar_step_ptr_t(),3);
276
277     // Test operator-> on planar ptrs
278     {
279     rgb8c_planar_ptr_t cp(&rgb8);
280     rgb8_planar_ptr_t p(&rgb8);
281 //    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.
282     }
283 //  xy_locator.y()++;
284
285     // dimensions to explore
286     //
287     // values, references, pointers
288     // color spaces (rgb,cmyk,gray)
289     // channel ordering (bgr vs rgb)
290     // planar vs interleaved
291
292 // Pixel POINTERS
293 //  using RGB8ConstPtr = iterator_traits<rgb8_ptr_t>::pointer const;
294     using RGB8ConstPtr = rgb8_ptr_t const;
295     using RGB8ConstPlanarPtr = rgb8_planar_ptr_t const;
296 //  using RGB8ConstPlanarPtr = iterator_traits<rgb8_planar_ptr_t>::pointer const;
297
298 // constructing from values, references and other pointers
299     RGB8ConstPtr rgb8_const_ptr=NULL; ignore_unused_variable_warning(rgb8_const_ptr);
300     rgb8_ptr_t rgb8ptr=&rgb8;
301
302     rgb8=bgr8_pixel_t(30,20,10);
303     rgb8_planar_ptr_t rgb8_pptr=&rgb8;
304     ++rgb8_pptr;
305     rgb8_pptr--;
306     rgb8_pptr[0]=rgb8;
307     RGB8ConstPlanarPtr rgb8_const_planar_ptr=&rgb8;
308
309     rgb8c_planar_ptr_t r8c=&rgb8;
310     r8c=&rgb8;
311
312     rgb8_pptr=&rgb8;
313
314     //  rgb8_const_planar_ptr=&rgb16p;                  // error: incompatible bit depth
315
316     //  iterator_traits<CMYK8>::pointer cmyk8_ptr_t=&rgb8;    // error: incompatible pointer type
317
318     RGB8ConstPtr rgb8_const_ptr_err=rgb8ptr;        // const pointer from non-regular pointer
319 ignore_unused_variable_warning(rgb8_const_ptr_err);
320 // dereferencing pointers to obtain references
321     rgb8_ref_t rgb8ref_2=*rgb8ptr; ignore_unused_variable_warning(rgb8ref_2);
322     assert(rgb8ref_2==rgb8);
323     //  RGB8Ref rgb8ref_2_err=*rgb8_const_planar_ptr;   // error: non-const reference from const pointer
324
325     rgb8_planar_ref_t rgb8planarref_3=*rgb8_pptr; // planar reference from planar pointer
326     assert(rgb8planarref_3==rgb8);
327     //  RGB8Ref rgb8ref_3=*rgb8_planar_ptr_t; // error: non-planar reference from planar pointer
328
329     const rgb8_pixel_t crgb8=rgb8;
330     *rgb8_pptr=rgb8;
331     *rgb8_pptr=crgb8;
332
333     memunit_advance(rgb8_pptr,3);
334     memunit_advance(rgb8_pptr,-3);
335 }
336 */
337
338 int main()
339 {
340     try
341     {
342         test_pixel_iterator();
343
344         return EXIT_SUCCESS;
345     }
346     catch (std::exception const& e)
347     {
348         std::cerr << e.what() << std::endl;
349         return EXIT_FAILURE;
350     }
351     catch (...)
352     {
353         return EXIT_FAILURE;
354     }
355 }