# HG changeset patch # User Sebastien Jodogne # Date 1383669685 -3600 # Node ID d233b50901055502f133416b4ae67abbc05fd766 # Parent f0232774b913544866f40a45550762e2b5257820 accept more transfer syntaxes for C-Store SCP, write meta-header when receiving files diff -r f0232774b913 -r d233b5090105 NEWS --- a/NEWS Mon Nov 04 15:07:58 2013 +0100 +++ b/NEWS Tue Nov 05 17:41:25 2013 +0100 @@ -2,7 +2,9 @@ =============================== -* Fixes and improvements thanks to cppcheck +* Accept more transfer syntaxes for C-Store SCP (including JPEG) +* Create the meta-header when receiving files through C-Store SCP +* Fixes and improvements thanks to the static analyzer cppcheck Version 0.7.1 (2013/10/30) diff -r f0232774b913 -r d233b5090105 OrthancServer/FromDcmtkBridge.cpp --- a/OrthancServer/FromDcmtkBridge.cpp Mon Nov 04 15:07:58 2013 +0100 +++ b/OrthancServer/FromDcmtkBridge.cpp Tue Nov 05 17:41:25 2013 +0100 @@ -98,6 +98,7 @@ #include #include #include +#include #include #include @@ -1554,25 +1555,41 @@ // syntax, with explicit length. // http://support.dcmtk.org/docs/dcxfer_8h-source.html - E_TransferSyntax xfer = EXS_LittleEndianExplicit; + + + /** + * Note that up to Orthanc 0.7.1 (inclusive), the + * "EXS_LittleEndianExplicit" was always used to save the DICOM + * dataset into memory. We now keep the original transfer syntax + * (if available). + **/ + E_TransferSyntax xfer = dataSet->getOriginalXfer(); + if (xfer == EXS_Unknown) + { + // No information about the original transfer syntax: This is + // most probably a DICOM dataset that was read from memory. + xfer = EXS_LittleEndianExplicit; + } + E_EncodingType encodingType = /*opt_sequenceType*/ EET_ExplicitLength; - uint32_t s = dataSet->getLength(xfer, encodingType); + // Create the meta-header information + DcmFileFormat ff(dataSet); + ff.validateMetaInfo(xfer); + // Create a memory buffer with the proper size + uint32_t s = ff.calcElementLength(xfer, encodingType); buffer.resize(s); DcmOutputBufferStream ob(&buffer[0], s); - dataSet->transferInit(); + // Fill the memory buffer with the meta-header and the dataset + ff.transferInit(); + OFCondition c = ff.write(ob, xfer, encodingType, NULL, + /*opt_groupLength*/ EGL_recalcGL, + /*opt_paddingType*/ EPD_withoutPadding); + ff.transferEnd(); -#if DCMTK_VERSION_NUMBER >= 360 - OFCondition c = dataSet->write(ob, xfer, encodingType, NULL, - /*opt_groupLength*/ EGL_recalcGL, - /*opt_paddingType*/ EPD_withoutPadding); -#else - OFCondition c = dataSet->write(ob, xfer, encodingType, NULL); -#endif - - dataSet->transferEnd(); + // Handle errors if (c.good()) { return true; @@ -1582,15 +1599,5 @@ buffer.clear(); return false; } - -#if 0 - OFCondition cond = cbdata->dcmff->saveFile(fileName.c_str(), xfer, - encodingType, - /*opt_groupLength*/ EGL_recalcGL, - /*opt_paddingType*/ EPD_withoutPadding, - OFstatic_cast(Uint32, /*opt_filepad*/ 0), - OFstatic_cast(Uint32, /*opt_itempad*/ 0), - (opt_useMetaheader) ? EWM_fileformat : EWM_dataset); -#endif } } diff -r f0232774b913 -r d233b5090105 OrthancServer/Internals/CommandDispatcher.cpp --- a/OrthancServer/Internals/CommandDispatcher.cpp Mon Nov 04 15:07:58 2013 +0100 +++ b/OrthancServer/Internals/CommandDispatcher.cpp Tue Nov 05 17:41:25 2013 +0100 @@ -240,9 +240,6 @@ knownAbstractSyntaxes.push_back(UID_MOVEStudyRootQueryRetrieveInformationModel); } - const char* transferSyntaxes[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - int numTransferSyntaxes = 0; - cond = ASC_receiveAssociation(net, &assoc, /*opt_maxPDU*/ ASC_DEFAULTMAXPDU, NULL, NULL, @@ -267,13 +264,49 @@ LOG(INFO) << "Association Received"; - transferSyntaxes[0] = UID_LittleEndianExplicitTransferSyntax; - transferSyntaxes[1] = UID_BigEndianExplicitTransferSyntax; - transferSyntaxes[2] = UID_LittleEndianImplicitTransferSyntax; - numTransferSyntaxes = 3; + std::vector transferSyntaxes; + +#if 0 + // This is the list of the transfer syntaxes that were supported up to Orthanc 0.7.1 + transferSyntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); + transferSyntaxes.push_back(UID_BigEndianExplicitTransferSyntax); + transferSyntaxes.push_back(UID_LittleEndianImplicitTransferSyntax); +#else + transferSyntaxes.push_back(UID_LittleEndianImplicitTransferSyntax); + transferSyntaxes.push_back(UID_DeflatedExplicitVRLittleEndianTransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess1TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess2_4TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess3_5TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess6_8TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess7_9TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess10_12TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess11_13TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess14TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess15TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess16_18TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess17_19TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess20_22TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess21_23TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess24_26TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess25_27TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess28TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess29TransferSyntax); + transferSyntaxes.push_back(UID_JPEGProcess14SV1TransferSyntax); + transferSyntaxes.push_back(UID_JPEGLSLosslessTransferSyntax); + transferSyntaxes.push_back(UID_JPEGLSLossyTransferSyntax); + transferSyntaxes.push_back(UID_JPEG2000LosslessOnlyTransferSyntax); + transferSyntaxes.push_back(UID_JPEG2000TransferSyntax); + transferSyntaxes.push_back(UID_JPEG2000Part2MulticomponentImageCompressionLosslessOnlyTransferSyntax); + transferSyntaxes.push_back(UID_JPEG2000Part2MulticomponentImageCompressionTransferSyntax); + transferSyntaxes.push_back(UID_JPIPReferencedTransferSyntax); + transferSyntaxes.push_back(UID_JPIPReferencedDeflateTransferSyntax); + transferSyntaxes.push_back(UID_MPEG2MainProfileAtMainLevelTransferSyntax); + transferSyntaxes.push_back(UID_MPEG2MainProfileAtHighLevelTransferSyntax); + transferSyntaxes.push_back(UID_RLELosslessTransferSyntax); +#endif /* accept the Verification SOP Class if presented */ - cond = ASC_acceptContextsWithPreferredTransferSyntaxes( assoc->params, &knownAbstractSyntaxes[0], knownAbstractSyntaxes.size(), transferSyntaxes, numTransferSyntaxes); + cond = ASC_acceptContextsWithPreferredTransferSyntaxes( assoc->params, &knownAbstractSyntaxes[0], knownAbstractSyntaxes.size(), &transferSyntaxes[0], transferSyntaxes.size()); if (cond.bad()) { LOG(INFO) << cond.text(); @@ -282,7 +315,7 @@ } /* the array of Storage SOP Class UIDs comes from dcuid.h */ - cond = ASC_acceptContextsWithPreferredTransferSyntaxes( assoc->params, dcmAllStorageSOPClassUIDs, numberOfAllDcmStorageSOPClassUIDs, transferSyntaxes, numTransferSyntaxes); + cond = ASC_acceptContextsWithPreferredTransferSyntaxes( assoc->params, dcmAllStorageSOPClassUIDs, numberOfAllDcmStorageSOPClassUIDs, &transferSyntaxes[0], transferSyntaxes.size()); if (cond.bad()) { LOG(INFO) << cond.text(); @@ -293,7 +326,7 @@ #if ORTHANC_PROMISCUOUS == 1 /* accept everything not known not to be a storage SOP class */ cond = acceptUnknownContextsWithPreferredTransferSyntaxes( - assoc->params, transferSyntaxes, numTransferSyntaxes); + assoc->params, &transferSyntaxes[0], transferSyntaxes.size()); if (cond.bad()) { LOG(INFO) << cond.text();