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);