comparison UnitTestsSources/FromDcmtkTests.cpp @ 3886:b808958dff2a transcoding

transcoding to jpeg-ls
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 05 May 2020 16:03:46 +0200
parents e23026566536
children 25c122277f53
comparison
equal deleted inserted replaced
3885:e23026566536 3886:b808958dff2a
1925 #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 1925 #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1
1926 1926
1927 #include "../Core/DicomNetworking/DicomStoreUserConnection.h" 1927 #include "../Core/DicomNetworking/DicomStoreUserConnection.h"
1928 1928
1929 #include <dcmtk/dcmjpeg/djrploss.h> // for DJ_RPLossy 1929 #include <dcmtk/dcmjpeg/djrploss.h> // for DJ_RPLossy
1930 #include <dcmtk/dcmjpeg/djrplol.h> // for DJ_RPLossless 1930 //#include <dcmtk/dcmjpeg/djrplol.h> // for DJ_RPLossless
1931 #include <dcmtk/dcmjpls/djrparam.h> // for DJLSRepresentationParameter
1931 1932
1932 1933
1933 #if !defined(ORTHANC_ENABLE_DCMTK_JPEG) 1934 #if !defined(ORTHANC_ENABLE_DCMTK_JPEG)
1934 # error Macro ORTHANC_ENABLE_DCMTK_JPEG must be defined 1935 # error Macro ORTHANC_ENABLE_DCMTK_JPEG must be defined
1935 #endif 1936 #endif
2093 throw OrthancException(ErrorCode_BadFileFormat, 2094 throw OrthancException(ErrorCode_BadFileFormat,
2094 "Missing \"Bits Stored\" tag in DICOM instance"); 2095 "Missing \"Bits Stored\" tag in DICOM instance");
2095 } 2096 }
2096 } 2097 }
2097 2098
2099 static std::string GetSopInstanceUid(DcmDataset& dataset)
2100 {
2101 const char* v = NULL;
2102
2103 if (dataset.findAndGetString(DCM_SOPInstanceUID, v).good() &&
2104 v != NULL)
2105 {
2106 return std::string(v);
2107 }
2108 else
2109 {
2110 throw OrthancException(ErrorCode_BadFileFormat, "File without SOP instance UID");
2111 }
2112 }
2113
2114 static void CheckSopInstanceUid(DcmFileFormat& dicom,
2115 const std::string& sopInstanceUid,
2116 bool mustEqual)
2117 {
2118 if (dicom.getDataset() == NULL)
2119 {
2120 throw OrthancException(ErrorCode_InternalError);
2121 }
2122
2123 bool ok;
2124
2125 if (mustEqual)
2126 {
2127 ok = (GetSopInstanceUid(*dicom.getDataset()) == sopInstanceUid);
2128 }
2129 else
2130 {
2131 ok = (GetSopInstanceUid(*dicom.getDataset()) != sopInstanceUid);
2132 }
2133
2134 if (!ok)
2135 {
2136 throw OrthancException(ErrorCode_InternalError,
2137 mustEqual ? "The SOP instance UID has changed unexpectedly during transcoding" :
2138 "The SOP instance UID has not changed as expected during transcoding");
2139 }
2140 }
2141
2098 public: 2142 public:
2099 DcmtkTranscoder() : 2143 DcmtkTranscoder() :
2100 lossyQuality_(90) 2144 lossyQuality_(90)
2101 { 2145 {
2102 } 2146 }
2156 throw OrthancException(ErrorCode_BadFileFormat, 2200 throw OrthancException(ErrorCode_BadFileFormat,
2157 "Cannot determine the transfer syntax"); 2201 "Cannot determine the transfer syntax");
2158 } 2202 }
2159 2203
2160 const uint16_t bitsStored = GetBitsStored(*dicom.getDataset()); 2204 const uint16_t bitsStored = GetBitsStored(*dicom.getDataset());
2205 std::string sourceSopInstanceUid = GetSopInstanceUid(*dicom.getDataset());
2161 2206
2162 if (allowedSyntaxes.find(syntax) != allowedSyntaxes.end()) 2207 if (allowedSyntaxes.find(syntax) != allowedSyntaxes.end())
2163 { 2208 {
2164 // No transcoding is needed 2209 // No transcoding is needed
2165 return true; 2210 return true;
2166 } 2211 }
2167 2212
2168 if (allowedSyntaxes.find(DicomTransferSyntax_LittleEndianImplicit) != allowedSyntaxes.end() && 2213 if (allowedSyntaxes.find(DicomTransferSyntax_LittleEndianImplicit) != allowedSyntaxes.end() &&
2169 FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_LittleEndianImplicit, NULL)) 2214 FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_LittleEndianImplicit, NULL))
2170 { 2215 {
2216 CheckSopInstanceUid(dicom, sourceSopInstanceUid, true);
2171 return true; 2217 return true;
2172 } 2218 }
2173 2219
2174 if (allowedSyntaxes.find(DicomTransferSyntax_LittleEndianExplicit) != allowedSyntaxes.end() && 2220 if (allowedSyntaxes.find(DicomTransferSyntax_LittleEndianExplicit) != allowedSyntaxes.end() &&
2175 FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_LittleEndianExplicit, NULL)) 2221 FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_LittleEndianExplicit, NULL))
2176 { 2222 {
2223 CheckSopInstanceUid(dicom, sourceSopInstanceUid, true);
2177 return true; 2224 return true;
2178 } 2225 }
2179 2226
2180 if (allowedSyntaxes.find(DicomTransferSyntax_BigEndianExplicit) != allowedSyntaxes.end() && 2227 if (allowedSyntaxes.find(DicomTransferSyntax_BigEndianExplicit) != allowedSyntaxes.end() &&
2181 FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_BigEndianExplicit, NULL)) 2228 FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_BigEndianExplicit, NULL))
2182 { 2229 {
2230 CheckSopInstanceUid(dicom, sourceSopInstanceUid, true);
2183 return true; 2231 return true;
2184 } 2232 }
2185 2233
2186 if (allowedSyntaxes.find(DicomTransferSyntax_DeflatedLittleEndianExplicit) != allowedSyntaxes.end() && 2234 if (allowedSyntaxes.find(DicomTransferSyntax_DeflatedLittleEndianExplicit) != allowedSyntaxes.end() &&
2187 FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_DeflatedLittleEndianExplicit, NULL)) 2235 FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_DeflatedLittleEndianExplicit, NULL))
2188 { 2236 {
2237 CheckSopInstanceUid(dicom, sourceSopInstanceUid, true);
2189 return true; 2238 return true;
2190 } 2239 }
2191 2240
2192 #if ORTHANC_ENABLE_JPEG == 1 2241 #if ORTHANC_ENABLE_DCMTK_JPEG == 1
2193 if (allowedSyntaxes.find(DicomTransferSyntax_JPEGProcess1) != allowedSyntaxes.end() && 2242 if (allowedSyntaxes.find(DicomTransferSyntax_JPEGProcess1) != allowedSyntaxes.end() &&
2194 allowNewSopInstanceUid && 2243 allowNewSopInstanceUid &&
2195 bitsStored == 8) 2244 bitsStored == 8)
2196 { 2245 {
2197 DJ_RPLossy rpLossy(lossyQuality_); 2246 DJ_RPLossy parameters(lossyQuality_);
2198 2247
2199 if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGProcess1, &rpLossy)) 2248 if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGProcess1, &parameters))
2200 { 2249 {
2250 CheckSopInstanceUid(dicom, sourceSopInstanceUid, false);
2201 return true; 2251 return true;
2202 } 2252 }
2203 } 2253 }
2204 #endif 2254 #endif
2205 2255
2206 #if ORTHANC_ENABLE_JPEG == 1 2256 #if ORTHANC_ENABLE_DCMTK_JPEG == 1
2207 if (allowedSyntaxes.find(DicomTransferSyntax_JPEGProcess2_4) != allowedSyntaxes.end() && 2257 if (allowedSyntaxes.find(DicomTransferSyntax_JPEGProcess2_4) != allowedSyntaxes.end() &&
2208 allowNewSopInstanceUid && 2258 allowNewSopInstanceUid &&
2209 bitsStored <= 12) 2259 bitsStored <= 12)
2210 { 2260 {
2211 DJ_RPLossy rpLossy(lossyQuality_); 2261 DJ_RPLossy parameters(lossyQuality_);
2212 if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGProcess2_4, &rpLossy)) 2262 if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGProcess2_4, &parameters))
2213 { 2263 {
2264 CheckSopInstanceUid(dicom, sourceSopInstanceUid, false);
2265 return true;
2266 }
2267 }
2268 #endif
2269
2270 #if ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS == 1
2271 if (allowedSyntaxes.find(DicomTransferSyntax_JPEGLSLossless) != allowedSyntaxes.end())
2272 {
2273 // Check out "dcmjpls/apps/dcmcjpls.cc"
2274 DJLSRepresentationParameter parameters(2 /* opt_nearlossless_deviation */,
2275 OFTrue /* opt_useLosslessProcess */);
2276
2277 /**
2278 * WARNING: This call results in a segmentation fault if using
2279 * the DCMTK package 3.6.2 from Ubuntu 18.04.
2280 **/
2281 if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGLSLossless, &parameters))
2282 {
2283 CheckSopInstanceUid(dicom, sourceSopInstanceUid, true);
2284 return true;
2285 }
2286 }
2287 #endif
2288
2289 #if ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS == 1
2290 if (allowNewSopInstanceUid &&
2291 allowedSyntaxes.find(DicomTransferSyntax_JPEGLSLossy) != allowedSyntaxes.end())
2292 {
2293 // Check out "dcmjpls/apps/dcmcjpls.cc"
2294 DJLSRepresentationParameter parameters(2 /* opt_nearlossless_deviation */,
2295 OFFalse /* opt_useLosslessProcess */);
2296
2297 /**
2298 * WARNING: This call results in a segmentation fault if using
2299 * the DCMTK package 3.6.2 from Ubuntu 18.04.
2300 **/
2301 if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGLSLossy, &parameters))
2302 {
2303 CheckSopInstanceUid(dicom, sourceSopInstanceUid, false);
2214 return true; 2304 return true;
2215 } 2305 }
2216 } 2306 }
2217 #endif 2307 #endif
2218 2308
2231 scu.SetCommonClassesProposed(false); 2321 scu.SetCommonClassesProposed(false);
2232 scu.SetRetiredBigEndianProposed(true); 2322 scu.SetRetiredBigEndianProposed(true);
2233 2323
2234 DcmtkTranscoder transcoder; 2324 DcmtkTranscoder transcoder;
2235 2325
2236 for (int j = 0; j < 2; j++) 2326 //for (int j = 0; j < 2; j++)
2237 for (int i = 0; i <= DicomTransferSyntax_XML; i++) 2327 for (int i = 0; i <= DicomTransferSyntax_XML; i++)
2238 { 2328 {
2239 DicomTransferSyntax a = (DicomTransferSyntax) i; 2329 DicomTransferSyntax a = (DicomTransferSyntax) i;
2240 2330
2241 std::string path = ("/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/" + 2331 std::string path = ("/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/" +
2266 } 2356 }
2267 } 2357 }
2268 } 2358 }
2269 2359
2270 2360
2361
2362
2363 TEST(Toto, DISABLED_Transcode4)
2364 {
2365 std::string source;
2366 Orthanc::SystemToolbox::ReadFile(source, "/home/jodogne/Subversion/orthanc-tests/Database/KarstenHilbertRF.dcm");
2367
2368 std::unique_ptr<DcmFileFormat> toto(FromDcmtkBridge::LoadFromMemoryBuffer(source.c_str(), source.size()));
2369 DicomTransferSyntax sourceSyntax;
2370 ASSERT_TRUE(FromDcmtkBridge::LookupOrthancTransferSyntax(sourceSyntax, *toto));
2371
2372 DcmtkTranscoder transcoder;
2373
2374 for (int i = 0; i <= DicomTransferSyntax_XML; i++)
2375 {
2376 DicomTransferSyntax a = (DicomTransferSyntax) i;
2377 std::set<DicomTransferSyntax> s;
2378 s.insert(a);
2379 std::unique_ptr<DcmFileFormat> transcoded(transcoder.Transcode(source.c_str(), source.size(), s, true));
2380 if (transcoded.get() == NULL)
2381 {
2382 printf("**************** CANNOT: [%s] => [%s]\n",
2383 GetTransferSyntaxUid(sourceSyntax), GetTransferSyntaxUid(a));
2384 }
2385 else
2386 {
2387 std::string t;
2388 FromDcmtkBridge::SaveToMemoryBuffer(t, *transcoded->getDataset());
2389 printf("SIZE: %lu\n", t.size());
2390
2391 const char* v = NULL;
2392 transcoded->getDataset()->findAndGetString(DCM_SOPInstanceUID, v);
2393 if (std::string(v) != "1.3.12.2.1107.5.12.1.2013021918595000.1.1")
2394 {
2395 printf("CHANGED SOP INSTANCE UID\n");
2396 }
2397 }
2398 }
2399 }
2400
2401
2271 #endif 2402 #endif