Mercurial > hg > orthanc
changeset 2204:0158f2de8cad
Fix handling of worklist SCP with ReferencedStudySequence and ReferencedPatientSequence
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 08 Dec 2016 14:46:13 +0100 |
parents | 7d5320c59a05 |
children | 395522e46b2b |
files | NEWS OrthancServer/Internals/FindScp.cpp |
diffstat | 2 files changed, 59 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Thu Dec 08 12:48:34 2016 +0100 +++ b/NEWS Thu Dec 08 14:46:13 2016 +0100 @@ -41,6 +41,7 @@ * Upgrade to curl 7.50.3 for static and Windows builds * Content-Type for JSON documents is now "application/json; charset=utf-8" * Ignore "Group Length" tags in C-FIND queries +* Fix handling of worklist SCP with ReferencedStudySequence and ReferencedPatientSequence Version 1.1.0 (2016/06/27)
--- a/OrthancServer/Internals/FindScp.cpp Thu Dec 08 12:48:34 2016 +0100 +++ b/OrthancServer/Internals/FindScp.cpp Thu Dec 08 14:46:13 2016 +0100 @@ -89,6 +89,48 @@ #include "../OrthancInitialization.h" #include <dcmtk/dcmdata/dcfilefo.h> +#include <dcmtk/dcmdata/dcdeftag.h> + + + +/** + * The function below is extracted from DCMTK 3.6.0, cf. file + * "dcmtk-3.6.0/dcmwlm/libsrc/wldsfs.cc". + **/ + +static void HandleExistentButEmptyReferencedStudyOrPatientSequenceAttributes(DcmDataset *dataset, + const DcmTagKey &sequenceTagKey) +// Date : May 3, 2005 +// Author : Thomas Wilkens +// Task : This function performs a check on a sequence attribute in the given dataset. At two different places +// in the definition of the DICOM worklist management service, a sequence attribute with a return type +// of 2 is mentioned containing two 1C attributes in its item; the condition of the two 1C attributes +// specifies that in case a sequence item is present, then these two attributes must be existent and +// must contain a value. (I am talking about ReferencedStudySequence and ReferencedPatientSequence.) +// In cases where the sequence attribute contains exactly one item with an empty ReferencedSOPClass +// and an empty ReferencedSOPInstance, we want to remove the item from the sequence. This is what +// this function does. +// Parameters : dataset - [in] Dataset in which the consistency of the sequence attribute shall be checked. +// sequenceTagKey - [in] DcmTagKey of the sequence attribute which shall be checked. +// Return Value : none. +{ + DcmElement *sequenceAttribute = NULL, *referencedSOPClassUIDAttribute = NULL, *referencedSOPInstanceUIDAttribute = NULL; + + // in case the sequence attribute contains exactly one item with an empty + // ReferencedSOPClassUID and an empty ReferencedSOPInstanceUID, remove the item + if( dataset->findAndGetElement( sequenceTagKey, sequenceAttribute ).good() && + ( (DcmSequenceOfItems*)sequenceAttribute )->card() == 1 && + ( (DcmSequenceOfItems*)sequenceAttribute )->getItem(0)->findAndGetElement( DCM_ReferencedSOPClassUID, referencedSOPClassUIDAttribute ).good() && + referencedSOPClassUIDAttribute->getLength() == 0 && + ( (DcmSequenceOfItems*)sequenceAttribute )->getItem(0)->findAndGetElement( DCM_ReferencedSOPInstanceUID, referencedSOPInstanceUIDAttribute, OFFalse ).good() && + referencedSOPInstanceUIDAttribute->getLength() == 0 ) + { + DcmItem *item = ((DcmSequenceOfItems*)sequenceAttribute)->remove( ((DcmSequenceOfItems*)sequenceAttribute)->getItem(0) ); + delete item; + } +} + + namespace Orthanc { @@ -110,6 +152,20 @@ }; + + static void FixWorklistQuery(ParsedDicomFile& query) + { + // TODO: Check out + // WlmDataSourceFileSystem::HandleExistentButEmptyDescriptionAndCodeSequenceAttributes()" + // in DCMTK 3.6.0 + + DcmDataset* dataset = query.GetDcmtkObject().getDataset(); + HandleExistentButEmptyReferencedStudyOrPatientSequenceAttributes(dataset, DCM_ReferencedStudySequence); + HandleExistentButEmptyReferencedStudyOrPatientSequenceAttributes(dataset, DCM_ReferencedPatientSequence); + } + + + void FindScpCallback( /* in */ void *callbackData, @@ -141,6 +197,8 @@ if (data.worklistHandler_ != NULL) { ParsedDicomFile query(*requestIdentifiers); + FixWorklistQuery(query); + data.worklistHandler_->Handle(data.answers_, query, *data.remoteIp_, *data.remoteAet_, *data.calledAet_);