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 }