Mercurial > hg > orthanc
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 |