DGtal  1.5.beta
NeighborhoodConfigurations.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file NeighborhoodConfigurations.ih
19  *
20  * @author Pablo Hernandez-Cerdan. Institute of Fundamental Sciences.
21  * Massey University. Palmerston North, New Zealand
22  *
23  * @date 2018/01/01
24  *
25  * Implementation of header NeighborhoodConfigurations.h
26  *
27  * This file is part of the DGtal library.
28  */
29 
30 #include <fstream>
31 #include "DGtal/kernel/SpaceND.h"
32 #include "DGtal/kernel/domains/HyperRectDomain.h"
33 // zlib + boost for reading compressed tables
34 #include <boost/iostreams/filtering_streambuf.hpp>
35 #include <boost/iostreams/copy.hpp>
36 #include <boost/iostreams/filter/zlib.hpp>
37 namespace DGtal{
38  namespace functions {
39 /*---------------------------------------------------------------------*/
40 
41  DGtal::CountedPtr< boost::dynamic_bitset<> >
42  loadTable(const std::string &input_filename,
43  const unsigned int known_size,
44  const bool compressed)
45  {
46  using ConfigMap = boost::dynamic_bitset<> ;
47  CountedPtr<ConfigMap> table(new ConfigMap(known_size));
48  try {
49  if (compressed) {
50  std::ifstream in_file(input_filename, std::ios::binary);
51  namespace io = boost::iostreams ;
52  io::filtering_streambuf<io::input> filter;
53  filter.push(io::zlib_decompressor());
54  filter.push(in_file);
55  std::stringstream compressed_stream;
56  io::copy(filter,compressed_stream);
57  compressed_stream >> *table ;
58  } else {
59  std::ifstream in_file(input_filename);
60  in_file >> *table ;
61  }
62  } catch(std::exception &e) {
63  throw std::runtime_error("loadTable error in: " + input_filename + " with exception: " + e.what());
64  }
65 
66  return table ;
67  }
68 
69  template<unsigned int N>
70  inline
71  DGtal::CountedPtr< boost::dynamic_bitset<> >
72  loadTable(const std::string &input_filename, const bool compressed)
73  {
74  if (N == 3) // Default
75  return loadTable(input_filename, 67108864, compressed);
76  if (N == 2)
77  return loadTable(input_filename, 256, compressed);
78  throw std::domain_error("loadTable<N> error, template parameter N = "
79  + std::to_string(N) + " is invalid (use N = 2 or N = 3)");
80 
81  }
82 
83 /*---------------------------------------------------------------------*/
84 
85  template<typename TPoint>
86  inline
87  DGtal::CountedPtr<
88  std::unordered_map<TPoint, NeighborhoodConfiguration > >
89  mapZeroPointNeighborhoodToConfigurationMask()
90  {
91  using Map = std::unordered_map<TPoint, NeighborhoodConfiguration> ;
92  NeighborhoodConfiguration mask = 1 ;
93  CountedPtr<Map> mapPtr(new Map);
94  Map& amap = *mapPtr;
95  auto p1 = TPoint::diagonal(-1);
96  auto p2 = TPoint::diagonal(1);
97  auto center = TPoint::diagonal(0);
98  // HyperRect Domain with lexicograpicOrder ensures same order.
99  using Space = SpaceND< TPoint::dimension , DGtal::int32_t>;
100  using Domain = HyperRectDomain< Space >;
101  const Domain domain(p1, p2);
102  for ( auto it = domain.begin(), itE = domain.end() ;
103  it!=itE ; ++it)
104  {
105  if (*it == center ) continue;
106  amap[*it] = mask;
107  mask <<= 1 ;
108  }
109 
110  return mapPtr;
111  }
112 
113  } // namespace functions
114 } // namespace DGtal