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