dcmtk 简单的C-FIND查询实现

利用DCMTK简单实现C-FIND

利用 Dcmtk封装的dcmscu即可实现C-FIND、C-GET、C-MOVE、C-STORE、等
具体的自己多研究DcmScu这个类

#include <iostream>
#include "dcmtk/dcmnet/scu.h"
#include "dcmtk/dcmdata/dcpath.h"     /* for DcmPathProcessor */
static OFLogger getscuLogger = OFLog::getLogger("dcmtk.apps." "FINDSCU");
static void prepareTS(E_TransferSyntax ts, OFList<OFString>& syntaxes);
static void applyOverrideKeys(DcmDataset *dataset, const  OFList<OFString> overrideKeys);
int main()
{
	DcmSCU scu;
	OFString temp_str;
	OFList<OFString> overrideKeys;
	overrideKeys.push_back("0008,0052=STUDY");
	overrideKeys.push_back("0008,0050=202006010058");
	overrideKeys.push_back("0020,000D=");
	if (!dcmDataDict.isDictionaryLoaded())
	{
		OFLOG_WARN(getscuLogger, "no data dictionary loaded, check environment variable:"); 
	}
	/*设置 scu*/
	OFList<OFString> syntaxes;
	prepareTS(EXS_Unknown, syntaxes);
	scu.setMaxReceivePDULength(ASC_DEFAULTMAXPDU);
	scu.setACSETimeout(30);
	scu.setDIMSEBlockingMode(DIMSE_BLOCKING);
	scu.setDIMSETimeout(0);
	scu.setAETitle("RADIANT");
	scu.setPeerHostName("192.168.0.136");
	scu.setPeerPort(OFstatic_cast(Uint16, 4242));
	scu.setPeerAETitle("ORTHANC");
	scu.setVerbosePCMode(OFFalse);
	scu.setSelfPort(1112);
	scu.addPresentationContext(UID_FINDStudyRootQueryRetrieveInformationModel, syntaxes);
	auto cond = scu.initNetwork();
	if (cond.bad())
	{
		OFLOG_FATAL(getscuLogger, "No Acceptable Presentation Contexts");
		return -1;
	}
	cond = scu.negotiateAssociation();
	if (cond.bad())
	{
		OFLOG_FATAL(getscuLogger, "No Acceptable Presentation Contexts");
		exit(1);
	}
	cond = EC_Normal;
	T_ASC_PresentationContextID pcid = scu.findPresentationContextID(UID_FINDStudyRootQueryRetrieveInformationModel,"");
	if (pcid == 0)
	{
		OFLOG_FATAL(getscuLogger, "No adequate Presentation Contexts for sending C-FIND");
		return -1;
	}
	DcmFileFormat dcmff;
	DcmDataset *dset = dcmff.getDataset();
	OFList<QRResponse*> responses;
	//查询
	applyOverrideKeys(dset, overrideKeys);
	cond = scu.sendFINDRequest(pcid, dset, &responses);
	if (!responses.empty())
	{
		/* output final status report */
		OFLOG_INFO(getscuLogger, "Final status report from last C-FIND message:");
		/* delete responses */
		std::cout << responses.size() << std::endl;
		for (auto &item:responses)
		{
			if (item->m_dataset)
			{
				OFString studyUID;
				auto result = item->m_dataset->findAndGetOFString(DCM_StudyInstanceUID, studyUID);
				std::cout << "studyUID:" << studyUID.c_str() << std::endl;
				if (result.bad())
				{
					std::cout << result.text() << std::endl;
				}
			}
		}
		
		OFListIterator(QRResponse*) iter = responses.begin();
		OFListConstIterator(QRResponse*) last = responses.end();
		while (iter != last)
		{
			delete (*iter);
			iter = responses.erase(iter);
		}
	}
	if (cond.good())
	{
	}
	if (cond == EC_Normal)
	{
		scu.releaseAssociation();
	}
	else
	{
		if (cond == DUL_PEERREQUESTEDRELEASE)
			scu.closeAssociation(DCMSCU_PEER_REQUESTED_RELEASE);
		else if (cond == DUL_PEERABORTEDASSOCIATION)
			scu.closeAssociation(DCMSCU_PEER_ABORTED_ASSOCIATION);
		else
		{
			OFLOG_ERROR(getscuLogger, "Find SCU Failed: " << DimseCondition::dump(temp_str, cond));
			scu.abortAssociation();
		}
		/* TODO: need to find better exit codes */
	}
	return 0;
}

void applyOverrideKeys(DcmDataset *dataset, const OFList<OFString> overrideKeys)
{
	/* replace specific keys by those in overrideKeys */
	OFListConstIterator(OFString) path = overrideKeys.begin();
	OFListConstIterator(OFString) endOfList = overrideKeys.end();
	DcmPathProcessor proc;
	proc.setItemWildcardSupport(OFFalse);
	proc.checkPrivateReservations(OFFalse);
	OFCondition cond;
	while (path != endOfList)
	{
		cond = proc.applyPathWithValue(dataset, *path);
		if (cond.bad())
		{
			OFLOG_ERROR(getscuLogger, "Bad override key/path: " << *path << ": " << cond.text());
		}
		path++;
	}
}
void prepareTS(E_TransferSyntax ts, OFList<OFString>& syntaxes)
{
	switch (ts)
	{
	case EXS_LittleEndianImplicit:
		/* we only support Little Endian Implicit */
		syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax);
		break;
	case EXS_LittleEndianExplicit:
		/* we prefer Little Endian Explicit */
		syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax);
		syntaxes.push_back(UID_BigEndianExplicitTransferSyntax);
		syntaxes.push_back(UID_LittleEndianImplicitTransferSyntax);
		break;
	case EXS_BigEndianExplicit:
		/* we prefer Big Endian Explicit */
		syntaxes.push_back(UID_BigEndianExplicitTransferSyntax);
		syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax);
		syntaxes.push_back(UID_LittleEndianImplicitTransferSyntax);
		break;
#ifdef WITH_ZLIB
	case EXS_DeflatedLittleEndianExplicit:
		/* we prefer Deflated Little Endian Explicit */
		syntaxes.push_back(UID_DeflatedExplicitVRLittleEndianTransferSyntax);
		syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax);
		syntaxes.push_back(UID_BigEndianExplicitTransferSyntax);
		syntaxes.push_back(UID_LittleEndianImplicitTransferSyntax);
		break;
#endif
	default:
		DcmXfer xfer(ts);
		if (xfer.isEncapsulated())
		{
			syntaxes.push_back(xfer.getXferID());
		}
		/* We prefer explicit transfer syntaxes.
		* If we are running on a Little Endian machine we prefer
		* LittleEndianExplicitTransferSyntax to BigEndianTransferSyntax.
		*/
		if (gLocalByteOrder == EBO_LittleEndian)  /* defined in dcxfer.h */
		{
			syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax);
			syntaxes.push_back(UID_BigEndianExplicitTransferSyntax);
		}
		else
		{
			syntaxes.push_back(UID_BigEndianExplicitTransferSyntax);
			syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax);
		}
		syntaxes.push_back(UID_LittleEndianImplicitTransferSyntax);
		break;
	}
}
posted @ 2020-06-08 16:51  轻风々  阅读(2165)  评论(1编辑  收藏  举报