changeset 6478:b168eb544b0c pixel-anon

added enum TranscodingSopInstanceUidMode
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 25 Nov 2025 08:08:08 +0100
parents a85d8643792e
children eac46cac2ed5
files OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.cpp OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.h OrthancFramework/Sources/DicomParsing/IDicomTranscoder.h OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.cpp OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.h OrthancFramework/Sources/Enumerations.h OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp OrthancServer/Plugins/Engine/OrthancPlugins.cpp OrthancServer/Sources/OrthancGetRequestHandler.cpp OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp OrthancServer/Sources/ServerContext.cpp OrthancServer/Sources/ServerContext.h OrthancServer/Sources/ServerJobs/ArchiveJob.cpp OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.cpp
diffstat 16 files changed, 84 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake	Tue Nov 25 08:08:08 2025 +0100
@@ -558,6 +558,7 @@
 
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/DicomParsing/Internals/DicomFrameIndex.cpp
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/DicomParsing/Internals/DicomImageDecoder.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/../../Sources/DicomParsing/Internals/SopInstanceUidFixer.cpp
     )
 
   if (NOT ORTHANC_SANDBOXED)
--- a/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp	Tue Nov 25 08:08:08 2025 +0100
@@ -581,7 +581,7 @@
         targetSyntaxes.insert(preferredTransferSyntax);
         attemptedSyntaxes.insert(preferredTransferSyntax);
 
-        success = transcoder.Transcode(transcoded, source, targetSyntaxes, true);
+        success = transcoder.Transcode(transcoded, source, targetSyntaxes, TranscodingSopInstanceUidMode_AllowNew);
         isDestructiveCompressionAllowed = true;
       }
 
@@ -612,7 +612,7 @@
 
         if (!targetSyntaxes.empty())
         {
-          success = transcoder.Transcode(transcoded, source, targetSyntaxes, false);
+          success = transcoder.Transcode(transcoded, source, targetSyntaxes, TranscodingSopInstanceUidMode_NoChange);
           isDestructiveCompressionAllowed = false;
         }
       }
--- a/OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.cpp	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.cpp	Tue Nov 25 08:08:08 2025 +0100
@@ -36,6 +36,7 @@
 
 
 #include "FromDcmtkBridge.h"
+#include "Internals/SopInstanceUidFixer.h"
 #include "../Logging.h"
 #include "../OrthancException.h"
 #include "../Toolbox.h"
@@ -105,11 +106,12 @@
     return false;
   }
 
+
   bool DcmtkTranscoder::InplaceTranscode(DicomTransferSyntax& selectedSyntax /* out */,
                                          std::string& failureReason /* out */,
                                          DcmFileFormat& dicom, /* in/out */
                                          const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                                         bool allowNewSopInstanceUid,
+                                         TranscodingSopInstanceUidMode mode,
                                          unsigned int lossyQuality) 
   {
     std::vector<std::string> failureReasons;
@@ -155,6 +157,12 @@
       return true;
     }
 
+    // The SOP Instance UID fixer has only an effect if "mode" is TranscodingSopInstanceUidMode_Preserve
+    // and if transcoding to a lossy transfer syntax
+    const Internals::SopInstanceUidFixer fixer(mode, dicom);
+
+    const bool allowNewSopInstanceUid = (mode == TranscodingSopInstanceUidMode_AllowNew ||
+                                         mode == TranscodingSopInstanceUidMode_Preserve);
 
 #if ORTHANC_ENABLE_DCMTK_JPEG == 1
     if (allowedSyntaxes.find(DicomTransferSyntax_JPEGProcess1) != allowedSyntaxes.end())
@@ -174,6 +182,7 @@
           
         if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGProcess1, &parameters))
         {
+          fixer.Apply(dicom);
           selectedSyntax = DicomTransferSyntax_JPEGProcess1;
           return true;
         }
@@ -199,6 +208,7 @@
         DJ_RPLossy parameters(lossyQuality);
         if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGProcess2_4, &parameters))
         {
+          fixer.Apply(dicom);
           selectedSyntax = DicomTransferSyntax_JPEGProcess2_4;
           return true;
         }
@@ -215,6 +225,7 @@
                                0 /* opt_point_transform */);
       if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGProcess14, &parameters))
       {
+        fixer.Apply(dicom);
         selectedSyntax = DicomTransferSyntax_JPEGProcess14;
         return true;
       }
@@ -271,6 +282,7 @@
        **/              
       if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGLSLossy, &parameters))
       {
+        fixer.Apply(dicom);
         selectedSyntax = DicomTransferSyntax_JPEGLSLossy;
         return true;
       }
@@ -316,16 +328,16 @@
   bool DcmtkTranscoder::Transcode(DicomImage& target,
                                   DicomImage& source /* in, "GetParsed()" possibly modified */,
                                   const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                                  bool allowNewSopInstanceUid)
+                                  TranscodingSopInstanceUidMode mode)
   {
-    return Transcode(target, source, allowedSyntaxes, allowNewSopInstanceUid, defaultLossyQuality_);
+    return Transcode(target, source, allowedSyntaxes, mode, defaultLossyQuality_);
   }
 
 
   bool DcmtkTranscoder::Transcode(DicomImage& target,
                                   DicomImage& source /* in, "GetParsed()" possibly modified */,
                                   const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                                  bool allowNewSopInstanceUid,
+                                  TranscodingSopInstanceUidMode mode,
                                   unsigned int lossyQuality)
   {
     Semaphore::Locker lock(maxConcurrentExecutionsSemaphore_); // limit the number of concurrent executions
@@ -373,7 +385,7 @@
       return true;
     }
     else if (InplaceTranscode(targetSyntax, failureReason, source.GetParsed(),
-                              allowedSyntaxes, allowNewSopInstanceUid, lossyQuality))
+                              allowedSyntaxes, mode, lossyQuality))
     {   
       // Sanity check
       DicomTransferSyntax targetSyntax2;
@@ -385,9 +397,13 @@
         source.Clear();
         
 #if !defined(NDEBUG)
-        // Only run the sanity check in debug mode
-        CheckTranscoding(target, sourceSyntax, sourceSopInstanceUid,
-                         allowedSyntaxes, allowNewSopInstanceUid);
+        {
+          // Only run the sanity check in debug mode
+          const bool allowNewSopInstanceUid = (mode == TranscodingSopInstanceUidMode_AllowNew ||
+                                               mode == TranscodingSopInstanceUidMode_Preserve);
+          CheckTranscoding(target, sourceSyntax, sourceSopInstanceUid,
+                           allowedSyntaxes, allowNewSopInstanceUid);
+        }
 #endif
         
         return true;
--- a/OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.h	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.h	Tue Nov 25 08:08:08 2025 +0100
@@ -48,7 +48,7 @@
                           std::string& failureReason /* out */,
                           DcmFileFormat& dicom,
                           const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                          bool allowNewSopInstanceUid,
+                          TranscodingSopInstanceUidMode mode,
                           unsigned int lossyQuality);
     
   public:
@@ -63,12 +63,12 @@
     virtual bool Transcode(DicomImage& target,
                            DicomImage& source /* in, "GetParsed()" possibly modified */,
                            const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                           bool allowNewSopInstanceUid) ORTHANC_OVERRIDE;
+                           TranscodingSopInstanceUidMode mode) ORTHANC_OVERRIDE;
 
     virtual bool Transcode(DicomImage& target,
                            DicomImage& source /* in, "GetParsed()" possibly modified */,
                            const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                           bool allowNewSopInstanceUid,
+                           TranscodingSopInstanceUidMode mode,
                            unsigned int lossyQuality) ORTHANC_OVERRIDE;
   };
 }
--- a/OrthancFramework/Sources/DicomParsing/IDicomTranscoder.h	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancFramework/Sources/DicomParsing/IDicomTranscoder.h	Tue Nov 25 08:08:08 2025 +0100
@@ -56,8 +56,6 @@
 
       void Serialize();
 
-      DcmFileFormat* ReleaseParsed();
-
     public:
       DicomImage();
       
@@ -81,6 +79,8 @@
 
       DcmFileFormat& GetParsed();
 
+      DcmFileFormat* ReleaseParsed();
+
       ParsedDicomFile* ReleaseAsParsedDicomFile();
 
       const void* GetBufferData();
@@ -114,12 +114,12 @@
     virtual bool Transcode(DicomImage& target,
                            DicomImage& source /* in, "GetParsed()" possibly modified */,
                            const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                           bool allowNewSopInstanceUid) = 0;
+                           TranscodingSopInstanceUidMode mode) = 0;
 
     virtual bool Transcode(DicomImage& target,
                            DicomImage& source /* in, "GetParsed()" possibly modified */,
                            const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                           bool allowNewSopInstanceUid,
+                           TranscodingSopInstanceUidMode mode,
                            unsigned int lossyQuality) = 0;
 
     static std::string GetSopInstanceUid(DcmFileFormat& dicom);
--- a/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.cpp	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.cpp	Tue Nov 25 08:08:08 2025 +0100
@@ -28,6 +28,7 @@
 #include "../Logging.h"
 #include "../OrthancException.h"
 #include "FromDcmtkBridge.h"
+#include "Internals/SopInstanceUidFixer.h"
 
 #if !defined(NDEBUG)  // For debugging
 #  include "ParsedDicomFile.h"
@@ -59,16 +60,16 @@
   bool MemoryBufferTranscoder::Transcode(DicomImage& target,
                                          DicomImage& source,
                                          const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                                         bool allowNewSopInstanceUid,
+                                         TranscodingSopInstanceUidMode mode,
                                          unsigned int lossyQualityNotUsed)
   {
-    return Transcode(target, source, allowedSyntaxes, allowNewSopInstanceUid);
+    return Transcode(target, source, allowedSyntaxes, mode);
   }
 
   bool MemoryBufferTranscoder::Transcode(DicomImage& target,
                                          DicomImage& source,
                                          const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                                         bool allowNewSopInstanceUid)
+                                         TranscodingSopInstanceUidMode mode)
   {
     target.Clear();
     
@@ -84,6 +85,10 @@
     const std::string sourceSopInstanceUid = GetSopInstanceUid(source.GetParsed());
 #endif
 
+    Internals::SopInstanceUidFixer fixer(mode, source);
+    const bool allowNewSopInstanceUid = (mode == TranscodingSopInstanceUidMode_AllowNew ||
+                                         mode == TranscodingSopInstanceUidMode_Preserve);
+
     std::string buffer;
     if (TranscodeBuffer(buffer, source.GetBufferData(), source.GetBufferSize(),
                         allowedSyntaxes, allowNewSopInstanceUid))
@@ -98,6 +103,7 @@
                        allowedSyntaxes, allowNewSopInstanceUid);
 #endif
 
+      fixer.Apply(target);
       return true;
     }
     else
--- a/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.h	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.h	Tue Nov 25 08:08:08 2025 +0100
@@ -42,12 +42,12 @@
     virtual bool Transcode(DicomImage& target /* out */,
                            DicomImage& source,
                            const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                           bool allowNewSopInstanceUid) ORTHANC_OVERRIDE;
+                           TranscodingSopInstanceUidMode mode) ORTHANC_OVERRIDE;
 
     virtual bool Transcode(DicomImage& target /* out */,
                            DicomImage& source,
                            const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                           bool allowNewSopInstanceUid,
+                           TranscodingSopInstanceUidMode mode,
                            unsigned int lossyQualityNotUsed) ORTHANC_OVERRIDE;
   };
 }
--- a/OrthancFramework/Sources/Enumerations.h	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancFramework/Sources/Enumerations.h	Tue Nov 25 08:08:08 2025 +0100
@@ -809,6 +809,13 @@
     ErrorPayloadType_RetrieveJob = 3,
   };
 
+  enum TranscodingSopInstanceUidMode
+  {
+    TranscodingSopInstanceUidMode_NoChange,   // Never change the SOP Instance UID (only allows transcoding to lossless)
+    TranscodingSopInstanceUidMode_AllowNew,   // Allow transcoding to lossless and lossy (if lossy, a new SOP Instance UID is generated)
+    TranscodingSopInstanceUidMode_Preserve    // Allow transcoding to lossless and lossy (if lossy, preserve the original SOP Instance UID)
+  };
+
 
   ORTHANC_PUBLIC
   const char* EnumerationToString(ErrorCode code);
--- a/OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp	Tue Nov 25 08:08:08 2025 +0100
@@ -3681,7 +3681,7 @@
     IDicomTranscoder::DicomImage source, target;
     source.AcquireParsed(dynamic_cast<DcmFileFormat*>(toto->clone()));
 
-    if (!transcoder.Transcode(target, source, s, true))
+    if (!transcoder.Transcode(target, source, s, TranscodingSopInstanceUidMode_AllowNew))
     {
       printf("**************** CANNOT: [%s] => [%s]\n",
              GetTransferSyntaxUid(sourceSyntax), GetTransferSyntaxUid(a));
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Tue Nov 25 08:08:08 2025 +0100
@@ -5792,11 +5792,10 @@
 
           IDicomTranscoder::DicomImage transcoded;
           bool success;
-          
+
           {
             PImpl::ServerContextReference lock(*pimpl_);
-            success = lock.GetContext().Transcode(
-              transcoded, source, syntaxes, true /* allow new sop */);
+            success = lock.GetContext().Transcode(transcoded, source, syntaxes, TranscodingSopInstanceUidMode_AllowNew);
           }
 
           if (success)
--- a/OrthancServer/Sources/OrthancGetRequestHandler.cpp	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancServer/Sources/OrthancGetRequestHandler.cpp	Tue Nov 25 08:08:08 2025 +0100
@@ -325,7 +325,7 @@
       std::set<DicomTransferSyntax> ts;
       ts.insert(selectedSyntax);
       
-      if (context_.Transcode(transcoded, source, ts, true))
+      if (context_.Transcode(transcoded, source, ts, TranscodingSopInstanceUidMode_AllowNew))
       {
         // Transcoding has succeeded
         DcmDataset *stDetailTmp = NULL;
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Tue Nov 25 08:08:08 2025 +0100
@@ -432,7 +432,7 @@
         std::set<DicomTransferSyntax> allowedSyntaxes;
         allowedSyntaxes.insert(GetTransferSyntax(call.GetArgument(GET_TRANSCODE, "")));
 
-        if (context.Transcode(targetImage, sourceImage, allowedSyntaxes, true, lossyQuality))
+        if (context.Transcode(targetImage, sourceImage, allowedSyntaxes, TranscodingSopInstanceUidMode_AllowNew, lossyQuality))
         {
           call.GetOutput().SetContentFilename(filename.c_str());
           call.GetOutput().AnswerBuffer(targetImage.GetBufferData(), targetImage.GetBufferSize(), MimeType_Dicom);
--- a/OrthancServer/Sources/ServerContext.cpp	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancServer/Sources/ServerContext.cpp	Tue Nov 25 08:08:08 2025 +0100
@@ -1018,7 +1018,7 @@
         
         IDicomTranscoder::DicomImage transcoded;
         
-        if (Transcode(transcoded, source, syntaxes, true /* allow new SOP instance UID */))
+        if (Transcode(transcoded, source, syntaxes, TranscodingSopInstanceUidMode_AllowNew /* allow new SOP instance UID */))
         {
           std::unique_ptr<ParsedDicomFile> tmp(transcoded.ReleaseAsParsedDicomFile());
 
@@ -1943,7 +1943,7 @@
       source.SetExternalBuffer(buffer, size);
       allowedSyntaxes.insert(DicomTransferSyntax_LittleEndianExplicit);
 
-      if (Transcode(explicitTemporaryImage, source, allowedSyntaxes, true))
+      if (Transcode(explicitTemporaryImage, source, allowedSyntaxes, TranscodingSopInstanceUidMode_AllowNew))
       {
         std::unique_ptr<ParsedDicomFile> file(explicitTemporaryImage.ReleaseAsParsedDicomFile());
         return file->DecodeFrame(frameIndex);
@@ -2017,7 +2017,7 @@
       std::set<DicomTransferSyntax> syntaxes;
       syntaxes.insert(targetSyntax);
 
-      if (Transcode(targetDicom, sourceDicom, syntaxes, true))
+      if (Transcode(targetDicom, sourceDicom, syntaxes, TranscodingSopInstanceUidMode_AllowNew))
       {
         cacheAccessor.AddTranscodedInstance(attachmentId, targetSyntax, reinterpret_cast<const char*>(targetDicom.GetBufferData()), targetDicom.GetBufferSize());
         target = std::string(reinterpret_cast<const char*>(targetDicom.GetBufferData()), targetDicom.GetBufferSize());
@@ -2033,7 +2033,7 @@
   bool ServerContext::Transcode(DicomImage& target,
                                 DicomImage& source /* in, "GetParsed()" possibly modified */,
                                 const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                                bool allowNewSopInstanceUid)
+                                TranscodingSopInstanceUidMode mode)
   {
     unsigned int lossyQuality;
 
@@ -2042,19 +2042,19 @@
       lossyQuality = lock.GetConfiguration().GetDicomLossyTranscodingQuality();
     }
 
-    return Transcode(target, source, allowedSyntaxes, allowNewSopInstanceUid, lossyQuality);
+    return Transcode(target, source, allowedSyntaxes, mode, lossyQuality);
   }
 
 
   bool ServerContext::Transcode(DicomImage& target,
                                 DicomImage& source /* in, "GetParsed()" possibly modified */,
                                 const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                                bool allowNewSopInstanceUid,
+                                TranscodingSopInstanceUidMode mode,
                                 unsigned int lossyQuality)
   {
     if (builtinDecoderTranscoderOrder_ == BuiltinDecoderTranscoderOrder_Before)
     {
-      if (dcmtkTranscoder_->Transcode(target, source, allowedSyntaxes, allowNewSopInstanceUid, lossyQuality))
+      if (dcmtkTranscoder_->Transcode(target, source, allowedSyntaxes, mode, lossyQuality))
       {
         return true;
       }
@@ -2064,7 +2064,7 @@
     if (HasPlugins() &&
         GetPlugins().HasCustomTranscoder())
     {
-      if (GetPlugins().Transcode(target, source, allowedSyntaxes, allowNewSopInstanceUid))  // TODO: pass lossyQuality to plugins -> needs a new plugin interface
+      if (GetPlugins().Transcode(target, source, allowedSyntaxes, mode))  // TODO: pass lossyQuality to plugins -> needs a new plugin interface
       {
         return true;
       }
@@ -2078,7 +2078,7 @@
 
     if (builtinDecoderTranscoderOrder_ == BuiltinDecoderTranscoderOrder_After)
     {
-      return dcmtkTranscoder_->Transcode(target, source, allowedSyntaxes, allowNewSopInstanceUid, lossyQuality);
+      return dcmtkTranscoder_->Transcode(target, source, allowedSyntaxes, mode, lossyQuality);
     }
     else
     {
@@ -2109,7 +2109,7 @@
 
       std::set<DicomTransferSyntax> uncompressedTransferSyntax;
       uncompressedTransferSyntax.insert(DicomTransferSyntax_LittleEndianExplicit);
-      Transcode(transcoded, source, uncompressedTransferSyntax, true);
+      Transcode(transcoded, source, uncompressedTransferSyntax, TranscodingSopInstanceUidMode_AllowNew);
 
       dicomFile.reset(transcoded.ReleaseAsParsedDicomFile());
 
@@ -2154,24 +2154,19 @@
       std::set<DicomTransferSyntax> s;
       s.insert(targetSyntax);
 
-      if (Transcode(transcoded, source, s, true, lossyQuality))
-      {      
-        dicomFile.reset(transcoded.ReleaseAsParsedDicomFile());
+      TranscodingSopInstanceUidMode mode;
+      if (keepSOPInstanceUidDuringLossyTranscoding)
+      {
+        mode = TranscodingSopInstanceUidMode_Preserve;
+      }
+      else
+      {
+        mode = TranscodingSopInstanceUidMode_AllowNew;
+      }
 
-        if (keepSOPInstanceUidDuringLossyTranscoding)
-        {
-          // Fix the SOP instance UID in order the preserve the
-          // references between instance UIDs in the DICOM hierarchy
-          // (the UID might have changed during this last transcoding step in the case of lossy transcoding)
-          if (dicomFile.get() == NULL ||
-              dicomFile->GetDcmtkObject().getDataset() == NULL ||
-              !dicomFile->GetDcmtkObject().getDataset()->putAndInsertString(
-                DCM_SOPInstanceUID, modifiedUid.c_str(), OFTrue /* replace */).good())
-          {
-            throw OrthancException(ErrorCode_InternalError);
-          }
-        }
-        return;
+      if (Transcode(transcoded, source, s, mode, lossyQuality))
+      {
+        dicomFile.reset(transcoded.ReleaseAsParsedDicomFile());
       }
       else
       {
--- a/OrthancServer/Sources/ServerContext.h	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancServer/Sources/ServerContext.h	Tue Nov 25 08:08:08 2025 +0100
@@ -590,12 +590,12 @@
     virtual bool Transcode(DicomImage& target,
                            DicomImage& source /* in, "GetParsed()" possibly modified */,
                            const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                           bool allowNewSopInstanceUid) ORTHANC_OVERRIDE;
-    
+                           TranscodingSopInstanceUidMode mode) ORTHANC_OVERRIDE;
+
     virtual bool Transcode(DicomImage& target,
                            DicomImage& source /* in, "GetParsed()" possibly modified */,
                            const std::set<DicomTransferSyntax>& allowedSyntaxes,
-                           bool allowNewSopInstanceUid,
+                           TranscodingSopInstanceUidMode mode,
                            unsigned int lossyQuality) ORTHANC_OVERRIDE;
 
     virtual bool TranscodeWithCache(std::string& target,
--- a/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp	Tue Nov 25 08:08:08 2025 +0100
@@ -116,7 +116,7 @@
         IDicomTranscoder::DicomImage source, transcoded;
         source.SetExternalBuffer(sourceBuffer);
 
-        if (context_.Transcode(transcoded, source, syntaxes, true /* allow new SOP instance UID */, lossyQuality_))
+        if (context_.Transcode(transcoded, source, syntaxes, TranscodingSopInstanceUidMode_AllowNew, lossyQuality_))
         {
           transcodedBuffer.assign(reinterpret_cast<const char*>(transcoded.GetBufferData()), transcoded.GetBufferSize());
           return true;
--- a/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.cpp	Sat Nov 22 12:29:36 2025 +0100
+++ b/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.cpp	Tue Nov 25 08:08:08 2025 +0100
@@ -69,7 +69,7 @@
         IDicomTranscoder::DicomImage source, transcoded;
         source.SetExternalBuffer(dicom);
 
-        if (context_.Transcode(transcoded, source, syntaxes, true))
+        if (context_.Transcode(transcoded, source, syntaxes, TranscodingSopInstanceUidMode_AllowNew))
         {
           body.assign(reinterpret_cast<const char*>(transcoded.GetBufferData()),
                       transcoded.GetBufferSize());