Mercurial > hg > orthanc
diff OrthancServer/FromDcmtkBridge.cpp @ 291:4d7469f72a0b
embedding of dicom dictionaries
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 14 Dec 2012 15:15:48 +0100 |
parents | 4031f73fe0e4 |
children | 238134081136 |
line wrap: on
line diff
--- a/OrthancServer/FromDcmtkBridge.cpp Fri Dec 14 11:24:24 2012 +0100 +++ b/OrthancServer/FromDcmtkBridge.cpp Fri Dec 14 15:15:48 2012 +0100 @@ -60,6 +60,8 @@ #include <dcmtk/dcmdata/dcuid.h> #include <boost/math/special_functions/round.hpp> +#include <glog/logging.h> +#include <dcmtk/dcmdata/dcostrmb.h> namespace Orthanc { @@ -73,10 +75,13 @@ is.setEos(); file_.reset(new DcmFileFormat); + file_->transferInit(); if (!file_->read(is).good()) { throw OrthancException(ErrorCode_BadFileFormat); } + file_->loadAllDataIntoMemory(); + file_->transferEnd(); } @@ -144,6 +149,58 @@ return true; } + + static void SendSequence(RestApiOutput& output, + DcmSequenceOfItems& sequence) + { + // This element is a sequence + Json::Value v = Json::arrayValue; + + for (unsigned long i = 0; i < sequence.card(); i++) + { + v.append(boost::lexical_cast<std::string>(i)); + } + + output.AnswerJson(v); + } + + static void SendField(RestApiOutput& output, + DcmElement& element) + { + // This element is not a sequence + std::string buffer; + buffer.resize(65536); + Uint32 length = element.getLength(); + Uint32 offset = 0; + + output.GetLowLevelOutput().SendOkHeader("application/octet-stream", true, length, NULL); + + while (offset < length) + { + Uint32 nbytes; + if (length - offset < buffer.size()) + { + nbytes = length - offset; + } + else + { + nbytes = buffer.size(); + } + + if (element.getPartialValue(&buffer[0], offset, nbytes).good()) + { + output.GetLowLevelOutput().Send(&buffer[0], nbytes); + offset += nbytes; + } + else + { + return; + } + } + + output.MarkLowLevelOutputDone(); + } + static void SendPathValueForLeaf(RestApiOutput& output, const std::string& tag, DcmItem& dicom) @@ -154,57 +211,22 @@ return; } - DcmElement* element = NULL; - if (dicom.findAndGetElement(k, element).good() && element != NULL) + DcmSequenceOfItems* sequence = NULL; + if (dicom.findAndGetSequence(k, sequence).good() && + sequence != NULL && + sequence->getVR() == EVR_SQ) { - if (element->getVR() == EVR_SQ) - { - // This element is a sequence - Json::Value v = Json::arrayValue; - DcmSequenceOfItems& sequence = dynamic_cast<DcmSequenceOfItems&>(*element); - - for (unsigned long i = 0; i < sequence.card(); i++) - { - v.append(boost::lexical_cast<std::string>(i)); - } - - output.AnswerJson(v); - } - else - { - // This element is not a sequence - std::string buffer; - buffer.resize(65536); - Uint32 length = element->getLength(); - Uint32 offset = 0; - - output.GetLowLevelOutput().SendOkHeader("application/octet-stream", true, length, NULL); + SendSequence(output, *sequence); + return; + } - while (offset < length) - { - Uint32 nbytes; - if (length - offset < buffer.size()) - { - nbytes = length - offset; - } - else - { - nbytes = buffer.size(); - } - - if (element->getPartialValue(&buffer[0], offset, nbytes).good()) - { - output.GetLowLevelOutput().Send(&buffer[0], nbytes); - offset += nbytes; - } - else - { - return; - } - } - - output.MarkLowLevelOutputDone(); - } + DcmElement* element = NULL; + if (dicom.findAndGetElement(k, element).good() && + element != NULL && + element->getVR() != EVR_UNKNOWN && + element->getVR() != EVR_SQ) + { + SendField(output, *element); } } @@ -728,15 +750,11 @@ { // Some patches for important tags because of different DICOM // dictionaries between DCMTK versions - if (t == DICOM_TAG_PATIENT_NAME) - return "PatientName"; - - if (t == DicomTag(0x0010, 0x0030)) - return "PatientBirthDate"; - - if (t == DicomTag(0x0010, 0x0040)) - return "PatientSex"; - + std::string n = t.GetMainTagsName(); + if (n.size() != 0) + { + return n; + } // End of patches DcmTagKey tag(t.GetGroup(), t.GetElement()); @@ -824,4 +842,53 @@ } } + bool FromDcmtkBridge::SaveToMemoryBuffer(std::string& buffer, + DcmDataset* dataSet) + { + // Determine the transfer syntax which shall be used to write the + // information to the file. We always switch to the Little Endian + // syntax, with explicit length. + + // http://support.dcmtk.org/docs/dcxfer_8h-source.html + E_TransferSyntax xfer = EXS_LittleEndianExplicit; + E_EncodingType encodingType = /*opt_sequenceType*/ EET_ExplicitLength; + + uint32_t s = dataSet->getLength(xfer, encodingType); + + buffer.resize(s); + DcmOutputBufferStream ob(&buffer[0], s); + + dataSet->transferInit(); + +#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(); + if (c.good()) + { + return true; + } + else + { + 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 + } + + }