# HG changeset patch # User Alain Mazy # Date 1555595576 -7200 # Node ID ef18ea68a362698a85411c0d633c532ed80f2df1 # Parent a1cd981a0f9a902b6e24aac149c3608dc5094ebb# Parent ab17e8e947768b6887af91cd06c43b7192fe51b9 merge diff -r a1cd981a0f9a -r ef18ea68a362 Core/DicomNetworking/DicomUserConnection.cpp --- a/Core/DicomNetworking/DicomUserConnection.cpp Thu Apr 18 15:52:25 2019 +0200 +++ b/Core/DicomNetworking/DicomUserConnection.cpp Thu Apr 18 15:52:56 2019 +0200 @@ -590,11 +590,11 @@ } } - return new ParsedDicomFile(*fix); + return new ParsedDicomFile(*fix, GetDefaultDicomEncoding(), false /* be strict */); } default: - return new ParsedDicomFile(fields); + return new ParsedDicomFile(fields, GetDefaultDicomEncoding(), false /* be strict */); } } diff -r a1cd981a0f9a -r ef18ea68a362 Core/DicomNetworking/Internals/CommandDispatcher.cpp --- a/Core/DicomNetworking/Internals/CommandDispatcher.cpp Thu Apr 18 15:52:25 2019 +0200 +++ b/Core/DicomNetworking/Internals/CommandDispatcher.cpp Thu Apr 18 15:52:56 2019 +0200 @@ -94,6 +94,8 @@ #include "../../Logging.h" #include /* for class DcmAssociationConfiguration */ +#include /* for variable dcmAllStorageSOPClassUIDs */ + #include static OFBool opt_rejectWithoutImplementationUID = OFFalse; @@ -169,7 +171,7 @@ } } } - + if (accepted) { cond = ASC_acceptPresentationContext( @@ -217,7 +219,7 @@ static OFCondition acceptUnknownContextsWithPreferredTransferSyntaxes( T_ASC_Parameters * params, const char* transferSyntaxes[], int transferSyntaxCount, - T_ASC_SC_ROLE acceptedRole = ASC_SC_ROLE_DEFAULT) + T_ASC_SC_ROLE acceptedRole) { OFCondition cond = EC_Normal; /* @@ -239,159 +241,6 @@ { namespace Internals { - /** - * EXTRACT OF FILE "dcmdata/libsrc/dcuid.cc" FROM DCMTK 3.6.0 - * (dcmAllStorageSOPClassUIDs). - * - * an array of const strings containing all known Storage SOP - * Classes that fit into the conventional - * PATIENT-STUDY-SERIES-INSTANCE information model, - * i.e. everything a Storage SCP might want to store in a PACS. - * Special cases such as hanging protocol storage or the Storage - * SOP Class are not included in this list. - * - * THIS LIST CONTAINS ALL STORAGE SOP CLASSES INCLUDING RETIRED - * ONES AND IS LARGER THAN 64 ENTRIES. - */ - - const char* orthancStorageSOPClassUIDs[] = - { - UID_AmbulatoryECGWaveformStorage, - UID_ArterialPulseWaveformStorage, - UID_AutorefractionMeasurementsStorage, - UID_BasicStructuredDisplayStorage, - UID_BasicTextSRStorage, - UID_BasicVoiceAudioWaveformStorage, - UID_BlendingSoftcopyPresentationStateStorage, -#if DCMTK_VERSION_NUMBER >= 361 - UID_BreastProjectionXRayImageStorageForProcessing, - UID_BreastProjectionXRayImageStorageForPresentation, -#endif - UID_BreastTomosynthesisImageStorage, - UID_CardiacElectrophysiologyWaveformStorage, - UID_ChestCADSRStorage, - UID_ColonCADSRStorage, - UID_ColorSoftcopyPresentationStateStorage, - UID_ComprehensiveSRStorage, - UID_ComputedRadiographyImageStorage, - UID_CTImageStorage, - UID_DeformableSpatialRegistrationStorage, - UID_DigitalIntraOralXRayImageStorageForPresentation, - UID_DigitalIntraOralXRayImageStorageForProcessing, - UID_DigitalMammographyXRayImageStorageForPresentation, - UID_DigitalMammographyXRayImageStorageForProcessing, - UID_DigitalXRayImageStorageForPresentation, - UID_DigitalXRayImageStorageForProcessing, - UID_EncapsulatedCDAStorage, - UID_EncapsulatedPDFStorage, - UID_EnhancedCTImageStorage, - UID_EnhancedMRColorImageStorage, - UID_EnhancedMRImageStorage, - UID_EnhancedPETImageStorage, - UID_EnhancedSRStorage, - UID_EnhancedUSVolumeStorage, - UID_EnhancedXAImageStorage, - UID_EnhancedXRFImageStorage, - UID_GeneralAudioWaveformStorage, - UID_GeneralECGWaveformStorage, - UID_GenericImplantTemplateStorage, - UID_GrayscaleSoftcopyPresentationStateStorage, - UID_HemodynamicWaveformStorage, - UID_ImplantAssemblyTemplateStorage, - UID_ImplantationPlanSRDocumentStorage, - UID_ImplantTemplateGroupStorage, - UID_IntraocularLensCalculationsStorage, - UID_KeratometryMeasurementsStorage, - UID_KeyObjectSelectionDocumentStorage, - UID_LensometryMeasurementsStorage, - UID_MacularGridThicknessAndVolumeReportStorage, - UID_MammographyCADSRStorage, - UID_MRImageStorage, - UID_MRSpectroscopyStorage, - UID_MultiframeGrayscaleByteSecondaryCaptureImageStorage, - UID_MultiframeGrayscaleWordSecondaryCaptureImageStorage, - UID_MultiframeSingleBitSecondaryCaptureImageStorage, - UID_MultiframeTrueColorSecondaryCaptureImageStorage, - UID_NuclearMedicineImageStorage, - UID_OphthalmicAxialMeasurementsStorage, - UID_OphthalmicPhotography16BitImageStorage, - UID_OphthalmicPhotography8BitImageStorage, - UID_OphthalmicTomographyImageStorage, - UID_OphthalmicVisualFieldStaticPerimetryMeasurementsStorage, - UID_PositronEmissionTomographyImageStorage, - UID_ProcedureLogStorage, - UID_PseudoColorSoftcopyPresentationStateStorage, - UID_RawDataStorage, - UID_RealWorldValueMappingStorage, - UID_RespiratoryWaveformStorage, - UID_RTBeamsTreatmentRecordStorage, - UID_RTBrachyTreatmentRecordStorage, - UID_RTDoseStorage, - UID_RTImageStorage, - UID_RTIonBeamsTreatmentRecordStorage, - UID_RTIonPlanStorage, - UID_RTPlanStorage, - UID_RTStructureSetStorage, - UID_RTTreatmentSummaryRecordStorage, - UID_SecondaryCaptureImageStorage, - UID_SegmentationStorage, - UID_SpatialFiducialsStorage, - UID_SpatialRegistrationStorage, - UID_SpectaclePrescriptionReportStorage, - UID_StereometricRelationshipStorage, - UID_SubjectiveRefractionMeasurementsStorage, - UID_SurfaceSegmentationStorage, - UID_TwelveLeadECGWaveformStorage, - UID_UltrasoundImageStorage, - UID_UltrasoundMultiframeImageStorage, - UID_VideoEndoscopicImageStorage, - UID_VideoMicroscopicImageStorage, - UID_VideoPhotographicImageStorage, - UID_VisualAcuityMeasurementsStorage, - UID_VLEndoscopicImageStorage, - UID_VLMicroscopicImageStorage, - UID_VLPhotographicImageStorage, - UID_VLSlideCoordinatesMicroscopicImageStorage, - UID_VLWholeSlideMicroscopyImageStorage, - UID_XAXRFGrayscaleSoftcopyPresentationStateStorage, - UID_XRay3DAngiographicImageStorage, - UID_XRay3DCraniofacialImageStorage, - UID_XRayAngiographicImageStorage, - UID_XRayRadiationDoseSRStorage, - UID_XRayRadiofluoroscopicImageStorage, - // retired - UID_RETIRED_HardcopyColorImageStorage, - UID_RETIRED_HardcopyGrayscaleImageStorage, - UID_RETIRED_NuclearMedicineImageStorage, - UID_RETIRED_StandaloneCurveStorage, - UID_RETIRED_StandaloneModalityLUTStorage, - UID_RETIRED_StandaloneOverlayStorage, - UID_RETIRED_StandalonePETCurveStorage, - UID_RETIRED_StandaloneVOILUTStorage, - UID_RETIRED_StoredPrintStorage, - UID_RETIRED_UltrasoundImageStorage, - UID_RETIRED_UltrasoundMultiframeImageStorage, - UID_RETIRED_VLImageStorage, -#if DCMTK_VERSION_NUMBER >= 364 - UID_RETIRED_VLMultiframeImageStorage, -#else - UID_RETIRED_VLMultiFrameImageStorage, -#endif - UID_RETIRED_XRayAngiographicBiPlaneImageStorage, - // draft - UID_DRAFT_SRAudioStorage, - UID_DRAFT_SRComprehensiveStorage, - UID_DRAFT_SRDetailStorage, - UID_DRAFT_SRTextStorage, - UID_DRAFT_WaveformStorage, - UID_DRAFT_RTBeamsDeliveryInstructionStorage, - NULL - }; - - const int orthancStorageSOPClassUIDsCount = (sizeof(orthancStorageSOPClassUIDs) / sizeof(const char*)) - 1; - - - OFCondition AssociationCleanup(T_ASC_Association *assoc) { OFCondition cond = ASC_dropSCPAssociation(assoc); @@ -588,7 +437,10 @@ } /* accept the Verification SOP Class if presented */ - cond = ASC_acceptContextsWithPreferredTransferSyntaxes(assoc->params, &knownAbstractSyntaxes[0], knownAbstractSyntaxes.size(), &transferSyntaxes[0], transferSyntaxes.size()); + cond = ASC_acceptContextsWithPreferredTransferSyntaxes( + assoc->params, + &knownAbstractSyntaxes[0], knownAbstractSyntaxes.size(), + &transferSyntaxes[0], transferSyntaxes.size()); if (cond.bad()) { LOG(INFO) << cond.text(); @@ -596,8 +448,24 @@ return NULL; } - /* the array of Storage SOP Class UIDs comes from dcuid.h */ - cond = ASC_acceptContextsWithPreferredTransferSyntaxes(assoc->params, orthancStorageSOPClassUIDs, orthancStorageSOPClassUIDsCount, &transferSyntaxes[0], transferSyntaxes.size()); + /* the array of Storage SOP Class UIDs that is defined within "dcmdata/libsrc/dcuid.cc" */ + size_t count = 0; + while (dcmAllStorageSOPClassUIDs[count] != NULL) + { + count++; + } + +#if DCMTK_VERSION_NUMBER >= 362 + // The global variable "numberOfDcmAllStorageSOPClassUIDs" is + // only published if DCMTK >= 3.6.2: + // https://bitbucket.org/sjodogne/orthanc/issues/137 + assert(count == numberOfDcmAllStorageSOPClassUIDs); +#endif + + cond = ASC_acceptContextsWithPreferredTransferSyntaxes( + assoc->params, + dcmAllStorageSOPClassUIDs, count, + &transferSyntaxes[0], transferSyntaxes.size()); if (cond.bad()) { LOG(INFO) << cond.text(); @@ -613,7 +481,7 @@ * to be a storage SOP class. **/ cond = acceptUnknownContextsWithPreferredTransferSyntaxes( - assoc->params, &transferSyntaxes[0], transferSyntaxes.size()); + assoc->params, &transferSyntaxes[0], transferSyntaxes.size(), ASC_SC_ROLE_DEFAULT); if (cond.bad()) { LOG(INFO) << cond.text(); diff -r a1cd981a0f9a -r ef18ea68a362 Core/DicomParsing/DicomModification.cpp --- a/Core/DicomParsing/DicomModification.cpp Thu Apr 18 15:52:25 2019 +0200 +++ b/Core/DicomParsing/DicomModification.cpp Thu Apr 18 15:52:56 2019 +0200 @@ -158,6 +158,13 @@ newValue = that_.MapDicomIdentifier(Toolbox::StripSpaces(value), ResourceType_Series); return Action_Replace; } + else if (parentTags.size() == 1 && + parentTags[0] == DICOM_TAG_REFERENCED_SERIES_SEQUENCE && + tag == DICOM_TAG_SERIES_INSTANCE_UID) + { + newValue = that_.MapDicomIdentifier(Toolbox::StripSpaces(value), ResourceType_Series); + return Action_Replace; + } else { return Action_None; diff -r a1cd981a0f9a -r ef18ea68a362 Core/DicomParsing/ParsedDicomFile.cpp --- a/Core/DicomParsing/ParsedDicomFile.cpp Thu Apr 18 15:52:25 2019 +0200 +++ b/Core/DicomParsing/ParsedDicomFile.cpp Thu Apr 18 15:52:56 2019 +0200 @@ -1024,13 +1024,6 @@ } - ParsedDicomFile::ParsedDicomFile(const DicomMap& map) : - pimpl_(new PImpl) - { - CreateFromDicomMap(map, GetDefaultDicomEncoding(), false /* be strict by default */); - } - - ParsedDicomFile::ParsedDicomFile(const void* content, size_t size) : pimpl_(new PImpl) { diff -r a1cd981a0f9a -r ef18ea68a362 Core/DicomParsing/ParsedDicomFile.h --- a/Core/DicomParsing/ParsedDicomFile.h Thu Apr 18 15:52:25 2019 +0200 +++ b/Core/DicomParsing/ParsedDicomFile.h Thu Apr 18 15:52:56 2019 +0200 @@ -101,8 +101,6 @@ Encoding defaultEncoding, bool permissive); - ParsedDicomFile(const DicomMap& map); - ParsedDicomFile(const void* content, size_t size); diff -r a1cd981a0f9a -r ef18ea68a362 NEWS --- a/NEWS Thu Apr 18 15:52:25 2019 +0200 +++ b/NEWS Thu Apr 18 15:52:56 2019 +0200 @@ -1,7 +1,15 @@ Pending changes in the mainline =============================== + +Maintenance +----------- + * Size of the Orthanc static binaries are reduced by compressing ICU data +* Anonymization: Preserve hierarchical relationships in (0008,1115) [] (0020,000e) +* Fix issue #136 (C-FIND request fails when found DICOM file does not have certain tags) +* Fix issue #137 (C-STORE fails for unknown SOP Class although server is configured to accept any) +* Fix issue #138 (POST to modalities/{name} accepts invalid characters) Version 1.5.6 (2019-03-01) diff -r a1cd981a0f9a -r ef18ea68a362 OrthancServer/DicomInstanceToStore.cpp --- a/OrthancServer/DicomInstanceToStore.cpp Thu Apr 18 15:52:25 2019 +0200 +++ b/OrthancServer/DicomInstanceToStore.cpp Thu Apr 18 15:52:56 2019 +0200 @@ -179,7 +179,9 @@ } else { - parsed_.TakeOwnership(new ParsedDicomFile(summary_.GetConstContent())); + parsed_.TakeOwnership(new ParsedDicomFile(summary_.GetConstContent(), + GetDefaultDicomEncoding(), + false /* be strict */)); } } diff -r a1cd981a0f9a -r ef18ea68a362 OrthancServer/OrthancConfiguration.cpp --- a/OrthancServer/OrthancConfiguration.cpp Thu Apr 18 15:52:25 2019 +0200 +++ b/OrthancServer/OrthancConfiguration.cpp Thu Apr 18 15:52:56 2019 +0200 @@ -759,6 +759,8 @@ void OrthancConfiguration::UpdateModality(const std::string& symbolicName, const RemoteModalityParameters& modality) { + CheckAlphanumeric(symbolicName); + modalities_[symbolicName] = modality; SaveModalities(); } @@ -774,6 +776,8 @@ void OrthancConfiguration::UpdatePeer(const std::string& symbolicName, const WebServiceParameters& peer) { + CheckAlphanumeric(symbolicName); + peer.CheckClientCertificate(); peers_[symbolicName] = peer; diff -r a1cd981a0f9a -r ef18ea68a362 OrthancServer/OrthancFindRequestHandler.cpp --- a/OrthancServer/OrthancFindRequestHandler.cpp Thu Apr 18 15:52:25 2019 +0200 +++ b/OrthancServer/OrthancFindRequestHandler.cpp Thu Apr 18 15:52:56 2019 +0200 @@ -371,7 +371,7 @@ } else { - ParsedDicomFile dicom(result); + ParsedDicomFile dicom(result, GetDefaultDicomEncoding(), true /* be permissive, cf. issue #136 */); for (std::list::const_iterator tag = sequencesToReturn.begin(); tag != sequencesToReturn.end(); ++tag) diff -r a1cd981a0f9a -r ef18ea68a362 OrthancServer/OrthancRestApi/OrthancRestModalities.cpp --- a/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp Thu Apr 18 15:52:25 2019 +0200 +++ b/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp Thu Apr 18 15:52:56 2019 +0200 @@ -442,10 +442,24 @@ ServerContext& context = OrthancRestApi::GetContext(call); Json::Value request; - if (call.ParseJsonRequest(request) && - request.type() == Json::objectValue && - request.isMember(KEY_LEVEL) && request[KEY_LEVEL].type() == Json::stringValue && - (!request.isMember(KEY_QUERY) || request[KEY_QUERY].type() == Json::objectValue)) + if (!call.ParseJsonRequest(request) || + request.type() != Json::objectValue) + { + throw OrthancException(ErrorCode_BadFileFormat, "Must provide a JSON object"); + } + else if (!request.isMember(KEY_LEVEL) || + request[KEY_LEVEL].type() != Json::stringValue) + { + throw OrthancException(ErrorCode_BadFileFormat, + "The JSON body must contain field " + std::string(KEY_LEVEL)); + } + else if (request.isMember(KEY_QUERY) && + request[KEY_QUERY].type() != Json::objectValue) + { + throw OrthancException(ErrorCode_BadFileFormat, + "The field " + std::string(KEY_QUERY) + " must contain a JSON object"); + } + else { std::auto_ptr handler(new QueryRetrieveHandler(context)); @@ -958,7 +972,8 @@ request[KEY_RESOURCES].type() != Json::arrayValue || request[KEY_LEVEL].type() != Json::stringValue) { - throw OrthancException(ErrorCode_BadFileFormat); + throw OrthancException(ErrorCode_BadFileFormat, "Must provide a JSON body containing fields " + + std::string(KEY_RESOURCES) + " and " + std::string(KEY_LEVEL)); } ResourceType level = StringToResourceType(request[KEY_LEVEL].asCString()); @@ -1236,6 +1251,10 @@ answers.ToJson(result, true); call.GetOutput().AnswerJson(result); } + else + { + throw OrthancException(ErrorCode_BadFileFormat, "Must provide a JSON object"); + } } diff -r a1cd981a0f9a -r ef18ea68a362 OrthancServer/ServerContext.cpp --- a/OrthancServer/ServerContext.cpp Thu Apr 18 15:52:25 2019 +0200 +++ b/OrthancServer/ServerContext.cpp Thu Apr 18 15:52:56 2019 +0200 @@ -245,7 +245,7 @@ OrthancConfiguration::ReaderLock lock; queryRetrieveArchive_.reset( - new SharedArchive(lock.GetConfiguration().GetUnsignedIntegerParameter("QueryRetrieveSize", 10))); + new SharedArchive(lock.GetConfiguration().GetUnsignedIntegerParameter("QueryRetrieveSize", 100))); mediaArchive_.reset( new SharedArchive(lock.GetConfiguration().GetUnsignedIntegerParameter("MediaArchiveSize", 1))); defaultLocalAet_ = lock.GetConfiguration().GetStringParameter("DicomAet", "ORTHANC"); diff -r a1cd981a0f9a -r ef18ea68a362 Resources/CMake/BoostConfiguration.cmake --- a/Resources/CMake/BoostConfiguration.cmake Thu Apr 18 15:52:25 2019 +0200 +++ b/Resources/CMake/BoostConfiguration.cmake Thu Apr 18 15:52:56 2019 +0200 @@ -147,6 +147,13 @@ add_definitions(-DBOOST_HAS_SCHED_YIELD=1) endif() + # Fix for error: "boost_1_69_0/boost/chrono/detail/inlined/mac/thread_clock.hpp:54:28: + # error: use of undeclared identifier 'pthread_mach_thread_np'" + # https://github.com/envoyproxy/envoy/pull/1785 + if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") + add_definitions(-D_DARWIN_C_SOURCE=1) + endif() + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") list(APPEND BOOST_SOURCES ${BOOST_SOURCES_DIR}/libs/thread/src/win32/tss_dll.cpp diff -r a1cd981a0f9a -r ef18ea68a362 Resources/CMake/LuaConfiguration.cmake --- a/Resources/CMake/LuaConfiguration.cmake Thu Apr 18 15:52:25 2019 +0200 +++ b/Resources/CMake/LuaConfiguration.cmake Thu Apr 18 15:52:56 2019 +0200 @@ -101,9 +101,9 @@ source_group(ThirdParty\\Lua REGULAR_EXPRESSION ${LUA_SOURCES_DIR}/.*) else() - include(FindLua51) + include(FindLua) - if (NOT LUA51_FOUND) + if (NOT LUA_FOUND) message(FATAL_ERROR "Please install the liblua-dev package") endif() diff -r a1cd981a0f9a -r ef18ea68a362 Resources/CMake/UuidConfiguration.cmake --- a/Resources/CMake/UuidConfiguration.cmake Thu Apr 18 15:52:25 2019 +0200 +++ b/Resources/CMake/UuidConfiguration.cmake Thu Apr 18 15:52:56 2019 +0200 @@ -114,12 +114,18 @@ message(FATAL_ERROR "Please install uuid-dev, e2fsprogs (OpenBSD) or e2fsprogs-libuuid (FreeBSD)") endif() - check_library_exists(uuid uuid_generate_random "" HAVE_UUID_LIB) - if (NOT HAVE_UUID_LIB) + find_library(LIBUUID uuid + PATHS + /usr/lib + /usr/local/lib + ) + + check_library_exists(${LIBUUID} uuid_generate_random "" HAVE_LIBUUID) + if (NOT HAVE_LIBUUID) message(FATAL_ERROR "Unable to find the uuid library") endif() - link_libraries(uuid) + link_libraries(${LIBUUID}) endif() endif() diff -r a1cd981a0f9a -r ef18ea68a362 Resources/Configuration.json --- a/Resources/Configuration.json Thu Apr 18 15:52:25 2019 +0200 +++ b/Resources/Configuration.json Thu Apr 18 15:52:56 2019 +0200 @@ -397,7 +397,7 @@ // Maximum number of query/retrieve DICOM requests that are // maintained by Orthanc. The least recently used requests get // deleted as new requests are issued. - "QueryRetrieveSize" : 10, + "QueryRetrieveSize" : 100, // When handling a C-Find SCP request, setting this flag to "true" // will enable case-sensitive match for PN value representation diff -r a1cd981a0f9a -r ef18ea68a362 Resources/Samples/Python/AutoClassify.py --- a/Resources/Samples/Python/AutoClassify.py Thu Apr 18 15:52:25 2019 +0200 +++ b/Resources/Samples/Python/AutoClassify.py Thu Apr 18 15:52:56 2019 +0200 @@ -107,7 +107,7 @@ }) for change in r['Changes']: - # We are only interested interested in the arrival of new instances + # We are only interested in the arrival of new instances if change['ChangeType'] == 'NewInstance': try: ClassifyInstance(change['ID']) diff -r a1cd981a0f9a -r ef18ea68a362 Resources/Samples/Python/ChangesLoop.py --- a/Resources/Samples/Python/ChangesLoop.py Thu Apr 18 15:52:25 2019 +0200 +++ b/Resources/Samples/Python/ChangesLoop.py Thu Apr 18 15:52:56 2019 +0200 @@ -71,7 +71,7 @@ }) for change in r['Changes']: - # We are only interested interested in the arrival of new instances + # We are only interested in the arrival of new instances if change['ChangeType'] == 'NewInstance': # Call the callback function path = change['Path'] diff -r a1cd981a0f9a -r ef18ea68a362 Resources/Samples/Python/HighPerformanceAutoRouting.py --- a/Resources/Samples/Python/HighPerformanceAutoRouting.py Thu Apr 18 15:52:25 2019 +0200 +++ b/Resources/Samples/Python/HighPerformanceAutoRouting.py Thu Apr 18 15:52:56 2019 +0200 @@ -70,7 +70,7 @@ }) for change in r['Changes']: - # We are only interested interested in the arrival of new instances + # We are only interested in the arrival of new instances if change['ChangeType'] == 'NewInstance': queue.put(change['ID']) diff -r a1cd981a0f9a -r ef18ea68a362 TODO --- a/TODO Thu Apr 18 15:52:25 2019 +0200 +++ b/TODO Thu Apr 18 15:52:56 2019 +0200 @@ -64,6 +64,8 @@ Short-term ---------- +* Support "Retrieve AE Title" (0008,0054) in C-FIND: + https://groups.google.com/d/msg/orthanc-users/wPl0g5mqZco/5X1Z8tEzBgAJ * Support C-GET: http://dclunie.blogspot.be/2016/05/to-c-move-is-human-to-c-get-divine.html * Check Big Endian transfer syntax in ParsedDicomFile::EmbedImage and diff -r a1cd981a0f9a -r ef18ea68a362 UnitTestsSources/FromDcmtkTests.cpp --- a/UnitTestsSources/FromDcmtkTests.cpp Thu Apr 18 15:52:25 2019 +0200 +++ b/UnitTestsSources/FromDcmtkTests.cpp Thu Apr 18 15:52:56 2019 +0200 @@ -1119,7 +1119,7 @@ { DicomMap m; - ParsedDicomFile dicom(m); + ParsedDicomFile dicom(m, GetDefaultDicomEncoding(), false); ASSERT_EQ(1u, dicom.GetDcmtkObject().getDataset()->card()); CheckEncoding(dicom, Encoding_Ascii); } @@ -1134,7 +1134,7 @@ { DicomMap m; m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, "ISO_IR 148", false); - ParsedDicomFile dicom(m); + ParsedDicomFile dicom(m, GetDefaultDicomEncoding(), false); ASSERT_EQ(1u, dicom.GetDcmtkObject().getDataset()->card()); CheckEncoding(dicom, Encoding_Latin5); }