comparison UnitTestsSources/FromDcmtkTests.cpp @ 3889:56ce23ba93b7 transcoding

PluginDicomTranscoder
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 05 May 2020 17:46:28 +0200
parents e46b7a997f0a
children 7a5fa8f307e9
comparison
equal deleted inserted replaced
3888:e46b7a997f0a 3889:56ce23ba93b7
1965 * Transcoding flavor that creates a new parsed DICOM file. A 1965 * Transcoding flavor that creates a new parsed DICOM file. A
1966 * "std::set<>" is used to give the possible plugin the 1966 * "std::set<>" is used to give the possible plugin the
1967 * possibility to do a single parsing for all the possible 1967 * possibility to do a single parsing for all the possible
1968 * transfer syntaxes. 1968 * transfer syntaxes.
1969 **/ 1969 **/
1970 virtual DcmFileFormat* Transcode(const void* buffer, 1970 virtual DcmFileFormat* TranscodeToParsed(const void* buffer,
1971 size_t size, 1971 size_t size,
1972 const std::set<DicomTransferSyntax>& allowedSyntaxes, 1972 const std::set<DicomTransferSyntax>& allowedSyntaxes,
1973 bool allowNewSopInstanceUid) = 0; 1973 bool allowNewSopInstanceUid) = 0;
1974
1975 virtual bool HasInplaceTranscode() const = 0;
1974 1976
1975 /** 1977 /**
1976 * In-place transcoding. This method is used first during 1978 * In-place transcoding. This method is preferred for C-STORE.
1977 * C-STORE. It can return "false" if inplace is not supported, in
1978 * which case the "Transcode()" method should be used.
1979 **/ 1979 **/
1980 virtual bool InplaceTranscode(DcmFileFormat& dicom, 1980 virtual bool InplaceTranscode(DcmFileFormat& dicom,
1981 const std::set<DicomTransferSyntax>& allowedSyntaxes, 1981 const std::set<DicomTransferSyntax>& allowedSyntaxes,
1982 bool allowNewSopInstanceUid) = 0; 1982 bool allowNewSopInstanceUid) = 0;
1983 1983
2032 uncompressedSyntaxes.insert(DicomTransferSyntax_BigEndianExplicit); 2032 uncompressedSyntaxes.insert(DicomTransferSyntax_BigEndianExplicit);
2033 } 2033 }
2034 2034
2035 std::unique_ptr<DcmFileFormat> transcoded; 2035 std::unique_ptr<DcmFileFormat> transcoded;
2036 2036
2037 if (transcoder.InplaceTranscode(*dicom, uncompressedSyntaxes, false)) 2037 if (transcoder.HasInplaceTranscode())
2038 { 2038 {
2039 // In-place transcoding is supported 2039 if (transcoder.InplaceTranscode(*dicom, uncompressedSyntaxes, false))
2040 transcoded.reset(dicom.release()); 2040 {
2041 // In-place transcoding is supported and has succeeded
2042 transcoded.reset(dicom.release());
2043 }
2041 } 2044 }
2042 else 2045 else
2043 { 2046 {
2044 transcoded.reset(transcoder.Transcode(buffer, size, uncompressedSyntaxes, false)); 2047 transcoded.reset(transcoder.TranscodeToParsed(buffer, size, uncompressedSyntaxes, false));
2045 } 2048 }
2046 2049
2047 // WARNING: The "dicom" variable must not be used below this 2050 // WARNING: The "dicom" variable must not be used below this
2048 // point. The "sopInstanceUid" might also have changed (if 2051 // point. The "sopInstanceUid" might also have changed (if
2049 // using lossy compression). 2052 // using lossy compression).
2172 unsigned int GetLossyQuality() const 2175 unsigned int GetLossyQuality() const
2173 { 2176 {
2174 return lossyQuality_; 2177 return lossyQuality_;
2175 } 2178 }
2176 2179
2177 virtual DcmFileFormat* Transcode(const void* buffer, 2180 virtual DcmFileFormat* TranscodeToParsed(const void* buffer,
2178 size_t size, 2181 size_t size,
2179 const std::set<DicomTransferSyntax>& allowedSyntaxes, 2182 const std::set<DicomTransferSyntax>& allowedSyntaxes,
2180 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE 2183 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE
2181 { 2184 {
2182 std::unique_ptr<DcmFileFormat> dicom(FromDcmtkBridge::LoadFromMemoryBuffer(buffer, size)); 2185 std::unique_ptr<DcmFileFormat> dicom(FromDcmtkBridge::LoadFromMemoryBuffer(buffer, size));
2183 2186
2184 if (dicom.get() == NULL) 2187 if (dicom.get() == NULL)
2185 { 2188 {
2192 } 2195 }
2193 else 2196 else
2194 { 2197 {
2195 return NULL; 2198 return NULL;
2196 } 2199 }
2200 }
2201
2202 virtual bool HasInplaceTranscode() const
2203 {
2204 return true;
2197 } 2205 }
2198 2206
2199 virtual bool InplaceTranscode(DcmFileFormat& dicom, 2207 virtual bool InplaceTranscode(DcmFileFormat& dicom,
2200 const std::set<DicomTransferSyntax>& allowedSyntaxes, 2208 const std::set<DicomTransferSyntax>& allowedSyntaxes,
2201 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE 2209 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE
2342 size_t size, 2350 size_t size,
2343 const std::set<DicomTransferSyntax>& allowedSyntaxes, 2351 const std::set<DicomTransferSyntax>& allowedSyntaxes,
2344 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE 2352 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE
2345 { 2353 {
2346 std::unique_ptr<DcmFileFormat> transcoded( 2354 std::unique_ptr<DcmFileFormat> transcoded(
2347 Transcode(buffer, size, allowedSyntaxes, allowNewSopInstanceUid)); 2355 TranscodeToParsed(buffer, size, allowedSyntaxes, allowNewSopInstanceUid));
2348 2356
2349 if (transcoded.get() == NULL) 2357 if (transcoded.get() == NULL)
2350 { 2358 {
2351 return false; 2359 return false;
2352 } 2360 }
2360 FromDcmtkBridge::SaveToMemoryBuffer(target, *transcoded->getDataset()); 2368 FromDcmtkBridge::SaveToMemoryBuffer(target, *transcoded->getDataset());
2361 return true; 2369 return true;
2362 } 2370 }
2363 } 2371 }
2364 }; 2372 };
2373
2374
2375
2376 class PluginDicomTranscoder: public IDicomTranscoder
2377 {
2378 private:
2379 bool tryDcmtk_;
2380 DcmtkTranscoder dcmtk_;
2381
2382 protected:
2383 virtual bool TranscodeInternal(std::string& target,
2384 const void* buffer,
2385 size_t size,
2386 const std::set<DicomTransferSyntax>& allowedSyntaxes,
2387 bool allowNewSopInstanceUid) = 0;
2388
2389 public:
2390 PluginDicomTranscoder(bool tryDcmtk) :
2391 tryDcmtk_(tryDcmtk)
2392 {
2393 }
2394
2395 virtual bool TranscodeToBuffer(std::string& target,
2396 const void* buffer,
2397 size_t size,
2398 const std::set<DicomTransferSyntax>& allowedSyntaxes,
2399 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE
2400 {
2401 if (tryDcmtk_)
2402 {
2403 return dcmtk_.TranscodeToBuffer(target, buffer, size, allowedSyntaxes, allowNewSopInstanceUid);
2404 }
2405 else
2406 {
2407 return TranscodeInternal(target, buffer, size, allowedSyntaxes, allowNewSopInstanceUid);
2408 }
2409 }
2410
2411 virtual DcmFileFormat* TranscodeToParsed(const void* buffer,
2412 size_t size,
2413 const std::set<DicomTransferSyntax>& allowedSyntaxes,
2414 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE
2415 {
2416 if (tryDcmtk_)
2417 {
2418 return dcmtk_.TranscodeToParsed(buffer, size, allowedSyntaxes, allowNewSopInstanceUid);
2419 }
2420 else
2421 {
2422 std::string transcoded;
2423 if (TranscodeInternal(transcoded, buffer, size, allowedSyntaxes, allowNewSopInstanceUid))
2424 {
2425 return FromDcmtkBridge::LoadFromMemoryBuffer(
2426 transcoded.empty() ? NULL : transcoded.c_str(), transcoded.size());
2427 }
2428 else
2429 {
2430 return NULL;
2431 }
2432 }
2433 }
2434
2435 virtual bool HasInplaceTranscode() const ORTHANC_OVERRIDE
2436 {
2437 return tryDcmtk_;
2438 }
2439
2440 virtual bool InplaceTranscode(DcmFileFormat& dicom,
2441 const std::set<DicomTransferSyntax>& allowedSyntaxes,
2442 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE
2443 {
2444 if (tryDcmtk_)
2445 {
2446 return dcmtk_.InplaceTranscode(dicom, allowedSyntaxes, allowNewSopInstanceUid);
2447 }
2448 else
2449 {
2450 // "HasInplaceTranscode()" should have been called
2451 throw OrthancException(ErrorCode_BadSequenceOfCalls);
2452 }
2453 }
2454 };
2365 } 2455 }
2366 2456
2367 2457
2368 TEST(Toto, DISABLED_Transcode3) 2458 TEST(Toto, DISABLED_Transcode3)
2369 { 2459 {
2374 scu.SetCommonClassesProposed(false); 2464 scu.SetCommonClassesProposed(false);
2375 scu.SetRetiredBigEndianProposed(true); 2465 scu.SetRetiredBigEndianProposed(true);
2376 2466
2377 DcmtkTranscoder transcoder; 2467 DcmtkTranscoder transcoder;
2378 2468
2379 //for (int j = 0; j < 2; j++) 2469 for (int j = 0; j < 2; j++)
2380 for (int i = 0; i <= DicomTransferSyntax_XML; i++) 2470 for (int i = 0; i <= DicomTransferSyntax_XML; i++)
2381 { 2471 {
2382 DicomTransferSyntax a = (DicomTransferSyntax) i; 2472 DicomTransferSyntax a = (DicomTransferSyntax) i;
2383 2473
2384 std::string path = ("/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/" + 2474 std::string path = ("/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/" +
2385 std::string(GetTransferSyntaxUid(a)) + ".dcm"); 2475 std::string(GetTransferSyntaxUid(a)) + ".dcm");
2386 if (Orthanc::SystemToolbox::IsRegularFile(path)) 2476 if (Orthanc::SystemToolbox::IsRegularFile(path))
2387 { 2477 {
2388 printf("\n======= %s\n", GetTransferSyntaxUid(a)); 2478 printf("\n======= %s\n", GetTransferSyntaxUid(a));
2389 2479
2390 std::string source; 2480 std::string source;
2391 Orthanc::SystemToolbox::ReadFile(source, path); 2481 Orthanc::SystemToolbox::ReadFile(source, path);
2392 2482
2393 std::string c, i; 2483 std::string c, i;
2394 try 2484 try
2395 {
2396 IDicomTranscoder::Store(c, i, scu, transcoder, source.c_str(), source.size());
2397 }
2398 catch (OrthancException& e)
2399 {
2400 if (e.GetErrorCode() == ErrorCode_NotImplemented)
2401 { 2485 {
2402 LOG(ERROR) << "cannot transcode " << GetTransferSyntaxUid(a); 2486 IDicomTranscoder::Store(c, i, scu, transcoder, source.c_str(), source.size());
2403 } 2487 }
2404 else 2488 catch (OrthancException& e)
2405 { 2489 {
2406 throw e; 2490 if (e.GetErrorCode() == ErrorCode_NotImplemented)
2491 {
2492 LOG(ERROR) << "cannot transcode " << GetTransferSyntaxUid(a);
2493 }
2494 else
2495 {
2496 throw e;
2497 }
2407 } 2498 }
2408 } 2499 }
2409 } 2500 }
2410 }
2411 } 2501 }
2412 2502
2413 2503
2414 2504
2415 2505