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 }