130
|
1 /**
|
|
2 * Orthanc - A Lightweight, RESTful DICOM Store
|
|
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 General Public License as
|
|
9 * published by the Free Software Foundation, either version 3 of the
|
|
10 * License, or (at your option) any later version.
|
|
11 *
|
|
12 * In addition, as a special exception, the copyright holders of this
|
|
13 * program give permission to link the code of its release with the
|
|
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it
|
|
15 * that use the same license as the "OpenSSL" library), and distribute
|
|
16 * the linked executables. You must obey the GNU General Public License
|
|
17 * in all respects for all of the code used other than "OpenSSL". If you
|
|
18 * modify file(s) with this exception, you may extend this exception to
|
|
19 * your version of the file(s), but you are not obligated to do so. If
|
|
20 * you do not wish to do so, delete this exception statement from your
|
|
21 * version. If you delete this exception statement from all source files
|
|
22 * in the program, then also delete it here.
|
|
23 *
|
|
24 * This program is distributed in the hope that it will be useful, but
|
|
25 * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
27 * General Public License for more details.
|
|
28 *
|
|
29 * You should have received a copy of the GNU General Public License
|
|
30 * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
31 **/
|
|
32
|
|
33
|
|
34 #pragma once
|
|
35
|
|
36 #include "../Enumerations.h"
|
|
37 #include "../OrthancException.h"
|
|
38
|
|
39 #include <limits>
|
|
40
|
|
41 namespace Orthanc
|
|
42 {
|
|
43 template <PixelFormat format,
|
|
44 typename _PixelType>
|
|
45 struct IntegerPixelTraits
|
|
46 {
|
|
47 typedef _PixelType PixelType;
|
|
48
|
|
49 ORTHANC_FORCE_INLINE
|
|
50 static PixelFormat GetPixelFormat()
|
|
51 {
|
|
52 return format;
|
|
53 }
|
|
54
|
|
55 ORTHANC_FORCE_INLINE
|
|
56 static PixelType IntegerToPixel(int64_t value)
|
|
57 {
|
|
58 if (value < static_cast<int64_t>(std::numeric_limits<PixelType>::min()) ||
|
|
59 value > static_cast<int64_t>(std::numeric_limits<PixelType>::max()))
|
|
60 {
|
|
61 throw OrthancException(ErrorCode_ParameterOutOfRange);
|
|
62 }
|
|
63 else
|
|
64 {
|
|
65 return static_cast<PixelType>(value);
|
|
66 }
|
|
67 }
|
|
68
|
|
69 ORTHANC_FORCE_INLINE
|
|
70 static void SetZero(PixelType& target)
|
|
71 {
|
|
72 target = 0;
|
|
73 }
|
|
74
|
|
75 ORTHANC_FORCE_INLINE
|
|
76 static void SetMinValue(PixelType& target)
|
|
77 {
|
|
78 target = std::numeric_limits<PixelType>::min();
|
|
79 }
|
|
80
|
|
81 ORTHANC_FORCE_INLINE
|
|
82 static void SetMaxValue(PixelType& target)
|
|
83 {
|
|
84 target = std::numeric_limits<PixelType>::max();
|
|
85 }
|
|
86
|
|
87 ORTHANC_FORCE_INLINE
|
|
88 static void Copy(PixelType& target,
|
|
89 const PixelType& source)
|
|
90 {
|
|
91 target = source;
|
|
92 }
|
|
93
|
|
94 ORTHANC_FORCE_INLINE
|
|
95 static float PixelToFloat(const PixelType& source)
|
|
96 {
|
|
97 return static_cast<float>(source);
|
|
98 }
|
|
99
|
|
100 ORTHANC_FORCE_INLINE
|
|
101 static void FloatToPixel(PixelType& target,
|
|
102 float value)
|
|
103 {
|
|
104 if (value < static_cast<float>(std::numeric_limits<PixelType>::min()))
|
|
105 {
|
|
106 target = std::numeric_limits<PixelType>::min();
|
|
107 }
|
|
108 else if (value > static_cast<float>(std::numeric_limits<PixelType>::max()))
|
|
109 {
|
|
110 target = std::numeric_limits<PixelType>::max();
|
|
111 }
|
|
112 else
|
|
113 {
|
|
114 target = static_cast<PixelType>(value);
|
|
115 }
|
|
116 }
|
|
117
|
|
118 ORTHANC_FORCE_INLINE
|
|
119 static bool IsEqual(const PixelType& a,
|
|
120 const PixelType& b)
|
|
121 {
|
|
122 return a == b;
|
|
123 }
|
|
124 };
|
|
125
|
|
126
|
|
127 template <PixelFormat Format>
|
|
128 struct PixelTraits;
|
|
129
|
|
130
|
|
131 template <>
|
|
132 struct PixelTraits<PixelFormat_Grayscale8> :
|
|
133 public IntegerPixelTraits<PixelFormat_Grayscale8, uint8_t>
|
|
134 {
|
|
135 };
|
|
136
|
|
137
|
|
138 template <>
|
|
139 struct PixelTraits<PixelFormat_Grayscale16> :
|
|
140 public IntegerPixelTraits<PixelFormat_Grayscale16, uint16_t>
|
|
141 {
|
|
142 };
|
|
143
|
|
144
|
|
145 template <>
|
|
146 struct PixelTraits<PixelFormat_SignedGrayscale16> :
|
|
147 public IntegerPixelTraits<PixelFormat_SignedGrayscale16, int16_t>
|
|
148 {
|
|
149 };
|
|
150
|
|
151
|
|
152 template <>
|
|
153 struct PixelTraits<PixelFormat_RGB24>
|
|
154 {
|
|
155 struct PixelType
|
|
156 {
|
|
157 uint8_t red_;
|
|
158 uint8_t green_;
|
|
159 uint8_t blue_;
|
|
160 };
|
|
161
|
|
162 ORTHANC_FORCE_INLINE
|
|
163 static PixelFormat GetPixelFormat()
|
|
164 {
|
|
165 return PixelFormat_RGB24;
|
|
166 }
|
|
167
|
|
168 ORTHANC_FORCE_INLINE
|
|
169 static void SetZero(PixelType& target)
|
|
170 {
|
|
171 target.red_ = 0;
|
|
172 target.green_ = 0;
|
|
173 target.blue_ = 0;
|
|
174 }
|
|
175
|
|
176 ORTHANC_FORCE_INLINE
|
|
177 static void Copy(PixelType& target,
|
|
178 const PixelType& source)
|
|
179 {
|
|
180 target.red_ = source.red_;
|
|
181 target.green_ = source.green_;
|
|
182 target.blue_ = source.blue_;
|
|
183 }
|
|
184
|
|
185 ORTHANC_FORCE_INLINE
|
|
186 static bool IsEqual(const PixelType& a,
|
|
187 const PixelType& b)
|
|
188 {
|
|
189 return (a.red_ == b.red_ &&
|
|
190 a.green_ == b.green_ &&
|
|
191 a.blue_ == b.blue_);
|
|
192 }
|
|
193
|
|
194 ORTHANC_FORCE_INLINE
|
|
195 static void FloatToPixel(PixelType& target,
|
|
196 float value)
|
|
197 {
|
|
198 uint8_t v;
|
|
199 PixelTraits<PixelFormat_Grayscale8>::FloatToPixel(v, value);
|
|
200
|
|
201 target.red_ = v;
|
|
202 target.green_ = v;
|
|
203 target.blue_ = v;
|
|
204 }
|
|
205 };
|
|
206
|
|
207
|
|
208 template <>
|
|
209 struct PixelTraits<PixelFormat_BGRA32>
|
|
210 {
|
|
211 struct PixelType
|
|
212 {
|
|
213 uint8_t blue_;
|
|
214 uint8_t green_;
|
|
215 uint8_t red_;
|
|
216 uint8_t alpha_;
|
|
217 };
|
|
218
|
|
219 ORTHANC_FORCE_INLINE
|
|
220 static PixelFormat GetPixelFormat()
|
|
221 {
|
|
222 return PixelFormat_BGRA32;
|
|
223 }
|
|
224
|
|
225 ORTHANC_FORCE_INLINE
|
|
226 static void SetZero(PixelType& target)
|
|
227 {
|
|
228 target.blue_ = 0;
|
|
229 target.green_ = 0;
|
|
230 target.red_ = 0;
|
|
231 target.alpha_ = 0;
|
|
232 }
|
|
233
|
|
234 ORTHANC_FORCE_INLINE
|
|
235 static void Copy(PixelType& target,
|
|
236 const PixelType& source)
|
|
237 {
|
|
238 target.blue_ = source.blue_;
|
|
239 target.green_ = source.green_;
|
|
240 target.red_ = source.red_;
|
|
241 target.alpha_ = source.alpha_;
|
|
242 }
|
|
243
|
|
244 ORTHANC_FORCE_INLINE
|
|
245 static bool IsEqual(const PixelType& a,
|
|
246 const PixelType& b)
|
|
247 {
|
|
248 return (a.blue_ == b.blue_ &&
|
|
249 a.green_ == b.green_ &&
|
|
250 a.red_ == b.red_ &&
|
|
251 a.alpha_ == b.alpha_);
|
|
252 }
|
|
253
|
|
254 ORTHANC_FORCE_INLINE
|
|
255 static void FloatToPixel(PixelType& target,
|
|
256 float value)
|
|
257 {
|
|
258 uint8_t v;
|
|
259 PixelTraits<PixelFormat_Grayscale8>::FloatToPixel(v, value);
|
|
260
|
|
261 target.blue_ = v;
|
|
262 target.green_ = v;
|
|
263 target.red_ = v;
|
|
264 target.alpha_ = 255;
|
|
265 }
|
|
266 };
|
|
267 }
|