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