OpenStructure
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
image_state_half_frequency_domain.hh
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // This file is part of the OpenStructure project <www.openstructure.org>
3 //
4 // Copyright (C) 2008-2011 by the OpenStructure authors
5 // Copyright (C) 2003-2010 by the IPLT authors
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License as published by the Free
9 // Software Foundation; either version 3.0 of the License, or (at your option)
10 // any later version.
11 // This library is distributed in the hope that it will be useful, but WITHOUT
12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 // details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with this library; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 //------------------------------------------------------------------------------
20 
21 /*
22  Author: Ansgar Philippsen
23 */
24 
25 #ifndef IMAGE_STATE_HALF_FREQUENCY_DOMAIN_HH
26 #define IMAGE_STATE_HALF_FREQUENCY_DOMAIN_HH
27 
28 #include <ost/base.hh>
29 #include <ost/img/point.hh>
30 #include <ost/img/size.hh>
31 #include <ost/img/extent.hh>
33 
34 #include "value_holder.hh"
35 #include "index.hh"
36 
37 #define CONJPOINT(a) ((a)[2]==0 ?((a)[1]==0?(a)[0]>0:(a)[1]>0):(a)[2]>0) ? (a) : -(a)
38 
39 namespace ost { namespace img { namespace image_state {
40 
41 namespace {
42 
43 int half_pos(int d)
44 {
45  return (d&0x1) ? (d-1)/2 : d/2;
46 }
47 
48 int half_neg(int d)
49 {
50  return (d&0x1) ? -((d-1)/2) : -(d/2-1);
51 }
52 
53 } // anon ns
54 
55 /*
56  1D half-frequency domain
57 
58  N | logical range | physical range
59  ----------------------------------------
60  even -(N/2-1) : N/2 0:N/2
61  odd -(N-1)/2 : (N-1)/2 0:N/2+1
62 
63 
64  2D half-frequency domain
65 
66  N is height
67  M is width
68 
69  N | logical range | physical range
70  ----------------------------------------
71  even -(N/2-1) : N/2 0:N/2
72  odd -(N-1)/2 : (N-1)/2 0:N/2+1
73 
74  M | logical range | physical range
75  ----------------------------------------
76  even -(M/2-1) : M/2 0:M-1
77  odd -(M-1)/2 : (M-1)/2 0:M-1
78 
79  the negative indices for the width are wrapped around, so
80  that -1 == M-1, -2 == M-2 etc.
81 
82 
83  3D half-frequency domain
84 
85  N is depth
86  M is height
87  L is width
88 
89  N | logical range | physical range
90  ----------------------------------------
91  even -(N/2-1) : N/2 0:N/2
92  odd -(N-1)/2 : (N-1)/2 0:N/2+1
93 
94  M/L | logical range | physical range
95  ----------------------------------------
96  even -(M/2-1) : M/2 0:M-1
97  odd -(M-1)/2 : (M-1)/2 0:M-1
98 
99  the negative indices for the width and height are wrapped around, so
100  that -1 == M-1, -2 == M-2 etc.
101 
102 */
103 
105 public:
107  logical_extent_(ExtractLogicalExtent(e)),
108  physical_extent_(ExtractPhysicalExtent(e)),
109  dim_(e.GetDim()),
110  spat_ori_()
111  {
112  assert(dim_>=1 && dim_<=3);
113  }
114 
116 
117  void SetSpatialOrigin(const Point& o) {spat_ori_=o;}
118 
119  Point GetSpatialOrigin() const {return spat_ori_;}
120 
121  // this is the physical extent
122  Extent GetExtent() const {return physical_extent_;}
123 
124  Extent GetLogicalExtent() const { return logical_extent_;}
125 
126  Extent GetPhysicalExtent() const { return physical_extent_;}
127 
128  template <typename V>
129  Real GetReal(const Point &p, const ValueHolder<V>& data) const {
130  if(logical_extent_.Contains(p)) {
131  return Val2Val<V,Real>(data.Value(Point2Index(CONJPOINT(p))));
132  }
133  return Real();
134  }
135 
136  template <typename V>
137  void SetReal(const Point &p, const Real& r, ValueHolder<V>& data) {
138  if(logical_extent_.Contains(p)) {
139  Point cp=CONJPOINT(p);
140  if(cp==p){
141  data.Value(Point2Index(cp))=Val2Val<Real,V>(r);
142  }
143  }
144  }
145 
146  template <typename V>
147  Complex GetComplex(const Point &p, const ValueHolder<V>& data) const {
148  if(logical_extent_.Contains(p)) {
149  Point cp=CONJPOINT(p);
150  if(cp==p){
151  return Val2Val<V,Complex>(data.Value(Point2Index(cp)));
152  }else{
153  return conj(Val2Val<V,Complex>(data.Value(Point2Index(cp))));
154  }
155  }
156  return Complex();
157  }
158 
159  template <typename V>
160  void SetComplex(const Point &p, const Complex& c, ValueHolder<V>& data) {
161  if(logical_extent_.Contains(p)) {
162  Point cp=CONJPOINT(p);
163  if(cp==p){
164  data.Value(Point2Index(cp))=Val2Val<Complex,V>(c);
165  }
166  }
167  }
168 
169  Index Point2Index(const Point& p) const {
170  const Size& size=physical_extent_.GetSize();
171  return Index(p[0]>=0?p[0]:size[0]+p[0],
172  p[1]>=0?p[1]:size[1]+p[1],
173  p[2]);
174  }
175 
177 #if 1
178  return Extent(Point(half_neg(e.GetWidth()),half_neg(e.GetHeight()),half_neg(e.GetDepth())),
179  Point(half_pos(e.GetWidth()),half_pos(e.GetHeight()),half_pos(e.GetDepth())));
180 #else
181 
182  if(e.GetDim()==1) {
183  return Extent(Point(half_neg(e.GetWidth())),Point(half_pos(e.GetWidth())));
184  } else if(e.GetDim()==2) {
185  return Extent(Point(half_neg(e.GetWidth()),half_neg(e.GetHeight())),
186  Point(half_pos(e.GetWidth()),half_pos(e.GetHeight())));
187  } else {
188  return Extent(Point(half_neg(e.GetWidth()),half_neg(e.GetHeight()),half_neg(e.GetDepth())),
189  Point(half_pos(e.GetWidth()),half_pos(e.GetHeight()),half_pos(e.GetDepth())));
190  }
191 #endif
192  }
193 
195  if(e.GetDim()==1) {
196  return Extent(Point(0),Point(half_pos(e.GetWidth())));
197  } else if(e.GetDim()==2) {
198  return Extent(Point(half_neg(e.GetWidth()),0,0),
199  Point(half_pos(e.GetWidth()),half_pos(e.GetHeight()),0));
200  } else {
201  return Extent(Point(half_neg(e.GetWidth()),half_neg(e.GetHeight()),0),
202  Point(half_pos(e.GetWidth()),half_pos(e.GetHeight()),half_pos(e.GetDepth())));
203  }
204  }
205 
206 private:
207  Extent logical_extent_;
208  Extent physical_extent_;
209  int dim_;
210  Point spat_ori_;
211 
212 };
213 
214 
215 
216 }}} // ns
217 
218 #endif