SLAMflex SE  0.1.0
SLAMflex provides detection and tracking of dominant planes for smartphone devices. This plane can then be used to show AR content relative to the plane orientation. The detection of plane is performed in the field of view of the smartphone camera. In subsequent frames it is tracked. The interface returns the plane position and orientation.
scalar_convert.h
Go to the documentation of this file.
1 /*
2  This file is part of the CVD Library.
3 
4  Copyright (C) 2005 The Authors
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc.,
19  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21 #ifndef CVD_SCALAR_CONVERT_H
22 #define CVD_SCALAR_CONVERT_H
23 
24 #include "byte.h"
25 #include "pixel_traits.h"
26 
27 namespace CVD
28 {
29 namespace Pixel
30 {
31 
32  namespace Internal
33  {
34 
35  //When we convert, we want the following thing to happen:
36  //conv(max_low_precision_number) == max_high_precision_number
37  //Since max is all ones, rightshifting truncates, resulting in all ones
38  //Left shifting is more tricky.
39  //All remaining empty bits need to be filled with the higest bits of the low precision number
40  //That applies recursively (consider converting byte to ulong)
41  //As an illustration, imagine converting the 4 bit umber 1011 to a 10 bit number. The
42  //result should be:
43  //1011 -> 1011 1011 10
44  //
45  // In other words, it's:
46  // truncate( 1011 * 1000100010.00100010001000100010001000...
47  //
48  // Which is equal to multiplying by (high_precision_max + 1)/(low_precision_max)
49  // Where strict rruncation occurs, ie 1.1111111... trucates to 1
50  //
51  template<class To, class From> struct int_info {
52  //Difference in number of bits used
54 
55  //Extra bits required to fill the space bits
56  //Number of complete copies required
57  static const int chunks=traits<To>::bits_used / traits<From>::bits_used;
58  //Number of extra bits
59  static const int extra_bits =traits<To>::bits_used % traits<From>::bits_used;
60  //Right shift required to leave extra bits behind:
61  static const int final_rshift = traits<From>::bits_used - extra_bits;
62 
63  //Which way do we need to shift
64  static const int shift_dir = (diff == 0)?0:((diff > 0)?1:-1);
65  };
66 
67  template<class To, int num, int shift, int bits, int r_shift> struct upshift
68  {
69  static To aggregate(To i)
70  {
72  }
73  };
74  template<class To, int shift, int bits, int r_shift> struct upshift<To,0,shift,bits,r_shift>
75  {
76  static To aggregate(To i)
77  {
78  return i >> r_shift;
79  }
80  };
81 
82  template<class To, class From, int i=int_info<To,From>::shift_dir> struct shift_convert {
83  template <class D> static To from(D f) {
84  return static_cast<To>(f);
85  }
86  };
87 
88  template<class To, class From> struct shift_convert<To, From, 1>
89  {
91  template <class D> static To from(D f) {
92  //return static_cast<To>(f) << int_info<To,From>::diff;
93  return upshift<To,info::chunks, info::diff, traits<From>::bits_used, info::final_rshift>::aggregate(static_cast<To>(f));
94  }
95  };
96 
97  template<class To, class From> struct shift_convert<To, From,-1> {
98  template <class D> static To from(D f) {
99  return static_cast<To>(f >> -int_info<To,From>::diff);
100  }
101  };
102 
103 
104  static float float_for_byte[512];
105  static double double_for_byte[512];
106 
107  template <class S> bool buildLookupTable(S table[]) {
108  for (int i=0; i<=511; i++)
109  table[i] = (S)((i-255)/255.0);
110  return true;
111  }
112  const static bool init_float_for_byte = buildLookupTable(float_for_byte);
113  const static bool init_double_for_byte = buildLookupTable(double_for_byte);
114  inline float byte_to_float(int b) { return float_for_byte[b+255]; }
115  inline double byte_to_double(int b) { return double_for_byte[b+255]; }
116 
117  //Convert a "D" to "To" scaled as if we are converting "From" type to a "To" type.
118  //Special code is invoked if both D and To are integral.
119  //FIXME: why is the test on "From", not "D"??
120  template <class From, class To, class D=From, bool int1 = traits<To>::integral && traits<From>::integral, bool int2 =traits<D>::integral> struct ScalarConvert {
121  static inline To from(const D& from) {
122  static const double factor = double(traits<To>::max_intensity)/traits<From>::max_intensity;
123  return static_cast<To>(from*factor);
124  }
125  };
126 
127 
128  //If the input and output are integral, then use integer only scaling code.
129  template <class From, class To, class D> struct ScalarConvert<From,To,D,true, true> {
130  static inline To from(const D& f) {
132  }
133  };
134 
135  //If the destination is bool, then use != 0.
136  //Note two classes are needed here so that they are both more specialized than
137  //the integral conversion code (above) in order to avoid ambiguities.
138  template<class From, class D> struct ScalarConvert<From, bool, D, true, true>
139  {
140  static inline bool from(const D& from)
141  {
142  return from != 0;
143  }
144  };
145  template<class From, class D> struct ScalarConvert<From, bool, D, true, false>
146  {
147  static inline bool from(const D& from)
148  {
149  return from != 0;
150  }
151  };
152 
153  //Lookup table conversion from byte to float.
154  //FIXME surely this can only work properly if D is also byte?
155  template <class D> struct ScalarConvert<byte,float,D,false,true> {
156  static inline float from(const D& from) {
157  return byte_to_float(from);
158  }
159  };
160 
161  //FIXME this is surely redundant
162  template <class D> struct ScalarConvert<byte,float,D,false,false> {
163  static inline float from(const D& from) {
164  return static_cast<float>(from * (1.0/255.0));
165  }
166  };
167 
168  template <class D> struct ScalarConvert<byte,double,D,false, true> {
169  static inline double from(const D& from) {
170  return byte_to_double(from);
171  }
172  };
173  template <class D> struct ScalarConvert<byte,double,D,false, false> {
174  static inline double from(const D& from) {
175  return from * (1.0/255.0);
176  }
177  };
178 
179  inline double byte_float_to_float(double d) {
181  }
182 
183 
184 
185  }
186 
187 
188  template <class To, class From, class D> inline To scalar_convert(const D& d) { return Internal::ScalarConvert<From,To,D>::from(d); }
189  //template <class To, class From> inline To scalar_convert(const From& d) { return Internal::ScalarConvert<From,To>::from(d); }
190 
191 }
192 }
193 #endif
static double double_for_byte[512]
float byte_to_float(int b)
double byte_float_to_float(double d)
bool buildLookupTable(S table[])
To scalar_convert(const D &d)
static const bool init_double_for_byte
Definition: abs.h:24
static const bool init_float_for_byte
unsigned char byte
Definition: byte.h:28
static To from(const D &from)
double byte_to_double(int b)
static float float_for_byte[512]