Mercurial > hg > orthanc
comparison OrthancServer/ParsedDicomFile.cpp @ 1924:6c73df12ca51
New URI: "/instances/.../frames/.../raw" to access the raw frames (bypass image decoding)
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 07 Mar 2016 17:43:20 +0100 |
parents | 41e402cd7b3a |
children | 84c7eaeb5244 |
comparison
equal
deleted
inserted
replaced
1923:6ac7f31fc543 | 1924:6c73df12ca51 |
---|---|
82 | 82 |
83 #include "OrthancInitialization.h" | 83 #include "OrthancInitialization.h" |
84 #include "ServerToolbox.h" | 84 #include "ServerToolbox.h" |
85 #include "FromDcmtkBridge.h" | 85 #include "FromDcmtkBridge.h" |
86 #include "ToDcmtkBridge.h" | 86 #include "ToDcmtkBridge.h" |
87 #include "Internals/DicomFrameIndex.h" | |
87 #include "../Core/Images/JpegReader.h" | 88 #include "../Core/Images/JpegReader.h" |
88 #include "../Core/Images/PngReader.h" | 89 #include "../Core/Images/PngReader.h" |
89 #include "../Core/Logging.h" | 90 #include "../Core/Logging.h" |
90 #include "../Core/OrthancException.h" | 91 #include "../Core/OrthancException.h" |
91 #include "../Core/Toolbox.h" | 92 #include "../Core/Toolbox.h" |
143 namespace Orthanc | 144 namespace Orthanc |
144 { | 145 { |
145 struct ParsedDicomFile::PImpl | 146 struct ParsedDicomFile::PImpl |
146 { | 147 { |
147 std::auto_ptr<DcmFileFormat> file_; | 148 std::auto_ptr<DcmFileFormat> file_; |
149 std::auto_ptr<DicomFrameIndex> frameIndex_; | |
148 }; | 150 }; |
149 | 151 |
150 | 152 |
151 // This method can only be called from the constructors! | 153 // This method can only be called from the constructors! |
152 void ParsedDicomFile::Setup(const void* buffer, | 154 void ParsedDicomFile::Setup(const void* buffer, |
514 } | 516 } |
515 | 517 |
516 | 518 |
517 void ParsedDicomFile::Remove(const DicomTag& tag) | 519 void ParsedDicomFile::Remove(const DicomTag& tag) |
518 { | 520 { |
521 InvalidateCache(); | |
522 | |
519 DcmTagKey key(tag.GetGroup(), tag.GetElement()); | 523 DcmTagKey key(tag.GetGroup(), tag.GetElement()); |
520 DcmElement* element = pimpl_->file_->getDataset()->remove(key); | 524 DcmElement* element = pimpl_->file_->getDataset()->remove(key); |
521 if (element != NULL) | 525 if (element != NULL) |
522 { | 526 { |
523 delete element; | 527 delete element; |
526 | 530 |
527 | 531 |
528 | 532 |
529 void ParsedDicomFile::RemovePrivateTagsInternal(const std::set<DicomTag>* toKeep) | 533 void ParsedDicomFile::RemovePrivateTagsInternal(const std::set<DicomTag>* toKeep) |
530 { | 534 { |
535 InvalidateCache(); | |
536 | |
531 DcmDataset& dataset = *pimpl_->file_->getDataset(); | 537 DcmDataset& dataset = *pimpl_->file_->getDataset(); |
532 | 538 |
533 // Loop over the dataset to detect its private tags | 539 // Loop over the dataset to detect its private tags |
534 typedef std::list<DcmElement*> Tags; | 540 typedef std::list<DcmElement*> Tags; |
535 Tags privateTags; | 541 Tags privateTags; |
589 | 595 |
590 void ParsedDicomFile::Insert(const DicomTag& tag, | 596 void ParsedDicomFile::Insert(const DicomTag& tag, |
591 const Json::Value& value, | 597 const Json::Value& value, |
592 bool decodeDataUriScheme) | 598 bool decodeDataUriScheme) |
593 { | 599 { |
600 InvalidateCache(); | |
601 | |
594 std::auto_ptr<DcmElement> element(FromDcmtkBridge::FromJson(tag, value, decodeDataUriScheme, GetEncoding())); | 602 std::auto_ptr<DcmElement> element(FromDcmtkBridge::FromJson(tag, value, decodeDataUriScheme, GetEncoding())); |
595 InsertInternal(*pimpl_->file_->getDataset(), element.release()); | 603 InsertInternal(*pimpl_->file_->getDataset(), element.release()); |
596 } | 604 } |
597 | 605 |
598 | 606 |
677 | 685 |
678 void ParsedDicomFile::Replace(const DicomTag& tag, | 686 void ParsedDicomFile::Replace(const DicomTag& tag, |
679 const std::string& utf8Value, | 687 const std::string& utf8Value, |
680 DicomReplaceMode mode) | 688 DicomReplaceMode mode) |
681 { | 689 { |
690 InvalidateCache(); | |
691 | |
682 std::auto_ptr<DcmElement> element(FromDcmtkBridge::CreateElementForTag(tag)); | 692 std::auto_ptr<DcmElement> element(FromDcmtkBridge::CreateElementForTag(tag)); |
683 FromDcmtkBridge::FillElementWithString(*element, tag, utf8Value, false, GetEncoding()); | 693 FromDcmtkBridge::FillElementWithString(*element, tag, utf8Value, false, GetEncoding()); |
684 ReplaceInternal(*pimpl_->file_->getDataset(), element, mode); | 694 ReplaceInternal(*pimpl_->file_->getDataset(), element, mode); |
685 UpdateStorageUid(tag, utf8Value, false); | 695 UpdateStorageUid(tag, utf8Value, false); |
686 } | 696 } |
689 void ParsedDicomFile::Replace(const DicomTag& tag, | 699 void ParsedDicomFile::Replace(const DicomTag& tag, |
690 const Json::Value& value, | 700 const Json::Value& value, |
691 bool decodeDataUriScheme, | 701 bool decodeDataUriScheme, |
692 DicomReplaceMode mode) | 702 DicomReplaceMode mode) |
693 { | 703 { |
704 InvalidateCache(); | |
705 | |
694 std::auto_ptr<DcmElement> element(FromDcmtkBridge::FromJson(tag, value, decodeDataUriScheme, GetEncoding())); | 706 std::auto_ptr<DcmElement> element(FromDcmtkBridge::FromJson(tag, value, decodeDataUriScheme, GetEncoding())); |
695 ReplaceInternal(*pimpl_->file_->getDataset(), element, mode); | 707 ReplaceInternal(*pimpl_->file_->getDataset(), element, mode); |
696 | 708 |
697 if (tag == DICOM_TAG_SOP_CLASS_UID || | 709 if (tag == DICOM_TAG_SOP_CLASS_UID || |
698 tag == DICOM_TAG_SOP_INSTANCE_UID) | 710 tag == DICOM_TAG_SOP_INSTANCE_UID) |
919 | 931 |
920 | 932 |
921 void ParsedDicomFile::EmbedImage(const std::string& mime, | 933 void ParsedDicomFile::EmbedImage(const std::string& mime, |
922 const std::string& content) | 934 const std::string& content) |
923 { | 935 { |
936 InvalidateCache(); | |
937 | |
924 if (mime == "image/png") | 938 if (mime == "image/png") |
925 { | 939 { |
926 PngReader reader; | 940 PngReader reader; |
927 reader.ReadFromMemory(content); | 941 reader.ReadFromMemory(content); |
928 EmbedImage(reader); | 942 EmbedImage(reader); |
1226 } | 1240 } |
1227 } | 1241 } |
1228 | 1242 |
1229 return result.release(); | 1243 return result.release(); |
1230 } | 1244 } |
1245 | |
1246 | |
1247 void ParsedDicomFile::GetRawFrame(std::string& target, | |
1248 std::string& mime, | |
1249 unsigned int frameId) | |
1250 { | |
1251 if (pimpl_->frameIndex_.get() == NULL) | |
1252 { | |
1253 pimpl_->frameIndex_.reset(new DicomFrameIndex(*pimpl_->file_->getDataset())); | |
1254 } | |
1255 | |
1256 pimpl_->frameIndex_->GetRawFrame(target, frameId); | |
1257 | |
1258 E_TransferSyntax transferSyntax = pimpl_->file_->getDataset()->getOriginalXfer(); | |
1259 switch (transferSyntax) | |
1260 { | |
1261 case EXS_JPEGProcess1TransferSyntax: | |
1262 mime = "image/jpeg"; | |
1263 break; | |
1264 | |
1265 case EXS_JPEG2000LosslessOnly: | |
1266 case EXS_JPEG2000: | |
1267 mime = "image/jp2"; | |
1268 | |
1269 default: | |
1270 mime = "application/octet-stream"; | |
1271 break; | |
1272 } | |
1273 } | |
1274 | |
1275 | |
1276 void ParsedDicomFile::InvalidateCache() | |
1277 { | |
1278 pimpl_->frameIndex_.reset(NULL); | |
1279 } | |
1231 } | 1280 } |