Mercurial > hg > orthanc
comparison OrthancFramework/Sources/DicomFormat/DicomStreamReader.cpp @ 4494:39192eb9b43d
New metadata automatically computed at the instance level: "PixelDataOffset"
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 04 Feb 2021 15:31:00 +0100 |
parents | b57ca702a430 |
children | 7053502fbf97 |
comparison
equal
deleted
inserted
replaced
4493:b57ca702a430 | 4494:39192eb9b43d |
---|---|
25 | 25 |
26 #include "../OrthancException.h" | 26 #include "../OrthancException.h" |
27 | 27 |
28 #include <cassert> | 28 #include <cassert> |
29 #include <sstream> | 29 #include <sstream> |
30 | 30 #include <boost/iostreams/device/array.hpp> |
31 #include <boost/iostreams/stream.hpp> | |
32 | |
33 | |
34 #include <iostream> | |
31 | 35 |
32 namespace Orthanc | 36 namespace Orthanc |
33 { | 37 { |
34 static bool IsNormalizationNeeded(const std::string& source, | 38 static bool IsNormalizationNeeded(const std::string& source, |
35 ValueRepresentation vr) | 39 ValueRepresentation vr) |
617 | 621 |
618 uint64_t GetPixelDataOffset() const | 622 uint64_t GetPixelDataOffset() const |
619 { | 623 { |
620 return pixelDataOffset_; | 624 return pixelDataOffset_; |
621 } | 625 } |
626 | |
627 static bool LookupPixelDataOffset(uint64_t& offset, | |
628 std::istream& stream) | |
629 { | |
630 PixelDataVisitor visitor; | |
631 bool isLittleEndian; | |
632 | |
633 { | |
634 DicomStreamReader reader(stream); | |
635 | |
636 try | |
637 { | |
638 reader.Consume(visitor); | |
639 isLittleEndian = reader.IsLittleEndian(); | |
640 } | |
641 catch (OrthancException& e) | |
642 { | |
643 // Invalid DICOM file | |
644 return false; | |
645 } | |
646 } | |
647 | |
648 if (visitor.HasPixelData()) | |
649 { | |
650 // Sanity check if we face an unsupported DICOM file: Make | |
651 // sure that we can read DICOM_TAG_PIXEL_DATA at the reported | |
652 // position in the stream | |
653 stream.seekg(visitor.GetPixelDataOffset(), stream.beg); | |
654 | |
655 std::string s; | |
656 s.resize(4); | |
657 stream.read(&s[0], s.size()); | |
658 | |
659 if (!isLittleEndian) | |
660 { | |
661 // Byte swapping if reading a file whose transfer syntax is | |
662 // 1.2.840.10008.1.2.2 (big endian explicit) | |
663 std::swap(s[0], s[1]); | |
664 std::swap(s[2], s[3]); | |
665 } | |
666 | |
667 if (stream.gcount() == static_cast<std::streamsize>(s.size()) && | |
668 s[0] == char(0xe0) && | |
669 s[1] == char(0x7f) && | |
670 s[2] == char(0x10) && | |
671 s[3] == char(0x00)) | |
672 { | |
673 offset = visitor.GetPixelDataOffset(); | |
674 return true; | |
675 } | |
676 else | |
677 { | |
678 return false; | |
679 } | |
680 } | |
681 else | |
682 { | |
683 return false; | |
684 } | |
685 } | |
622 }; | 686 }; |
623 | 687 |
624 | 688 |
625 bool DicomStreamReader::LookupPixelDataOffset(uint64_t& offset, | 689 bool DicomStreamReader::LookupPixelDataOffset(uint64_t& offset, |
626 const std::string& dicom) | 690 const std::string& dicom) |
627 { | 691 { |
628 std::stringstream stream(dicom); | 692 std::stringstream stream(dicom); |
629 | 693 return PixelDataVisitor::LookupPixelDataOffset(offset, stream); |
630 DicomStreamReader reader(stream); | 694 } |
631 | 695 |
632 PixelDataVisitor visitor; | 696 |
633 | 697 bool DicomStreamReader::LookupPixelDataOffset(uint64_t& offset, |
634 try | 698 const void* buffer, |
635 { | 699 size_t size) |
636 reader.Consume(visitor); | 700 { |
637 } | 701 boost::iostreams::array_source source(reinterpret_cast<const char*>(buffer), size); |
638 catch (OrthancException& e) | 702 boost::iostreams::stream<boost::iostreams::array_source> stream(source); |
639 { | 703 return PixelDataVisitor::LookupPixelDataOffset(offset, stream); |
640 // Invalid DICOM file | |
641 return false; | |
642 } | |
643 | |
644 if (visitor.HasPixelData()) | |
645 { | |
646 offset = visitor.GetPixelDataOffset(); | |
647 return true; | |
648 } | |
649 else | |
650 { | |
651 return false; | |
652 } | |
653 } | 704 } |
654 } | 705 } |
706 |