Mercurial > hg > orthanc
comparison OrthancServer/Internals/DicomImageDecoder.cpp @ 942:b3f6fb1130cd
fixes thanks to cppcheck
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 25 Jun 2014 11:36:41 +0200 |
parents | e21d1a5f5934 |
children | f009f7c75069 |
comparison
equal
deleted
inserted
replaced
941:83489fddd8c5 | 942:b3f6fb1130cd |
---|---|
98 #endif | 98 #endif |
99 | 99 |
100 | 100 |
101 namespace Orthanc | 101 namespace Orthanc |
102 { | 102 { |
103 class DicomImageDecoder::ImageSource | |
104 { | |
105 private: | |
106 std::string psmct_; | |
107 std::auto_ptr<DicomIntegerPixelAccessor> slowAccessor_; | |
108 std::auto_ptr<ImageAccessor> fastAccessor_; | |
109 | |
110 public: | |
111 void Setup(DcmDataset& dataset, | |
112 unsigned int frame) | |
113 { | |
114 psmct_.clear(); | |
115 slowAccessor_.reset(NULL); | |
116 fastAccessor_.reset(NULL); | |
117 | |
118 // See also: http://support.dcmtk.org/wiki/dcmtk/howto/accessing-compressed-data | |
119 | |
120 DicomMap m; | |
121 FromDcmtkBridge::Convert(m, dataset); | |
122 | |
123 /** | |
124 * Create an accessor to the raw values of the DICOM image. | |
125 **/ | |
126 | |
127 DcmElement* e; | |
128 if (dataset.findAndGetElement(ToDcmtkBridge::Convert(DICOM_TAG_PIXEL_DATA), e).good() && | |
129 e != NULL) | |
130 { | |
131 Uint8* pixData = NULL; | |
132 if (e->getUint8Array(pixData) == EC_Normal) | |
133 { | |
134 slowAccessor_.reset(new DicomIntegerPixelAccessor(m, pixData, e->getLength())); | |
135 } | |
136 } | |
137 else if (DicomImageDecoder::DecodePsmctRle1(psmct_, dataset)) | |
138 { | |
139 LOG(INFO) << "The PMSCT_RLE1 decoding has succeeded"; | |
140 Uint8* pixData = NULL; | |
141 if (psmct_.size() > 0) | |
142 { | |
143 pixData = reinterpret_cast<Uint8*>(&psmct_[0]); | |
144 } | |
145 | |
146 slowAccessor_.reset(new DicomIntegerPixelAccessor(m, pixData, psmct_.size())); | |
147 } | |
148 | |
149 if (slowAccessor_.get() == NULL) | |
150 { | |
151 throw OrthancException(ErrorCode_BadFileFormat); | |
152 } | |
153 | |
154 slowAccessor_->SetCurrentFrame(frame); | |
155 | |
156 | |
157 /** | |
158 * If possible, create a fast ImageAccessor to the image buffer. | |
159 **/ | |
160 | |
161 | |
162 } | |
163 | |
164 unsigned int GetWidth() const | |
165 { | |
166 assert(slowAccessor_.get() != NULL); | |
167 return slowAccessor_->GetInformation().GetWidth(); | |
168 } | |
169 | |
170 unsigned int GetHeight() const | |
171 { | |
172 assert(slowAccessor_.get() != NULL); | |
173 return slowAccessor_->GetInformation().GetHeight(); | |
174 } | |
175 | |
176 unsigned int GetChannelCount() const | |
177 { | |
178 assert(slowAccessor_.get() != NULL); | |
179 return slowAccessor_->GetInformation().GetChannelCount(); | |
180 } | |
181 | |
182 const DicomIntegerPixelAccessor& GetAccessor() const | |
183 { | |
184 assert(slowAccessor_.get() != NULL); | |
185 return *slowAccessor_; | |
186 } | |
187 | |
188 bool HasFastAccessor() const | |
189 { | |
190 return fastAccessor_.get() != NULL; | |
191 } | |
192 | |
193 const ImageAccessor& GetFastAccessor() const | |
194 { | |
195 assert(HasFastAccessor()); | |
196 return *fastAccessor_; | |
197 } | |
198 }; | |
199 | |
200 | |
201 static const DicomTag DICOM_TAG_CONTENT(0x07a1, 0x100a); | 103 static const DicomTag DICOM_TAG_CONTENT(0x07a1, 0x100a); |
202 static const DicomTag DICOM_TAG_COMPRESSION_TYPE(0x07a1, 0x1011); | 104 static const DicomTag DICOM_TAG_COMPRESSION_TYPE(0x07a1, 0x1011); |
203 | 105 |
204 bool DicomImageDecoder::IsPsmctRle1(DcmDataset& dataset) | 106 |
107 static bool IsJpegLossless(const DcmDataset& dataset) | |
108 { | |
109 // http://support.dcmtk.org/docs/dcxfer_8h-source.html | |
110 return (dataset.getOriginalXfer() == EXS_JPEGLSLossless || | |
111 dataset.getOriginalXfer() == EXS_JPEGLSLossy); | |
112 } | |
113 | |
114 | |
115 static bool IsPsmctRle1(DcmDataset& dataset) | |
205 { | 116 { |
206 DcmElement* e; | 117 DcmElement* e; |
207 char* c; | 118 char* c; |
208 | 119 |
209 // Check whether the DICOM instance contains an image encoded with | 120 // Check whether the DICOM instance contains an image encoded with |
222 return true; | 133 return true; |
223 } | 134 } |
224 } | 135 } |
225 | 136 |
226 | 137 |
227 bool DicomImageDecoder::DecodePsmctRle1(std::string& output, | 138 static bool DecodePsmctRle1(std::string& output, |
228 DcmDataset& dataset) | 139 DcmDataset& dataset) |
229 { | 140 { |
230 // Check whether the DICOM instance contains an image encoded with | 141 // Check whether the DICOM instance contains an image encoded with |
231 // the PMSCT_RLE1 scheme. | 142 // the PMSCT_RLE1 scheme. |
232 if (!IsPsmctRle1(dataset)) | 143 if (!IsPsmctRle1(dataset)) |
233 { | 144 { |
307 | 218 |
308 return true; | 219 return true; |
309 } | 220 } |
310 | 221 |
311 | 222 |
223 class DicomImageDecoder::ImageSource | |
224 { | |
225 private: | |
226 std::string psmct_; | |
227 std::auto_ptr<DicomIntegerPixelAccessor> slowAccessor_; | |
228 std::auto_ptr<ImageAccessor> fastAccessor_; | |
229 | |
230 public: | |
231 void Setup(DcmDataset& dataset, | |
232 unsigned int frame) | |
233 { | |
234 psmct_.clear(); | |
235 slowAccessor_.reset(NULL); | |
236 fastAccessor_.reset(NULL); | |
237 | |
238 // See also: http://support.dcmtk.org/wiki/dcmtk/howto/accessing-compressed-data | |
239 | |
240 DicomMap m; | |
241 FromDcmtkBridge::Convert(m, dataset); | |
242 | |
243 /** | |
244 * Create an accessor to the raw values of the DICOM image. | |
245 **/ | |
246 | |
247 DcmElement* e; | |
248 if (dataset.findAndGetElement(ToDcmtkBridge::Convert(DICOM_TAG_PIXEL_DATA), e).good() && | |
249 e != NULL) | |
250 { | |
251 Uint8* pixData = NULL; | |
252 if (e->getUint8Array(pixData) == EC_Normal) | |
253 { | |
254 slowAccessor_.reset(new DicomIntegerPixelAccessor(m, pixData, e->getLength())); | |
255 } | |
256 } | |
257 else if (DecodePsmctRle1(psmct_, dataset)) | |
258 { | |
259 LOG(INFO) << "The PMSCT_RLE1 decoding has succeeded"; | |
260 Uint8* pixData = NULL; | |
261 if (psmct_.size() > 0) | |
262 { | |
263 pixData = reinterpret_cast<Uint8*>(&psmct_[0]); | |
264 } | |
265 | |
266 slowAccessor_.reset(new DicomIntegerPixelAccessor(m, pixData, psmct_.size())); | |
267 } | |
268 | |
269 if (slowAccessor_.get() == NULL) | |
270 { | |
271 throw OrthancException(ErrorCode_BadFileFormat); | |
272 } | |
273 | |
274 slowAccessor_->SetCurrentFrame(frame); | |
275 | |
276 | |
277 /** | |
278 * If possible, create a fast ImageAccessor to the image buffer. | |
279 **/ | |
280 | |
281 | |
282 } | |
283 | |
284 unsigned int GetWidth() const | |
285 { | |
286 assert(slowAccessor_.get() != NULL); | |
287 return slowAccessor_->GetInformation().GetWidth(); | |
288 } | |
289 | |
290 unsigned int GetHeight() const | |
291 { | |
292 assert(slowAccessor_.get() != NULL); | |
293 return slowAccessor_->GetInformation().GetHeight(); | |
294 } | |
295 | |
296 unsigned int GetChannelCount() const | |
297 { | |
298 assert(slowAccessor_.get() != NULL); | |
299 return slowAccessor_->GetInformation().GetChannelCount(); | |
300 } | |
301 | |
302 const DicomIntegerPixelAccessor& GetAccessor() const | |
303 { | |
304 assert(slowAccessor_.get() != NULL); | |
305 return *slowAccessor_; | |
306 } | |
307 | |
308 bool HasFastAccessor() const | |
309 { | |
310 return fastAccessor_.get() != NULL; | |
311 } | |
312 | |
313 const ImageAccessor& GetFastAccessor() const | |
314 { | |
315 assert(HasFastAccessor()); | |
316 return *fastAccessor_; | |
317 } | |
318 }; | |
319 | |
320 | |
312 void DicomImageDecoder::SetupImageBuffer(ImageBuffer& target, | 321 void DicomImageDecoder::SetupImageBuffer(ImageBuffer& target, |
313 DcmDataset& dataset) | 322 DcmDataset& dataset) |
314 { | 323 { |
315 DicomMap m; | 324 DicomMap m; |
316 FromDcmtkBridge::Convert(m, dataset); | 325 FromDcmtkBridge::Convert(m, dataset); |
328 } | 337 } |
329 | 338 |
330 target.SetHeight(info.GetHeight()); | 339 target.SetHeight(info.GetHeight()); |
331 target.SetWidth(info.GetWidth()); | 340 target.SetWidth(info.GetWidth()); |
332 target.SetFormat(format); | 341 target.SetFormat(format); |
333 } | |
334 | |
335 | |
336 bool DicomImageDecoder::IsJpegLossless(const DcmDataset& dataset) | |
337 { | |
338 // http://support.dcmtk.org/docs/dcxfer_8h-source.html | |
339 return (dataset.getOriginalXfer() == EXS_JPEGLSLossless || | |
340 dataset.getOriginalXfer() == EXS_JPEGLSLossy); | |
341 } | 342 } |
342 | 343 |
343 | 344 |
344 bool DicomImageDecoder::IsUncompressedImage(const DcmDataset& dataset) | 345 bool DicomImageDecoder::IsUncompressedImage(const DcmDataset& dataset) |
345 { | 346 { |