Mercurial > hg > orthanc
changeset 956:2fd5a163776d
primitives for proper encoding handling
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 25 Jun 2014 16:08:47 +0200 |
parents | 8811abd6aec9 |
children | 63973b76a51f |
files | Core/Enumerations.h Core/Toolbox.cpp OrthancServer/FromDcmtkBridge.cpp OrthancServer/FromDcmtkBridge.h OrthancServer/ParsedDicomFile.cpp OrthancServer/ParsedDicomFile.h |
diffstat | 6 files changed, 46 insertions(+), 105 deletions(-) [+] |
line wrap: on
line diff
--- a/Core/Enumerations.h Wed Jun 25 15:32:02 2014 +0200 +++ b/Core/Enumerations.h Wed Jun 25 16:08:47 2014 +0200 @@ -230,6 +230,7 @@ enum Encoding { + Encoding_Ascii, Encoding_Utf8, Encoding_Latin1 };
--- a/Core/Toolbox.cpp Wed Jun 25 15:32:02 2014 +0200 +++ b/Core/Toolbox.cpp Wed Jun 25 16:08:47 2014 +0200 @@ -505,6 +505,9 @@ // Already in UTF-8: No conversion is required return source; + case Encoding_Ascii: + return ConvertToAscii(source);; + case Encoding_Latin1: encoding = "ISO-8859-1"; break;
--- a/OrthancServer/FromDcmtkBridge.cpp Wed Jun 25 15:32:02 2014 +0200 +++ b/OrthancServer/FromDcmtkBridge.cpp Wed Jun 25 16:08:47 2014 +0200 @@ -115,8 +115,18 @@ GetCharValue(c[3])); } + + Encoding FromDcmtkBridge::DetectEncoding(DcmDataset& dataset) + { + // TODO Implement this! + return Encoding_Latin1; + } + + void FromDcmtkBridge::Convert(DicomMap& target, DcmDataset& dataset) { + Encoding encoding = DetectEncoding(dataset); + target.Clear(); for (unsigned long i = 0; i < dataset.card(); i++) { @@ -125,7 +135,7 @@ { target.SetValue(element->getTag().getGTag(), element->getTag().getETag(), - ConvertLeafElement(*element)); + ConvertLeafElement(*element, encoding)); } } } @@ -137,7 +147,8 @@ } - DicomValue* FromDcmtkBridge::ConvertLeafElement(DcmElement& element) + DicomValue* FromDcmtkBridge::ConvertLeafElement(DcmElement& element, + Encoding encoding) { if (!element.isLeaf()) { @@ -151,7 +162,7 @@ c != NULL) { std::string s(c); - std::string utf8 = Toolbox::ConvertToUtf8(s, Encoding_Latin1); // TODO Parameter? + std::string utf8 = Toolbox::ConvertToUtf8(s, encoding); return new DicomString(utf8); } else @@ -313,25 +324,28 @@ static void StoreElement(Json::Value& target, DcmElement& element, - unsigned int maxStringLength); + unsigned int maxStringLength, + Encoding encoding); static void StoreItem(Json::Value& target, DcmItem& item, - unsigned int maxStringLength) + unsigned int maxStringLength, + Encoding encoding) { target = Json::Value(Json::objectValue); for (unsigned long i = 0; i < item.card(); i++) { DcmElement* element = item.getElement(i); - StoreElement(target, *element, maxStringLength); + StoreElement(target, *element, maxStringLength, encoding); } } static void StoreElement(Json::Value& target, DcmElement& element, - unsigned int maxStringLength) + unsigned int maxStringLength, + Encoding encoding) { assert(target.type() == Json::objectValue); @@ -356,7 +370,7 @@ value["PrivateCreator"] = tagbis.getPrivateCreator(); } - std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(element)); + std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(element, encoding)); if (v->IsNull()) { value["Type"] = "Null"; @@ -393,7 +407,7 @@ { DcmItem* child = sequence.getItem(i); Json::Value& v = children.append(Json::objectValue); - StoreItem(v, *child, maxStringLength); + StoreItem(v, *child, maxStringLength, encoding); } target[formattedTag]["Name"] = tagName; @@ -407,7 +421,7 @@ DcmDataset& dataset, unsigned int maxStringLength) { - StoreItem(root, dataset, maxStringLength); + StoreItem(root, dataset, maxStringLength, DetectEncoding(dataset)); }
--- a/OrthancServer/FromDcmtkBridge.h Wed Jun 25 15:32:02 2014 +0200 +++ b/OrthancServer/FromDcmtkBridge.h Wed Jun 25 16:08:47 2014 +0200 @@ -44,11 +44,14 @@ class FromDcmtkBridge { public: + static Encoding DetectEncoding(DcmDataset& dataset); + static void Convert(DicomMap& target, DcmDataset& dataset); static DicomTag GetTag(const DcmElement& element); - static DicomValue* ConvertLeafElement(DcmElement& element); + static DicomValue* ConvertLeafElement(DcmElement& element, + Encoding encoding); static void ToJson(Json::Value& target, DcmDataset& dataset,
--- a/OrthancServer/ParsedDicomFile.cpp Wed Jun 25 15:32:02 2014 +0200 +++ b/OrthancServer/ParsedDicomFile.cpp Wed Jun 25 16:08:47 2014 +0200 @@ -146,6 +146,7 @@ struct ParsedDicomFile::PImpl { std::auto_ptr<DcmFileFormat> file_; + Encoding encoding_; }; @@ -170,6 +171,8 @@ } pimpl_->file_->loadAllDataIntoMemory(); pimpl_->file_->transferEnd(); + + pimpl_->encoding_ = FromDcmtkBridge::DetectEncoding(*pimpl_->file_->getDataset()); } @@ -872,7 +875,7 @@ return false; } - std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(*element)); + std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(*element, pimpl_->encoding_)); if (v.get() == NULL) { @@ -887,7 +890,6 @@ } - DicomInstanceHasher ParsedDicomFile::GetHasher() { std::string patientId, studyUid, seriesUid, instanceUid; @@ -904,98 +906,6 @@ } - static void StoreElement(Json::Value& target, - DcmElement& element, - unsigned int maxStringLength); - - static void StoreItem(Json::Value& target, - DcmItem& item, - unsigned int maxStringLength) - { - target = Json::Value(Json::objectValue); - - for (unsigned long i = 0; i < item.card(); i++) - { - DcmElement* element = item.getElement(i); - StoreElement(target, *element, maxStringLength); - } - } - - - static void StoreElement(Json::Value& target, - DcmElement& element, - unsigned int maxStringLength) - { - assert(target.type() == Json::objectValue); - - DicomTag tag(FromDcmtkBridge::GetTag(element)); - const std::string formattedTag = tag.Format(); - -#if 0 - const std::string tagName = FromDcmtkBridge::GetName(tag); -#else - // This version of the code gives access to the name of the private tags - DcmTag tagbis(element.getTag()); - const std::string tagName(tagbis.getTagName()); -#endif - - if (element.isLeaf()) - { - Json::Value value(Json::objectValue); - value["Name"] = tagName; - - if (tagbis.getPrivateCreator() != NULL) - { - value["PrivateCreator"] = tagbis.getPrivateCreator(); - } - - std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(element)); - if (v->IsNull()) - { - value["Type"] = "Null"; - value["Value"] = Json::nullValue; - } - else - { - std::string s = v->AsString(); - if (maxStringLength == 0 || - s.size() <= maxStringLength) - { - value["Type"] = "String"; - value["Value"] = s; - } - else - { - value["Type"] = "TooLong"; - value["Value"] = Json::nullValue; - } - } - - target[formattedTag] = value; - } - else - { - Json::Value children(Json::arrayValue); - - // "All subclasses of DcmElement except for DcmSequenceOfItems - // are leaf nodes, while DcmSequenceOfItems, DcmItem, DcmDataset - // etc. are not." The following cast is thus OK. - DcmSequenceOfItems& sequence = dynamic_cast<DcmSequenceOfItems&>(element); - - for (unsigned long i = 0; i < sequence.card(); i++) - { - DcmItem* child = sequence.getItem(i); - Json::Value& v = children.append(Json::objectValue); - StoreItem(v, *child, maxStringLength); - } - - target[formattedTag]["Name"] = tagName; - target[formattedTag]["Type"] = "Sequence"; - target[formattedTag]["Value"] = children; - } - } - - template <typename T> static void ExtractPngImageTruncate(std::string& result, DicomIntegerPixelAccessor& accessor, @@ -1044,6 +954,7 @@ ParsedDicomFile::ParsedDicomFile() : pimpl_(new PImpl) { pimpl_->file_.reset(new DcmFileFormat); + pimpl_->encoding_ = Encoding_Ascii; Replace(DICOM_TAG_PATIENT_ID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Patient)); Replace(DICOM_TAG_STUDY_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study)); Replace(DICOM_TAG_SERIES_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series)); @@ -1073,6 +984,8 @@ pimpl_(new PImpl) { pimpl_->file_.reset(dynamic_cast<DcmFileFormat*>(other.pimpl_->file_->clone())); + + pimpl_->encoding_ = other.pimpl_->encoding_; } @@ -1279,4 +1192,9 @@ writer.WriteToMemory(result, accessor); } + + Encoding ParsedDicomFile::GetEncoding() const + { + return pimpl_->encoding_; + } }