DICOM醫(yī)學(xué)圖像處理:storescp.exe與storescu.exe源碼剖析,學(xué)習(xí)C
本文關(guān)鍵詞:醫(yī)學(xué)圖像處理,由筆耕文化傳播整理發(fā)布。
背景:
上一篇專欄博文中針對(duì)PACS終端(或設(shè)備終端,如CT設(shè)備)與RIS系統(tǒng)之間worklist查詢進(jìn)行了介紹,并著重對(duì)比分析了DICOM3.0中各部分對(duì)DICOM網(wǎng)絡(luò)通訊服務(wù)的定義。此次通過結(jié)合早些時(shí)間的博文DICOM醫(yī)學(xué)圖像處理:基于DCMTK工具包學(xué)習(xí)和分析worklist,對(duì)DCMTK開源庫(kù)中提供的storescp.exe和storescu.exe工具的源碼進(jìn)行剖析,從底層深入了解C-STORE服務(wù)的觸發(fā)及響應(yīng)。
分析思路:storescp.exe和storescu.exe分別充當(dāng)著C-STORE服務(wù)的SCP和SCU,因此猜測(cè)兩個(gè)工具包一定是利用了DCMTK提供的DcmSCP和DcmSCU類來分別實(shí)現(xiàn)的。為了驗(yàn)證自己的想法,從分析storescp.exe源碼文件storescp.cc入手,對(duì)比storescp.cc與scp.cc,尋找兩者的共同點(diǎn)。倘若與我們的設(shè)想一致,就新建一個(gè)C++本地工程,利用DcmSCP類來建立自己的C-STORE SCP端,期望達(dá)到與storescp.exe工具包相同的效果。
storescp.cc與scp.cc源碼分析: 1)storescp.cc源碼分析storescp.cc是DCMTK提供的storescp.exe工具的源文件。直接打開storescp.cc文件,首先可以看到作者給出的注釋:
Purpose概括了該工具的主要用途——是存儲(chǔ)服務(wù)的提供者,用來響應(yīng)C-STORE 操作。由于storescp.exe是一個(gè)命令行工具,即用戶可以通過不同的參數(shù)設(shè)置或組合來實(shí)現(xiàn)不同的功能。因此在storescp.cc文件開頭main主函數(shù)外部定義了眾多全局的命令行參數(shù)變量,例如我們上一篇博文DICOM醫(yī)學(xué)圖像處理:全面分析DICOM3.0標(biāo)準(zhǔn)中的通訊服務(wù)模塊中使用的storescp.exe -d 104 -aet OFFIS命令行中的104相對(duì)應(yīng)的參數(shù)是opt_port, 從參數(shù)opt_前綴亦可以猜出用途。
由于storescp.exe工具是需要與客戶端進(jìn)行交互的,接下來進(jìn)入到main主函數(shù)后的第一件事情就是初始化網(wǎng)絡(luò)環(huán)境。如下圖所示,作者利用條件編譯(如下圖中的紅圈所示)以來實(shí)現(xiàn)不同系統(tǒng)的網(wǎng)絡(luò)環(huán)境的初始化,由于我使用的是Windows7操作系統(tǒng),因此條件編譯的結(jié)果是調(diào)用WSAStartup初始化Windows 套接字(Socket)的網(wǎng)絡(luò)環(huán)境。
網(wǎng)絡(luò)環(huán)境的初始化是main函數(shù)的第一步操作,隨后就是前面提到的命令行參數(shù)的解析,因?yàn)閟torescpp.exe是命令行類型的工具包。從文件260行至992行就是命令行參數(shù)的解析部分,我們暫時(shí)直接跳過該部分,簡(jiǎn)單地認(rèn)為該部分實(shí)現(xiàn)的功能就是對(duì)應(yīng)參數(shù)的賦值。
接下來正式進(jìn)入到了DICOM模塊,
第一步,加載DICOM字典文件。該步驟幾乎是所有與DICOM操作相關(guān)的文件的第一步。其實(shí)就是加載一個(gè)預(yù)先寫好的包含各種DICOM3.0標(biāo)準(zhǔn)中規(guī)定的字段的文本文件。
第二步,初始化網(wǎng)絡(luò)連接,創(chuàng)建網(wǎng)絡(luò)連接的一個(gè)實(shí)例,格式為T_ASC_Network(如下圖),記住該類型,不要與后面出現(xiàn)的T_ASC_Association混淆了。其實(shí)在第一步和第二步之間我們省略了部分代碼,該部分主要是用來控制storescp.exe工具的運(yùn)行機(jī)制,是單線程還是多線程。
第三步,進(jìn)入外層while循環(huán)。在利用ASC_initializeNetwork初始化網(wǎng)絡(luò)環(huán)境后,就進(jìn)入到了while循環(huán)內(nèi)的acceptAssociation函數(shù)。這也是正常情況下,while循環(huán)中唯一的工作函數(shù)。隨后就是待連接斷開后的收尾工作。
第四步,單步調(diào)試進(jìn)入acceptAssociation函數(shù)內(nèi)部。從函數(shù)前面的注釋了解到函數(shù)是用來接收處理鏈接請(qǐng)求的,注意看函數(shù)的參數(shù),傳遞進(jìn)去的是上面我們初始化后獲得的網(wǎng)絡(luò)連接變量net,ascfig是通過解析命令行而獲得的配置參數(shù)。
第五步,函數(shù)acceptAssociation內(nèi)部開始通過調(diào)用ASC_receiveAssociation來嘗試獲取客戶端的連接請(qǐng)求,該函數(shù)與socket編程中的accept函數(shù)類似,可以設(shè)置阻塞模式和非阻塞模式(關(guān)于套接字的阻塞模式和非阻塞模式的區(qū)別可參見《Windows網(wǎng)絡(luò)編程》)。調(diào)用該函數(shù)后storescp.exe工具就暫停,等待客戶端發(fā)起鏈接。
第六步,當(dāng)有客戶端連接進(jìn)入后,ASC_receiveAssociation函數(shù)返回,隨后會(huì)出現(xiàn)眾多以ASC_為前綴的函數(shù),主要有ASC_acceptContextsWithPreferredTransferSyntaxes、ASC_setAPTitles、ASC_getApplicationContextName,以及如果發(fā)生錯(cuò)誤情況下會(huì)調(diào)用的ASC_rejectAssociation。參照博文DICOM醫(yī)學(xué)圖像處理:全面分析DICOM3.0標(biāo)準(zhǔn)中的通訊服務(wù)模塊中的分析可知,以ASC_為前綴的函數(shù)屬于DICOM3.0中的Association Managements,主要在第8部分講解。用來實(shí)現(xiàn)上層DIMSE與下層DUL(Dicom Upper Layer Protocol)的溝通,所處的位置如下圖(更詳細(xì)的介紹可參照上一篇博文)。由此可知該部分是在ASC_receiveAssociation接收到客戶端連接后,所進(jìn)行的有關(guān)連接層的相關(guān)配置。(要留意該部分的配置流程,下面的實(shí)例講解中會(huì)重點(diǎn)介紹由于該部分配置錯(cuò)誤,導(dǎo)致模擬的工具包無法正常運(yùn)行【注1】)。
第七步,接收客戶端連接并配置完成后就是發(fā)送確認(rèn)消息,即調(diào)用函數(shù)ASC_acknowledgeAssociation。此處注意從ASC_receiveAssociation函數(shù)返回后,后續(xù)的相關(guān)ASC_函數(shù)操作的參數(shù)就從T_ASC_Network類型的net變成了T_ASC_Association類型的assoc,其代表的是客戶端的連接。
第八步,storescp.exe發(fā)送完確認(rèn)消息后,接下來就需要處理客戶端發(fā)來的具體請(qǐng)求了。該部分工作包含在processCommands中。
第九步,進(jìn)入到processCommands函數(shù)內(nèi)部,就是我們所遇到的第二個(gè)內(nèi)部while循環(huán),與第三步中的while外部循環(huán)不同的是該內(nèi)部循環(huán)用來接收客戶端發(fā)來的DIMSE消息的,而第三步中的while循環(huán)是用來循環(huán)等待客戶端連接請(qǐng)求。
第十步,內(nèi)部while循環(huán)內(nèi),調(diào)用DIMSE_前綴函數(shù),來實(shí)現(xiàn)DIMSE層的信息交互,這也是C-ECHO、C-STORE、C-FIND等請(qǐng)求具體實(shí)現(xiàn)的部分。首先調(diào)用DIMSE_receiveCommand接收客戶端的DIMSE消息,隨后根據(jù)DIMSE中的CommandSet的類型,分別進(jìn)行處理,如下圖所示,可以看出storescp.exe工具能夠?qū)-ECHO和C-STORE進(jìn)行處理。
至此,通過上述大致的十步我們對(duì)storescp.exe源碼有了一個(gè)較深刻全面的認(rèn)識(shí)。從調(diào)用的ASC_和DIMSE_函數(shù)來看,storescp.exe完全按照DICOM3.0的網(wǎng)絡(luò)通訊協(xié)議來處理C-ECHO和C-STORE請(qǐng)求的。
根據(jù)OFFIS官網(wǎng)給出的關(guān)于dcmnet網(wǎng)絡(luò)通訊包的介紹(),可知DCMTK庫(kù)中提供了兩個(gè)來實(shí)現(xiàn)DICOM網(wǎng)絡(luò)通訊兩端的類DcmSCP和DcmSCU。那么storescp.exe為什么沒有直接用DcmSCP來實(shí)現(xiàn)C-STORE的服務(wù)端呢?利用DcmSCP類是否可以來實(shí)現(xiàn)storescp.exe工具的功能呢?
2)scp.cc源碼分析:參照OFFIS論壇中的一篇帖子(?f=1&t=4041&hilit=addPresentationContext&sid=d4de67ef5faada44233de627a062d3b7)中對(duì)DcmSCP的簡(jiǎn)短使用,來具體分析一下DcmSCP類的源碼文件scp.cc。
第一步,DcmSCP的構(gòu)造函數(shù)。如下圖,在構(gòu)造函數(shù)內(nèi)部,完成了對(duì)網(wǎng)絡(luò)環(huán)境的初始化,這與storescp.exe的main函數(shù)起初的代碼是相同的。
第二步,根據(jù)OFFIS官網(wǎng)提供的類說明文件,在DcmSCP開放的函數(shù)中l(wèi)isten用于實(shí)現(xiàn)對(duì)客戶端請(qǐng)求的處理。其余的公共函數(shù)從名稱上就可以看出大多是配置和獲取相關(guān)參數(shù)的函數(shù),不是以set為前綴就是get,所以接下來重點(diǎn)分析listen函數(shù)內(nèi)部的實(shí)現(xiàn)。
第三步,進(jìn)入到listen函數(shù)內(nèi)部。發(fā)現(xiàn)listen函數(shù)起始部分是用來加載DICOM字典文件的,與storescp.cc文件中DICOM部分的第一步相同。接下來就是相關(guān)的服務(wù)開啟模式(單線程or多線程,阻塞or非阻塞)。
第四步,隨后出現(xiàn)了ASC_initializeNetwork函數(shù),用來初始化網(wǎng)絡(luò)連接。
第五步,進(jìn)入到第一個(gè)while循環(huán),循環(huán)內(nèi)部調(diào)用的是waitForAssociation函數(shù),用來等待客戶端的實(shí)際連接請(qǐng)求,注意此時(shí)的參數(shù)也是T_ASC_Network類型的m_net,這一點(diǎn)與storescp.exe情況相同。
第六步,進(jìn)入到waitForAssociation函數(shù)內(nèi)部,出現(xiàn)的是ASC_receiveAssociation函數(shù),這與storescp.exe源碼分析中的第五步相同。隨后出現(xiàn)的也是以ASC_為前綴的眾多函數(shù),用來配置網(wǎng)絡(luò)連接的具體參數(shù)。
第七步,參數(shù)配置完成后,就是發(fā)送響應(yīng)給客戶端,即調(diào)用ASC_acknowledgeAssociation函數(shù)——與storescp.exe源碼分析的第七步相同。
第八步,隨后scp.cc內(nèi)部將處理客戶端指令的操作封裝在了handleAssociation函數(shù)內(nèi)部,需要注意的是此處handleAssociation函數(shù)并不需要傳遞任何參數(shù)進(jìn)去,因?yàn)門_ASC_Association類型的變量assoc是保存在DcmSCP內(nèi)部的私有成員變量——這一點(diǎn)與storescp.exe直接將assoc變量傳遞給processCommands函數(shù)不同【注2】。
第九步,handleAssociation函數(shù)內(nèi)部需要處理的就是DIMSE層面的指令交互工作。因此為了完整接收客戶端的DIMSE指令,同樣出現(xiàn)了第二個(gè)while循環(huán),循環(huán)內(nèi)部調(diào)用了DIMSE_receiveCommand指令——這與storescp.exe中的processCommands函數(shù)內(nèi)部相同。
第十步,最后進(jìn)入到了handleIncomingCommand函數(shù)內(nèi)部,根據(jù)DIMSE中的CommandSet類型來分別進(jìn)行C-ECHO和C-STORE的處理。
至此,DcmSCP的原文件scp.cc分析完成了。通過與storescp.exe的源文件storescp.cc對(duì)比發(fā)現(xiàn),兩者基本是相同的流程,無非一個(gè)是用類來進(jìn)行了封裝,另一個(gè)是實(shí)現(xiàn)了命令行工具。
3)storescp.cc與scp.cc共同點(diǎn):兩者共同的處理流程如下圖所示,
從上圖可以看出,我們起初的猜測(cè)是正確的,利用DcmSCP是可以實(shí)現(xiàn)storescp.exe工具的,那么為什么DCMTK給出的storescp.exe工具包沒有用DcmSCP類來實(shí)現(xiàn)呢?猜測(cè)有可能是DcmSCP類和storescp.exe工具的開發(fā)者是并行工作的,因此也就無法使用DcmSCP來實(shí)現(xiàn)storescp.exe工具了,并且兩者的基本流程是相同的,也沒必要對(duì)storescp.exe進(jìn)行再次修改,畢竟該工具的用途有限。
模擬構(gòu)建自己的C-STORE SCP: 1)直接利用DcmSCP自建C-STORE SCP端:通過上一節(jié)的分析,我們決定嘗試?yán)肈cmSCP類來構(gòu)建C-STORE的SCP端,來替代storescp.exe工具。
利用VS2012構(gòu)建C++的工程,命名為C-STORETest,直接利用DcmSCP類來實(shí)現(xiàn)C-STORE的SCP端,具體代碼如下:
// C-STORETest.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。 // #include "stdafx.h" //add the include files of Dcmtk library #include "dcmtk/config/osconfig.h" #include "dcmtk/dcmdata/dctk.h" #include "dcmtk/dcmnet/scp.h" #include "ZSDcmStoreSCP.h" #include "global.h" int _tmain(int argc, _TCHAR* argv[]) { DcmSCP mStoreSCP; mStoreSCP.setAETitle("ZS-TEST"); mStoreSCP.setPort(104); mStoreSCP.setVerbosePCMode(true); mStoreSCP.setACSETimeout(-1); mStoreSCP.setDIMSETimeout(10000); mStoreSCP.setDIMSEBlockingMode(DIMSE_NONBLOCKING); OFList< OFString > transferSyntaxes; transferSyntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); transferSyntaxes.push_back(UID_LittleEndianImplicitTransferSyntax); mStoreSCP.addPresentationContext(UID_CTImageStorage,transferSyntaxes); //mStoreSCP.SET mStoreSCP.listen(); return 0; }編譯完成后,打開一個(gè)cmd客戶端,啟動(dòng)storescu.exe與我們自建的C-STORETest進(jìn)行連接,得到的結(jié)果如下:
發(fā)現(xiàn)服務(wù)端(上圖左側(cè))給出的錯(cuò)誤提示顯示“無法處理該類型的DIMSE請(qǐng)求”,而客戶端(上圖右側(cè))顯示連接被終止(Aborting Association)。這是什么原因呢?后來經(jīng)過自己閱讀OFFIS官網(wǎng)關(guān)于DcmSCP類的描述后,找到了問題的原因。原來DcmSCP類的實(shí)現(xiàn)還處在測(cè)試實(shí)驗(yàn)階段,DcmSCP給出的listen函數(shù)內(nèi)部暫時(shí)只能夠處理C-ECHO請(qǐng)求,
按照官方的提示,要想實(shí)現(xiàn)相應(yīng)C-STORE指令,需要我們手動(dòng)擴(kuò)展DcmSCP類。(原來如此,由此看來之所以沒有使用DcmSCP來實(shí)現(xiàn)storescp.exe工具的真正原因是DcmSCP功能還不完善,并不能處理C-STORE指令)。
2)擴(kuò)展DcmSCP類處理C-STORE請(qǐng)求:既然找到了問題所在,那么我們就按照官方的說法嘗試對(duì)DcmSCP進(jìn)行擴(kuò)展,添加處理C-STORE指令的部分。直接的想法是將storescp.exe工程中的針對(duì)C-STORE請(qǐng)求的處理函數(shù)提取出來,添加到DcmSCP的擴(kuò)展類ZSDcmStoreSCP中。因此在ZSDcmStoreSCP類中添加了函數(shù)storeSCP、storeSCPCallback,如下圖所示:
同樣需要對(duì)listen函數(shù)進(jìn)行擴(kuò)展。原本以為只需要重載DcmSCP中處理DIMSE具體CommandSet的函數(shù)handleIncomingCommand即可,但是在擴(kuò)展過程中發(fā)現(xiàn)storescp.exe處理C-STORE的函數(shù)storeSCP和storeSCPCallback都要以T_ASC_association類型為參數(shù),而DcmSCP的m_assoc是私有變量并且沒有留給我們獲取該私有變量的接口,因此無法將storeSCP、storeSCPCallback函數(shù)直接添加到handleIncomingCommand內(nèi)部。
為了實(shí)現(xiàn)直接利用storeSCP、storeSCPCallback函數(shù),我們必須想辦法獲得T_ASC_association變量assoc,通過上述對(duì)DcmSCP的源碼剖析我們可知,,在waitForAssociation函數(shù)內(nèi)部調(diào)用ASC_receiveAssociation之后,DcmSCP才從T_ASC_Network出獲得到了客戶端的T_ASC_association連接變量assoc。那么我們是否可以通過重載waitForAssociation函數(shù)來提取出assoc變量呢?在嘗試這給ZSDcmStoreSCP類添加新的成員變量T_ASC_association* zs_assoc后,將waitForAssociation內(nèi)部的調(diào)用基類DcmSCP中m_assoc的地方統(tǒng)統(tǒng)換成zs_assoc,直接替換后發(fā)現(xiàn),我們需要重載的不只waitForAssociation一個(gè)函數(shù),諸如dropAndDestroyAssociation、negotiateAssociation、refuseAssociation等等函數(shù)都需要重新覆蓋,關(guān)鍵是waitForAssociation內(nèi)部的核心函數(shù)handleAssociation也要覆蓋,因?yàn)樵摵瘮?shù)并不需要任何參數(shù)(見上一節(jié)的【注2】),其內(nèi)部直接調(diào)用的就是DcmSCP的私有成員變量m_assoc,因此為了提取一個(gè)m_assoc變量,我們需要將DcmSCP基類中的眾多函數(shù)進(jìn)行重寫,這還算上的是對(duì)DcmSCP的派生擴(kuò)展么?
在沒有找到很好的解決辦法之前,我將waitForAssociation函數(shù)和handleAssociation函數(shù)內(nèi)部的源碼直接剪切出來一起放到了listen函數(shù)內(nèi)部,然后用我們自己的zs_assoc替換掉了DcmSCP的m_assoc,如是從ZSDcmStoreSCP外觀上看來我只對(duì)DcmSCP類的listen函數(shù)、handleIncomingCommand函數(shù)進(jìn)行了擴(kuò)展而已,另外將storescp.exe中的storeSCP和storeSCPCallback函數(shù)添加到ZSDcmStoreSCP類中,為了使得上述兩個(gè)函數(shù)能夠順利運(yùn)行,也添加了些許storescp.exe中定義的命令行參數(shù)變量。
問題分析: 1)ZSDcmStoreSCP無法響應(yīng)原本DcmSCP能夠響應(yīng)的C-ECHO:將上述完成的ZSDcmStoreSCP類添加到工程中,創(chuàng)建ZSDcmStoreSCP對(duì)象,調(diào)用listen()函數(shù)(具體代碼如下),啟動(dòng)服務(wù)端程序,同樣利用storescu.exe進(jìn)行客戶端模擬,測(cè)試發(fā)現(xiàn)連C-ECHO也無法響應(yīng)。
// C-STORETest.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。 // #include "stdafx.h" //add the include files of Dcmtk library #include "dcmtk/config/osconfig.h" #include "dcmtk/dcmdata/dctk.h" #include "dcmtk/dcmnet/scp.h" #include "ZSDcmStoreSCP.h" #include "global.h" int _tmain(int argc, _TCHAR* argv[]) { ZSDcmStoreSCP mZSStoreScp; mZSStoreScp.setAETitle("ZS-TEST"); mZSStoreScp.setPort(104); mZSStoreScp.setVerbosePCMode(true); mZSStoreScp.setACSETimeout(-1); mZSStoreScp.setDIMSETimeout(10000); mZSStoreScp.setDIMSEBlockingMode(DIMSE_NONBLOCKING); OFList< OFString > transferSyntaxes; transferSyntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); transferSyntaxes.push_back(UID_LittleEndianImplicitTransferSyntax); mZSStoreScp.addPresentationContext(UID_CTImageStorage,transferSyntaxes); //mStoreSCP.SET mZSStoreScp.listen(); return 0; }從上圖可以看書,客戶端在發(fā)送完A-ASSOCIATE-RQ消息后,再無響應(yīng)而直接出現(xiàn)了連接請(qǐng)求失敗。再次利用上一篇博文中使用的RawCap.exe抓取本地回路數(shù)據(jù)包,利用Wireshark查看數(shù)據(jù)包發(fā)現(xiàn),客戶端在發(fā)送完A-ASSOCIATE-RQ后,服務(wù)端并未發(fā)送A-ASSOCIATE-RSP,因此確定問題出在了我們自己封裝的ZSDcmStoreSCP內(nèi)部。
單步調(diào)試后發(fā)現(xiàn),在函數(shù)判別過程中,assoc->presentationContextList變量為空,因此猜測(cè)對(duì)ASC_receiveAssociation接收到客戶端的鏈接assoc后的ASC_相關(guān)配置有問題(參見上一節(jié)的【注1】)。
通過排查發(fā)現(xiàn)在拆解waitForAssociation函數(shù)時(shí)將ASC_receiveAssociation函數(shù)后面的眾多ASC_開頭的函數(shù)給漏掉了,將該段代碼補(bǔ)充完全(如下圖所示),
重新編譯,利用storescu.exe進(jìn)行測(cè)試,測(cè)試結(jié)果如下,通過使用Wireshark觀察RawCap.exe抓取的數(shù)據(jù)包可以肯定此次C-ECHO請(qǐng)求能夠順利響應(yīng),但是對(duì)于C-STORE的請(qǐng)求在保存dcm文件的時(shí)候出現(xiàn)了問題。目前還未查清楚具體問題出現(xiàn)在什么地方。
知識(shí)點(diǎn)補(bǔ)充:
上述storescp.cc和scp.cc中出現(xiàn)了大量的ASC_XXX函數(shù)和DIMSE_XXX函數(shù),這與我們前一篇博文分析的DICOM網(wǎng)絡(luò)通訊服務(wù)整體結(jié)構(gòu)是相吻合的,借著此次實(shí)現(xiàn)C-STORE請(qǐng)求響應(yīng)的過程再次熟悉一下DICOM3.0標(biāo)準(zhǔn)中的幾個(gè)概念,尤其是第一次出現(xiàn)配置錯(cuò)誤時(shí)的TransferSyntax和PresentationContext,加深一下理解。
(該部分同樣還是直接摘抄自DICOM3.0標(biāo)準(zhǔn)的英文官方版,同樣不做翻譯,實(shí)在是英文不好,能力有限,靜候國(guó)內(nèi)大牛出現(xiàn))
Presentation Context– the set of DICOM network services used over an Association, as negotiated between Application Entities;includes Abstract Syntaxesand Transfer Syntaxes.
Transfer Syntax– the encoding used for exchange of DICOM information objects and messages.Examples: JPEGcompressed (images), little endian explicit value representation.
Abstract Syntax – the information agreed to be exchanged between applications, generally equivalent to a Service/Object Pair (SOP) Class.Examples : Verification SOP Class, Modality Worklist Information Model Find SOP Class, Computed Radiography Image Storage SOP Class.
Service/Object Pair (SOP) Class– the specification of the networkor media transfer (service) of a particular type of data (object); the fundamentalunit of DICOM interoperability specification.Examples: Ultrasound Image Storage Service, Basic Grayscale Print Management.
Service/Object Pair (SOP) Instance– an information object; a specific occurrence of information exchanged in a SOP Class.Examples: a specific x-ray image.
Presentation Context consists of an Abstract Syntax plus a list of acceptable Transfer Syntaxes. The Abstract Syntax identifies one SOP Class or MetaSOP Class (a collection of related SOP Classes identified by a single Abstract Syntax UID). By listing the Application Entities with their proposed and accepted Presentation Contexts, the Conformance Statement is identifying the set of Information Objects and Service Classes which are recognized by this implementation。
TransferSyntax是Presentation Context屬性的一種;
TransferSyntax只對(duì)DICOM 消息中的Data Set部分生效。
TransferSyntax是描述真實(shí)世界中一種或幾種Abstract Syntax的編碼規(guī)則。
原本希望通過擴(kuò)展DcmSCP類來輕松加愉快的仿真storescp.exe工具,但是在實(shí)現(xiàn)過程中發(fā)現(xiàn)dcmtk3.6.0版本中的DcmSCP類設(shè)計(jì)存在著缺陷,使得后續(xù)的繼承和擴(kuò)展比較費(fèi)力。搜索OFFIS的官網(wǎng)發(fā)現(xiàn),在最近新發(fā)布的dcmtk3.6.1版本中,竟然給出了DcmStoreSCP和DcmStoreSCU兩個(gè)C-STORE請(qǐng)求處理類,而且分別派生自DcmSCP和DcmSCU,不知道OFFIS的大師是否對(duì)DcmSCP類進(jìn)行了修改?后續(xù)會(huì)對(duì)新版DcmSCP與舊版DcmSCP的比較,以及DcmStoreSCP和DcmStoreSCU的使用進(jìn)行分析,期望找到本文中出現(xiàn)問題的解決方法(注:在下一篇博文中再給出完成的ZSDcmStoreSCP類的代碼)。
(未完待續(xù)……)
后續(xù)博文預(yù)告:1)storescp.exe與sotrescu.exe的源碼剖析:學(xué)習(xí)C-STORE請(qǐng)求(續(xù))
2)dcmtk3.6.0的DcmSCP與dcmtk3.6.1的DcmSCP分析,以及dcmtk3.6.1的DcmStoreSCP和DcmStoreSCU的使用
3)Dcmtk與fo-dicom保存文件的不同設(shè)計(jì)模式:?jiǎn)尉程VS多線程
4)wlmscpfs.exe與findscu.exe的源碼剖析:學(xué)習(xí)C-FIND請(qǐng)求
作者:zssure@163.com
時(shí)間:2014-09-12
本文關(guān)鍵詞:醫(yī)學(xué)圖像處理,由筆耕文化傳播整理發(fā)布。
本文編號(hào):65799
本文鏈接:http://www.sikaile.net/wenshubaike/dxkc/65799.html