Mercurial > hg > orthanc-stone
annotate OrthancStone/Sources/Toolbox/SubpixelReader.h @ 1817:385c268e8b56
cppcheck
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 25 May 2021 19:51:45 +0200 |
parents | 9ac2a65d4172 |
children | 3889ae96d2e9 |
rev | line source |
---|---|
182 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
1739
9ac2a65d4172
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1598
diff
changeset
|
5 * Copyright (C) 2017-2021 Osimis S.A., Belgium |
182 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
1598
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public License |
182 | 9 * as published by the Free Software Foundation, either version 3 of |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
1598
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
15 * Lesser General Public License for more details. |
1596
4fb8fdf03314
removed annoying whitespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1571
diff
changeset
|
16 * |
1598
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
18 * License along with this program. If not, see |
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
19 * <http://www.gnu.org/licenses/>. |
182 | 20 **/ |
21 | |
22 | |
23 #pragma once | |
24 | |
194
7a031ac16b2d
rename Enumerations.h to StoneEnumerations.h to avoid clashes with Orthanc
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
183
diff
changeset
|
25 #include "../StoneEnumerations.h" |
182 | 26 #include "GeometryToolbox.h" |
27 | |
1455
30deba7bc8e2
simplifying include_directories
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1270
diff
changeset
|
28 #include <Images/ImageTraits.h> |
182 | 29 |
30 #include <boost/noncopyable.hpp> | |
31 #include <cmath> | |
32 | |
33 namespace OrthancStone | |
34 { | |
35 namespace Internals | |
36 { | |
37 class SubpixelReaderBase : public boost::noncopyable | |
38 { | |
39 private: | |
40 const Orthanc::ImageAccessor& source_; | |
41 unsigned int width_; | |
42 unsigned int height_; | |
43 | |
44 public: | |
1571 | 45 explicit SubpixelReaderBase(const Orthanc::ImageAccessor& source) : |
182 | 46 source_(source), |
47 width_(source.GetWidth()), | |
48 height_(source.GetHeight()) | |
49 { | |
50 } | |
51 | |
52 ORTHANC_FORCE_INLINE | |
53 const Orthanc::ImageAccessor& GetSource() const | |
54 { | |
55 return source_; | |
56 } | |
57 | |
58 ORTHANC_FORCE_INLINE | |
59 unsigned int GetWidth() const | |
60 { | |
61 return width_; | |
62 } | |
63 | |
64 ORTHANC_FORCE_INLINE | |
65 unsigned int GetHeight() const | |
66 { | |
67 return height_; | |
68 } | |
69 }; | |
70 } | |
71 | |
72 | |
73 template <Orthanc::PixelFormat Format, | |
74 ImageInterpolation Interpolation> | |
75 class SubpixelReader; | |
76 | |
77 | |
78 template <Orthanc::PixelFormat Format> | |
79 class SubpixelReader<Format, ImageInterpolation_Nearest> : | |
80 public Internals::SubpixelReaderBase | |
81 { | |
82 public: | |
83 typedef Orthanc::PixelTraits<Format> Traits; | |
84 typedef typename Traits::PixelType PixelType; | |
85 | |
1571 | 86 explicit SubpixelReader(const Orthanc::ImageAccessor& source) : |
182 | 87 SubpixelReaderBase(source) |
88 { | |
89 } | |
90 | |
91 inline bool GetValue(PixelType& target, | |
92 float x, | |
93 float y) const; | |
183 | 94 |
95 inline bool GetFloatValue(float& target, | |
96 float x, | |
97 float y) const; | |
182 | 98 }; |
183 | 99 |
182 | 100 |
101 | |
102 template <Orthanc::PixelFormat Format> | |
103 class SubpixelReader<Format, ImageInterpolation_Bilinear> : | |
104 public Internals::SubpixelReaderBase | |
105 { | |
106 public: | |
107 typedef Orthanc::PixelTraits<Format> Traits; | |
108 typedef typename Traits::PixelType PixelType; | |
109 | |
1571 | 110 explicit SubpixelReader(const Orthanc::ImageAccessor& source) : |
182 | 111 SubpixelReaderBase(source) |
112 { | |
113 } | |
114 | |
183 | 115 inline bool GetFloatValue(float& target, |
116 float x, | |
117 float y) const; | |
118 | |
182 | 119 inline bool GetValue(PixelType& target, |
120 float x, | |
183 | 121 float y) const; |
182 | 122 }; |
123 | |
124 | |
125 | |
126 template <Orthanc::PixelFormat Format> | |
127 bool SubpixelReader<Format, ImageInterpolation_Nearest>::GetValue(PixelType& target, | |
128 float x, | |
129 float y) const | |
130 { | |
131 if (x < 0 || | |
132 y < 0) | |
133 { | |
134 return false; | |
135 } | |
136 else | |
137 { | |
138 unsigned int ux = static_cast<unsigned int>(std::floor(x)); | |
139 unsigned int uy = static_cast<unsigned int>(std::floor(y)); | |
140 | |
141 if (ux < GetWidth() && | |
142 uy < GetHeight()) | |
143 { | |
144 Orthanc::ImageTraits<Format>::GetPixel(target, GetSource(), ux, uy); | |
145 return true; | |
146 } | |
147 else | |
148 { | |
149 return false; | |
150 } | |
151 } | |
152 } | |
153 | |
154 | |
155 | |
156 template <Orthanc::PixelFormat Format> | |
183 | 157 bool SubpixelReader<Format, ImageInterpolation_Nearest>::GetFloatValue(float& target, |
158 float x, | |
159 float y) const | |
160 { | |
161 PixelType value; | |
162 | |
163 if (GetValue(value, x, y)) | |
164 { | |
165 target = Traits::PixelToFloat(value); | |
166 return true; | |
167 } | |
168 else | |
169 { | |
170 return false; | |
171 } | |
172 } | |
173 | |
174 | |
175 | |
176 template <Orthanc::PixelFormat Format> | |
182 | 177 bool SubpixelReader<Format, ImageInterpolation_Bilinear>::GetValue(PixelType& target, |
178 float x, | |
183 | 179 float y) const |
180 { | |
181 float value; | |
182 | |
183 if (GetFloatValue(value, x, y)) | |
184 { | |
185 Traits::FloatToPixel(target, value); | |
186 return true; | |
187 } | |
188 else | |
189 { | |
190 return false; | |
191 } | |
192 } | |
193 | |
194 | |
195 | |
196 template <Orthanc::PixelFormat Format> | |
197 bool SubpixelReader<Format, ImageInterpolation_Bilinear>::GetFloatValue(float& target, | |
198 float x, | |
199 float y) const | |
182 | 200 { |
201 x -= 0.5f; | |
202 y -= 0.5f; | |
203 | |
204 if (x < 0 || | |
205 y < 0) | |
206 { | |
207 return false; | |
208 } | |
209 else | |
210 { | |
211 unsigned int ux = static_cast<unsigned int>(std::floor(x)); | |
212 unsigned int uy = static_cast<unsigned int>(std::floor(y)); | |
213 | |
214 float f00, f01, f10, f11; | |
215 | |
216 if (ux < GetWidth() && | |
217 uy < GetHeight()) | |
218 { | |
219 f00 = Orthanc::ImageTraits<Format>::GetFloatPixel(GetSource(), ux, uy); | |
220 } | |
221 else | |
222 { | |
223 return false; | |
224 } | |
225 | |
226 if (ux + 1 < GetWidth()) | |
227 { | |
228 f01 = Orthanc::ImageTraits<Format>::GetFloatPixel(GetSource(), ux + 1, uy); | |
229 } | |
230 else | |
231 { | |
232 f01 = f00; | |
233 } | |
234 | |
235 if (uy + 1 < GetHeight()) | |
236 { | |
237 f10 = Orthanc::ImageTraits<Format>::GetFloatPixel(GetSource(), ux, uy + 1); | |
238 } | |
239 else | |
240 { | |
241 f10 = f00; | |
242 } | |
243 | |
244 if (ux + 1 < GetWidth() && | |
245 uy + 1 < GetHeight()) | |
246 { | |
247 f11 = Orthanc::ImageTraits<Format>::GetFloatPixel(GetSource(), ux + 1, uy + 1); | |
248 } | |
249 else | |
250 { | |
251 f11 = f00; | |
252 } | |
253 | |
254 float ax = x - static_cast<float>(ux); | |
255 float ay = y - static_cast<float>(uy); | |
183 | 256 target = GeometryToolbox::ComputeBilinearInterpolationUnitSquare(ax, ay, f00, f01, f10, f11); |
182 | 257 |
258 return true; | |
259 } | |
260 } | |
261 } |