Mercurial > hg > orthanc
comparison Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp @ 2464:61fc5133e5d5
Fix for Osimis issue WVB-319: Some images are not loading in US_MF
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 05 Jan 2018 16:38:25 +0100 |
parents | 878b59270859 |
children | a5196a7d98c6 |
comparison
equal
deleted
inserted
replaced
2463:be5c0f4155f6 | 2464:61fc5133e5d5 |
---|---|
112 } | 112 } |
113 else | 113 else |
114 { | 114 { |
115 if (image.GetPixelFormat().GetSamplesPerPixel() == 3 && | 115 if (image.GetPixelFormat().GetSamplesPerPixel() == 3 && |
116 image.GetPhotometricInterpretation() != gdcm::PhotometricInterpretation::RGB && | 116 image.GetPhotometricInterpretation() != gdcm::PhotometricInterpretation::RGB && |
117 image.GetPhotometricInterpretation() != gdcm::PhotometricInterpretation::YBR_FULL && | |
117 (image.GetTransferSyntax() != gdcm::TransferSyntax::JPEG2000Lossless || | 118 (image.GetTransferSyntax() != gdcm::TransferSyntax::JPEG2000Lossless || |
118 image.GetPhotometricInterpretation() != gdcm::PhotometricInterpretation::YBR_RCT)) | 119 image.GetPhotometricInterpretation() != gdcm::PhotometricInterpretation::YBR_RCT)) |
119 { | 120 { |
120 photometric_.reset(new gdcm::ImageChangePhotometricInterpretation()); | 121 photometric_.reset(new gdcm::ImageChangePhotometricInterpretation()); |
121 photometric_->SetInput(image); | 122 photometric_->SetInput(image); |
190 throw std::runtime_error("Unsupported pixel format"); | 191 throw std::runtime_error("Unsupported pixel format"); |
191 } | 192 } |
192 } | 193 } |
193 else if (image.GetPixelFormat().GetSamplesPerPixel() == 3 && | 194 else if (image.GetPixelFormat().GetSamplesPerPixel() == 3 && |
194 (image.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::RGB || | 195 (image.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::RGB || |
196 image.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::YBR_FULL || | |
195 image.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::YBR_RCT)) | 197 image.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::YBR_RCT)) |
196 { | 198 { |
197 switch (image.GetPixelFormat()) | 199 switch (image.GetPixelFormat()) |
198 { | 200 { |
199 case gdcm::PixelFormat::UINT8: | 201 case gdcm::PixelFormat::UINT8: |
255 default: | 257 default: |
256 throw std::runtime_error("Unsupport pixel format"); | 258 throw std::runtime_error("Unsupport pixel format"); |
257 } | 259 } |
258 } | 260 } |
259 | 261 |
262 static void ConvertYbrToRgb(uint8_t rgb[3], | |
263 const uint8_t ybr[3]) | |
264 { | |
265 // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2 | |
266 // https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion | |
267 | |
268 const float Y = ybr[0]; | |
269 const float Cb = ybr[1]; | |
270 const float Cr = ybr[2]; | |
271 | |
272 const float result[3] = { | |
273 Y + 1.402f * (Cr - 128.0f), | |
274 Y - 0.344136f * (Cb - 128.0f) - 0.714136f * (Cr - 128.0f), | |
275 Y + 1.772f * (Cb - 128.0f) | |
276 }; | |
277 | |
278 for (uint8_t i = 0; i < 3 ; i++) | |
279 { | |
280 if (result[i] < 0) | |
281 { | |
282 rgb[i] = 0; | |
283 } | |
284 else if (result[i] > 255) | |
285 { | |
286 rgb[i] = 255; | |
287 } | |
288 else | |
289 { | |
290 rgb[i] = static_cast<uint8_t>(result[i]); | |
291 } | |
292 } | |
293 } | |
294 | |
295 | |
296 static void FixPhotometricInterpretation(OrthancImageWrapper& image, | |
297 gdcm::PhotometricInterpretation interpretation) | |
298 { | |
299 switch (interpretation) | |
300 { | |
301 case gdcm::PhotometricInterpretation::RGB: | |
302 return; | |
303 | |
304 case gdcm::PhotometricInterpretation::YBR_FULL: | |
305 { | |
306 // Fix for Osimis issue WVB-319: Some images are not loading in US_MF | |
307 | |
308 uint32_t width = image.GetWidth(); | |
309 uint32_t height = image.GetHeight(); | |
310 uint32_t pitch = image.GetPitch(); | |
311 uint8_t* buffer = reinterpret_cast<uint8_t*>(image.GetBuffer()); | |
312 | |
313 if (image.GetFormat() != OrthancPluginPixelFormat_RGB24 || | |
314 pitch < 3 * width) | |
315 { | |
316 throw std::runtime_error("Internal error"); | |
317 } | |
318 | |
319 for (uint32_t y = 0; y < height; y++) | |
320 { | |
321 uint8_t* p = buffer + y * pitch; | |
322 for (uint32_t x = 0; x < width; x++, p += 3) | |
323 { | |
324 const uint8_t ybr[3] = { p[0], p[1], p[2] }; | |
325 uint8_t rgb[3]; | |
326 ConvertYbrToRgb(rgb, ybr); | |
327 p[0] = rgb[0]; | |
328 p[1] = rgb[1]; | |
329 p[2] = rgb[2]; | |
330 } | |
331 } | |
332 | |
333 return; | |
334 } | |
335 | |
336 default: | |
337 throw std::runtime_error("Unsupported output photometric interpretation"); | |
338 } | |
339 } | |
340 | |
260 | 341 |
261 OrthancPluginImage* GdcmImageDecoder::Decode(OrthancPluginContext* context, | 342 OrthancPluginImage* GdcmImageDecoder::Decode(OrthancPluginContext* context, |
262 unsigned int frameIndex) const | 343 unsigned int frameIndex) const |
263 { | 344 { |
264 unsigned int frames = GetFramesCount(); | 345 unsigned int frames = GetFramesCount(); |
308 memcpy(b, a, sourcePitch); | 389 memcpy(b, a, sourcePitch); |
309 a += sourcePitch; | 390 a += sourcePitch; |
310 b += targetPitch; | 391 b += targetPitch; |
311 } | 392 } |
312 } | 393 } |
313 | 394 |
395 FixPhotometricInterpretation(target, pimpl_->GetImage().GetPhotometricInterpretation()); | |
396 | |
314 return target.Release(); | 397 return target.Release(); |
315 } | 398 } |
316 } | 399 } |