Mercurial > hg > orthanc
comparison UnitTestsSources/FromDcmtkTests.cpp @ 3896:210af28c4087 transcoding
merge
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Thu, 07 May 2020 11:32:15 +0200 |
parents | 8f7ad4989fec |
children | 6762a97deabc |
comparison
equal
deleted
inserted
replaced
3895:37cf1889667a | 3896:210af28c4087 |
---|---|
1922 | 1922 |
1923 | 1923 |
1924 | 1924 |
1925 #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 | 1925 #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 |
1926 | 1926 |
1927 #include "../Core/DicomParsing/Internals/DicomFrameIndex.h" | 1927 #include "../Core/DicomNetworking/DicomStoreUserConnection.h" |
1928 | 1928 #include "../Core/DicomParsing/DcmtkTranscoder.h" |
1929 #include <dcmtk/dcmdata/dcostrmb.h> | 1929 |
1930 #include <dcmtk/dcmdata/dcpixel.h> | 1930 TEST(Toto, DISABLED_Transcode3) |
1931 #include <dcmtk/dcmdata/dcpxitem.h> | 1931 { |
1932 #include <dcmtk/dcmjpeg/djrploss.h> // for DJ_RPLossy | 1932 DicomAssociationParameters p; |
1933 #include <dcmtk/dcmjpeg/djrplol.h> // for DJ_RPLossless | 1933 p.SetRemotePort(2000); |
1934 | 1934 |
1935 | 1935 DicomStoreUserConnection scu(p); |
1936 namespace Orthanc | 1936 scu.SetCommonClassesProposed(false); |
1937 { | 1937 scu.SetRetiredBigEndianProposed(true); |
1938 class IDicomTranscoder : public boost::noncopyable | 1938 |
1939 { | 1939 DcmtkTranscoder transcoder; |
1940 public: | 1940 |
1941 virtual ~IDicomTranscoder() | 1941 for (int j = 0; j < 2; j++) |
1942 { | 1942 for (int i = 0; i <= DicomTransferSyntax_XML; i++) |
1943 } | 1943 { |
1944 | 1944 DicomTransferSyntax a = (DicomTransferSyntax) i; |
1945 virtual DcmFileFormat& GetDicom() = 0; | 1945 |
1946 | 1946 std::string path = ("/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/" + |
1947 virtual DicomTransferSyntax GetTransferSyntax() = 0; | 1947 std::string(GetTransferSyntaxUid(a)) + ".dcm"); |
1948 | 1948 if (Orthanc::SystemToolbox::IsRegularFile(path)) |
1949 virtual std::string GetSopClassUid() = 0; | |
1950 | |
1951 virtual std::string GetSopInstanceUid() = 0; | |
1952 | |
1953 virtual unsigned int GetFramesCount() = 0; | |
1954 | |
1955 virtual ImageAccessor* DecodeFrame(unsigned int frame) = 0; | |
1956 | |
1957 virtual void GetCompressedFrame(std::string& target, | |
1958 unsigned int frame) = 0; | |
1959 | |
1960 // NB: Transcoding can change the value of "GetSopInstanceUid()" | |
1961 // and "GetTransferSyntax()" if lossy compression is applied | |
1962 virtual bool Transcode(std::string& target, | |
1963 std::set<DicomTransferSyntax> syntaxes, | |
1964 bool allowNewSopInstanceUid) = 0; | |
1965 | |
1966 virtual void WriteToMemoryBuffer(std::string& target) = 0; | |
1967 }; | |
1968 | |
1969 | |
1970 class DcmtkTranscoder : public IDicomTranscoder | |
1971 { | |
1972 private: | |
1973 std::unique_ptr<DcmFileFormat> dicom_; | |
1974 std::unique_ptr<DicomFrameIndex> index_; | |
1975 DicomTransferSyntax transferSyntax_; | |
1976 std::string sopClassUid_; | |
1977 std::string sopInstanceUid_; | |
1978 uint16_t bitsStored_; | |
1979 unsigned int lossyQuality_; | |
1980 | |
1981 static std::string GetStringTag(DcmDataset& dataset, | |
1982 const DcmTagKey& tag) | |
1983 { | |
1984 const char* value = NULL; | |
1985 | |
1986 if (!dataset.findAndGetString(tag, value).good() || | |
1987 value == NULL) | |
1988 { | 1949 { |
1989 throw OrthancException(ErrorCode_BadFileFormat, | 1950 printf("\n======= %s\n", GetTransferSyntaxUid(a)); |
1990 "Missing SOP class/instance UID in DICOM instance"); | 1951 |
1952 std::string source; | |
1953 Orthanc::SystemToolbox::ReadFile(source, path); | |
1954 | |
1955 std::string c, i; | |
1956 try | |
1957 { | |
1958 scu.Transcode(c, i, transcoder, source.c_str(), source.size(), false, "", 0); | |
1959 } | |
1960 catch (OrthancException& e) | |
1961 { | |
1962 if (e.GetErrorCode() == ErrorCode_NotImplemented) | |
1963 { | |
1964 LOG(ERROR) << "cannot transcode " << GetTransferSyntaxUid(a); | |
1965 } | |
1966 else | |
1967 { | |
1968 throw e; | |
1969 } | |
1970 } | |
1971 } | |
1972 } | |
1973 } | |
1974 | |
1975 | |
1976 TEST(Toto, DISABLED_Transcode4) | |
1977 { | |
1978 std::string source; | |
1979 Orthanc::SystemToolbox::ReadFile(source, "/home/jodogne/Subversion/orthanc-tests/Database/KarstenHilbertRF.dcm"); | |
1980 | |
1981 std::unique_ptr<DcmFileFormat> toto(FromDcmtkBridge::LoadFromMemoryBuffer(source.c_str(), source.size())); | |
1982 DicomTransferSyntax sourceSyntax; | |
1983 ASSERT_TRUE(FromDcmtkBridge::LookupOrthancTransferSyntax(sourceSyntax, *toto)); | |
1984 | |
1985 DcmtkTranscoder transcoder; | |
1986 | |
1987 for (int i = 0; i <= DicomTransferSyntax_XML; i++) | |
1988 { | |
1989 DicomTransferSyntax a = (DicomTransferSyntax) i; | |
1990 std::set<DicomTransferSyntax> s; | |
1991 s.insert(a); | |
1992 | |
1993 std::string t; | |
1994 | |
1995 bool hasSopInstanceUidChanged; | |
1996 | |
1997 if (!transcoder.TranscodeToBuffer(t, hasSopInstanceUidChanged, source.c_str(), source.size(), s, true)) | |
1998 { | |
1999 printf("**************** CANNOT: [%s] => [%s]\n", | |
2000 GetTransferSyntaxUid(sourceSyntax), GetTransferSyntaxUid(a)); | |
2001 } | |
2002 else | |
2003 { | |
2004 bool lossy = (a == DicomTransferSyntax_JPEGProcess1 || | |
2005 a == DicomTransferSyntax_JPEGProcess2_4 || | |
2006 a == DicomTransferSyntax_JPEGLSLossy); | |
2007 | |
2008 printf("SIZE: %lu\n", t.size()); | |
2009 if (hasSopInstanceUidChanged) | |
2010 { | |
2011 ASSERT_TRUE(lossy); | |
1991 } | 2012 } |
1992 else | 2013 else |
1993 { | 2014 { |
1994 return std::string(value); | 2015 ASSERT_FALSE(lossy); |
1995 } | 2016 } |
1996 } | 2017 } |
1997 | 2018 } |
1998 void Setup(DcmFileFormat* dicom) | 2019 } |
1999 { | |
2000 lossyQuality_ = 90; | |
2001 | |
2002 dicom_.reset(dicom); | |
2003 | |
2004 if (dicom == NULL || | |
2005 dicom_->getDataset() == NULL) | |
2006 { | |
2007 throw OrthancException(ErrorCode_NullPointer); | |
2008 } | |
2009 | |
2010 DcmDataset& dataset = *dicom_->getDataset(); | |
2011 index_.reset(new DicomFrameIndex(dataset)); | |
2012 | |
2013 E_TransferSyntax xfer = dataset.getOriginalXfer(); | |
2014 if (xfer == EXS_Unknown) | |
2015 { | |
2016 dataset.updateOriginalXfer(); | |
2017 xfer = dataset.getOriginalXfer(); | |
2018 if (xfer == EXS_Unknown) | |
2019 { | |
2020 throw OrthancException(ErrorCode_BadFileFormat, | |
2021 "Cannot determine the transfer syntax of the DICOM instance"); | |
2022 } | |
2023 } | |
2024 | |
2025 if (!FromDcmtkBridge::LookupOrthancTransferSyntax(transferSyntax_, xfer)) | |
2026 { | |
2027 throw OrthancException( | |
2028 ErrorCode_BadFileFormat, | |
2029 "Unsupported transfer syntax: " + boost::lexical_cast<std::string>(xfer)); | |
2030 } | |
2031 | |
2032 if (!dataset.findAndGetUint16(DCM_BitsStored, bitsStored_).good()) | |
2033 { | |
2034 throw OrthancException(ErrorCode_BadFileFormat, | |
2035 "Missing \"Bits Stored\" tag in DICOM instance"); | |
2036 } | |
2037 | |
2038 sopClassUid_ = GetStringTag(dataset, DCM_SOPClassUID); | |
2039 sopInstanceUid_ = GetStringTag(dataset, DCM_SOPInstanceUID); | |
2040 } | |
2041 | |
2042 public: | |
2043 DcmtkTranscoder(DcmFileFormat* dicom) // Takes ownership | |
2044 { | |
2045 Setup(dicom); | |
2046 } | |
2047 | |
2048 DcmtkTranscoder(const void* dicom, | |
2049 size_t size) | |
2050 { | |
2051 Setup(FromDcmtkBridge::LoadFromMemoryBuffer(dicom, size)); | |
2052 } | |
2053 | |
2054 void SetLossyQuality(unsigned int quality) | |
2055 { | |
2056 if (quality <= 0 || | |
2057 quality > 100) | |
2058 { | |
2059 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
2060 } | |
2061 else | |
2062 { | |
2063 lossyQuality_ = quality; | |
2064 } | |
2065 } | |
2066 | |
2067 unsigned int GetLossyQuality() const | |
2068 { | |
2069 return lossyQuality_; | |
2070 } | |
2071 | |
2072 unsigned int GetBitsStored() const | |
2073 { | |
2074 return bitsStored_; | |
2075 } | |
2076 | |
2077 virtual DcmFileFormat& GetDicom() | |
2078 { | |
2079 assert(dicom_ != NULL); | |
2080 return *dicom_; | |
2081 } | |
2082 | |
2083 virtual DicomTransferSyntax GetTransferSyntax() ORTHANC_OVERRIDE | |
2084 { | |
2085 return transferSyntax_; | |
2086 } | |
2087 | |
2088 virtual std::string GetSopClassUid() ORTHANC_OVERRIDE | |
2089 { | |
2090 return sopClassUid_; | |
2091 } | |
2092 | |
2093 virtual std::string GetSopInstanceUid() ORTHANC_OVERRIDE | |
2094 { | |
2095 return sopInstanceUid_; | |
2096 } | |
2097 | |
2098 virtual unsigned int GetFramesCount() ORTHANC_OVERRIDE | |
2099 { | |
2100 return index_->GetFramesCount(); | |
2101 } | |
2102 | |
2103 virtual void WriteToMemoryBuffer(std::string& target) ORTHANC_OVERRIDE | |
2104 { | |
2105 if (!FromDcmtkBridge::SaveToMemoryBuffer(target, *dicom_)) | |
2106 { | |
2107 throw OrthancException(ErrorCode_InternalError, | |
2108 "Cannot write the DICOM instance to a memory buffer"); | |
2109 } | |
2110 } | |
2111 | |
2112 virtual ImageAccessor* DecodeFrame(unsigned int frame) ORTHANC_OVERRIDE | |
2113 { | |
2114 assert(dicom_->getDataset() != NULL); | |
2115 return DicomImageDecoder::Decode(*dicom_->getDataset(), frame); | |
2116 } | |
2117 | |
2118 virtual void GetCompressedFrame(std::string& target, | |
2119 unsigned int frame) ORTHANC_OVERRIDE | |
2120 { | |
2121 index_->GetRawFrame(target, frame); | |
2122 } | |
2123 | |
2124 virtual bool Transcode(std::string& target, | |
2125 std::set<DicomTransferSyntax> syntaxes, | |
2126 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE | |
2127 { | |
2128 assert(dicom_ != NULL && | |
2129 dicom_->getDataset() != NULL); | |
2130 | |
2131 if (syntaxes.find(GetTransferSyntax()) != syntaxes.end()) | |
2132 { | |
2133 printf("NO TRANSCODING\n"); | |
2134 | |
2135 // No change in the transfer syntax => simply serialize the current dataset | |
2136 WriteToMemoryBuffer(target); | |
2137 return true; | |
2138 } | |
2139 | |
2140 printf(">> %d\n", bitsStored_); | |
2141 | |
2142 DJ_RPLossy rpLossy(lossyQuality_); | |
2143 | |
2144 if (syntaxes.find(DicomTransferSyntax_LittleEndianImplicit) != syntaxes.end() && | |
2145 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_LittleEndianImplicit, NULL)) | |
2146 { | |
2147 transferSyntax_ = DicomTransferSyntax_LittleEndianImplicit; | |
2148 return true; | |
2149 } | |
2150 else if (syntaxes.find(DicomTransferSyntax_LittleEndianExplicit) != syntaxes.end() && | |
2151 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_LittleEndianExplicit, NULL)) | |
2152 { | |
2153 transferSyntax_ = DicomTransferSyntax_LittleEndianExplicit; | |
2154 return true; | |
2155 } | |
2156 else if (syntaxes.find(DicomTransferSyntax_BigEndianExplicit) != syntaxes.end() && | |
2157 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_BigEndianExplicit, NULL)) | |
2158 { | |
2159 transferSyntax_ = DicomTransferSyntax_BigEndianExplicit; | |
2160 return true; | |
2161 } | |
2162 else if (syntaxes.find(DicomTransferSyntax_JPEGProcess1) != syntaxes.end() && | |
2163 allowNewSopInstanceUid && | |
2164 GetBitsStored() == 8 && | |
2165 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_JPEGProcess1, &rpLossy)) | |
2166 { | |
2167 transferSyntax_ = DicomTransferSyntax_JPEGProcess1; | |
2168 sopInstanceUid_ = GetStringTag(*dicom_->getDataset(), DCM_SOPInstanceUID); | |
2169 return true; | |
2170 } | |
2171 else if (syntaxes.find(DicomTransferSyntax_JPEGProcess2_4) != syntaxes.end() && | |
2172 allowNewSopInstanceUid && | |
2173 GetBitsStored() <= 12 && | |
2174 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_JPEGProcess2_4, &rpLossy)) | |
2175 { | |
2176 transferSyntax_ = DicomTransferSyntax_JPEGProcess2_4; | |
2177 sopInstanceUid_ = GetStringTag(*dicom_->getDataset(), DCM_SOPInstanceUID); | |
2178 return true; | |
2179 } | |
2180 else | |
2181 { | |
2182 return false; | |
2183 } | |
2184 } | |
2185 }; | |
2186 } | |
2187 | |
2188 | |
2189 | |
2190 | |
2191 static bool Transcode(std::string& buffer, | |
2192 DcmDataset& dataSet, | |
2193 E_TransferSyntax xfer) | |
2194 { | |
2195 // Determine the transfer syntax which shall be used to write the | |
2196 // information to the file. We always switch to the Little Endian | |
2197 // syntax, with explicit length. | |
2198 | |
2199 // http://support.dcmtk.org/docs/dcxfer_8h-source.html | |
2200 | |
2201 | |
2202 /** | |
2203 * Note that up to Orthanc 0.7.1 (inclusive), the | |
2204 * "EXS_LittleEndianExplicit" was always used to save the DICOM | |
2205 * dataset into memory. We now keep the original transfer syntax | |
2206 * (if available). | |
2207 **/ | |
2208 //E_TransferSyntax xfer = dataSet.getOriginalXfer(); | |
2209 if (xfer == EXS_Unknown) | |
2210 { | |
2211 // No information about the original transfer syntax: This is | |
2212 // most probably a DICOM dataset that was read from memory. | |
2213 xfer = EXS_LittleEndianExplicit; | |
2214 } | |
2215 | |
2216 E_EncodingType encodingType = /*opt_sequenceType*/ EET_ExplicitLength; | |
2217 | |
2218 // Create the meta-header information | |
2219 DcmFileFormat ff(&dataSet); | |
2220 ff.validateMetaInfo(xfer); | |
2221 ff.removeInvalidGroups(); | |
2222 | |
2223 // Create a memory buffer with the proper size | |
2224 { | |
2225 const uint32_t estimatedSize = ff.calcElementLength(xfer, encodingType); // (*) | |
2226 buffer.resize(estimatedSize); | |
2227 } | |
2228 | |
2229 DcmOutputBufferStream ob(&buffer[0], buffer.size()); | |
2230 | |
2231 // Fill the memory buffer with the meta-header and the dataset | |
2232 ff.transferInit(); | |
2233 OFCondition c = ff.write(ob, xfer, encodingType, NULL, | |
2234 /*opt_groupLength*/ EGL_recalcGL, | |
2235 /*opt_paddingType*/ EPD_withoutPadding); | |
2236 ff.transferEnd(); | |
2237 | |
2238 if (c.good()) | |
2239 { | |
2240 // The DICOM file is successfully written, truncate the target | |
2241 // buffer if its size was overestimated by (*) | |
2242 ob.flush(); | |
2243 | |
2244 size_t effectiveSize = static_cast<size_t>(ob.tell()); | |
2245 if (effectiveSize < buffer.size()) | |
2246 { | |
2247 buffer.resize(effectiveSize); | |
2248 } | |
2249 | |
2250 return true; | |
2251 } | |
2252 else | |
2253 { | |
2254 // Error | |
2255 buffer.clear(); | |
2256 return false; | |
2257 } | |
2258 } | |
2259 | |
2260 | |
2261 #include <boost/filesystem.hpp> | |
2262 | |
2263 | |
2264 static void TestFile(const std::string& path) | |
2265 { | |
2266 static unsigned int count = 0; | |
2267 count++; | |
2268 | |
2269 | |
2270 printf("** %s\n", path.c_str()); | |
2271 | |
2272 std::string s; | |
2273 SystemToolbox::ReadFile(s, path); | |
2274 | |
2275 Orthanc::DcmtkTranscoder transcoder(s.c_str(), s.size()); | |
2276 | |
2277 /*if (transcoder.GetBitsStored() != 8) // TODO | |
2278 return; */ | |
2279 | |
2280 { | |
2281 char buf[1024]; | |
2282 sprintf(buf, "/tmp/source-%06d.dcm", count); | |
2283 printf(">> %s\n", buf); | |
2284 Orthanc::SystemToolbox::WriteFile(s, buf); | |
2285 } | |
2286 | |
2287 printf("[%s] [%s] [%s] %d %d\n", GetTransferSyntaxUid(transcoder.GetTransferSyntax()), | |
2288 transcoder.GetSopClassUid().c_str(), transcoder.GetSopInstanceUid().c_str(), | |
2289 transcoder.GetFramesCount(), transcoder.GetTransferSyntax()); | |
2290 | |
2291 for (size_t i = 0; i < transcoder.GetFramesCount(); i++) | |
2292 { | |
2293 std::string f; | |
2294 transcoder.GetCompressedFrame(f, i); | |
2295 | |
2296 if (i == 0) | |
2297 { | |
2298 char buf[1024]; | |
2299 sprintf(buf, "/tmp/frame-%06d.raw", count); | |
2300 printf(">> %s\n", buf); | |
2301 Orthanc::SystemToolbox::WriteFile(f, buf); | |
2302 } | |
2303 } | |
2304 | |
2305 { | |
2306 std::string t; | |
2307 transcoder.WriteToMemoryBuffer(t); | |
2308 | |
2309 Orthanc::DcmtkTranscoder transcoder2(t.c_str(), t.size()); | |
2310 printf(">> %d %d ; %lu bytes\n", transcoder.GetTransferSyntax(), transcoder2.GetTransferSyntax(), t.size()); | |
2311 } | |
2312 | |
2313 { | |
2314 std::string a = transcoder.GetSopInstanceUid(); | |
2315 DicomTransferSyntax b = transcoder.GetTransferSyntax(); | |
2316 | |
2317 std::set<DicomTransferSyntax> syntaxes; | |
2318 syntaxes.insert(DicomTransferSyntax_JPEGProcess2_4); | |
2319 //syntaxes.insert(DicomTransferSyntax_LittleEndianExplicit); | |
2320 | |
2321 std::string t; | |
2322 bool ok = transcoder.Transcode(t, syntaxes, true); | |
2323 printf("Transcoding: %d\n", ok); | |
2324 | |
2325 if (ok) | |
2326 { | |
2327 printf("[%s] => [%s]\n", a.c_str(), transcoder.GetSopInstanceUid().c_str()); | |
2328 printf("[%s] => [%s]\n", GetTransferSyntaxUid(b), | |
2329 GetTransferSyntaxUid(transcoder.GetTransferSyntax())); | |
2330 | |
2331 { | |
2332 char buf[1024]; | |
2333 sprintf(buf, "/tmp/transcoded-%06d.dcm", count); | |
2334 printf(">> %s\n", buf); | |
2335 Orthanc::SystemToolbox::WriteFile(t, buf); | |
2336 } | |
2337 | |
2338 Orthanc::DcmtkTranscoder transcoder2(t.c_str(), t.size()); | |
2339 printf(" => transcoded transfer syntax %d ; %lu bytes\n", transcoder2.GetTransferSyntax(), t.size()); | |
2340 } | |
2341 } | |
2342 | |
2343 printf("\n"); | |
2344 } | |
2345 | |
2346 TEST(Toto, DISABLED_Transcode) | |
2347 { | |
2348 //OFLog::configure(OFLogger::DEBUG_LOG_LEVEL); | |
2349 | |
2350 if (0) | |
2351 { | |
2352 std::string s; | |
2353 //SystemToolbox::ReadFile(s, "/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/1.2.840.10008.1.2.4.50.dcm"); | |
2354 //SystemToolbox::ReadFile(s, "/home/jodogne/DICOM/Alain.dcm"); | |
2355 //SystemToolbox::ReadFile(s, "/home/jodogne/Subversion/orthanc-tests/Database/Brainix/Epi/IM-0001-0002.dcm"); | |
2356 SystemToolbox::ReadFile(s, "/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/1.2.840.10008.1.2.1.dcm"); | |
2357 | |
2358 std::unique_ptr<DcmFileFormat> dicom(FromDcmtkBridge::LoadFromMemoryBuffer(s.c_str(), s.size())); | |
2359 | |
2360 // less /home/jodogne/Downloads/dcmtk-3.6.4/dcmdata/include/dcmtk/dcmdata/dcxfer.h | |
2361 printf(">> %d\n", dicom->getDataset()->getOriginalXfer()); // => 4 == EXS_JPEGProcess1 | |
2362 | |
2363 const DcmRepresentationParameter *p; | |
2364 | |
2365 #if 0 | |
2366 E_TransferSyntax target = EXS_LittleEndianExplicit; | |
2367 p = NULL; | |
2368 #elif 0 | |
2369 E_TransferSyntax target = EXS_JPEGProcess14SV1; | |
2370 DJ_RPLossless rp_lossless(6, 0); | |
2371 p = &rp_lossless; | |
2372 #else | |
2373 E_TransferSyntax target = EXS_JPEGProcess1; | |
2374 DJ_RPLossy rp_lossy(90); // quality | |
2375 p = &rp_lossy; | |
2376 #endif | |
2377 | |
2378 ASSERT_TRUE(dicom->getDataset()->chooseRepresentation(target, p).good()); | |
2379 ASSERT_TRUE(dicom->getDataset()->canWriteXfer(target)); | |
2380 | |
2381 std::string t; | |
2382 ASSERT_TRUE(Transcode(t, *dicom->getDataset(), target)); | |
2383 | |
2384 SystemToolbox::WriteFile(s, "source.dcm"); | |
2385 SystemToolbox::WriteFile(t, "target.dcm"); | |
2386 } | |
2387 | |
2388 if (1) | |
2389 { | |
2390 const char* const PATH = "/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes"; | |
2391 | |
2392 for (boost::filesystem::directory_iterator it(PATH); | |
2393 it != boost::filesystem::directory_iterator(); ++it) | |
2394 { | |
2395 if (boost::filesystem::is_regular_file(it->status())) | |
2396 { | |
2397 TestFile(it->path().string()); | |
2398 } | |
2399 } | |
2400 } | |
2401 | |
2402 if (0) | |
2403 { | |
2404 TestFile("/home/jodogne/Subversion/orthanc-tests/Database/Multiframe.dcm"); | |
2405 TestFile("/home/jodogne/Subversion/orthanc-tests/Database/Issue44/Monochrome1-Jpeg.dcm"); | |
2406 } | |
2407 | |
2408 if (0) | |
2409 { | |
2410 TestFile("/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/1.2.840.10008.1.2.1.dcm"); | |
2411 } | |
2412 } | |
2413 | |
2414 | |
2415 | |
2416 #include "../Core/DicomNetworking/DicomAssociation.h" | |
2417 #include "../Core/DicomNetworking/DicomControlUserConnection.h" | |
2418 #include "../Core/DicomNetworking/DicomStoreUserConnection.h" | |
2419 | |
2420 TEST(Toto, DISABLED_DicomAssociation) | |
2421 { | |
2422 DicomAssociationParameters params; | |
2423 params.SetLocalApplicationEntityTitle("ORTHANC"); | |
2424 params.SetRemoteApplicationEntityTitle("PACS"); | |
2425 params.SetRemotePort(2001); | |
2426 | |
2427 #if 0 | |
2428 DicomAssociation assoc; | |
2429 assoc.ProposeGenericPresentationContext(UID_StorageCommitmentPushModelSOPClass); | |
2430 assoc.ProposeGenericPresentationContext(UID_VerificationSOPClass); | |
2431 assoc.ProposePresentationContext(UID_ComputedRadiographyImageStorage, | |
2432 DicomTransferSyntax_JPEGProcess1); | |
2433 assoc.ProposePresentationContext(UID_ComputedRadiographyImageStorage, | |
2434 DicomTransferSyntax_JPEGProcess2_4); | |
2435 assoc.ProposePresentationContext(UID_ComputedRadiographyImageStorage, | |
2436 DicomTransferSyntax_JPEG2000); | |
2437 | |
2438 assoc.Open(params); | |
2439 | |
2440 int presID = ASC_findAcceptedPresentationContextID(&assoc.GetDcmtkAssociation(), UID_ComputedRadiographyImageStorage); | |
2441 printf(">> %d\n", presID); | |
2442 | |
2443 std::map<DicomTransferSyntax, uint8_t> pc; | |
2444 printf(">> %d\n", assoc.LookupAcceptedPresentationContext(pc, UID_ComputedRadiographyImageStorage)); | |
2445 | |
2446 for (std::map<DicomTransferSyntax, uint8_t>::const_iterator | |
2447 it = pc.begin(); it != pc.end(); ++it) | |
2448 { | |
2449 printf("[%s] => %d\n", GetTransferSyntaxUid(it->first), it->second); | |
2450 } | |
2451 #else | |
2452 { | |
2453 DicomControlUserConnection assoc(params); | |
2454 | |
2455 try | |
2456 { | |
2457 printf(">> %d\n", assoc.Echo()); | |
2458 } | |
2459 catch (OrthancException&) | |
2460 { | |
2461 } | |
2462 } | |
2463 | |
2464 params.SetRemoteApplicationEntityTitle("PACS"); | |
2465 params.SetRemotePort(2000); | |
2466 | |
2467 { | |
2468 DicomControlUserConnection assoc(params); | |
2469 printf(">> %d\n", assoc.Echo()); | |
2470 } | |
2471 | 2020 |
2472 #endif | 2021 #endif |
2473 } | |
2474 | |
2475 static void TestTranscode(DicomStoreUserConnection& scu, | |
2476 const std::string& sopClassUid, | |
2477 DicomTransferSyntax transferSyntax) | |
2478 { | |
2479 uint8_t id; | |
2480 | |
2481 if (scu.NegotiatePresentationContext(id, sopClassUid, transferSyntax)) | |
2482 { | |
2483 printf("**** OK, without transcoding !! %d\n", id); | |
2484 } | |
2485 else | |
2486 { | |
2487 // Transcoding - only in Orthanc >= 1.7.0 | |
2488 | |
2489 const DicomTransferSyntax uncompressed[] = { | |
2490 DicomTransferSyntax_LittleEndianImplicit, // Default transfer syntax | |
2491 DicomTransferSyntax_LittleEndianExplicit, | |
2492 DicomTransferSyntax_BigEndianExplicit | |
2493 }; | |
2494 | |
2495 bool found = false; | |
2496 for (size_t i = 0; i < 3; i++) | |
2497 { | |
2498 if (scu.LookupPresentationContext(id, sopClassUid, uncompressed[i])) | |
2499 { | |
2500 printf("**** TRANSCODING to %s => %d\n", | |
2501 GetTransferSyntaxUid(uncompressed[i]), id); | |
2502 found = true; | |
2503 break; | |
2504 } | |
2505 } | |
2506 | |
2507 if (!found) | |
2508 { | |
2509 printf("**** KO KO KO\n"); | |
2510 } | |
2511 } | |
2512 } | |
2513 | |
2514 | |
2515 TEST(Toto, DISABLED_Store) | |
2516 { | |
2517 DicomAssociationParameters params; | |
2518 params.SetLocalApplicationEntityTitle("ORTHANC"); | |
2519 params.SetRemoteApplicationEntityTitle("STORESCP"); | |
2520 params.SetRemotePort(2000); | |
2521 | |
2522 DicomStoreUserConnection assoc(params); | |
2523 assoc.RegisterStorageClass(UID_MRImageStorage, DicomTransferSyntax_JPEGProcess1); | |
2524 assoc.RegisterStorageClass(UID_MRImageStorage, DicomTransferSyntax_JPEGProcess2_4); | |
2525 //assoc.RegisterStorageClass(UID_MRImageStorage, DicomTransferSyntax_LittleEndianExplicit); | |
2526 | |
2527 //assoc.SetUncompressedSyntaxesProposed(false); // Necessary for transcoding | |
2528 //assoc.SetCommonClassesProposed(false); | |
2529 TestTranscode(assoc, UID_MRImageStorage, DicomTransferSyntax_JPEG2000); | |
2530 TestTranscode(assoc, UID_MRImageStorage, DicomTransferSyntax_LittleEndianExplicit); | |
2531 } | |
2532 | |
2533 | |
2534 TEST(Toto, DISABLED_Store2) | |
2535 { | |
2536 DicomAssociationParameters params; | |
2537 params.SetLocalApplicationEntityTitle("ORTHANC"); | |
2538 params.SetRemoteApplicationEntityTitle("STORESCP"); | |
2539 params.SetRemotePort(2000); | |
2540 | |
2541 DicomStoreUserConnection assoc(params); | |
2542 //assoc.SetCommonClassesProposed(false); | |
2543 assoc.SetRetiredBigEndianProposed(true); | |
2544 | |
2545 std::string s; | |
2546 Orthanc::SystemToolbox::ReadFile(s, "/tmp/i/" + std::string(GetTransferSyntaxUid(DicomTransferSyntax_BigEndianExplicit)) +".dcm"); | |
2547 | |
2548 std::string c, i; | |
2549 assoc.Store(c, i, s.c_str(), s.size()); | |
2550 printf("[%s] [%s]\n", c.c_str(), i.c_str()); | |
2551 } | |
2552 | |
2553 #endif |