comparison OrthancServer/FromDcmtkBridge.cpp @ 864:2c545bb20dd3 jpeg

refactoring
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 10 Jun 2014 17:25:57 +0200
parents 3c0d0836f704
children 87791ebc1f50
comparison
equal deleted inserted replaced
863:3c0d0836f704 864:2c545bb20dd3
426 FromDcmtkBridge::ToJson(target, *dicom.getDataset(), maxStringLength); 426 FromDcmtkBridge::ToJson(target, *dicom.getDataset(), maxStringLength);
427 } 427 }
428 } 428 }
429 429
430 430
431 static void ExtractPngImageColorPreview(std::string& result,
432 DicomIntegerPixelAccessor& accessor)
433 {
434 assert(accessor.GetInformation().GetChannelCount() == 3);
435 PngWriter w;
436
437 std::vector<uint8_t> image(accessor.GetInformation().GetWidth() * accessor.GetInformation().GetHeight() * 3, 0);
438 uint8_t* pixel = &image[0];
439
440 for (unsigned int y = 0; y < accessor.GetInformation().GetHeight(); y++)
441 {
442 for (unsigned int x = 0; x < accessor.GetInformation().GetWidth(); x++)
443 {
444 for (unsigned int c = 0; c < 3; c++, pixel++)
445 {
446 int32_t v = accessor.GetValue(x, y, c);
447 if (v < 0)
448 *pixel = 0;
449 else if (v > 255)
450 *pixel = 255;
451 else
452 *pixel = v;
453 }
454 }
455 }
456
457 w.WriteToMemory(result, accessor.GetInformation().GetWidth(), accessor.GetInformation().GetHeight(),
458 accessor.GetInformation().GetWidth() * 3, PixelFormat_RGB24, &image[0]);
459 }
460
461
462 static void ExtractPngImageGrayscalePreview(std::string& result,
463 DicomIntegerPixelAccessor& accessor)
464 {
465 assert(accessor.GetInformation().GetChannelCount() == 1);
466 PngWriter w;
467
468 int32_t min, max;
469 accessor.GetExtremeValues(min, max);
470
471 std::vector<uint8_t> image(accessor.GetInformation().GetWidth() * accessor.GetInformation().GetHeight(), 0);
472 if (min != max)
473 {
474 uint8_t* pixel = &image[0];
475 for (unsigned int y = 0; y < accessor.GetInformation().GetHeight(); y++)
476 {
477 for (unsigned int x = 0; x < accessor.GetInformation().GetWidth(); x++, pixel++)
478 {
479 int32_t v = accessor.GetValue(x, y);
480 *pixel = static_cast<uint8_t>(
481 boost::math::lround(static_cast<float>(v - min) /
482 static_cast<float>(max - min) * 255.0f));
483 }
484 }
485 }
486
487 w.WriteToMemory(result, accessor.GetInformation().GetWidth(), accessor.GetInformation().GetHeight(),
488 accessor.GetInformation().GetWidth(), PixelFormat_Grayscale8, &image[0]);
489 }
490
491
492 template <typename T>
493 static void ExtractPngImageTruncate(std::string& result,
494 DicomIntegerPixelAccessor& accessor,
495 PixelFormat format)
496 {
497 assert(accessor.GetInformation().GetChannelCount() == 1);
498
499 PngWriter w;
500
501 std::vector<T> image(accessor.GetInformation().GetWidth() * accessor.GetInformation().GetHeight(), 0);
502 T* pixel = &image[0];
503 for (unsigned int y = 0; y < accessor.GetInformation().GetHeight(); y++)
504 {
505 for (unsigned int x = 0; x < accessor.GetInformation().GetWidth(); x++, pixel++)
506 {
507 int32_t v = accessor.GetValue(x, y);
508 if (v < static_cast<int32_t>(std::numeric_limits<T>::min()))
509 *pixel = std::numeric_limits<T>::min();
510 else if (v > static_cast<int32_t>(std::numeric_limits<T>::max()))
511 *pixel = std::numeric_limits<T>::max();
512 else
513 *pixel = static_cast<T>(v);
514 }
515 }
516
517 w.WriteToMemory(result, accessor.GetInformation().GetWidth(), accessor.GetInformation().GetHeight(),
518 accessor.GetInformation().GetWidth() * sizeof(T), format, &image[0]);
519 }
520
521
522
523
524 void FromDcmtkBridge::ExtractPngImage(std::string& result, 431 void FromDcmtkBridge::ExtractPngImage(std::string& result,
525 DcmDataset& dataset, 432 DcmDataset& dataset,
526 unsigned int frame, 433 unsigned int frame,
527 ImageExtractionMode mode) 434 ImageExtractionMode mode)
528 { 435 {
529 // TODO CONTINUE THIS
530
531 ImageBuffer tmp; 436 ImageBuffer tmp;
532 bool ok = false; 437 bool ok = false;
533 438
534 switch (mode) 439 switch (mode)
535 { 440 {
551 456
552 default: 457 default:
553 throw OrthancException(ErrorCode_ParameterOutOfRange); 458 throw OrthancException(ErrorCode_ParameterOutOfRange);
554 } 459 }
555 460
556 if (ok) 461 if (!ok)
557 {
558 ImageAccessor accessor(tmp.GetAccessor());
559 PngWriter writer;
560 writer.WriteToMemory(result, accessor);
561 return;
562 }
563 else
564 { 462 {
565 throw OrthancException(ErrorCode_BadFileFormat); 463 throw OrthancException(ErrorCode_BadFileFormat);
566 } 464 }
567 465
568 466 ImageAccessor accessor(tmp.GetAccessor());
569 // See also: http://support.dcmtk.org/wiki/dcmtk/howto/accessing-compressed-data 467 PngWriter writer;
570 468 writer.WriteToMemory(result, accessor);
571 std::auto_ptr<DicomIntegerPixelAccessor> accessor;
572
573 DicomMap m;
574 FromDcmtkBridge::Convert(m, dataset);
575
576 std::string privateContent;
577
578 DcmElement* e;
579 if (dataset.findAndGetElement(ToDcmtkBridge::Convert(DICOM_TAG_PIXEL_DATA), e).good() &&
580 e != NULL)
581 {
582 Uint8* pixData = NULL;
583 if (e->getUint8Array(pixData) == EC_Normal)
584 {
585 accessor.reset(new DicomIntegerPixelAccessor(m, pixData, e->getLength()));
586 accessor->SetCurrentFrame(frame);
587 }
588 }
589 else if (DicomImageDecoder::DecodePsmctRle1(privateContent, dataset))
590 {
591 LOG(INFO) << "The PMSCT_RLE1 decoding has succeeded";
592 Uint8* pixData = NULL;
593 if (privateContent.size() > 0)
594 pixData = reinterpret_cast<Uint8*>(&privateContent[0]);
595 accessor.reset(new DicomIntegerPixelAccessor(m, pixData, privateContent.size()));
596 accessor->SetCurrentFrame(frame);
597 }
598
599 if (accessor.get() == NULL)
600 {
601 throw OrthancException(ErrorCode_BadFileFormat);
602 }
603
604 PixelFormat format;
605 bool supported = false;
606
607 if (accessor->GetInformation().GetChannelCount() == 1)
608 {
609 switch (mode)
610 {
611 case ImageExtractionMode_Preview:
612 supported = true;
613 format = PixelFormat_Grayscale8;
614 break;
615
616 case ImageExtractionMode_UInt8:
617 supported = true;
618 format = PixelFormat_Grayscale8;
619 break;
620
621 case ImageExtractionMode_UInt16:
622 supported = true;
623 format = PixelFormat_Grayscale16;
624 break;
625
626 case ImageExtractionMode_Int16:
627 supported = true;
628 format = PixelFormat_SignedGrayscale16;
629 break;
630
631 default:
632 supported = false;
633 break;
634 }
635 }
636 else if (accessor->GetInformation().GetChannelCount() == 3)
637 {
638 switch (mode)
639 {
640 case ImageExtractionMode_Preview:
641 supported = true;
642 format = PixelFormat_RGB24;
643 break;
644
645 default:
646 supported = false;
647 break;
648 }
649 }
650
651 if (!supported)
652 {
653 throw OrthancException(ErrorCode_NotImplemented);
654 }
655
656 if (accessor.get() == NULL ||
657 accessor->GetInformation().GetWidth() == 0 ||
658 accessor->GetInformation().GetHeight() == 0)
659 {
660 PngWriter w;
661 w.WriteToMemory(result, 0, 0, 0, format, NULL);
662 }
663 else
664 {
665 switch (mode)
666 {
667 case ImageExtractionMode_Preview:
668 if (format == PixelFormat_Grayscale8)
669 ExtractPngImageGrayscalePreview(result, *accessor);
670 else
671 ExtractPngImageColorPreview(result, *accessor);
672 break;
673
674 case ImageExtractionMode_UInt8:
675 ExtractPngImageTruncate<uint8_t>(result, *accessor, format);
676 break;
677
678 case ImageExtractionMode_UInt16:
679 ExtractPngImageTruncate<uint16_t>(result, *accessor, format);
680 break;
681
682 case ImageExtractionMode_Int16:
683 ExtractPngImageTruncate<int16_t>(result, *accessor, format);
684 break;
685
686 default:
687 throw OrthancException(ErrorCode_NotImplemented);
688 }
689 }
690 } 469 }
691 470
692 471
693 void FromDcmtkBridge::ExtractPngImage(std::string& result, 472 void FromDcmtkBridge::ExtractPngImage(std::string& result,
694 const std::string& dicomContent, 473 const std::string& dicomContent,