diff OrthancServer/ParsedDicomFile.cpp @ 1555:d6a93e12b1c1

Creation of DICOM files with encapsulated PDF
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 20 Aug 2015 15:18:13 +0200
parents c388502a066d
children b8dc2f855a83
line wrap: on
line diff
--- a/OrthancServer/ParsedDicomFile.cpp	Thu Aug 20 11:56:42 2015 +0200
+++ b/OrthancServer/ParsedDicomFile.cpp	Thu Aug 20 15:18:13 2015 +0200
@@ -107,6 +107,7 @@
 #include <dcmtk/dcmdata/dcistrmb.h>
 #include <dcmtk/dcmdata/dcuid.h>
 #include <dcmtk/dcmdata/dcmetinf.h>
+#include <dcmtk/dcmdata/dcdeftag.h>
 
 #include <dcmtk/dcmdata/dcvrae.h>
 #include <dcmtk/dcmdata/dcvras.h>
@@ -1133,16 +1134,23 @@
 
   void ParsedDicomFile::EmbedImage(const std::string& dataUriScheme)
   {
-    std::string mime, content;
-    Toolbox::DecodeDataUriScheme(mime, content, dataUriScheme);
+    std::string mime, base64;
+    Toolbox::DecodeDataUriScheme(mime, base64, dataUriScheme);
+
+    std::string content;
+    Toolbox::DecodeBase64(content, base64);
 
-    std::string decoded;
-    Toolbox::DecodeBase64(decoded, content);
+    EmbedImage(mime, content);
+  }
+
 
+  void ParsedDicomFile::EmbedImage(const std::string& mime,
+                                   const std::string& content)
+  {
     if (mime == "image/png")
     {
       PngReader reader;
-      reader.ReadFromMemory(decoded);
+      reader.ReadFromMemory(content);
       EmbedImage(reader);
     }
     else
@@ -1408,4 +1416,59 @@
       FromDcmtkBridge::ToJson(target, *pimpl_->file_->getDataset());
     }
   }
+
+
+  bool ParsedDicomFile::HasTag(const DicomTag& tag) const
+  {
+    DcmTag key(tag.GetGroup(), tag.GetElement());
+    return pimpl_->file_->getDataset()->tagExists(key);
+  }
+
+
+  void ParsedDicomFile::EmbedPdf(const std::string& pdf)
+  {
+    if (pdf.size() < 5 ||  // (*)
+        strncmp("%PDF-", pdf.c_str(), 5) != 0)
+    {
+      LOG(ERROR) << "Not a PDF file";
+      throw OrthancException(ErrorCode_BadFileFormat);
+    }
+
+    Replace(DICOM_TAG_SOP_CLASS_UID, UID_EncapsulatedPDFStorage);
+    Replace(FromDcmtkBridge::Convert(DCM_Modality), "OT");
+    Replace(FromDcmtkBridge::Convert(DCM_ConversionType), "WSD");
+    Replace(FromDcmtkBridge::Convert(DCM_MIMETypeOfEncapsulatedDocument), "application/pdf");
+    Replace(FromDcmtkBridge::Convert(DCM_SeriesNumber), "1");
+
+    std::auto_ptr<DcmPolymorphOBOW> element(new DcmPolymorphOBOW(DCM_EncapsulatedDocument));
+
+    size_t s = pdf.size();
+    if (s & 1)
+    {
+      // The size of the buffer must be even
+      s += 1;
+    }
+
+    Uint8* bytes = NULL;
+    OFCondition result = element->createUint8Array(s, bytes);
+    if (!result.good() || bytes == NULL)
+    {
+      throw OrthancException(ErrorCode_NotEnoughMemory);
+    }
+
+    // Blank pad byte (no access violation, as "pdf.size() >= 5" because of (*) )
+    bytes[s - 1] = 0;
+
+    memcpy(bytes, pdf.c_str(), pdf.size());
+      
+    DcmPolymorphOBOW* obj = element.release();
+    result = pimpl_->file_->getDataset()->insert(obj);
+
+    if (!result.good())
+    {
+      delete obj;
+      throw OrthancException(ErrorCode_NotEnoughMemory);
+    }
+  }
+
 }