comparison UnitTestsSources/FromDcmtkTests.cpp @ 3819:1237bd0bbdb2 transcoding

update sop class/instance uid if transcoding
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 08 Apr 2020 17:00:33 +0200
parents abd3a1d114c0
children f89eac983c9b
comparison
equal deleted inserted replaced
3814:023b2a9f3aa1 3819:1237bd0bbdb2
1933 public: 1933 public:
1934 virtual ~IDicomTranscoder() 1934 virtual ~IDicomTranscoder()
1935 { 1935 {
1936 } 1936 }
1937 1937
1938 virtual DcmFileFormat& GetDicom() = 0;
1939
1938 virtual DicomTransferSyntax GetTransferSyntax() = 0; 1940 virtual DicomTransferSyntax GetTransferSyntax() = 0;
1939 1941
1940 virtual std::string GetSopClassUid() = 0; 1942 virtual std::string GetSopClassUid() = 0;
1941 1943
1942 virtual std::string GetSopInstanceUid() = 0; 1944 virtual std::string GetSopInstanceUid() = 0;
1946 virtual ImageAccessor* DecodeFrame(unsigned int frame) = 0; 1948 virtual ImageAccessor* DecodeFrame(unsigned int frame) = 0;
1947 1949
1948 virtual void GetCompressedFrame(std::string& target, 1950 virtual void GetCompressedFrame(std::string& target,
1949 unsigned int frame) = 0; 1951 unsigned int frame) = 0;
1950 1952
1953 // NB: Transcoding can change the value of "GetSopInstanceUid()"
1954 // and "GetTransferSyntax()" if lossy compression is applied
1951 virtual bool Transcode(std::string& target, 1955 virtual bool Transcode(std::string& target,
1952 std::set<DicomTransferSyntax> syntaxes, 1956 std::set<DicomTransferSyntax> syntaxes,
1953 bool allowNewSopInstanceUid) = 0; 1957 bool allowNewSopInstanceUid) = 0;
1954 1958
1955 virtual void WriteToMemoryBuffer(std::string& target) = 0; 1959 virtual void WriteToMemoryBuffer(std::string& target) = 0;
1965 std::string sopClassUid_; 1969 std::string sopClassUid_;
1966 std::string sopInstanceUid_; 1970 std::string sopInstanceUid_;
1967 uint16_t bitsStored_; 1971 uint16_t bitsStored_;
1968 unsigned int lossyQuality_; 1972 unsigned int lossyQuality_;
1969 1973
1974 static std::string GetStringTag(DcmDataset& dataset,
1975 const DcmTagKey& tag)
1976 {
1977 const char* value = NULL;
1978
1979 if (!dataset.findAndGetString(tag, value).good() ||
1980 value == NULL)
1981 {
1982 throw OrthancException(ErrorCode_BadFileFormat,
1983 "Missing SOP class/instance UID in DICOM instance");
1984 }
1985 else
1986 {
1987 return std::string(value);
1988 }
1989 }
1990
1970 void Setup(DcmFileFormat* dicom) 1991 void Setup(DcmFileFormat* dicom)
1971 { 1992 {
1972 lossyQuality_ = 90; 1993 lossyQuality_ = 90;
1973 1994
1974 dicom_.reset(dicom); 1995 dicom_.reset(dicom);
2005 { 2026 {
2006 throw OrthancException(ErrorCode_BadFileFormat, 2027 throw OrthancException(ErrorCode_BadFileFormat,
2007 "Missing \"Bits Stored\" tag in DICOM instance"); 2028 "Missing \"Bits Stored\" tag in DICOM instance");
2008 } 2029 }
2009 2030
2010 const char* a = NULL; 2031 sopClassUid_ = GetStringTag(dataset, DCM_SOPClassUID);
2011 const char* b = NULL; 2032 sopInstanceUid_ = GetStringTag(dataset, DCM_SOPInstanceUID);
2012
2013 if (!dataset.findAndGetString(DCM_SOPClassUID, a).good() ||
2014 !dataset.findAndGetString(DCM_SOPInstanceUID, b).good() ||
2015 a == NULL ||
2016 b == NULL)
2017 {
2018 throw OrthancException(ErrorCode_BadFileFormat,
2019 "Missing SOP class/instance UID in DICOM instance");
2020 }
2021
2022 sopClassUid_.assign(a);
2023 sopInstanceUid_.assign(b);
2024 } 2033 }
2025 2034
2026 public: 2035 public:
2027 DcmtkTranscoder(DcmFileFormat* dicom) // Takes ownership 2036 DcmtkTranscoder(DcmFileFormat* dicom) // Takes ownership
2028 { 2037 {
2056 unsigned int GetBitsStored() const 2065 unsigned int GetBitsStored() const
2057 { 2066 {
2058 return bitsStored_; 2067 return bitsStored_;
2059 } 2068 }
2060 2069
2070 virtual DcmFileFormat& GetDicom()
2071 {
2072 assert(dicom_ != NULL);
2073 return *dicom_;
2074 }
2075
2061 virtual DicomTransferSyntax GetTransferSyntax() ORTHANC_OVERRIDE 2076 virtual DicomTransferSyntax GetTransferSyntax() ORTHANC_OVERRIDE
2062 { 2077 {
2063 return transferSyntax_; 2078 return transferSyntax_;
2064 } 2079 }
2065 2080
2101 2116
2102 virtual bool Transcode(std::string& target, 2117 virtual bool Transcode(std::string& target,
2103 std::set<DicomTransferSyntax> syntaxes, 2118 std::set<DicomTransferSyntax> syntaxes,
2104 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE 2119 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE
2105 { 2120 {
2121 assert(dicom_ != NULL &&
2122 dicom_->getDataset() != NULL);
2123
2106 if (syntaxes.find(GetTransferSyntax()) != syntaxes.end()) 2124 if (syntaxes.find(GetTransferSyntax()) != syntaxes.end())
2107 { 2125 {
2108 printf("NO TRANSCODING\n"); 2126 printf("NO TRANSCODING\n");
2109 2127
2110 // No change in the transfer syntax => simply serialize the current dataset 2128 // No change in the transfer syntax => simply serialize the current dataset
2117 DJ_RPLossy rpLossy(lossyQuality_); 2135 DJ_RPLossy rpLossy(lossyQuality_);
2118 2136
2119 if (syntaxes.find(DicomTransferSyntax_LittleEndianImplicit) != syntaxes.end() && 2137 if (syntaxes.find(DicomTransferSyntax_LittleEndianImplicit) != syntaxes.end() &&
2120 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_LittleEndianImplicit, NULL)) 2138 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_LittleEndianImplicit, NULL))
2121 { 2139 {
2140 transferSyntax_ = DicomTransferSyntax_LittleEndianImplicit;
2122 return true; 2141 return true;
2123 } 2142 }
2124 else if (syntaxes.find(DicomTransferSyntax_LittleEndianExplicit) != syntaxes.end() && 2143 else if (syntaxes.find(DicomTransferSyntax_LittleEndianExplicit) != syntaxes.end() &&
2125 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_LittleEndianExplicit, NULL)) 2144 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_LittleEndianExplicit, NULL))
2126 { 2145 {
2146 transferSyntax_ = DicomTransferSyntax_LittleEndianExplicit;
2127 return true; 2147 return true;
2128 } 2148 }
2129 else if (syntaxes.find(DicomTransferSyntax_BigEndianExplicit) != syntaxes.end() && 2149 else if (syntaxes.find(DicomTransferSyntax_BigEndianExplicit) != syntaxes.end() &&
2130 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_BigEndianExplicit, NULL)) 2150 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_BigEndianExplicit, NULL))
2131 { 2151 {
2152 transferSyntax_ = DicomTransferSyntax_BigEndianExplicit;
2132 return true; 2153 return true;
2133 } 2154 }
2134 else if (syntaxes.find(DicomTransferSyntax_JPEGProcess1) != syntaxes.end() && 2155 else if (syntaxes.find(DicomTransferSyntax_JPEGProcess1) != syntaxes.end() &&
2135 allowNewSopInstanceUid && 2156 allowNewSopInstanceUid &&
2136 GetBitsStored() == 8 && 2157 GetBitsStored() == 8 &&
2137 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_JPEGProcess1, &rpLossy)) 2158 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_JPEGProcess1, &rpLossy))
2138 { 2159 {
2160 transferSyntax_ = DicomTransferSyntax_JPEGProcess1;
2161 sopInstanceUid_ = GetStringTag(*dicom_->getDataset(), DCM_SOPInstanceUID);
2139 return true; 2162 return true;
2140 } 2163 }
2141 else if (syntaxes.find(DicomTransferSyntax_JPEGProcess2_4) != syntaxes.end() && 2164 else if (syntaxes.find(DicomTransferSyntax_JPEGProcess2_4) != syntaxes.end() &&
2142 allowNewSopInstanceUid && 2165 allowNewSopInstanceUid &&
2143 GetBitsStored() <= 12 && 2166 GetBitsStored() <= 12 &&
2144 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_JPEGProcess2_4, &rpLossy)) 2167 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_JPEGProcess2_4, &rpLossy))
2145 { 2168 {
2169 transferSyntax_ = DicomTransferSyntax_JPEGProcess2_4;
2170 sopInstanceUid_ = GetStringTag(*dicom_->getDataset(), DCM_SOPInstanceUID);
2146 return true; 2171 return true;
2147 } 2172 }
2148 else 2173 else
2149 { 2174 {
2150 return false; 2175 return false;
2277 Orthanc::DcmtkTranscoder transcoder2(t.c_str(), t.size()); 2302 Orthanc::DcmtkTranscoder transcoder2(t.c_str(), t.size());
2278 printf(">> %d %d ; %lu bytes\n", transcoder.GetTransferSyntax(), transcoder2.GetTransferSyntax(), t.size()); 2303 printf(">> %d %d ; %lu bytes\n", transcoder.GetTransferSyntax(), transcoder2.GetTransferSyntax(), t.size());
2279 } 2304 }
2280 2305
2281 { 2306 {
2307 std::string a = transcoder.GetSopInstanceUid();
2308 DicomTransferSyntax b = transcoder.GetTransferSyntax();
2309
2282 std::set<DicomTransferSyntax> syntaxes; 2310 std::set<DicomTransferSyntax> syntaxes;
2283 syntaxes.insert(DicomTransferSyntax_JPEGProcess2_4); 2311 syntaxes.insert(DicomTransferSyntax_JPEGProcess2_4);
2284 //syntaxes.insert(DicomTransferSyntax_LittleEndianExplicit); 2312 //syntaxes.insert(DicomTransferSyntax_LittleEndianExplicit);
2285 2313
2286 std::string t; 2314 std::string t;
2287 bool ok = transcoder.Transcode(t, syntaxes, true); 2315 bool ok = transcoder.Transcode(t, syntaxes, true);
2288 printf("Transcoding: %d\n", ok); 2316 printf("Transcoding: %d\n", ok);
2289 2317
2290 if (ok) 2318 if (ok)
2291 { 2319 {
2320 printf("[%s] => [%s]\n", a.c_str(), transcoder.GetSopInstanceUid().c_str());
2321 printf("[%s] => [%s]\n", GetTransferSyntaxUid(b),
2322 GetTransferSyntaxUid(transcoder.GetTransferSyntax()));
2323
2292 { 2324 {
2293 char buf[1024]; 2325 char buf[1024];
2294 sprintf(buf, "/tmp/transcoded-%06d.dcm", count); 2326 sprintf(buf, "/tmp/transcoded-%06d.dcm", count);
2295 printf(">> %s\n", buf); 2327 printf(">> %s\n", buf);
2296 Orthanc::SystemToolbox::WriteFile(t, buf); 2328 Orthanc::SystemToolbox::WriteFile(t, buf);