$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
test_simple_point3d_lut_26_6.cc
1 // Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #include <mln/core/image/image3d.hh>
27 #include <mln/core/alias/neighb3d.hh>
28 #include <mln/make/box3d.hh>
29 
30 #include "tools/connectivity_numbers_3d.hh"
31 
32 // To avoid heavy recompilation times due to the huge size of the
33 // look-up table, only fetch the table's declaration. Its
34 // implementation is compiled separately and linked to this program.
35 #define MLN_INCLUDE_ONLY
36 # include "tools/simple_point3d_lut_26_6.hh"
37 #undef MLN_INCLUDE_ONLY
38 
39 
40 int
41 main()
42 {
43  using namespace mln;
44 
45  // FIXME: This part is very similar to
46  // milena/tests/topo/connectivity_numbers_2d.cc and
47  // milena/tools/connectivity_numbers_3d.hh. Factor.
48 
49  typedef image3d<bool> I;
50  // B must be a model of mln::Box.
51  typedef mln_domain_(I) B;
52  typedef mln_psite_(I) P;
53 
54  B b = make::box3d(-1,-1,-1, 1,1,1);
55  I fg_ima(b, 0);
56  I bg_ima(b, 0);
57  P p(0, 0, 0);
58 
59  const unsigned dim = 3;
60  const unsigned max_nneighbs = mlc_pow_int(3, dim) - 1;
61  const unsigned nconfigs = mlc_pow_int(2, max_nneighbs);
62 
63  typedef neighb3d N;
64  N nbh = c26();
65 
66  int exit_status = EXIT_SUCCESS;
67 
68  for (config_3d_t i = 0; i < nconfigs; ++i)
69  {
70  /* Create the local i-th configuration around P.
71 
72  Note that the value corresponding to P is always `false', to
73  prevent the connection of two components through P. */
74  data::fill(fg_ima, false);
75  data::fill(bg_ima, false);
76  config_3d_t tmp = i;
77  mln_fwd_niter_(N) n(nbh, p);
78  for_all(n)
79  {
80  if (tmp % 2)
81  fg_ima(n) = true;
82  else
83  bg_ima(n) = true;
84  tmp = tmp >> 1;
85  }
86 
87  // Compute the simple point criterion for (26, 6)-connectivity
88  conn_number_t conn_number_fg = connectivity_number_3d__26_6_one(fg_ima);
89  conn_number_t conn_number_bg = connectivity_number_3d__6_26_one(bg_ima);
90  bool conn_number_computed = conn_number_fg == 1 &&conn_number_bg == 1;
91 
92 
93  // Retrieve the simple point criterion for (26, 6)-connectivity
94  // number using the LUT.
95  conn_number_t conn_number_from_lut;
96  {
97  // ``Unpack'' the i-th value.
98 
99  // FIXME: Redundant with some code from
100  // mln/topo/is_simple_point3d.hh.
101 
102  size_t pos = i;
103 
104  /* `simple_point3d_lut_26_6' is a packed bit array. We must
105  first retrieve the cell ``containing'' the index `pos'. */
106  size_t cell = pos / 8;
107  /* FIXME: We use hard-coded neighborhoods here instead of using
108  nbh_fg_ and nbh_bg_ (for this first test version). */
109  unsigned char pack = mln::topo::simple_point3d_lut_26_6[cell];
110 
111  /* Compute the position of the neighborhood configuration within
112  the packed set of valued and create a mask corresponding to
113  this position (offset). */
114  size_t offset = pos % 8;
115  unsigned char mask = 1 << offset;
116 
117  /* If the pack contains a 1 at position `offset', then `pack &
118  mask' is a non-null value. Otherwise it is zero. We can
119  therefore use it to create a boolean return value. */
120  bool result = pack & mask;
121  conn_number_from_lut = result;
122  }
123 
124  // Compare them.
125  if (conn_number_computed != conn_number_from_lut)
126  {
127  std::cout
128  << "Inconsistency for the " << i << "-th configuration: "
129  << conn_number_computed << " != " << conn_number_from_lut
130  << std::endl;
131  exit_status = EXIT_FAILURE;
132  }
133  }
134 
135  return exit_status;
136 }