comparison OrthancServer/OrthancRestApi/OrthancRestResources.cpp @ 2281:e002430baa41

Fix issue #44 (Bad interpretation of photometric interpretation MONOCHROME1)
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 09 Jun 2017 16:14:52 +0200
parents a3a65de1840f
children 563bf878407a
comparison
equal deleted inserted replaced
2280:2e7a8ce24be2 2281:e002430baa41
265 class ImageToEncode 265 class ImageToEncode
266 { 266 {
267 private: 267 private:
268 std::auto_ptr<ImageAccessor>& image_; 268 std::auto_ptr<ImageAccessor>& image_;
269 ImageExtractionMode mode_; 269 ImageExtractionMode mode_;
270 bool invert_;
270 std::string format_; 271 std::string format_;
271 std::string answer_; 272 std::string answer_;
272 273
273 public: 274 public:
274 ImageToEncode(std::auto_ptr<ImageAccessor>& image, 275 ImageToEncode(std::auto_ptr<ImageAccessor>& image,
275 ImageExtractionMode mode) : 276 ImageExtractionMode mode,
277 bool invert) :
276 image_(image), 278 image_(image),
277 mode_(mode) 279 mode_(mode),
280 invert_(invert)
278 { 281 {
279 } 282 }
280 283
281 void Answer(RestApiOutput& output) 284 void Answer(RestApiOutput& output)
282 { 285 {
284 } 287 }
285 288
286 void EncodeUsingPng() 289 void EncodeUsingPng()
287 { 290 {
288 format_ = "image/png"; 291 format_ = "image/png";
289 DicomImageDecoder::ExtractPngImage(answer_, image_, mode_); 292 DicomImageDecoder::ExtractPngImage(answer_, image_, mode_, invert_);
290 } 293 }
291 294
292 void EncodeUsingJpeg(uint8_t quality) 295 void EncodeUsingJpeg(uint8_t quality)
293 { 296 {
294 format_ = "image/jpeg"; 297 format_ = "image/jpeg";
295 DicomImageDecoder::ExtractJpegImage(answer_, image_, mode_, quality); 298 DicomImageDecoder::ExtractJpegImage(answer_, image_, mode_, invert_, quality);
296 } 299 }
297 }; 300 };
298 301
299 class EncodePng : public HttpContentNegociation::IHandler 302 class EncodePng : public HttpContentNegociation::IHandler
300 { 303 {
371 catch (boost::bad_lexical_cast) 374 catch (boost::bad_lexical_cast)
372 { 375 {
373 return; 376 return;
374 } 377 }
375 378
379 bool invert = false;
376 std::auto_ptr<ImageAccessor> decoded; 380 std::auto_ptr<ImageAccessor> decoded;
377 381
378 try 382 try
379 { 383 {
380 std::string publicId = call.GetUriComponent("id", ""); 384 std::string publicId = call.GetUriComponent("id", "");
391 * Note that we call "DecodeUnsafe()": We do not fallback to 395 * Note that we call "DecodeUnsafe()": We do not fallback to
392 * the builtin decoder if no installed decoder plugin is able 396 * the builtin decoder if no installed decoder plugin is able
393 * to decode the image. This allows us to take advantage of 397 * to decode the image. This allows us to take advantage of
394 * the cache below. 398 * the cache below.
395 **/ 399 **/
400
401 if (mode == ImageExtractionMode_Preview &&
402 decoded.get() != NULL)
403 {
404 // TODO Optimize this lookup for photometric interpretation:
405 // It should be implemented by the plugin to avoid parsing
406 // twice the DICOM file
407 ParsedDicomFile parsed(dicomContent);
408
409 PhotometricInterpretation photometric;
410 if (parsed.LookupPhotometricInterpretation(photometric))
411 {
412 invert = (photometric == PhotometricInterpretation_Monochrome1);
413 }
414 }
396 } 415 }
397 #endif 416 #endif
398 417
399 if (decoded.get() == NULL) 418 if (decoded.get() == NULL)
400 { 419 {
401 // Use Orthanc's built-in decoder, using the cache to speed-up 420 // Use Orthanc's built-in decoder, using the cache to speed-up
402 // things on multi-frame images 421 // things on multi-frame images
403 ServerContext::DicomCacheLocker locker(OrthancRestApi::GetContext(call), publicId); 422 ServerContext::DicomCacheLocker locker(context, publicId);
404 decoded.reset(DicomImageDecoder::Decode(locker.GetDicom(), frame)); 423 decoded.reset(DicomImageDecoder::Decode(locker.GetDicom(), frame));
424
425 PhotometricInterpretation photometric;
426 if (mode == ImageExtractionMode_Preview &&
427 locker.GetDicom().LookupPhotometricInterpretation(photometric))
428 {
429 invert = (photometric == PhotometricInterpretation_Monochrome1);
430 }
405 } 431 }
406 } 432 }
407 catch (OrthancException& e) 433 catch (OrthancException& e)
408 { 434 {
409 if (e.GetErrorCode() == ErrorCode_ParameterOutOfRange) 435 if (e.GetErrorCode() == ErrorCode_ParameterOutOfRange)
421 447
422 call.GetOutput().Redirect(root + "app/images/unsupported.png"); 448 call.GetOutput().Redirect(root + "app/images/unsupported.png");
423 } 449 }
424 } 450 }
425 451
426 ImageToEncode image(decoded, mode); 452 ImageToEncode image(decoded, mode, invert);
427 453
428 HttpContentNegociation negociation; 454 HttpContentNegociation negociation;
429 EncodePng png(image); negociation.Register("image/png", png); 455 EncodePng png(image); negociation.Register("image/png", png);
430 EncodeJpeg jpeg(image, call); negociation.Register("image/jpeg", jpeg); 456 EncodeJpeg jpeg(image, call); negociation.Register("image/jpeg", jpeg);
431 457