comparison OrthancServer/ParsedDicomFile.cpp @ 1689:26083d84d237

refactoring
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 07 Oct 2015 16:54:05 +0200
parents 14a32b2fa63e
children 558b25228a23
comparison
equal deleted inserted replaced
1688:27d70e9ee2e4 1689:26083d84d237
517 SendPathValueForLeaf(output, uri.back(), *dicom, transferSyntax); 517 SendPathValueForLeaf(output, uri.back(), *dicom, transferSyntax);
518 } 518 }
519 } 519 }
520 520
521 521
522
523
524
525 static DcmElement* CreateElementForTag(const DicomTag& tag)
526 {
527 DcmTag key(tag.GetGroup(), tag.GetElement());
528
529 switch (key.getEVR())
530 {
531 // http://support.dcmtk.org/docs/dcvr_8h-source.html
532
533 /**
534 * TODO.
535 **/
536
537 case EVR_OB: // other byte
538 case EVR_OF: // other float
539 case EVR_OW: // other word
540 case EVR_AT: // attribute tag
541 throw OrthancException(ErrorCode_NotImplemented);
542
543 case EVR_UN: // unknown value representation
544 throw OrthancException(ErrorCode_ParameterOutOfRange);
545
546
547 /**
548 * String types.
549 * http://support.dcmtk.org/docs/classDcmByteString.html
550 **/
551
552 case EVR_AS: // age string
553 return new DcmAgeString(key);
554
555 case EVR_AE: // application entity title
556 return new DcmApplicationEntity(key);
557
558 case EVR_CS: // code string
559 return new DcmCodeString(key);
560
561 case EVR_DA: // date string
562 return new DcmDate(key);
563
564 case EVR_DT: // date time string
565 return new DcmDateTime(key);
566
567 case EVR_DS: // decimal string
568 return new DcmDecimalString(key);
569
570 case EVR_IS: // integer string
571 return new DcmIntegerString(key);
572
573 case EVR_TM: // time string
574 return new DcmTime(key);
575
576 case EVR_UI: // unique identifier
577 return new DcmUniqueIdentifier(key);
578
579 case EVR_ST: // short text
580 return new DcmShortText(key);
581
582 case EVR_LO: // long string
583 return new DcmLongString(key);
584
585 case EVR_LT: // long text
586 return new DcmLongText(key);
587
588 case EVR_UT: // unlimited text
589 return new DcmUnlimitedText(key);
590
591 case EVR_SH: // short string
592 return new DcmShortString(key);
593
594 case EVR_PN: // person name
595 return new DcmPersonName(key);
596
597
598 /**
599 * Numerical types
600 **/
601
602 case EVR_SL: // signed long
603 return new DcmSignedLong(key);
604
605 case EVR_SS: // signed short
606 return new DcmSignedShort(key);
607
608 case EVR_UL: // unsigned long
609 return new DcmUnsignedLong(key);
610
611 case EVR_US: // unsigned short
612 return new DcmUnsignedShort(key);
613
614 case EVR_FL: // float single-precision
615 return new DcmFloatingPointSingle(key);
616
617 case EVR_FD: // float double-precision
618 return new DcmFloatingPointDouble(key);
619
620
621 /**
622 * Sequence types, should never occur at this point.
623 **/
624
625 case EVR_SQ: // sequence of items
626 throw OrthancException(ErrorCode_ParameterOutOfRange);
627
628
629 /**
630 * Internal to DCMTK.
631 **/
632
633 case EVR_ox: // OB or OW depending on context
634 case EVR_xs: // SS or US depending on context
635 case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name)
636 case EVR_na: // na="not applicable", for data which has no VR
637 case EVR_up: // up="unsigned pointer", used internally for DICOMDIR suppor
638 case EVR_item: // used internally for items
639 case EVR_metainfo: // used internally for meta info datasets
640 case EVR_dataset: // used internally for datasets
641 case EVR_fileFormat: // used internally for DICOM files
642 case EVR_dicomDir: // used internally for DICOMDIR objects
643 case EVR_dirRecord: // used internally for DICOMDIR records
644 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image
645 case EVR_pixelItem: // used internally for pixel items in a compressed image
646 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR)
647 case EVR_PixelData: // used internally for uncompressed pixeld data
648 case EVR_OverlayData: // used internally for overlay data
649 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR
650 default:
651 break;
652 }
653
654 throw OrthancException(ErrorCode_InternalError);
655 }
656
657
658
659 static void FillElementWithString(DcmElement& element,
660 const DicomTag& tag,
661 const std::string& value)
662 {
663 DcmTag key(tag.GetGroup(), tag.GetElement());
664 bool ok = false;
665
666 try
667 {
668 switch (key.getEVR())
669 {
670 // http://support.dcmtk.org/docs/dcvr_8h-source.html
671
672 /**
673 * TODO.
674 **/
675
676 case EVR_OB: // other byte
677 case EVR_OF: // other float
678 case EVR_OW: // other word
679 case EVR_AT: // attribute tag
680 throw OrthancException(ErrorCode_NotImplemented);
681
682 case EVR_UN: // unknown value representation
683 throw OrthancException(ErrorCode_ParameterOutOfRange);
684
685
686 /**
687 * String types.
688 **/
689
690 case EVR_DS: // decimal string
691 case EVR_IS: // integer string
692 case EVR_AS: // age string
693 case EVR_DA: // date string
694 case EVR_DT: // date time string
695 case EVR_TM: // time string
696 case EVR_AE: // application entity title
697 case EVR_CS: // code string
698 case EVR_SH: // short string
699 case EVR_LO: // long string
700 case EVR_ST: // short text
701 case EVR_LT: // long text
702 case EVR_UT: // unlimited text
703 case EVR_PN: // person name
704 case EVR_UI: // unique identifier
705 {
706 ok = element.putString(value.c_str()).good();
707 break;
708 }
709
710
711 /**
712 * Numerical types
713 **/
714
715 case EVR_SL: // signed long
716 {
717 ok = element.putSint32(boost::lexical_cast<Sint32>(value)).good();
718 break;
719 }
720
721 case EVR_SS: // signed short
722 {
723 ok = element.putSint16(boost::lexical_cast<Sint16>(value)).good();
724 break;
725 }
726
727 case EVR_UL: // unsigned long
728 {
729 ok = element.putUint32(boost::lexical_cast<Uint32>(value)).good();
730 break;
731 }
732
733 case EVR_US: // unsigned short
734 {
735 ok = element.putUint16(boost::lexical_cast<Uint16>(value)).good();
736 break;
737 }
738
739 case EVR_FL: // float single-precision
740 {
741 ok = element.putFloat32(boost::lexical_cast<float>(value)).good();
742 break;
743 }
744
745 case EVR_FD: // float double-precision
746 {
747 ok = element.putFloat64(boost::lexical_cast<double>(value)).good();
748 break;
749 }
750
751
752 /**
753 * Sequence types, should never occur at this point.
754 **/
755
756 case EVR_SQ: // sequence of items
757 {
758 ok = false;
759 break;
760 }
761
762
763 /**
764 * Internal to DCMTK.
765 **/
766
767 case EVR_ox: // OB or OW depending on context
768 case EVR_xs: // SS or US depending on context
769 case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name)
770 case EVR_na: // na="not applicable", for data which has no VR
771 case EVR_up: // up="unsigned pointer", used internally for DICOMDIR suppor
772 case EVR_item: // used internally for items
773 case EVR_metainfo: // used internally for meta info datasets
774 case EVR_dataset: // used internally for datasets
775 case EVR_fileFormat: // used internally for DICOM files
776 case EVR_dicomDir: // used internally for DICOMDIR objects
777 case EVR_dirRecord: // used internally for DICOMDIR records
778 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image
779 case EVR_pixelItem: // used internally for pixel items in a compressed image
780 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR)
781 case EVR_PixelData: // used internally for uncompressed pixeld data
782 case EVR_OverlayData: // used internally for overlay data
783 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR
784 default:
785 break;
786 }
787 }
788 catch (boost::bad_lexical_cast&)
789 {
790 ok = false;
791 }
792
793 if (!ok)
794 {
795 throw OrthancException(ErrorCode_InternalError);
796 }
797 }
798
799
800 void ParsedDicomFile::Remove(const DicomTag& tag) 522 void ParsedDicomFile::Remove(const DicomTag& tag)
801 { 523 {
802 DcmTagKey key(tag.GetGroup(), tag.GetElement()); 524 DcmTagKey key(tag.GetGroup(), tag.GetElement());
803 DcmElement* element = pimpl_->file_->getDataset()->remove(key); 525 DcmElement* element = pimpl_->file_->getDataset()->remove(key);
804 if (element != NULL) 526 if (element != NULL)
855 } 577 }
856 } 578 }
857 } 579 }
858 580
859 581
860
861
862 void ParsedDicomFile::Insert(const DicomTag& tag, 582 void ParsedDicomFile::Insert(const DicomTag& tag,
863 const std::string& value) 583 const std::string& value)
864 { 584 {
865 OFCondition cond; 585 OFCondition cond;
866 586
874 cond = pimpl_->file_->getDataset()->putAndInsertUint8Array 594 cond = pimpl_->file_->getDataset()->putAndInsertUint8Array
875 (key, (const Uint8*) value.c_str(), value.size(), false); 595 (key, (const Uint8*) value.c_str(), value.size(), false);
876 } 596 }
877 else 597 else
878 { 598 {
879 std::auto_ptr<DcmElement> element(CreateElementForTag(tag)); 599 std::auto_ptr<DcmElement> element(FromDcmtkBridge::CreateElementForTag(tag));
880 FillElementWithString(*element, tag, value); 600 FromDcmtkBridge::FillElementWithString(*element, tag, value, false);
881 601
882 cond = pimpl_->file_->getDataset()->insert(element.release(), false, false); 602 cond = pimpl_->file_->getDataset()->insert(element.release(), false, false);
883 } 603 }
884 604
885 if (!cond.good()) 605 if (!cond.good())
914 return; 634 return;
915 } 635 }
916 } 636 }
917 else 637 else
918 { 638 {
919 if (FromDcmtkBridge::IsPrivateTag(tag) || 639 FromDcmtkBridge::FillElementWithString(*element, tag, value, false);
920 FromDcmtkBridge::IsUnknownTag(tag))
921 {
922 if (!element->putUint8Array((const Uint8*) value.c_str(), value.size()).good())
923 {
924 throw OrthancException(ErrorCode_InternalError);
925 }
926 }
927 else
928 {
929 FillElementWithString(*element, tag, value);
930 }
931 } 640 }
932 641
933 642
934 /** 643 /**
935 * dcmodify will automatically correct 'Media Storage SOP Class 644 * dcmodify will automatically correct 'Media Storage SOP Class