# HG changeset patch # User Sebastien Jodogne # Date 1586358033 -7200 # Node ID 1237bd0bbdb290d690e383cc1a0c1823b25d1228 # Parent 023b2a9f3aa140939179703e3a876c74fb5dcf43 update sop class/instance uid if transcoding diff -r 023b2a9f3aa1 -r 1237bd0bbdb2 Core/DicomNetworking/DicomUserConnection.cpp --- a/Core/DicomNetworking/DicomUserConnection.cpp Tue Apr 07 17:35:44 2020 +0200 +++ b/Core/DicomNetworking/DicomUserConnection.cpp Wed Apr 08 17:00:33 2020 +0200 @@ -240,6 +240,10 @@ std::vector& asFallback, const std::string& aet) { + // Presentation context IDs must be odd numbers, hence the + // increments by 2: + // http://dicom.nema.org/medical/dicom/2019e/output/chtml/part08/sect_9.3.2.2.html + Check(ASC_addPresentationContext(params, presentationContextId, sopClass.c_str(), asPreferred, 1), aet, "initializing"); @@ -1177,6 +1181,28 @@ "Unable to negotiate a presentation context with AET " + remoteAet_); } + +#if 0 + // Manual loop over the accepted transfer syntaxes + LST_HEAD **l = &pimpl_->params_->DULparams.acceptedPresentationContext; + if (*l != NULL) + { + DUL_PRESENTATIONCONTEXT* pc = (DUL_PRESENTATIONCONTEXT*) LST_Head(l); + LST_Position(l, (LST_NODE*)pc); + while (pc) + { + if (pc->result == ASC_P_ACCEPTANCE) + { + printf("Accepted: %d [%s] [%s]\n", pc->presentationContextID, pc->abstractSyntax, pc->acceptedTransferSyntax); + } + else + { + printf("Rejected: %d [%s]\n", pc->presentationContextID, pc->abstractSyntax); + } + pc = (DUL_PRESENTATIONCONTEXT*) LST_Next(l); + } + } +#endif } void DicomUserConnection::Close() diff -r 023b2a9f3aa1 -r 1237bd0bbdb2 UnitTestsSources/FromDcmtkTests.cpp --- a/UnitTestsSources/FromDcmtkTests.cpp Tue Apr 07 17:35:44 2020 +0200 +++ b/UnitTestsSources/FromDcmtkTests.cpp Wed Apr 08 17:00:33 2020 +0200 @@ -1935,6 +1935,8 @@ { } + virtual DcmFileFormat& GetDicom() = 0; + virtual DicomTransferSyntax GetTransferSyntax() = 0; virtual std::string GetSopClassUid() = 0; @@ -1948,6 +1950,8 @@ virtual void GetCompressedFrame(std::string& target, unsigned int frame) = 0; + // NB: Transcoding can change the value of "GetSopInstanceUid()" + // and "GetTransferSyntax()" if lossy compression is applied virtual bool Transcode(std::string& target, std::set syntaxes, bool allowNewSopInstanceUid) = 0; @@ -1967,6 +1971,23 @@ uint16_t bitsStored_; unsigned int lossyQuality_; + static std::string GetStringTag(DcmDataset& dataset, + const DcmTagKey& tag) + { + const char* value = NULL; + + if (!dataset.findAndGetString(tag, value).good() || + value == NULL) + { + throw OrthancException(ErrorCode_BadFileFormat, + "Missing SOP class/instance UID in DICOM instance"); + } + else + { + return std::string(value); + } + } + void Setup(DcmFileFormat* dicom) { lossyQuality_ = 90; @@ -2007,20 +2028,8 @@ "Missing \"Bits Stored\" tag in DICOM instance"); } - const char* a = NULL; - const char* b = NULL; - - if (!dataset.findAndGetString(DCM_SOPClassUID, a).good() || - !dataset.findAndGetString(DCM_SOPInstanceUID, b).good() || - a == NULL || - b == NULL) - { - throw OrthancException(ErrorCode_BadFileFormat, - "Missing SOP class/instance UID in DICOM instance"); - } - - sopClassUid_.assign(a); - sopInstanceUid_.assign(b); + sopClassUid_ = GetStringTag(dataset, DCM_SOPClassUID); + sopInstanceUid_ = GetStringTag(dataset, DCM_SOPInstanceUID); } public: @@ -2058,6 +2067,12 @@ return bitsStored_; } + virtual DcmFileFormat& GetDicom() + { + assert(dicom_ != NULL); + return *dicom_; + } + virtual DicomTransferSyntax GetTransferSyntax() ORTHANC_OVERRIDE { return transferSyntax_; @@ -2103,6 +2118,9 @@ std::set syntaxes, bool allowNewSopInstanceUid) ORTHANC_OVERRIDE { + assert(dicom_ != NULL && + dicom_->getDataset() != NULL); + if (syntaxes.find(GetTransferSyntax()) != syntaxes.end()) { printf("NO TRANSCODING\n"); @@ -2119,16 +2137,19 @@ if (syntaxes.find(DicomTransferSyntax_LittleEndianImplicit) != syntaxes.end() && FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_LittleEndianImplicit, NULL)) { + transferSyntax_ = DicomTransferSyntax_LittleEndianImplicit; return true; } else if (syntaxes.find(DicomTransferSyntax_LittleEndianExplicit) != syntaxes.end() && FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_LittleEndianExplicit, NULL)) { + transferSyntax_ = DicomTransferSyntax_LittleEndianExplicit; return true; } else if (syntaxes.find(DicomTransferSyntax_BigEndianExplicit) != syntaxes.end() && FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_BigEndianExplicit, NULL)) { + transferSyntax_ = DicomTransferSyntax_BigEndianExplicit; return true; } else if (syntaxes.find(DicomTransferSyntax_JPEGProcess1) != syntaxes.end() && @@ -2136,6 +2157,8 @@ GetBitsStored() == 8 && FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_JPEGProcess1, &rpLossy)) { + transferSyntax_ = DicomTransferSyntax_JPEGProcess1; + sopInstanceUid_ = GetStringTag(*dicom_->getDataset(), DCM_SOPInstanceUID); return true; } else if (syntaxes.find(DicomTransferSyntax_JPEGProcess2_4) != syntaxes.end() && @@ -2143,6 +2166,8 @@ GetBitsStored() <= 12 && FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_JPEGProcess2_4, &rpLossy)) { + transferSyntax_ = DicomTransferSyntax_JPEGProcess2_4; + sopInstanceUid_ = GetStringTag(*dicom_->getDataset(), DCM_SOPInstanceUID); return true; } else @@ -2279,6 +2304,9 @@ } { + std::string a = transcoder.GetSopInstanceUid(); + DicomTransferSyntax b = transcoder.GetTransferSyntax(); + std::set syntaxes; syntaxes.insert(DicomTransferSyntax_JPEGProcess2_4); //syntaxes.insert(DicomTransferSyntax_LittleEndianExplicit); @@ -2289,6 +2317,10 @@ if (ok) { + printf("[%s] => [%s]\n", a.c_str(), transcoder.GetSopInstanceUid().c_str()); + printf("[%s] => [%s]\n", GetTransferSyntaxUid(b), + GetTransferSyntaxUid(transcoder.GetTransferSyntax())); + { char buf[1024]; sprintf(buf, "/tmp/transcoded-%06d.dcm", count);