comparison Resources/Orthanc/Core/DicomFormat/DicomImageInformation.cpp @ 200:03afbee0cc7b

integration of Orthanc core into Stone
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 23 Mar 2018 11:04:03 +0100
parents
children
comparison
equal deleted inserted replaced
199:dabe9982fca3 200:03afbee0cc7b
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 #include "../PrecompiledHeaders.h"
35
36 #ifndef NOMINMAX
37 #define NOMINMAX
38 #endif
39
40 #include "DicomImageInformation.h"
41
42 #include "../OrthancException.h"
43 #include "../Toolbox.h"
44 #include <boost/lexical_cast.hpp>
45 #include <limits>
46 #include <cassert>
47 #include <stdio.h>
48
49 namespace Orthanc
50 {
51 DicomImageInformation::DicomImageInformation(const DicomMap& values)
52 {
53 unsigned int pixelRepresentation;
54 unsigned int planarConfiguration = 0;
55
56 try
57 {
58 std::string p = values.GetValue(DICOM_TAG_PHOTOMETRIC_INTERPRETATION).GetContent();
59 Toolbox::ToUpperCase(p);
60
61 if (p == "RGB")
62 {
63 photometric_ = PhotometricInterpretation_RGB;
64 }
65 else if (p == "MONOCHROME1")
66 {
67 photometric_ = PhotometricInterpretation_Monochrome1;
68 }
69 else if (p == "MONOCHROME2")
70 {
71 photometric_ = PhotometricInterpretation_Monochrome2;
72 }
73 else if (p == "PALETTE COLOR")
74 {
75 photometric_ = PhotometricInterpretation_Palette;
76 }
77 else if (p == "HSV")
78 {
79 photometric_ = PhotometricInterpretation_HSV;
80 }
81 else if (p == "ARGB")
82 {
83 photometric_ = PhotometricInterpretation_ARGB;
84 }
85 else if (p == "CMYK")
86 {
87 photometric_ = PhotometricInterpretation_CMYK;
88 }
89 else if (p == "YBR_FULL")
90 {
91 photometric_ = PhotometricInterpretation_YBRFull;
92 }
93 else if (p == "YBR_FULL_422")
94 {
95 photometric_ = PhotometricInterpretation_YBRFull422;
96 }
97 else if (p == "YBR_PARTIAL_420")
98 {
99 photometric_ = PhotometricInterpretation_YBRPartial420;
100 }
101 else if (p == "YBR_PARTIAL_422")
102 {
103 photometric_ = PhotometricInterpretation_YBRPartial422;
104 }
105 else if (p == "YBR_ICT")
106 {
107 photometric_ = PhotometricInterpretation_YBR_ICT;
108 }
109 else if (p == "YBR_RCT")
110 {
111 photometric_ = PhotometricInterpretation_YBR_RCT;
112 }
113 else
114 {
115 photometric_ = PhotometricInterpretation_Unknown;
116 }
117
118 width_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_COLUMNS).GetContent());
119 height_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_ROWS).GetContent());
120 bitsAllocated_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_BITS_ALLOCATED).GetContent());
121
122 try
123 {
124 samplesPerPixel_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_SAMPLES_PER_PIXEL).GetContent());
125 }
126 catch (OrthancException&)
127 {
128 samplesPerPixel_ = 1; // Assume 1 color channel
129 }
130
131 try
132 {
133 bitsStored_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_BITS_STORED).GetContent());
134 }
135 catch (OrthancException&)
136 {
137 bitsStored_ = bitsAllocated_;
138 }
139
140 try
141 {
142 highBit_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_HIGH_BIT).GetContent());
143 }
144 catch (OrthancException&)
145 {
146 highBit_ = bitsStored_ - 1;
147 }
148
149 try
150 {
151 pixelRepresentation = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_PIXEL_REPRESENTATION).GetContent());
152 }
153 catch (OrthancException&)
154 {
155 pixelRepresentation = 0; // Assume unsigned pixels
156 }
157
158 if (samplesPerPixel_ > 1)
159 {
160 // The "Planar Configuration" is only set when "Samples per Pixels" is greater than 1
161 // http://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.7.6.3.1.3
162 try
163 {
164 planarConfiguration = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_PLANAR_CONFIGURATION).GetContent());
165 }
166 catch (OrthancException&)
167 {
168 planarConfiguration = 0; // Assume interleaved color channels
169 }
170 }
171 }
172 catch (boost::bad_lexical_cast&)
173 {
174 throw OrthancException(ErrorCode_NotImplemented);
175 }
176 catch (OrthancException&)
177 {
178 throw OrthancException(ErrorCode_NotImplemented);
179 }
180
181 if (values.HasTag(DICOM_TAG_NUMBER_OF_FRAMES))
182 {
183 try
184 {
185 numberOfFrames_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_NUMBER_OF_FRAMES).GetContent());
186 }
187 catch (boost::bad_lexical_cast&)
188 {
189 throw OrthancException(ErrorCode_NotImplemented);
190 }
191 }
192 else
193 {
194 numberOfFrames_ = 1;
195 }
196
197 if ((bitsAllocated_ != 8 && bitsAllocated_ != 16 &&
198 bitsAllocated_ != 24 && bitsAllocated_ != 32) ||
199 numberOfFrames_ == 0 ||
200 (planarConfiguration != 0 && planarConfiguration != 1))
201 {
202 throw OrthancException(ErrorCode_NotImplemented);
203 }
204
205 if (samplesPerPixel_ == 0)
206 {
207 throw OrthancException(ErrorCode_NotImplemented);
208 }
209
210 bytesPerValue_ = bitsAllocated_ / 8;
211
212 isPlanar_ = (planarConfiguration != 0 ? true : false);
213 isSigned_ = (pixelRepresentation != 0 ? true : false);
214 }
215
216
217 bool DicomImageInformation::ExtractPixelFormat(PixelFormat& format,
218 bool ignorePhotometricInterpretation) const
219 {
220 if (photometric_ == PhotometricInterpretation_Palette)
221 {
222 if (GetBitsStored() == 8 && GetChannelCount() == 1 && !IsSigned())
223 {
224 format = PixelFormat_RGB24;
225 return true;
226 }
227
228 if (GetBitsStored() == 16 && GetChannelCount() == 1 && !IsSigned())
229 {
230 format = PixelFormat_RGB48;
231 return true;
232 }
233 }
234
235 if (ignorePhotometricInterpretation ||
236 photometric_ == PhotometricInterpretation_Monochrome1 ||
237 photometric_ == PhotometricInterpretation_Monochrome2)
238 {
239 if (GetBitsStored() == 8 && GetChannelCount() == 1 && !IsSigned())
240 {
241 format = PixelFormat_Grayscale8;
242 return true;
243 }
244
245 if (GetBitsAllocated() == 16 && GetChannelCount() == 1 && !IsSigned())
246 {
247 format = PixelFormat_Grayscale16;
248 return true;
249 }
250
251 if (GetBitsAllocated() == 16 && GetChannelCount() == 1 && IsSigned())
252 {
253 format = PixelFormat_SignedGrayscale16;
254 return true;
255 }
256 }
257
258 if (GetBitsStored() == 8 &&
259 GetChannelCount() == 3 &&
260 !IsSigned() &&
261 (ignorePhotometricInterpretation || photometric_ == PhotometricInterpretation_RGB))
262 {
263 format = PixelFormat_RGB24;
264 return true;
265 }
266
267 return false;
268 }
269
270
271 size_t DicomImageInformation::GetFrameSize() const
272 {
273 return (GetHeight() *
274 GetWidth() *
275 GetBytesPerValue() *
276 GetChannelCount());
277 }
278 }