Mercurial > hg > orthanc
comparison UnitTestsSources/FromDcmtkTests.cpp @ 3743:33c19a6643e1
creating IDicomTranscoder abstraction
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 12 Mar 2020 16:08:08 +0100 |
parents | 090022f1b5e1 |
children | accf1b60b108 |
comparison
equal
deleted
inserted
replaced
3733:c1550e710410 | 3743:33c19a6643e1 |
---|---|
1915 | 1915 |
1916 | 1916 |
1917 | 1917 |
1918 #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 | 1918 #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 |
1919 | 1919 |
1920 #include "../Core/DicomFormat/DicomImageInformation.h" | |
1921 | |
1922 namespace Orthanc | |
1923 { | |
1924 class IDicomTranscoder : public boost::noncopyable | |
1925 { | |
1926 public: | |
1927 virtual ~IDicomTranscoder() | |
1928 { | |
1929 } | |
1930 | |
1931 virtual DicomTransferSyntax GetTransferSyntax() = 0; | |
1932 | |
1933 virtual std::string GetSopClassUid() = 0; | |
1934 | |
1935 virtual std::string GetSopInstanceUid() = 0; | |
1936 | |
1937 virtual unsigned int GetFramesCount() = 0; | |
1938 | |
1939 virtual IDicomTranscoder* Transcode(std::set<DicomTransferSyntax> syntaxes, | |
1940 bool allowNewSopInstanceUid) = 0; | |
1941 | |
1942 virtual ImageAccessor* DecodeFrame(unsigned int frame) = 0; | |
1943 | |
1944 virtual void GetCompressedFrame(std::string& target, | |
1945 unsigned int frame) = 0; | |
1946 }; | |
1947 | |
1948 | |
1949 class DcmtkTranscoder : public IDicomTranscoder | |
1950 { | |
1951 private: | |
1952 std::unique_ptr<DcmFileFormat> dicom_; | |
1953 DicomTransferSyntax transferSyntax_; | |
1954 std::string sopClassUid_; | |
1955 std::string sopInstanceUid_; | |
1956 DicomMap tags_; | |
1957 std::unique_ptr<DicomImageInformation> info_; | |
1958 | |
1959 void Setup(DcmFileFormat* dicom) | |
1960 { | |
1961 dicom_.reset(dicom); | |
1962 | |
1963 if (dicom == NULL || | |
1964 dicom_->getDataset() == NULL) | |
1965 { | |
1966 throw OrthancException(ErrorCode_NullPointer); | |
1967 } | |
1968 | |
1969 DcmDataset& dataset = *dicom_->getDataset(); | |
1970 | |
1971 tags_.Clear(); | |
1972 FromDcmtkBridge::ExtractDicomSummary(tags_, dataset); | |
1973 | |
1974 info_.reset(new DicomImageInformation(tags_)); | |
1975 | |
1976 E_TransferSyntax xfer = dataset.getOriginalXfer(); | |
1977 if (xfer == EXS_Unknown) | |
1978 { | |
1979 dataset.updateOriginalXfer(); | |
1980 xfer = dataset.getOriginalXfer(); | |
1981 if (xfer == EXS_Unknown) | |
1982 { | |
1983 throw OrthancException(ErrorCode_BadFileFormat, | |
1984 "Cannot determine the transfer syntax of the DICOM instance"); | |
1985 } | |
1986 } | |
1987 | |
1988 if (!FromDcmtkBridge::LookupOrthancTransferSyntax(transferSyntax_, xfer)) | |
1989 { | |
1990 throw OrthancException( | |
1991 ErrorCode_BadFileFormat, | |
1992 "Unsupported transfer syntax: " + boost::lexical_cast<std::string>(xfer)); | |
1993 } | |
1994 | |
1995 if (!tags_.LookupStringValue(sopClassUid_, Orthanc::DICOM_TAG_SOP_CLASS_UID, false) || | |
1996 !tags_.LookupStringValue(sopInstanceUid_, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false)) | |
1997 { | |
1998 throw OrthancException(ErrorCode_BadFileFormat, | |
1999 "Missing SOP class/instance UID in DICOM instance"); | |
2000 } | |
2001 } | |
2002 | |
2003 public: | |
2004 DcmtkTranscoder(DcmFileFormat* dicom) // Takes ownership | |
2005 { | |
2006 Setup(dicom); | |
2007 } | |
2008 | |
2009 DcmtkTranscoder(const void* dicom, | |
2010 size_t size) | |
2011 { | |
2012 Setup(FromDcmtkBridge::LoadFromMemoryBuffer(dicom, size)); | |
2013 } | |
2014 | |
2015 DcmtkTranscoder(const ParsedDicomFile& dicom) | |
2016 { | |
2017 Setup(new DcmFileFormat(dicom.GetDcmtkObject())); | |
2018 } | |
2019 | |
2020 virtual DicomTransferSyntax GetTransferSyntax() ORTHANC_OVERRIDE | |
2021 { | |
2022 return transferSyntax_; | |
2023 } | |
2024 | |
2025 virtual std::string GetSopClassUid() ORTHANC_OVERRIDE | |
2026 { | |
2027 return sopClassUid_; | |
2028 } | |
2029 | |
2030 virtual std::string GetSopInstanceUid() ORTHANC_OVERRIDE | |
2031 { | |
2032 return sopInstanceUid_; | |
2033 } | |
2034 | |
2035 virtual unsigned int GetFramesCount() ORTHANC_OVERRIDE | |
2036 { | |
2037 return info_->GetNumberOfFrames(); | |
2038 } | |
2039 | |
2040 virtual IDicomTranscoder* Transcode(std::set<DicomTransferSyntax> syntaxes, | |
2041 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE | |
2042 { | |
2043 throw OrthancException(ErrorCode_NotImplemented); | |
2044 } | |
2045 | |
2046 virtual ImageAccessor* DecodeFrame(unsigned int frame) ORTHANC_OVERRIDE | |
2047 { | |
2048 throw OrthancException(ErrorCode_NotImplemented); | |
2049 } | |
2050 | |
2051 virtual void GetCompressedFrame(std::string& target, | |
2052 unsigned int frame) ORTHANC_OVERRIDE | |
2053 { | |
2054 throw OrthancException(ErrorCode_NotImplemented); | |
2055 } | |
2056 }; | |
2057 } | |
2058 | |
2059 | |
2060 | |
1920 #include <dcmtk/dcmdata/dcostrmb.h> | 2061 #include <dcmtk/dcmdata/dcostrmb.h> |
1921 | 2062 |
1922 static bool Transcode(std::string& buffer, | 2063 static bool Transcode(std::string& buffer, |
1923 DcmDataset& dataSet, | 2064 DcmDataset& dataSet, |
1924 E_TransferSyntax xfer) | 2065 E_TransferSyntax xfer) |
1989 } | 2130 } |
1990 | 2131 |
1991 #include "dcmtk/dcmjpeg/djrploss.h" /* for DJ_RPLossy */ | 2132 #include "dcmtk/dcmjpeg/djrploss.h" /* for DJ_RPLossy */ |
1992 #include "dcmtk/dcmjpeg/djrplol.h" /* for DJ_RPLossless */ | 2133 #include "dcmtk/dcmjpeg/djrplol.h" /* for DJ_RPLossless */ |
1993 | 2134 |
2135 #include <boost/filesystem.hpp> | |
2136 | |
2137 | |
2138 static void TestFile(const std::string& path) | |
2139 { | |
2140 printf("** %s\n", path.c_str()); | |
2141 | |
2142 std::string s; | |
2143 SystemToolbox::ReadFile(s, path); | |
2144 | |
2145 Orthanc::DcmtkTranscoder transcoder(s.c_str(), s.size()); | |
2146 | |
2147 printf("[%s] [%s] [%s] %d\n\n", GetTransferSyntaxUid(transcoder.GetTransferSyntax()), | |
2148 transcoder.GetSopClassUid().c_str(), transcoder.GetSopInstanceUid().c_str(), | |
2149 transcoder.GetFramesCount()); | |
2150 } | |
2151 | |
1994 TEST(Toto, Transcode) | 2152 TEST(Toto, Transcode) |
1995 { | 2153 { |
1996 OFLog::configure(OFLogger::DEBUG_LOG_LEVEL); | 2154 if (0) |
1997 std::string s; | 2155 { |
1998 //SystemToolbox::ReadFile(s, "/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/1.2.840.10008.1.2.4.50.dcm"); | 2156 OFLog::configure(OFLogger::DEBUG_LOG_LEVEL); |
1999 //SystemToolbox::ReadFile(s, "/home/jodogne/DICOM/Alain.dcm"); | 2157 |
2000 SystemToolbox::ReadFile(s, "/home/jodogne/Subversion/orthanc-tests/Database/Brainix/Epi/IM-0001-0002.dcm"); | 2158 std::string s; |
2001 | 2159 //SystemToolbox::ReadFile(s, "/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/1.2.840.10008.1.2.4.50.dcm"); |
2002 std::auto_ptr<DcmFileFormat> dicom(FromDcmtkBridge::LoadFromMemoryBuffer(s.c_str(), s.size())); | 2160 //SystemToolbox::ReadFile(s, "/home/jodogne/DICOM/Alain.dcm"); |
2003 | 2161 SystemToolbox::ReadFile(s, "/home/jodogne/Subversion/orthanc-tests/Database/Brainix/Epi/IM-0001-0002.dcm"); |
2004 // less /home/jodogne/Downloads/dcmtk-3.6.4/dcmdata/include/dcmtk/dcmdata/dcxfer.h | 2162 |
2005 printf(">> %d\n", dicom->getDataset()->getOriginalXfer()); // => 4 == EXS_JPEGProcess1 | 2163 std::auto_ptr<DcmFileFormat> dicom(FromDcmtkBridge::LoadFromMemoryBuffer(s.c_str(), s.size())); |
2006 | 2164 |
2007 const DcmRepresentationParameter *p; | 2165 // less /home/jodogne/Downloads/dcmtk-3.6.4/dcmdata/include/dcmtk/dcmdata/dcxfer.h |
2166 printf(">> %d\n", dicom->getDataset()->getOriginalXfer()); // => 4 == EXS_JPEGProcess1 | |
2167 | |
2168 const DcmRepresentationParameter *p; | |
2008 | 2169 |
2009 #if 0 | 2170 #if 0 |
2010 E_TransferSyntax target = EXS_LittleEndianExplicit; | 2171 E_TransferSyntax target = EXS_LittleEndianExplicit; |
2011 p = NULL; | 2172 p = NULL; |
2012 #elif 1 | 2173 #elif 1 |
2013 E_TransferSyntax target = EXS_JPEGProcess14SV1; | 2174 E_TransferSyntax target = EXS_JPEGProcess14SV1; |
2014 DJ_RPLossless rp_lossless(6, 0); | 2175 DJ_RPLossless rp_lossless(6, 0); |
2015 p = &rp_lossless; | 2176 p = &rp_lossless; |
2016 #else | 2177 #else |
2017 E_TransferSyntax target = EXS_JPEGProcess1; | 2178 E_TransferSyntax target = EXS_JPEGProcess1; |
2018 DJ_RPLossy rp_lossy(90); // quality | 2179 DJ_RPLossy rp_lossy(90); // quality |
2019 p = &rp_lossy; | 2180 p = &rp_lossy; |
2020 #endif | 2181 #endif |
2021 | 2182 |
2022 //E_TransferSyntax target = EXS_LittleEndianImplicit; | 2183 ASSERT_TRUE(dicom->getDataset()->chooseRepresentation(target, p).good()); |
2023 | 2184 ASSERT_TRUE(dicom->getDataset()->canWriteXfer(target)); |
2024 ASSERT_TRUE(dicom->getDataset()->chooseRepresentation(target, p).good()); | 2185 |
2025 ASSERT_TRUE(dicom->getDataset()->canWriteXfer(target)); | 2186 std::string t; |
2026 | 2187 ASSERT_TRUE(Transcode(t, *dicom->getDataset(), target)); |
2027 std::string t; | 2188 |
2028 ASSERT_TRUE(Transcode(t, *dicom->getDataset(), target)); | 2189 SystemToolbox::WriteFile(s, "source.dcm"); |
2029 | 2190 SystemToolbox::WriteFile(t, "target.dcm"); |
2030 SystemToolbox::WriteFile(s, "source.dcm"); | 2191 } |
2031 SystemToolbox::WriteFile(t, "target.dcm"); | 2192 |
2193 if (1) | |
2194 { | |
2195 const char* const PATH = "/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes"; | |
2196 | |
2197 for (boost::filesystem::directory_iterator it(PATH); | |
2198 it != boost::filesystem::directory_iterator(); ++it) | |
2199 { | |
2200 if (boost::filesystem::is_regular_file(it->status())) | |
2201 { | |
2202 TestFile(it->path().string()); | |
2203 } | |
2204 } | |
2205 | |
2206 TestFile("/home/jodogne/Subversion/orthanc-tests/Database/Multiframe.dcm"); | |
2207 } | |
2032 } | 2208 } |
2033 | 2209 |
2034 #endif | 2210 #endif |