Mercurial > hg > orthanc-stone
comparison Framework/Toolbox/SubpixelReader.h @ 182:2cbfb08f3a95 wasm
ImageGeometry.cpp
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 15 Mar 2018 12:12:01 +0100 |
parents | |
children | 98da3a8d4820 |
comparison
equal
deleted
inserted
replaced
181:ff8556874557 | 182:2cbfb08f3a95 |
---|---|
1 /** | |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
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 | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #pragma once | |
23 | |
24 #include "../Enumerations.h" | |
25 #include "GeometryToolbox.h" | |
26 | |
27 #include <Core/Images/ImageTraits.h> | |
28 | |
29 #include <boost/noncopyable.hpp> | |
30 #include <cmath> | |
31 | |
32 namespace OrthancStone | |
33 { | |
34 namespace Internals | |
35 { | |
36 class SubpixelReaderBase : public boost::noncopyable | |
37 { | |
38 private: | |
39 const Orthanc::ImageAccessor& source_; | |
40 unsigned int width_; | |
41 unsigned int height_; | |
42 | |
43 public: | |
44 SubpixelReaderBase(const Orthanc::ImageAccessor& source) : | |
45 source_(source), | |
46 width_(source.GetWidth()), | |
47 height_(source.GetHeight()) | |
48 { | |
49 } | |
50 | |
51 ORTHANC_FORCE_INLINE | |
52 const Orthanc::ImageAccessor& GetSource() const | |
53 { | |
54 return source_; | |
55 } | |
56 | |
57 ORTHANC_FORCE_INLINE | |
58 unsigned int GetWidth() const | |
59 { | |
60 return width_; | |
61 } | |
62 | |
63 ORTHANC_FORCE_INLINE | |
64 unsigned int GetHeight() const | |
65 { | |
66 return height_; | |
67 } | |
68 }; | |
69 } | |
70 | |
71 | |
72 template <Orthanc::PixelFormat Format, | |
73 ImageInterpolation Interpolation> | |
74 class SubpixelReader; | |
75 | |
76 | |
77 template <Orthanc::PixelFormat Format> | |
78 class SubpixelReader<Format, ImageInterpolation_Nearest> : | |
79 public Internals::SubpixelReaderBase | |
80 { | |
81 public: | |
82 typedef Orthanc::PixelTraits<Format> Traits; | |
83 typedef typename Traits::PixelType PixelType; | |
84 | |
85 SubpixelReader(const Orthanc::ImageAccessor& source) : | |
86 SubpixelReaderBase(source) | |
87 { | |
88 } | |
89 | |
90 inline bool GetValue(PixelType& target, | |
91 float x, | |
92 float y) const; | |
93 }; | |
94 | |
95 | |
96 template <Orthanc::PixelFormat Format> | |
97 class SubpixelReader<Format, ImageInterpolation_Bilinear> : | |
98 public Internals::SubpixelReaderBase | |
99 { | |
100 public: | |
101 typedef Orthanc::PixelTraits<Format> Traits; | |
102 typedef typename Traits::PixelType PixelType; | |
103 | |
104 SubpixelReader(const Orthanc::ImageAccessor& source) : | |
105 SubpixelReaderBase(source) | |
106 { | |
107 } | |
108 | |
109 inline bool GetValue(PixelType& target, | |
110 float x, | |
111 float y); | |
112 }; | |
113 | |
114 | |
115 | |
116 template <Orthanc::PixelFormat Format> | |
117 bool SubpixelReader<Format, ImageInterpolation_Nearest>::GetValue(PixelType& target, | |
118 float x, | |
119 float y) const | |
120 { | |
121 if (x < 0 || | |
122 y < 0) | |
123 { | |
124 return false; | |
125 } | |
126 else | |
127 { | |
128 unsigned int ux = static_cast<unsigned int>(std::floor(x)); | |
129 unsigned int uy = static_cast<unsigned int>(std::floor(y)); | |
130 | |
131 if (ux < GetWidth() && | |
132 uy < GetHeight()) | |
133 { | |
134 Orthanc::ImageTraits<Format>::GetPixel(target, GetSource(), ux, uy); | |
135 return true; | |
136 } | |
137 else | |
138 { | |
139 return false; | |
140 } | |
141 } | |
142 } | |
143 | |
144 | |
145 | |
146 template <Orthanc::PixelFormat Format> | |
147 bool SubpixelReader<Format, ImageInterpolation_Bilinear>::GetValue(PixelType& target, | |
148 float x, | |
149 float y) | |
150 { | |
151 x -= 0.5f; | |
152 y -= 0.5f; | |
153 | |
154 if (x < 0 || | |
155 y < 0) | |
156 { | |
157 return false; | |
158 } | |
159 else | |
160 { | |
161 unsigned int ux = static_cast<unsigned int>(std::floor(x)); | |
162 unsigned int uy = static_cast<unsigned int>(std::floor(y)); | |
163 | |
164 float f00, f01, f10, f11; | |
165 | |
166 if (ux < GetWidth() && | |
167 uy < GetHeight()) | |
168 { | |
169 f00 = Orthanc::ImageTraits<Format>::GetFloatPixel(GetSource(), ux, uy); | |
170 } | |
171 else | |
172 { | |
173 return false; | |
174 } | |
175 | |
176 if (ux + 1 < GetWidth()) | |
177 { | |
178 f01 = Orthanc::ImageTraits<Format>::GetFloatPixel(GetSource(), ux + 1, uy); | |
179 } | |
180 else | |
181 { | |
182 f01 = f00; | |
183 } | |
184 | |
185 if (uy + 1 < GetHeight()) | |
186 { | |
187 f10 = Orthanc::ImageTraits<Format>::GetFloatPixel(GetSource(), ux, uy + 1); | |
188 } | |
189 else | |
190 { | |
191 f10 = f00; | |
192 } | |
193 | |
194 if (ux + 1 < GetWidth() && | |
195 uy + 1 < GetHeight()) | |
196 { | |
197 f11 = Orthanc::ImageTraits<Format>::GetFloatPixel(GetSource(), ux + 1, uy + 1); | |
198 } | |
199 else | |
200 { | |
201 f11 = f00; | |
202 } | |
203 | |
204 float ax = x - static_cast<float>(ux); | |
205 float ay = y - static_cast<float>(uy); | |
206 float value = GeometryToolbox::ComputeBilinearInterpolationUnitSquare(ax, ay, f00, f01, f10, f11); | |
207 | |
208 Traits::FloatToPixel(target, value); | |
209 return true; | |
210 } | |
211 } | |
212 } |