Mercurial > hg > orthanc
comparison OrthancServer/DicomProtocol/DicomUserConnection.cpp @ 2202:9b373b7d6713
Fix handling of encodings in C-FIND requests
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 08 Dec 2016 12:45:06 +0100 |
parents | 7219cdce7bba |
children | 21713ce8717b |
comparison
equal
deleted
inserted
replaced
2201:307365d0991a | 2202:9b373b7d6713 |
---|---|
476 } | 476 } |
477 } | 477 } |
478 } | 478 } |
479 | 479 |
480 | 480 |
481 static DcmDataset* ConvertQueryFields(const DicomMap& fields, | 481 static ParsedDicomFile* ConvertQueryFields(const DicomMap& fields, |
482 ModalityManufacturer manufacturer) | 482 ModalityManufacturer manufacturer) |
483 { | 483 { |
484 switch (manufacturer) | 484 switch (manufacturer) |
485 { | 485 { |
486 case ModalityManufacturer_AgfaImpax: | 486 case ModalityManufacturer_AgfaImpax: |
487 case ModalityManufacturer_SyngoVia: | 487 case ModalityManufacturer_SyngoVia: |
511 fix->SetValue(*it, "", false); | 511 fix->SetValue(*it, "", false); |
512 } | 512 } |
513 } | 513 } |
514 } | 514 } |
515 | 515 |
516 return ToDcmtkBridge::Convert(*fix); | 516 return new ParsedDicomFile(*fix); |
517 } | 517 } |
518 | 518 |
519 default: | 519 default: |
520 return ToDcmtkBridge::Convert(fields); | 520 return new ParsedDicomFile(fields); |
521 } | 521 } |
522 } | 522 } |
523 | 523 |
524 | 524 |
525 static void ExecuteFind(DicomFindAnswers& answers, | 525 static void ExecuteFind(DicomFindAnswers& answers, |
575 DicomMap fields; | 575 DicomMap fields; |
576 FixFindQuery(fields, level, originalFields); | 576 FixFindQuery(fields, level, originalFields); |
577 | 577 |
578 CheckIsOpen(); | 578 CheckIsOpen(); |
579 | 579 |
580 std::auto_ptr<DcmDataset> dataset(ConvertQueryFields(fields, manufacturer_)); | 580 std::auto_ptr<ParsedDicomFile> query(ConvertQueryFields(fields, manufacturer_)); |
581 DcmDataset* dataset = query->GetDcmtkObject().getDataset(); | |
582 | |
581 const char* clevel = NULL; | 583 const char* clevel = NULL; |
582 const char* sopClass = NULL; | 584 const char* sopClass = NULL; |
583 | 585 |
584 switch (level) | 586 switch (level) |
585 { | 587 { |
586 case ResourceType_Patient: | 588 case ResourceType_Patient: |
587 clevel = "PATIENT"; | 589 clevel = "PATIENT"; |
588 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "PATIENT"); | 590 DU_putStringDOElement(dataset, DcmTagKey(0x0008, 0x0052), "PATIENT"); |
589 sopClass = UID_FINDPatientRootQueryRetrieveInformationModel; | 591 sopClass = UID_FINDPatientRootQueryRetrieveInformationModel; |
590 break; | 592 break; |
591 | 593 |
592 case ResourceType_Study: | 594 case ResourceType_Study: |
593 clevel = "STUDY"; | 595 clevel = "STUDY"; |
594 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "STUDY"); | 596 DU_putStringDOElement(dataset, DcmTagKey(0x0008, 0x0052), "STUDY"); |
595 sopClass = UID_FINDStudyRootQueryRetrieveInformationModel; | 597 sopClass = UID_FINDStudyRootQueryRetrieveInformationModel; |
596 break; | 598 break; |
597 | 599 |
598 case ResourceType_Series: | 600 case ResourceType_Series: |
599 clevel = "SERIES"; | 601 clevel = "SERIES"; |
600 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "SERIES"); | 602 DU_putStringDOElement(dataset, DcmTagKey(0x0008, 0x0052), "SERIES"); |
601 sopClass = UID_FINDStudyRootQueryRetrieveInformationModel; | 603 sopClass = UID_FINDStudyRootQueryRetrieveInformationModel; |
602 break; | 604 break; |
603 | 605 |
604 case ResourceType_Instance: | 606 case ResourceType_Instance: |
605 clevel = "INSTANCE"; | 607 clevel = "INSTANCE"; |
607 manufacturer_ == ModalityManufacturer_Dcm4Chee) | 609 manufacturer_ == ModalityManufacturer_Dcm4Chee) |
608 { | 610 { |
609 // This is a particular case for ClearCanvas, thanks to Peter Somlo <peter.somlo@gmail.com>. | 611 // This is a particular case for ClearCanvas, thanks to Peter Somlo <peter.somlo@gmail.com>. |
610 // https://groups.google.com/d/msg/orthanc-users/j-6C3MAVwiw/iolB9hclom8J | 612 // https://groups.google.com/d/msg/orthanc-users/j-6C3MAVwiw/iolB9hclom8J |
611 // http://www.clearcanvas.ca/Home/Community/OldForums/tabid/526/aff/11/aft/14670/afv/topic/Default.aspx | 613 // http://www.clearcanvas.ca/Home/Community/OldForums/tabid/526/aff/11/aft/14670/afv/topic/Default.aspx |
612 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "IMAGE"); | 614 DU_putStringDOElement(dataset, DcmTagKey(0x0008, 0x0052), "IMAGE"); |
613 } | 615 } |
614 else | 616 else |
615 { | 617 { |
616 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "INSTANCE"); | 618 DU_putStringDOElement(dataset, DcmTagKey(0x0008, 0x0052), "INSTANCE"); |
617 } | 619 } |
618 | 620 |
619 sopClass = UID_FINDStudyRootQueryRetrieveInformationModel; | 621 sopClass = UID_FINDStudyRootQueryRetrieveInformationModel; |
620 break; | 622 break; |
621 | 623 |
628 switch (level) | 630 switch (level) |
629 { | 631 { |
630 case ResourceType_Instance: | 632 case ResourceType_Instance: |
631 // SOP Instance UID | 633 // SOP Instance UID |
632 if (!fields.HasTag(0x0008, 0x0018)) | 634 if (!fields.HasTag(0x0008, 0x0018)) |
633 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0018), ""); | 635 DU_putStringDOElement(dataset, DcmTagKey(0x0008, 0x0018), ""); |
634 | 636 |
635 case ResourceType_Series: | 637 case ResourceType_Series: |
636 // Series instance UID | 638 // Series instance UID |
637 if (!fields.HasTag(0x0020, 0x000e)) | 639 if (!fields.HasTag(0x0020, 0x000e)) |
638 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0020, 0x000e), ""); | 640 DU_putStringDOElement(dataset, DcmTagKey(0x0020, 0x000e), ""); |
639 | 641 |
640 case ResourceType_Study: | 642 case ResourceType_Study: |
641 // Accession number | 643 // Accession number |
642 if (!fields.HasTag(0x0008, 0x0050)) | 644 if (!fields.HasTag(0x0008, 0x0050)) |
643 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0050), ""); | 645 DU_putStringDOElement(dataset, DcmTagKey(0x0008, 0x0050), ""); |
644 | 646 |
645 // Study instance UID | 647 // Study instance UID |
646 if (!fields.HasTag(0x0020, 0x000d)) | 648 if (!fields.HasTag(0x0020, 0x000d)) |
647 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0020, 0x000d), ""); | 649 DU_putStringDOElement(dataset, DcmTagKey(0x0020, 0x000d), ""); |
648 | 650 |
649 case ResourceType_Patient: | 651 case ResourceType_Patient: |
650 // Patient ID | 652 // Patient ID |
651 if (!fields.HasTag(0x0010, 0x0020)) | 653 if (!fields.HasTag(0x0010, 0x0020)) |
652 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0010, 0x0020), ""); | 654 DU_putStringDOElement(dataset, DcmTagKey(0x0010, 0x0020), ""); |
653 | 655 |
654 break; | 656 break; |
655 | 657 |
656 default: | 658 default: |
657 throw OrthancException(ErrorCode_ParameterOutOfRange); | 659 throw OrthancException(ErrorCode_ParameterOutOfRange); |
658 } | 660 } |
659 | 661 |
660 assert(clevel != NULL && sopClass != NULL); | 662 assert(clevel != NULL && sopClass != NULL); |
661 ExecuteFind(result, pimpl_->assoc_, dataset.get(), sopClass, false, clevel, pimpl_->dimseTimeout_); | 663 ExecuteFind(result, pimpl_->assoc_, dataset, sopClass, false, clevel, pimpl_->dimseTimeout_); |
662 } | 664 } |
663 | 665 |
664 | 666 |
665 void DicomUserConnection::MoveInternal(const std::string& targetAet, | 667 void DicomUserConnection::MoveInternal(const std::string& targetAet, |
666 ResourceType level, | 668 ResourceType level, |
667 const DicomMap& fields) | 669 const DicomMap& fields) |
668 { | 670 { |
669 CheckIsOpen(); | 671 CheckIsOpen(); |
670 | 672 |
671 std::auto_ptr<DcmDataset> dataset(ConvertQueryFields(fields, manufacturer_)); | 673 std::auto_ptr<ParsedDicomFile> query(ConvertQueryFields(fields, manufacturer_)); |
674 DcmDataset* dataset = query->GetDcmtkObject().getDataset(); | |
672 | 675 |
673 const char* sopClass = UID_MOVEStudyRootQueryRetrieveInformationModel; | 676 const char* sopClass = UID_MOVEStudyRootQueryRetrieveInformationModel; |
674 switch (level) | 677 switch (level) |
675 { | 678 { |
676 case ResourceType_Patient: | 679 case ResourceType_Patient: |
677 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "PATIENT"); | 680 DU_putStringDOElement(dataset, DcmTagKey(0x0008, 0x0052), "PATIENT"); |
678 break; | 681 break; |
679 | 682 |
680 case ResourceType_Study: | 683 case ResourceType_Study: |
681 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "STUDY"); | 684 DU_putStringDOElement(dataset, DcmTagKey(0x0008, 0x0052), "STUDY"); |
682 break; | 685 break; |
683 | 686 |
684 case ResourceType_Series: | 687 case ResourceType_Series: |
685 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "SERIES"); | 688 DU_putStringDOElement(dataset, DcmTagKey(0x0008, 0x0052), "SERIES"); |
686 break; | 689 break; |
687 | 690 |
688 case ResourceType_Instance: | 691 case ResourceType_Instance: |
689 if (manufacturer_ == ModalityManufacturer_ClearCanvas || | 692 if (manufacturer_ == ModalityManufacturer_ClearCanvas || |
690 manufacturer_ == ModalityManufacturer_Dcm4Chee) | 693 manufacturer_ == ModalityManufacturer_Dcm4Chee) |
691 { | 694 { |
692 // This is a particular case for ClearCanvas, thanks to Peter Somlo <peter.somlo@gmail.com>. | 695 // This is a particular case for ClearCanvas, thanks to Peter Somlo <peter.somlo@gmail.com>. |
693 // https://groups.google.com/d/msg/orthanc-users/j-6C3MAVwiw/iolB9hclom8J | 696 // https://groups.google.com/d/msg/orthanc-users/j-6C3MAVwiw/iolB9hclom8J |
694 // http://www.clearcanvas.ca/Home/Community/OldForums/tabid/526/aff/11/aft/14670/afv/topic/Default.aspx | 697 // http://www.clearcanvas.ca/Home/Community/OldForums/tabid/526/aff/11/aft/14670/afv/topic/Default.aspx |
695 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "IMAGE"); | 698 DU_putStringDOElement(dataset, DcmTagKey(0x0008, 0x0052), "IMAGE"); |
696 } | 699 } |
697 else | 700 else |
698 { | 701 { |
699 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "INSTANCE"); | 702 DU_putStringDOElement(dataset, DcmTagKey(0x0008, 0x0052), "INSTANCE"); |
700 } | 703 } |
701 break; | 704 break; |
702 | 705 |
703 default: | 706 default: |
704 throw OrthancException(ErrorCode_ParameterOutOfRange); | 707 throw OrthancException(ErrorCode_ParameterOutOfRange); |
720 strncpy(request.MoveDestination, targetAet.c_str(), DIC_AE_LEN); | 723 strncpy(request.MoveDestination, targetAet.c_str(), DIC_AE_LEN); |
721 | 724 |
722 T_DIMSE_C_MoveRSP response; | 725 T_DIMSE_C_MoveRSP response; |
723 DcmDataset* statusDetail = NULL; | 726 DcmDataset* statusDetail = NULL; |
724 DcmDataset* responseIdentifiers = NULL; | 727 DcmDataset* responseIdentifiers = NULL; |
725 OFCondition cond = DIMSE_moveUser(pimpl_->assoc_, presID, &request, dataset.get(), | 728 OFCondition cond = DIMSE_moveUser(pimpl_->assoc_, presID, &request, dataset, |
726 NULL, NULL, | 729 NULL, NULL, |
727 /*opt_blockMode*/ DIMSE_BLOCKING, | 730 /*opt_blockMode*/ DIMSE_BLOCKING, |
728 /*opt_dimse_timeout*/ pimpl_->dimseTimeout_, | 731 /*opt_dimse_timeout*/ pimpl_->dimseTimeout_, |
729 pimpl_->net_, NULL, NULL, | 732 pimpl_->net_, NULL, NULL, |
730 &response, &statusDetail, &responseIdentifiers); | 733 &response, &statusDetail, &responseIdentifiers); |