SLIP  1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
border_treatment.hpp
Go to the documentation of this file.
1 /*
2  * Copyright(c):
3  * Signal Image and Communications (SIC) Department
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * - University of Poitiers, France http://www.univ-poitiers.fr
6  * - XLIM Institute UMR CNRS 7252 http://www.xlim.fr/
7  *
8  * and
9  *
10  * D2 Fluid, Thermic and Combustion
11  * - University of Poitiers, France http://www.univ-poitiers.fr
12  * - PPRIME Institute - UPR CNRS 3346 http://www.pprime.fr
13  * - ISAE-ENSMA http://www.ensma.fr
14  *
15  * Contributor(s):
16  * The SLIP team,
17  * Benoit Tremblais <tremblais_AT_sic.univ-poitiers.fr>,
18  * Laurent David <laurent.david_AT_lea.univ-poitiers.fr>,
19  * Ludovic Chatellier <ludovic.chatellier_AT_univ-poitiers.fr>,
20  * Lionel Thomas <lionel.thomas_AT_univ-poitiers.fr>,
21  * Denis Arrivault <arrivault_AT_sic.univ-poitiers.fr>,
22  * Julien Dombre <julien.dombre_AT_univ-poitiers.fr>.
23  *
24  * Description:
25  * The Simple Library of Image Processing (SLIP) is a new image processing
26  * library. It is written in the C++ language following as much as possible
27  * the ISO/ANSI C++ standard. It is consequently compatible with any system
28  * satisfying the ANSI C++ complience. It works on different Unix , Linux ,
29  * Mircrosoft Windows and Mac OS X plateforms. SLIP is a research library that
30  * was created by the Signal, Image and Communications (SIC) departement of
31  * the XLIM, UMR 7252 CNRS Institute in collaboration with the Fluids, Thermic
32  * and Combustion departement of the P', UPR 3346 CNRS Institute of the
33  * University of Poitiers.
34  *
35  * The SLIP Library source code has been registered to the APP (French Agency
36  * for the Protection of Programs) by the University of Poitiers and CNRS,
37  * under registration number IDDN.FR.001.300034.000.S.P.2010.000.21000.
38 
39  * http://www.sic.sp2mi.univ-poitiers.fr/slip/
40  *
41  * This software is governed by the CeCILL-C license under French law and
42  * abiding by the rules of distribution of free software. You can use,
43  * modify and/ or redistribute the software under the terms of the CeCILL-C
44  * license as circulated by CEA, CNRS and INRIA at the following URL
45  * http://www.cecill.info.
46  * As a counterpart to the access to the source code and rights to copy,
47  * modify and redistribute granted by the license, users are provided only
48  * with a limited warranty and the software's author, the holder of the
49  * economic rights, and the successive licensors have only limited
50  * liability.
51  *
52  * In this respect, the user's attention is drawn to the risks associated
53  * with loading, using, modifying and/or developing or reproducing the
54  * software by the user in light of its specific status of free software,
55  * that may mean that it is complicated to manipulate, and that also
56  * therefore means that it is reserved for developers and experienced
57  * professionals having in-depth computer knowledge. Users are therefore
58  * encouraged to load and test the software's suitability as regards their
59  * requirements in conditions enabling the security of their systems and/or
60  * data to be ensured and, more generally, to use and operate it in the
61  * same conditions as regards security.
62  *
63  * The fact that you are presently reading this means that you have had
64  * knowledge of the CeCILL-C license and that you accept its terms.
65  */
66 
67 
74 #ifndef SLIP_BORDER_TREATMENT_HPP
75 #define SLIP_BORDER_TREATMENT_HPP
76 
77 
78 #include "iterator_types.hpp"
79 #include <algorithm>
80 #include <iterator>
81 namespace slip
82 {
83 
118 {
125 };
126 
127 
128  //
129  //fill border
130  //
131  //
132 template<typename>
133 struct __fill_border
134 {
135  template <typename _II>
136  static void
137  fill_border(_II first, _II last,
138  const typename std::iterator_traits<_II>::value_type& value,
139  const std::size_t size)
140  {}
141 };
142 
143 template<>
144 struct __fill_border<std::random_access_iterator_tag>
145 {
146  template <typename _II>
147  static void
148  fill_border(_II first, _II last,
149  const typename std::iterator_traits<_II>::value_type& value,
150  const std::size_t size)
151  {
152  typedef typename std::iterator_traits<_II>::value_type value_type;
153  std::fill_n(first,size,value);
154  std::fill_n(std::reverse_iterator<_II>(last),
155  size,value);
156  }
157 };
158 
159 
160 
161 
162 template<>
163 struct __fill_border<std::random_access_iterator2d_tag>
164 {
165  template <typename _II>
166  static void
167  fill_border(_II first, _II last,
168  const typename std::iterator_traits<_II>::value_type& value,
169  const std::size_t size)
170  {
171  typedef typename std::iterator_traits<_II>::value_type value_type;
172  typedef typename std::iterator_traits<_II>::difference_type _Difference;
173 
174  _Difference size_nd = last - first;
175  std::size_t rows = std::size_t(size_nd[0]);
176  std::size_t cols = std::size_t(size_nd[1]);
177 
178  for(std::size_t i = 0; i < rows;++i)
179  {
180  __fill_border<std::random_access_iterator_tag>::fill_border(first.row_begin(i),first.row_end(i),value,size);
181  }
182 
183  for(std::size_t j = 0; j < cols;++j)
184  {
185  __fill_border<std::random_access_iterator_tag>::fill_border(first.col_begin(j),first.col_end(j),value,size);
186  }
187 
188  for(std::size_t i = 0; i < size;++i)
189  {
190  __fill_border<std::random_access_iterator_tag>::fill_border(first.row_begin(i),first.row_end(i),value,size);
191  __fill_border<std::random_access_iterator_tag>::fill_border(first.row_begin(rows - size + i),first.row_end(rows - size + i),value,size);
192  }
193  }
194 };
195 template<>
196 struct __fill_border<std::random_access_iterator3d_tag>
197 {
198  template <typename _II>
199  static void
200  fill_border(_II first, _II last,
201  const typename std::iterator_traits<_II>::value_type& value,
202  const std::size_t size)
203  {
204  typedef typename std::iterator_traits<_II>::value_type value_type;
205  typedef typename std::iterator_traits<_II>::difference_type _Difference;
206 
207  _Difference size_nd = last - first;
208  std::size_t slices = std::size_t(size_nd[0]);
209  std::size_t rows = std::size_t(size_nd[1]);
210  std::size_t cols = std::size_t(size_nd[2]);
211 
212  for(std::size_t k = 0; k < slices;++k)
213  {
214  for(std::size_t i = 0; i < rows;++i)
215  {
216  __fill_border<std::random_access_iterator_tag>::fill_border(first.row_begin(k,i),first.row_end(k,i),value,size);
217  }
218  }
219 
220  for(std::size_t k = 0; k < slices; ++k)
221  {
222  for(std::size_t j = 0; j < cols;++j)
223  {
224  __fill_border<std::random_access_iterator_tag>::fill_border(first.col_begin(k,j),first.col_end(k,j),value,size);
225  }
226  }
227 
228  for(std::size_t i = 0; i < rows;++i)
229  {
230  for(std::size_t j = 0; j < cols;++j)
231  {
232  __fill_border<std::random_access_iterator_tag>::fill_border(first.slice_begin(i,j),first.slice_end(i,j),value,size);
233  }
234  }
235 
236  for(std::size_t k = 0; k < size; ++k)
237  {
238  for(std::size_t i = 0; i < rows;++i)
239  {
240  __fill_border<std::random_access_iterator_tag>::fill_border(first.row_begin(k,i),first.row_end(k,i),value,size);
241  __fill_border<std::random_access_iterator_tag>::fill_border(first.row_begin(k+slices-size,i),first.row_end(k+slices-size,i),value,size);
242  }
243  for(std::size_t j = 0; j < cols;++j)
244  {
245  __fill_border<std::random_access_iterator_tag>::fill_border(first.col_begin(k,j),first.col_end(k,j),value,size);
246  __fill_border<std::random_access_iterator_tag>::fill_border(first.col_begin(k+slices-size,j),first.col_end(k+slices-size,j),value,size);
247 
248  }
249 
250  }
251 
252 
253  for(std::size_t k = 0; k < slices; ++k)
254  {
255  for(std::size_t i = 0; i < size;++i)
256  {
257  __fill_border<std::random_access_iterator_tag>::fill_border(first.row_begin(k,i),first.row_end(k,i),value,size);
258  __fill_border<std::random_access_iterator_tag>::fill_border(first.row_begin(k, i + rows - size),first.row_end(k,i + rows - size),value,size);
259  }
260 
261  }
262  }
263 };
264 
265 
266 
275 template<>
276 struct __fill_border<std::random_access_iterator4d_tag>
277 {
278  template <typename _II>
279  static void
280  fill_border(_II first, _II last,
281  const typename std::iterator_traits<_II>::value_type& value,
282  const std::size_t size)
283  {
284  typedef typename std::iterator_traits<_II>::value_type value_type;
285  typedef typename std::iterator_traits<_II>::difference_type _Difference;
286 
287  _Difference size_nd = last - first;
288  std::size_t slabs = std::size_t(size_nd[0]);
289  std::size_t slices = std::size_t(size_nd[1]);
290  std::size_t rows = std::size_t(size_nd[2]);
291  std::size_t cols = std::size_t(size_nd[3]);
292 
293  for(std::size_t t = 0; t < slabs;++t)
294  {
295  for(std::size_t k = 0; k < slices;++k)
296  {
297  for(std::size_t i = 0; i < rows;++i)
298  {
300  first.row_end(t,k,i),value,size);
301  }
302  }
303  }
304 
305  for(std::size_t t = 0; t < slabs;++t)
306  {
307  for(std::size_t k = 0; k < slices; ++k)
308  {
309  for(std::size_t j = 0; j < cols;++j)
310  {
312  first.col_end(t,k,j),value,size);
313  }
314  }
315  }
316 
317  for(std::size_t t = 0; t < slabs;++t)
318  {
319  for(std::size_t i = 0; i < rows;++i)
320  {
321  for(std::size_t j = 0; j < cols;++j)
322  {
324  first.slice_end(t,i,j),value,size);
325  }
326  }
327  }
328 
329  for(std::size_t k = 0; k < slices;++k)
330  {
331  for(std::size_t i = 0; i < rows;++i)
332  {
333  for(std::size_t j = 0; j < cols;++j)
334  {
336  first.slab_end(k,i,j),value,size);
337  }
338  }
339  }
340  }
341 };
342 
343 
373 struct FillBorder
374 {
380  size_(1)
381  {}
385  FillBorder(const std::size_t size):
386  size_(size)
387  {}
388 
396  template<typename _II>
397  void operator() (_II first, _II last,
398  const typename std::iterator_traits<_II>::value_type& value =
399  typename std::iterator_traits<_II>::value_type())
400  {
401  typedef typename std::iterator_traits<_II>::iterator_category _Category;
403  }
404 
405  std::size_t size_;
406 
407 };
408 
439  template <typename _II>
440  void fill_border(_II first,_II last,
441  std::size_t b_size = 1,
442  const typename std::iterator_traits<_II>::value_type& value =
443  typename std::iterator_traits<_II>::value_type())
444  {
445  assert((last-first) >= 2*b_size);
446  typedef typename std::iterator_traits<_II>::iterator_category _Category;
447  __fill_border<_Category>::fill_border(first,last,value,b_size);
448  }
449 
450 //
451 // update border
452 //
453 //
454 template<typename>
455 struct __update_border
456 {
457  template <typename _II>
458  static void
459  update_border(_II first, _II last,
460  const slip::BORDER_TREATMENT border,
461  const std::size_t size = 1)
462  {}
463 };
464 
465 template<>
466 struct __update_border<std::random_access_iterator_tag>
467 {
468  template <typename _II>
469  static void
470  update_border(_II first, _II last,
471  const slip::BORDER_TREATMENT border,
472  const std::size_t size = 1)
473  {
474  typedef typename std::iterator_traits<_II>::value_type value_type;
475 
476  switch(border)
477  {
478  case slip::BORDER_TREATMENT_AVOID: break;
480  {
481  std::fill_n(first,size,value_type());
482  std::fill_n(std::reverse_iterator<_II>(last),
483  size,value_type());
484  }
485  break;
487  {
488  std::copy(first+size,first+(size+size),std::reverse_iterator<_II>(first+size));
489  std::copy(last-(size+size),
490  last - size,
491  std::reverse_iterator<_II>(last));
492  }
493  break;
495  {
496  std::copy(first+size,first+(size+size),last - size);
497  std::copy(std::reverse_iterator<_II>(last-size),
498  std::reverse_iterator<_II>(last-(size + size)),
499  std::reverse_iterator<_II>(first+size));
500 
501  }
502  break;
504  {
505  std::copy(first+size,first+(size+size),std::reverse_iterator<_II>(first+size));
506  std::copy(last-(size+size),
507  last - size,
508  std::reverse_iterator<_II>(last));
509  }
510  break;
512  {
513  value_type left = value_type(*(first + size));
514  value_type right = value_type(*(last - size - 1));
515  std::fill_n(first,size,left);
516  std::fill_n(std::reverse_iterator<_II>(last),
517  size,right);
518  }
519  break;
520  default:
521  {
522  std::fill_n(first,size,value_type());
523  std::fill_n(std::reverse_iterator<_II>(last-size),
524  size,value_type());
525  }
526  };
527  }
528 };
529 
530 
531 
532 
533 template<>
534 struct __update_border<std::random_access_iterator2d_tag>
535 {
536  template <typename _II>
537  static void
538  update_border(_II first, _II last,
539  const slip::BORDER_TREATMENT border,
540  const std::size_t size = 1)
541  {
542  typedef typename std::iterator_traits<_II>::value_type value_type;
543  typedef typename std::iterator_traits<_II>::difference_type _Difference;
544 
545  _Difference size_nd = last - first;
546  std::size_t rows = std::size_t(size_nd[0]);
547  std::size_t cols = std::size_t(size_nd[1]);
548 
549  for(std::size_t i = 0; i < rows;++i)
550  {
551  __update_border<std::random_access_iterator_tag>::update_border(first.row_begin(i),first.row_end(i),border,size);
552  }
553 
554  for(std::size_t j = 0; j < cols;++j)
555  {
556  __update_border<std::random_access_iterator_tag>::update_border(first.col_begin(j),first.col_end(j),border,size);
557  }
558 
559  for(std::size_t i = 0; i < size;++i)
560  {
561  __update_border<std::random_access_iterator_tag>::update_border(first.row_begin(i),first.row_end(i),border,size);
562  __update_border<std::random_access_iterator_tag>::update_border(first.row_begin(rows - size + i),first.row_end(rows - size + i),border,size);
563  }
564  }
565 };
566 template<>
567 struct __update_border<std::random_access_iterator3d_tag>
568 {
569  template <typename _II>
570  static void
571  update_border(_II first, _II last,
572  const slip::BORDER_TREATMENT border,
573  const std::size_t size = 1)
574  {
575  typedef typename std::iterator_traits<_II>::value_type value_type;
576  typedef typename std::iterator_traits<_II>::difference_type _Difference;
577 
578  _Difference size_nd = last - first;
579  std::size_t slices = std::size_t(size_nd[0]);
580  std::size_t rows = std::size_t(size_nd[1]);
581  std::size_t cols = std::size_t(size_nd[2]);
582 
583  for(std::size_t k = 0; k < slices;++k)
584  {
585  for(std::size_t i = 0; i < rows;++i)
586  {
587  __update_border<std::random_access_iterator_tag>::update_border(first.row_begin(k,i),first.row_end(k,i),border,size);
588  }
589  }
590 
591  for(std::size_t k = 0; k < slices; ++k)
592  {
593  for(std::size_t j = 0; j < cols;++j)
594  {
595  __update_border<std::random_access_iterator_tag>::update_border(first.col_begin(k,j),first.col_end(k,j),border,size);
596  }
597  }
598 
599  for(std::size_t i = 0; i < rows;++i)
600  {
601  for(std::size_t j = 0; j < cols;++j)
602  {
603  __update_border<std::random_access_iterator_tag>::update_border(first.slice_begin(i,j),first.slice_end(i,j),border,size);
604  }
605  }
606 
607  for(std::size_t k = 0; k < size; ++k)
608  {
609  for(std::size_t i = 0; i < rows;++i)
610  {
611  __update_border<std::random_access_iterator_tag>::update_border(first.row_begin(k,i),first.row_end(k,i),border,size);
612  __update_border<std::random_access_iterator_tag>::update_border(first.row_begin(k+slices-size,i),first.row_end(k+slices-size,i),border,size);
613  }
614  for(std::size_t j = 0; j < cols;++j)
615  {
616  __update_border<std::random_access_iterator_tag>::update_border(first.col_begin(k,j),first.col_end(k,j),border,size);
617  __update_border<std::random_access_iterator_tag>::update_border(first.col_begin(k+slices-size,j),first.col_end(k+slices-size,j),border,size);
618 
619  }
620 
621  }
622 
623 
624  for(std::size_t k = 0; k < slices; ++k)
625  {
626  for(std::size_t i = 0; i < size;++i)
627  {
628  __update_border<std::random_access_iterator_tag>::update_border(first.row_begin(k,i),first.row_end(k,i),border,size);
629  __update_border<std::random_access_iterator_tag>::update_border(first.row_begin(k, i + rows - size),first.row_end(k,i + rows - size),border,size);
630  }
631 
632  }
633  }
634 };
635 
644 template<>
645 struct __update_border<std::random_access_iterator4d_tag>
646 {
647  template <typename _II>
648  static void
649  update_border(_II first, _II last,
650  const slip::BORDER_TREATMENT border,
651  const std::size_t size = 1)
652  {
653  typedef typename std::iterator_traits<_II>::value_type value_type;
654  typedef typename std::iterator_traits<_II>::difference_type _Difference;
655 
656  _Difference size_nd = last - first;
657  std::size_t slabs = std::size_t(size_nd[0]);
658  std::size_t slices = std::size_t(size_nd[1]);
659  std::size_t rows = std::size_t(size_nd[2]);
660  std::size_t cols = std::size_t(size_nd[3]);
661 
662  for(std::size_t t = 0; t < slabs;++t)
663  {
664  for(std::size_t k = 0; k < slices;++k)
665  {
666  for(std::size_t i = 0; i < rows;++i)
667  {
669  first.row_end(t,k,i),border,size);
670  }
671  }
672  }
673 
674  for(std::size_t t = 0; t < slabs;++t)
675  {
676  for(std::size_t k = 0; k < slices; ++k)
677  {
678  for(std::size_t j = 0; j < cols;++j)
679  {
681  first.col_end(t,k,j),border,size);
682  }
683  }
684  }
685 
686  for(std::size_t t = 0; t < slabs;++t)
687  {
688  for(std::size_t i = 0; i < rows;++i)
689  {
690  for(std::size_t j = 0; j < cols;++j)
691  {
693  first.slice_end(t,i,j),border,size);
694  }
695  }
696  }
697 
698  for(std::size_t k = 0; k < slices;++k)
699  {
700  for(std::size_t i = 0; i < rows;++i)
701  {
702  for(std::size_t j = 0; j < cols;++j)
703  {
705  first.slab_end(k,i,j),border,size);
706  }
707  }
708  }
709  }
710 };
711 
742 { UpdateBorder(const slip::BORDER_TREATMENT border,const std::size_t size = 1):
747  border_(border),size_(size)
748  {}
749 
757  template<typename _II>
758  void operator() (_II first, _II last)
759  {
760  typedef typename std::iterator_traits<_II>::iterator_category _Category;
762  }
763 
765  std::size_t size_;
766 
767 };
768 
769 
801 template <typename _II>
802 void update_border(_II first, _II last,
803  const slip::BORDER_TREATMENT border,
804  const std::size_t b_size = 1)
805 {
806  typedef typename std::iterator_traits<_II>::iterator_category _Category;
807  return __update_border<_Category>::update_border(first,last,border,b_size);
808 }
809 
810 
811 
812 template<typename>
813 struct __add_border
814 {
815  template <typename _II, typename _OI>
816  static void
817  add_border(_II first, _II last,
818  const slip::BORDER_TREATMENT border,
819  _OI out_first, const std::size_t size = 1)
820  {}
821 };
822 
823 template<>
824 struct __add_border<std::random_access_iterator_tag>
825 {
826  template <typename _II, typename _OI>
827  static void
828  add_border(_II first, _II last,
829  const slip::BORDER_TREATMENT border,
830  _OI out_first, const std::size_t size = 1)
831  {
832  typedef typename std::iterator_traits<_OI>::value_type value_type;
833  typedef typename std::iterator_traits<_II>::iterator_category _Category;
834 
835  std::copy(first,last, out_first + size);
836 
838  out_first+(last-first)+(2*size),
839  border,
840  size);
841  }
842 };
843 
844 template<>
845 struct __add_border<std::random_access_iterator2d_tag>
846 {
847  template <typename _II, typename _OI>
848  static void
849  add_border(_II first, _II last,
850  const slip::BORDER_TREATMENT border,
851  _OI out_first, const std::size_t size = 1)
852  {
853  typedef typename std::iterator_traits<_OI>::value_type value_type;
854  typedef typename std::iterator_traits<_II>::difference_type _Difference;
855 
856  _Difference size_nd = last - first;
857  std::size_t rows = std::size_t(size_nd[0]);
858  std::size_t cols = std::size_t(size_nd[1]);
859 
860  for(std::size_t i = 0; i < rows;++i)
861  {
862  std::copy(first.row_begin(i),first.row_end(i),out_first.row_begin(i+size) + size);
863  __add_border<std::random_access_iterator_tag>::add_border(first.row_begin(i),first.row_end(i),border,out_first.row_begin(i+size),size);
864  }
865 
866  for(std::size_t j = 0; j < cols;++j)
867  {
868  __add_border<std::random_access_iterator_tag>::add_border(first.col_begin(j),first.col_end(j),border,out_first.col_begin(j+size),size);
869  }
870 
871  for(std::size_t i = 0; i < size;++i)
872  {
873  __add_border<std::random_access_iterator_tag>::add_border(out_first.row_begin(i)+size,out_first.row_end(i)-size,border,out_first.row_begin(i),size);
874  __add_border<std::random_access_iterator_tag>::add_border(out_first.row_begin(i + (rows + size))+size,out_first.row_end(i + (rows + size))-size,border,out_first.row_begin(i + (rows + size)),size);
875  }
876  }
877 };
878 
879 template<>
880 struct __add_border<std::random_access_iterator3d_tag>
881 {
882  template <typename _II, typename _OI>
883  static void
884  add_border(_II first, _II last,
885  const slip::BORDER_TREATMENT border,
886  _OI out_first, const std::size_t size = 1)
887  {
888  typedef typename std::iterator_traits<_OI>::value_type value_type;
889  typedef typename std::iterator_traits<_II>::difference_type _Difference;
890 
891  _Difference size_nd = last - first;
892  std::size_t slices = std::size_t(size_nd[0]);
893  std::size_t rows = std::size_t(size_nd[1]);
894  std::size_t cols = std::size_t(size_nd[2]);
895 
896  for(std::size_t k = 0; k < slices;++k)
897  {
898  for(std::size_t i = 0; i < rows;++i)
899  {
900 
901  std::copy(first.row_begin(k,i),first.row_end(k,i),out_first.row_begin(k+size,i+size) + size);
902  __add_border<std::random_access_iterator_tag>::add_border(first.row_begin(k,i),first.row_end(k,i),border,out_first.row_begin(k+size,i+size),size);
903  }
904  }
905 
906  for(std::size_t k = 0; k < slices; ++k)
907  {
908  for(std::size_t j = 0; j < cols;++j)
909  {
910  __add_border<std::random_access_iterator_tag>::add_border(first.col_begin(k,j),first.col_end(k,j),border,out_first.col_begin(k+size,j+size),size);
911  }
912  }
913 
914  for(std::size_t i = 0; i < rows;++i)
915  {
916  for(std::size_t j = 0; j < cols;++j)
917  {
918  __add_border<std::random_access_iterator_tag>::add_border(first.slice_begin(i,j),first.slice_end(i,j),border,out_first.slice_begin(i+size,j+size),size);
919  }
920  }
921 
922  for(std::size_t k = 0; k < size; ++k)
923  {
924  for(std::size_t i = 0; i < rows;++i)
925  {
926  __add_border<std::random_access_iterator_tag>::add_border(out_first.row_begin(k,i+size)+size,out_first.row_end(k,i+size)-size,border,out_first.row_begin(k,i+size),size);
927  __add_border<std::random_access_iterator_tag>::add_border(out_first.row_begin(k+(slices+size),i+size)+size,out_first.row_end(k+(slices+size),i+size)-size,border,out_first.row_begin(k+(slices+size),i+size),size);
928  }
929  for(std::size_t j = 0; j < cols;++j)
930  {
931  __add_border<std::random_access_iterator_tag>::add_border(out_first.col_begin(k,j+size)+size,out_first.col_end(k,j+size)-size,border,out_first.col_begin(k,j+size),size);
932  __add_border<std::random_access_iterator_tag>::add_border(out_first.col_begin(k+(slices+size),j+size)+size,out_first.col_end(k+(slices+size),j+size)-size,border,out_first.col_begin(k+(slices+size),j+size),size);
933 
934  }
935 
936  }
937 
938 
939  for(std::size_t k = 0; k < (slices + 2*size); ++k)
940  {
941  for(std::size_t i = 0; i < size;++i)
942  {
943  __add_border<std::random_access_iterator_tag>::add_border(out_first.row_begin(k,i)+size,out_first.row_end(k,i)-size,border,out_first.row_begin(k,i),size);
944  __add_border<std::random_access_iterator_tag>::add_border(out_first.row_begin(k, i + (rows + size))+size,out_first.row_end(k,i + (rows + size))-size,border,out_first.row_begin(k,i + (rows + size)),size);
945  }
946 
947  }
948  }
949 };
950 
951 
959 template<>
960 struct __add_border<std::random_access_iterator4d_tag>
961 {
962  template <typename _II, typename _OI>
963  static void
964  add_border(_II first, _II last,
965  const slip::BORDER_TREATMENT border,
966  _OI out_first, const std::size_t size = 1)
967  {
968  typedef typename std::iterator_traits<_OI>::value_type value_type;
969  typedef typename std::iterator_traits<_II>::difference_type _Difference;
970 
971  _Difference size_nd = last - first;
972  std::size_t slabs = std::size_t(size_nd[0]);
973  std::size_t slices = std::size_t(size_nd[1]);
974  std::size_t rows = std::size_t(size_nd[2]);
975  std::size_t cols = std::size_t(size_nd[3]);
976 
977  for(std::size_t t = 0; t < slabs; ++t)
978  {
979  for(std::size_t k = 0; k < slices;++k)
980  {
981  for(std::size_t i = 0; i < rows;++i)
982  {
983 
984  std::copy(first.row_begin(t,k,i),first.row_end(t,k,i),out_first.row_begin(t+size,k+size,i+size) + size);
985  __add_border<std::random_access_iterator_tag>::add_border(first.row_begin(t,k,i),first.row_end(t,k,i),
986  border,out_first.row_begin(t+size,k+size,i+size),size);
987  }
988  }
989  }
990 
991  for(std::size_t t = 0; t < slabs; ++t)
992  {
993  for(std::size_t k = 0; k < slices; ++k)
994  {
995  for(std::size_t j = 0; j < cols;++j)
996  {
998  first.col_end(t,k,j),border,out_first.col_begin(t+size,k+size,j+size),size);
999  }
1000  }
1001  }
1002 
1003  for(std::size_t t = 0; t < slabs; ++t)
1004  {
1005  for(std::size_t i = 0; i < rows;++i)
1006  {
1007  for(std::size_t j = 0; j < cols;++j)
1008  {
1010  first.slice_end(t,i,j),border,out_first.slice_begin(t+size,i+size,j+size),size);
1011  }
1012  }
1013  }
1014 
1015  for(std::size_t k = 0; k < slices; ++k)
1016  {
1017  for(std::size_t i = 0; i < rows;++i)
1018  {
1019  for(std::size_t j = 0; j < cols;++j)
1020  {
1022  first.slab_end(k,i,j),border,out_first.slab_begin(k+size,i+size,j+size),size);
1023  }
1024  }
1025  }
1026 
1027  for(std::size_t t = 0; t < size; ++t)
1028  {
1029  for(std::size_t k = 0; k < slices; ++k)
1030  {
1031  for(std::size_t i = 0; i < rows;++i)
1032  {
1033  __add_border<std::random_access_iterator_tag>::add_border(out_first.row_begin(t,k+size,i+size)+size,
1034  out_first.row_end(t,k+size,i+size)-size,border,out_first.row_begin(t,k+size,i+size),size);
1036  out_first.row_begin(t+(slabs+size),k+size,i+size)+size,
1037  out_first.row_end(t+(slabs+size),k+size,i+size)-size,border,
1038  out_first.row_begin(t+(slabs+size),k+size,i+size),size);
1039  }
1040  }
1041  for(std::size_t k = 0; k < slices; ++k)
1042  {
1043  for(std::size_t j = 0; j < cols;++j)
1044  {
1045  __add_border<std::random_access_iterator_tag>::add_border(out_first.col_begin(t,k+size,j+size)+size,
1046  out_first.col_end(t,k+size,j+size)-size,border,out_first.col_begin(t,k+size,j+size),size);
1048  out_first.col_begin(t+(slabs+size),k+size,j+size)+size,
1049  out_first.col_end(t+(slabs+size),k+size,j+size)-size,border,
1050  out_first.col_begin(t+(slabs+size),k+size,j+size),size);
1051 
1052  }
1053  }
1054  for(std::size_t i = 0; i < rows;++i)
1055  {
1056  for(std::size_t j = 0; j < cols;++j)
1057  {
1058  __add_border<std::random_access_iterator_tag>::add_border(out_first.slice_begin(t,i+size,j+size)+size,
1059  out_first.slice_end(t,i+size,j+size)-size,border,out_first.slice_begin(t,i+size,j+size),size);
1061  out_first.slice_begin(t+(slabs+size),i+size,j+size)+size,
1062  out_first.slice_end(t+(slabs+size),i+size,j+size)-size,border,
1063  out_first.slice_begin(t+(slabs+size),i+size,j+size),size);
1064 
1065  }
1066  }
1067  }
1068  for(std::size_t t = 0; t < (slabs + 2*size); ++t)
1069  {
1070  for(std::size_t k = 0; k < size; ++k)
1071  {
1072  for(std::size_t i = 0; i < rows;++i)
1073  {
1074  __add_border<std::random_access_iterator_tag>::add_border(out_first.row_begin(t,k,i+size)+size,
1075  out_first.row_end(t,k,i+size)-size,border,out_first.row_begin(t,k,i+size),size);
1076  __add_border<std::random_access_iterator_tag>::add_border(out_first.row_begin(t,k+(slices+size),i+size)+size,
1077  out_first.row_end(t,k+(slices+size),i+size)-size,border,out_first.row_begin(t,k+(slices+size),
1078  i+size),size);
1079  }
1080  for(std::size_t j = 0; j < cols;++j)
1081  {
1082  __add_border<std::random_access_iterator_tag>::add_border(out_first.col_begin(t,k,j+size)+size,
1083  out_first.col_end(t,k,j+size)-size,border,out_first.col_begin(t,k,j+size),size);
1084  __add_border<std::random_access_iterator_tag>::add_border(out_first.col_begin(t,k+(slices+size),j+size)+size,
1085  out_first.col_end(t,k+(slices+size),j+size)-size,border,out_first.col_begin(t,k+(slices+size),
1086  j+size),size);
1087  }
1088  }
1089 
1090  for(std::size_t k = 0; k < (slices + 2*size); ++k)
1091  {
1092  for(std::size_t i = 0; i < size;++i)
1093  {
1094  __add_border<std::random_access_iterator_tag>::add_border(out_first.row_begin(t,k,i)+size,
1095  out_first.row_end(t,k,i)-size,border,out_first.row_begin(t,k,i),size);
1097  out_first.row_begin(t,k, i + (rows + size))+size,
1098  out_first.row_end(t,k,i + (rows + size))-size,border,
1099  out_first.row_begin(t,k,i + (rows + size)),size);
1100  }
1101  }
1102  }
1103  }
1104 };
1105 
1106 
1132 struct AddBorder
1133 {
1138  AddBorder(const slip::BORDER_TREATMENT border,const std::size_t size = 1):
1139  border_(border),size_(size)
1140  {}
1150  template<typename _II, typename _OI>
1151  void operator() (_II first, _II last,_OI out_first)
1152  {
1153  typedef typename std::iterator_traits<_II>::iterator_category _Category;
1154  return __add_border<_Category>::add_border(first,last,border_,out_first,size_);
1155  }
1156 
1158  std::size_t size_;
1159 
1160 };
1161 
1190 template <typename _II, typename _OI>
1191 void add_border(_II first, _II last,_OI out_first, _OI out_last,
1192  const slip::BORDER_TREATMENT border,
1193  const std::size_t b_size = 1)
1194 {
1195 
1196  typedef typename std::iterator_traits<_II>::iterator_category _Category;
1197  return __add_border<_Category>::add_border(first,last,border,
1198  out_first,b_size);
1199 }
1200 
1228 template<typename Container1,
1229  typename Container2>
1230 void add_border1d(const Container1 & in,
1231  const slip::BORDER_TREATMENT border_type,
1232  Container2& out,
1233  const std::size_t border_size = 1)
1234 {
1235  const std::size_t size = in.size();
1236  slip::AddBorder b(border_type,border_size);
1237  out.resize(size+(2u*border_size));
1238  b(in.begin(),in.end(),out.begin());
1239 }
1268 template<typename Container2d1,
1269  typename Container2d2>
1270 void add_border2d(const Container2d1 & in,
1271  const slip::BORDER_TREATMENT border_type,
1272  Container2d2& out,
1273  const std::size_t border_size = 1)
1274 {
1275  const std::size_t rows = in.rows();
1276  const std::size_t cols = in.cols();
1277  slip::AddBorder b(border_type,border_size);
1278  out.resize(rows+(2u*border_size),cols+(2u*border_size));
1279  b(in.upper_left(),in.bottom_right(),out.upper_left());
1280 }
1281 
1311 template<typename Container3d1,
1312  typename Container3d2>
1313 void add_border3d(const Container3d1 & in,
1314  const slip::BORDER_TREATMENT border_type,
1315  Container3d2& out,
1316  const std::size_t border_size = 1)
1317 {
1318  const std::size_t slices = in.slices();
1319  const std::size_t rows = in.rows();
1320  const std::size_t cols = in.cols();
1321  slip::AddBorder b(border_type,border_size);
1322  out.resize(slices+ (2u*border_size),
1323  rows + (2u*border_size),
1324  cols + (2u*border_size));
1325  b(in.front_upper_left(),in.back_bottom_right(),out.front_upper_left());
1326 }
1327 
1358 template<typename Container4d1,
1359  typename Container4d2>
1360 void add_border4d(const Container4d1 & in,
1361  const slip::BORDER_TREATMENT border_type,
1362  Container4d2& out,
1363  const std::size_t border_size = 1)
1364 {
1365  const std::size_t slabs = in.slabs();
1366  const std::size_t slices = in.slices();
1367  const std::size_t rows = in.rows();
1368  const std::size_t cols = in.cols();
1369  slip::AddBorder b(border_type,border_size);
1370  out.resize(slabs + (2u*border_size),
1371  slices+ (2u*border_size),
1372  rows + (2u*border_size),
1373  cols + (2u*border_size));
1374  b(in.first_front_upper_left(),in.last_back_bottom_right(),out.first_front_upper_left());
1375 }
1376 
1377 }//slip::
1378 
1379 
1380 #endif //SLIP_BORDER_TREATMENT_HPP
UpdateBorder(const slip::BORDER_TREATMENT border, const std::size_t size=1)
Initializes the paramaters of the UpdateBorder functor.
void update_border(_II first, _II last, const slip::BORDER_TREATMENT border, const std::size_t b_size=1)
Updates the border of the range [first,last) according to b_size and border condition: border...
Generic fill border functor: fill border of 1d, 2d or 3d iterator ranges.
Generic add border functor: adds border of 1d, 2d or 3d iterator ranges.
FillBorder()
Initializes the paramaters of the FillBorder functor. The size of border size_ is egal to 1...
void operator()(_II first, _II last)
Updates the border of the range [first,last) according to the parameters of the functor.
Provides a class to tag SLIP iterators.
void add_border1d(const Container1 &in, const slip::BORDER_TREATMENT border_type, Container2 &out, const std::size_t border_size=1)
Adds the border at a 1d container according to the border condition border and the border size b_size...
void add_border3d(const Container3d1 &in, const slip::BORDER_TREATMENT border_type, Container3d2 &out, const std::size_t border_size=1)
Adds the border at a 3d container according to the border condition border and the border size b_size...
void add_border4d(const Container4d1 &in, const slip::BORDER_TREATMENT border_type, Container4d2 &out, const std::size_t border_size=1)
Adds the border at a 4d container according to the border condition border and the border size b_size...
void operator()(_II first, _II last, const typename std::iterator_traits< _II >::value_type &value=typename std::iterator_traits< _II >::value_type())
Fills the border of the range [first,last) according to the parameters of the functor.
slip::BORDER_TREATMENT border_
void add_border2d(const Container2d1 &in, const slip::BORDER_TREATMENT border_type, Container2d2 &out, const std::size_t border_size=1)
Adds the border at a 2d container according to the border condition border and the border size b_size...
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
Definition: copy_ext.hpp:177
void add_border(_II first, _II last, _OI out_first, _OI out_last, const slip::BORDER_TREATMENT border, const std::size_t b_size=1)
Adds the border of the range [first,last) according to the border condtion border and the border size...
AddBorder(const slip::BORDER_TREATMENT border, const std::size_t size=1)
Initializes the paramaters of the AddBorder functor.
FillBorder(const std::size_t size)
Initializes the paramaters of the FillBorder functor.
void operator()(_II first, _II last, _OI out_first)
Adds the border of the range [first,last) according to the parameters of the functor.
slip::BORDER_TREATMENT border_
Generic update border functor: update border of 1d, 2d or 3d iterator ranges.
BORDER_TREATMENT
Choose between different border treatment modes for convolution algorithms.
void fill_border(_II first, _II last, std::size_t b_size=1, const typename std::iterator_traits< _II >::value_type &value=typename std::iterator_traits< _II >::value_type())
Fills the border of the range [first,last) with value.