]> Creatis software - gdcm.git/blobdiff - src/gdcmFileHelper.cxx
ENH: hopefully fixed swig wrapping
[gdcm.git] / src / gdcmFileHelper.cxx
index 65edc40b1c6461ae3dc688fdfe150c94294723db..687d43ca6c37989e136b74e5a92cf6f170336436 100644 (file)
@@ -4,8 +4,8 @@
   Module:    $RCSfile: gdcmFileHelper.cxx,v $
   Language:  C++
 
   Module:    $RCSfile: gdcmFileHelper.cxx,v $
   Language:  C++
 
-  Date:      $Date: 2006/02/16 21:27:41 $
-  Version:   $Revision: 1.94 $
+  Date:      $Date: 2006/05/02 13:11:57 $
+  Version:   $Revision: 1.103 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
 #include "gdcmSeqEntry.h"
 #include "gdcmSQItem.h"
 #include "gdcmDataEntry.h"
 #include "gdcmSeqEntry.h"
 #include "gdcmSQItem.h"
 #include "gdcmDataEntry.h"
+#include "gdcmDocEntry.h"
 #include "gdcmFile.h"
 #include "gdcmPixelReadConvert.h"
 #include "gdcmPixelWriteConvert.h"
 #include "gdcmDocEntryArchive.h"
 #include "gdcmDictSet.h"
 #include "gdcmOrientation.h"
 #include "gdcmFile.h"
 #include "gdcmPixelReadConvert.h"
 #include "gdcmPixelWriteConvert.h"
 #include "gdcmDocEntryArchive.h"
 #include "gdcmDictSet.h"
 #include "gdcmOrientation.h"
-
 #if defined(__BORLANDC__)
    #include <mem.h> // for memset
 #endif 
 #if defined(__BORLANDC__)
    #include <mem.h> // for memset
 #endif 
@@ -73,7 +74,7 @@ fh->SetImageData( userPixels, userPixelsLength);
 fh->SetTypeToRaw(); // Even if it was possible to convert Palette to RGB
                      // (WriteMode is set)
  
 fh->SetTypeToRaw(); // Even if it was possible to convert Palette to RGB
                      // (WriteMode is set)
  
-fh->SetWriteTypeToDcmExpl(); // he wants Explicit Value Representation
+fh->SetWriteTypeToDcmExpl();  // he wants Explicit Value Representation
                               // Little Endian is the default
                               // no other value is allowed
                                 (-->SetWriteType(ExplicitVR);)
                               // Little Endian is the default
                               // no other value is allowed
                                 (-->SetWriteType(ExplicitVR);)
@@ -268,9 +269,10 @@ bool FileHelper::SetEntryBinArea(uint8_t *content, int lgth,
  *          failed).
  */ 
 DataEntry *FileHelper::InsertEntryString(std::string const &content,
  *          failed).
  */ 
 DataEntry *FileHelper::InsertEntryString(std::string const &content,
-                                                uint16_t group, uint16_t elem)
+                                         uint16_t group, uint16_t elem,
+                                         VRKey const &vr )
 {
 {
-   return FileInternal->InsertEntryString(content, group, elem);
+   return FileInternal->InsertEntryString(content, group, elem, vr);
 }
 
 /**
 }
 
 /**
@@ -285,9 +287,10 @@ DataEntry *FileHelper::InsertEntryString(std::string const &content,
  *          failed).
  */
 DataEntry *FileHelper::InsertEntryBinArea(uint8_t *binArea, int lgth,
  *          failed).
  */
 DataEntry *FileHelper::InsertEntryBinArea(uint8_t *binArea, int lgth,
-                                          uint16_t group, uint16_t elem)
+                                          uint16_t group, uint16_t elem,
+                                          VRKey const &vr )
 {
 {
-   return FileInternal->InsertEntryBinArea(binArea, lgth, group, elem);
+   return FileInternal->InsertEntryBinArea(binArea, lgth, group, elem, vr);
 }
 
 /**
 }
 
 /**
@@ -660,15 +663,50 @@ bool FileHelper::WriteAcr (std::string const &fileName)
  */
 bool FileHelper::Write(std::string const &fileName)
 {
  */
 bool FileHelper::Write(std::string const &fileName)
 {
+
+   CheckMandatoryElements(); //called once, here !
+   
+   bool flag = false;
+   DocEntry *e;   
    switch(WriteType)
    {
       case ImplicitVR:
          SetWriteFileTypeToImplicitVR();
          break;
    switch(WriteType)
    {
       case ImplicitVR:
          SetWriteFileTypeToImplicitVR();
          break;
       case Unknown:  // should never happen; ExplicitVR is the default value
       case ExplicitVR:
       case Unknown:  // should never happen; ExplicitVR is the default value
       case ExplicitVR:
-         SetWriteFileTypeToExplicitVR();
+
+   // User should ask gdcm to write an image in Explicit VR mode
+   // only when he is sure *all* the VR of *all* the DataElements is known.
+   // i.e : when there are *only* Public Groups
+   // or *all* the Shadow Groups are fully described in the relevant Shadow
+   // Dictionnary
+   // Let's just *dream* about it; *never* trust a user !
+   // We turn to Implicit VR if at least the VR of one element is unknown.
+   
+         e = FileInternal->GetFirstEntry();
+         while (e != 0)
+         {
+            if (e->GetVR() == "  ")  
+            {
+               SetWriteTypeToDcmImplVR();
+               SetWriteFileTypeToImplicitVR();
+               flag = true;
+               break;         
+            } 
+            e = FileInternal->GetNextEntry();
+         }        
+
+         if (!flag)
+         {
+            SetWriteFileTypeToExplicitVR();
+         }
          break;
          break;
+
+  SetWriteFileTypeToExplicitVR(); // to see JPRx
+  break;
       case ACR:
       case ACR_LIBIDO:
       // NOTHING is done here just for LibIDO.
       case ACR:
       case ACR_LIBIDO:
       // NOTHING is done here just for LibIDO.
@@ -678,16 +716,18 @@ bool FileHelper::Write(std::string const &fileName)
       // (shame on him !)
       // We add Recognition Code (RET)
         if ( ! FileInternal->GetDataEntry(0x0008, 0x0010) )
       // (shame on him !)
       // We add Recognition Code (RET)
         if ( ! FileInternal->GetDataEntry(0x0008, 0x0010) )
-            FileInternal->InsertEntryString("ACR-NEMA V1.0 ", 0x0008, 0x0010);
+            FileInternal->InsertEntryString("ACR-NEMA V1.0 ", 
+                                             0x0008, 0x0010, "LO");
          SetWriteFileTypeToACR();
         // SetWriteFileTypeToImplicitVR(); // ACR IS implicit VR !
          break;
          SetWriteFileTypeToACR();
         // SetWriteFileTypeToImplicitVR(); // ACR IS implicit VR !
          break;
+      /// \todo FIXME : JPEG may be either ExplicitVR or ImplicitVR
       case JPEG:
          SetWriteFileTypeToJPEG();
          break;
    }
       case JPEG:
          SetWriteFileTypeToJPEG();
          break;
    }
-   CheckMandatoryElements();
-
    // --------------------------------------------------------------
    // Special Patch to allow gdcm to re-write ACR-LibIDO formated images
    //
    // --------------------------------------------------------------
    // Special Patch to allow gdcm to re-write ACR-LibIDO formated images
    //
@@ -724,9 +764,10 @@ bool FileHelper::Write(std::string const &fileName)
       check = FileInternal->Write(fileName,WriteType);
    }
 
       check = FileInternal->Write(fileName,WriteType);
    }
 
-   RestoreWrite();
-   RestoreWriteFileType();
-   RestoreWriteMandatory();
+   RestoreWrite(); 
+  // RestoreWriteFileType();
+  // RestoreWriteMandatory();
+   
 
    // --------------------------------------------------------------
    // Special Patch to allow gdcm to re-write ACR-LibIDO formated images
 
    // --------------------------------------------------------------
    // Special Patch to allow gdcm to re-write ACR-LibIDO formated images
@@ -765,6 +806,7 @@ bool FileHelper::CheckWriteIntegrity()
       size_t decSize = FileInternal->GetXSize()
                      * FileInternal->GetYSize() 
                      * FileInternal->GetZSize()
       size_t decSize = FileInternal->GetXSize()
                      * FileInternal->GetYSize() 
                      * FileInternal->GetZSize()
+                     * FileInternal->GetTSize()     
                      * FileInternal->GetSamplesPerPixel()
                      * ( numberBitsAllocated / 8 );
       size_t rgbSize = decSize;
                      * FileInternal->GetSamplesPerPixel()
                      * ( numberBitsAllocated / 8 );
       size_t rgbSize = decSize;
@@ -811,7 +853,7 @@ void FileHelper::SetWriteToRaw()
    } 
    else
    {
    } 
    else
    {
-      DataEntry *photInt = CopyDataEntry(0x0028,0x0004);
+      DataEntry *photInt = CopyDataEntry(0x0028,0x0004,"CS");
       if (FileInternal->HasLUT() )
       {
          photInt->SetString("PALETTE COLOR ");
       if (FileInternal->HasLUT() )
       {
          photInt->SetString("PALETTE COLOR ");
@@ -856,13 +898,13 @@ void FileHelper::SetWriteToRGB()
    {
       PixelReadConverter->BuildRGBImage();
       
    {
       PixelReadConverter->BuildRGBImage();
       
-      DataEntry *spp = CopyDataEntry(0x0028,0x0002);
+      DataEntry *spp = CopyDataEntry(0x0028,0x0002,"US");
       spp->SetString("3 ");
 
       spp->SetString("3 ");
 
-      DataEntry *planConfig = CopyDataEntry(0x0028,0x0006);
+      DataEntry *planConfig = CopyDataEntry(0x0028,0x0006,"US");
       planConfig->SetString("0 ");
 
       planConfig->SetString("0 ");
 
-      DataEntry *photInt = CopyDataEntry(0x0028,0x0004);
+      DataEntry *photInt = CopyDataEntry(0x0028,0x0004,"CS");
       photInt->SetString("RGB ");
 
       if ( PixelReadConverter->GetRGB() )
       photInt->SetString("RGB ");
 
       if ( PixelReadConverter->GetRGB() )
@@ -913,13 +955,13 @@ void FileHelper::SetWriteToRGB()
       // samples per pixels = 1 (in the read file)
       if ( FileInternal->GetBitsAllocated()==24 ) 
       {
       // samples per pixels = 1 (in the read file)
       if ( FileInternal->GetBitsAllocated()==24 ) 
       {
-         DataEntry *bitsAlloc = CopyDataEntry(0x0028,0x0100);
+         DataEntry *bitsAlloc = CopyDataEntry(0x0028,0x0100,"US");
          bitsAlloc->SetString("8 ");
 
          bitsAlloc->SetString("8 ");
 
-         DataEntry *bitsStored = CopyDataEntry(0x0028,0x0101);
+         DataEntry *bitsStored = CopyDataEntry(0x0028,0x0101,"US");
          bitsStored->SetString("8 ");
 
          bitsStored->SetString("8 ");
 
-         DataEntry *highBit = CopyDataEntry(0x0028,0x0102);
+         DataEntry *highBit = CopyDataEntry(0x0028,0x0102,"US");
          highBit->SetString("7 ");
 
          Archive->Push(bitsAlloc);
          highBit->SetString("7 ");
 
          Archive->Push(bitsAlloc);
@@ -942,8 +984,10 @@ void FileHelper::SetWriteToRGB()
  */ 
 void FileHelper::RestoreWrite()
 {
  */ 
 void FileHelper::RestoreWrite()
 {
+
    Archive->Restore(0x0028,0x0002);
    Archive->Restore(0x0028,0x0004);
    Archive->Restore(0x0028,0x0002);
    Archive->Restore(0x0028,0x0004);
+   
    Archive->Restore(0x0028,0x0006);
    Archive->Restore(GetFile()->GetGrPixel(),GetFile()->GetNumPixel());
 
    Archive->Restore(0x0028,0x0006);
    Archive->Restore(GetFile()->GetGrPixel(),GetFile()->GetNumPixel());
 
@@ -963,7 +1007,6 @@ void FileHelper::RestoreWrite()
    // For the Palette Color Lookup Table UID
    Archive->Restore(0x0028,0x1203); 
 
    // For the Palette Color Lookup Table UID
    Archive->Restore(0x0028,0x1203); 
 
-
    // group 0002 may be pushed out for ACR-NEMA writting purposes 
    Archive->Restore(0x0002,0x0000);
    Archive->Restore(0x0002,0x0001);
    // group 0002 may be pushed out for ACR-NEMA writting purposes 
    Archive->Restore(0x0002,0x0000);
    Archive->Restore(0x0002,0x0001);
@@ -975,6 +1018,7 @@ void FileHelper::RestoreWrite()
    Archive->Restore(0x0002,0x0016);
    Archive->Restore(0x0002,0x0100);
    Archive->Restore(0x0002,0x0102);
    Archive->Restore(0x0002,0x0016);
    Archive->Restore(0x0002,0x0100);
    Archive->Restore(0x0002,0x0102);
+
 }
 
 /**
 }
 
 /**
@@ -1006,7 +1050,7 @@ void FileHelper::SetWriteFileTypeToJPEG()
    std::string ts = Util::DicomString( 
       Global::GetTS()->GetSpecialTransferSyntax(TS::JPEGBaselineProcess1) );
 
    std::string ts = Util::DicomString( 
       Global::GetTS()->GetSpecialTransferSyntax(TS::JPEGBaselineProcess1) );
 
-   DataEntry *tss = CopyDataEntry(0x0002,0x0010);
+   DataEntry *tss = CopyDataEntry(0x0002,0x0010,"UI");
    tss->SetString(ts);
 
    Archive->Push(tss);
    tss->SetString(ts);
 
    Archive->Push(tss);
@@ -1021,9 +1065,8 @@ void FileHelper::SetWriteFileTypeToExplicitVR()
    std::string ts = Util::DicomString( 
       Global::GetTS()->GetSpecialTransferSyntax(TS::ExplicitVRLittleEndian) );
 
    std::string ts = Util::DicomString( 
       Global::GetTS()->GetSpecialTransferSyntax(TS::ExplicitVRLittleEndian) );
 
-   DataEntry *tss = CopyDataEntry(0x0002,0x0010);
+   DataEntry *tss = CopyDataEntry(0x0002,0x0010,"UI");
    tss->SetString(ts);
    tss->SetString(ts);
-
    Archive->Push(tss);
    tss->Delete();
 }
    Archive->Push(tss);
    tss->Delete();
 }
@@ -1036,9 +1079,8 @@ void FileHelper::SetWriteFileTypeToImplicitVR()
    std::string ts = Util::DicomString(
       Global::GetTS()->GetSpecialTransferSyntax(TS::ImplicitVRLittleEndian) );
 
    std::string ts = Util::DicomString(
       Global::GetTS()->GetSpecialTransferSyntax(TS::ImplicitVRLittleEndian) );
 
-   DataEntry *tss = CopyDataEntry(0x0002,0x0010);
+   DataEntry *tss = CopyDataEntry(0x0002,0x0010,"UI");
    tss->SetString(ts);
    tss->SetString(ts);
-
    Archive->Push(tss);
    tss->Delete();
 }
    Archive->Push(tss);
    tss->Delete();
 }
@@ -1063,9 +1105,12 @@ void FileHelper::SetWriteToLibido()
    {
       std::string rows, columns; 
 
    {
       std::string rows, columns; 
 
-      DataEntry *newRow=DataEntry::New(oldRow->GetDictEntry());
-      DataEntry *newCol=DataEntry::New(oldCol->GetDictEntry());
-
+      //DataEntry *newRow=DataEntry::New(oldRow->GetDictEntry());
+      //DataEntry *newCol=DataEntry::New(oldCol->GetDictEntry());
+      
+      DataEntry *newRow=DataEntry::New(0x0028, 0x0010, "US");
+      DataEntry *newCol=DataEntry::New(0x0028, 0x0011, "US");
+      
       newRow->Copy(oldCol);
       newCol->Copy(oldRow);
 
       newRow->Copy(oldCol);
       newCol->Copy(oldRow);
 
@@ -1079,7 +1124,7 @@ void FileHelper::SetWriteToLibido()
       newCol->Delete();
    }
 
       newCol->Delete();
    }
 
-   DataEntry *libidoCode = CopyDataEntry(0x0008,0x0010);
+   DataEntry *libidoCode = CopyDataEntry(0x0008,0x0010,"LO");
    libidoCode->SetString("ACRNEMA_LIBIDO_1.1");
    Archive->Push(libidoCode);
    libidoCode->Delete();
    libidoCode->SetString("ACRNEMA_LIBIDO_1.1");
    Archive->Push(libidoCode);
    libidoCode->Delete();
@@ -1095,7 +1140,7 @@ void FileHelper::SetWriteToNoLibido()
    {
       if ( recCode->GetString() == "ACRNEMA_LIBIDO_1.1" )
       {
    {
       if ( recCode->GetString() == "ACRNEMA_LIBIDO_1.1" )
       {
-         DataEntry *libidoCode = CopyDataEntry(0x0008,0x0010);
+         DataEntry *libidoCode = CopyDataEntry(0x0008,0x0010,"LO");
          libidoCode->SetString("");
          Archive->Push(libidoCode);
          libidoCode->Delete();
          libidoCode->SetString("");
          Archive->Push(libidoCode);
          libidoCode->Delete();
@@ -1124,11 +1169,10 @@ void FileHelper::RestoreWriteOfLibido()
  * @param   group   Group number of the Entry 
  * @param   elem  Element number of the Entry
  * @param   vr  Value Representation of the Entry
  * @param   group   Group number of the Entry 
  * @param   elem  Element number of the Entry
  * @param   vr  Value Representation of the Entry
- *          FIXME : what is it used for?
  * \return  pointer to the new Bin Entry (NULL when creation failed).
  */ 
 DataEntry *FileHelper::CopyDataEntry(uint16_t group, uint16_t elem,
  * \return  pointer to the new Bin Entry (NULL when creation failed).
  */ 
 DataEntry *FileHelper::CopyDataEntry(uint16_t group, uint16_t elem,
-                                   const TagName &vr)
+                                   const VRKey &vr)
 {
    DocEntry *oldE = FileInternal->GetDocEntry(group, elem);
    DataEntry *newE;
 {
    DocEntry *oldE = FileInternal->GetDocEntry(group, elem);
    DataEntry *newE;
@@ -1139,7 +1183,8 @@ DataEntry *FileHelper::CopyDataEntry(uint16_t group, uint16_t elem,
 
    if ( oldE )
    {
 
    if ( oldE )
    {
-      newE = DataEntry::New(oldE->GetDictEntry());
+      //newE = DataEntry::New(oldE->GetDictEntry());
+      newE = DataEntry::New(group, elem, vr);
       newE->Copy(oldE);
    }
    else
       newE->Copy(oldE);
    }
    else
@@ -1190,11 +1235,16 @@ DataEntry *FileHelper::CopyDataEntry(uint16_t group, uint16_t elem,
 To be moved to User's guide / WIKI  ?
 
 We have to deal with 4 *very* different cases :
 To be moved to User's guide / WIKI  ?
 
 We have to deal with 4 *very* different cases :
--1) user created ex nihilo his own image  and wants to write it as a Dicom image.
+-1) user created ex nihilo his own image and wants to write it as a Dicom image.
+    USER_OWN_IMAGE
 -2) user modified the pixels of an existing image.
 -2) user modified the pixels of an existing image.
--3) user created a new image, using existing images (eg MIP, MPR, cartography image)
--4) user anonymized an image without processing the pixels.
-
+   FILTERED_IMAGE
+-3) user created a new image, using a set of existing images (eg MIP, MPR, cartography image)
+   CREATED_IMAGE
+-4) user modified/added some tags *without processing* the pixels (anonymization..
+   UNMODIFIED_PIXELS_IMAGE
+-Probabely some more to be added  
 gdcm::FileHelper::CheckMandatoryElements() deals automatically with these cases.
 
 1)2)3)4)
 gdcm::FileHelper::CheckMandatoryElements() deals automatically with these cases.
 
 1)2)3)4)
@@ -1211,17 +1261,15 @@ them.
      keeping the same 'Serie Instance UID' / 'Study Instance UID' for various images
  Warning :     
  The user shouldn't add any image to a 'Manufacturer Serie'
      keeping the same 'Serie Instance UID' / 'Study Instance UID' for various images
  Warning :     
  The user shouldn't add any image to a 'Manufacturer Serie'
-     but there is no way no to allowed him to do that
+     but there is no way no to allow him to do that
      
  None of the 'shadow elements' are droped out.
      
 
 1)
      
  None of the 'shadow elements' are droped out.
      
 
 1)
-'Modality' (0x0008,0x0060)       is defaulted to "OT" (other) if missing.
 'Conversion Type (0x0008,0x0064) is forced to 'SYN' (Synthetic Image).
 'Conversion Type (0x0008,0x0064) is forced to 'SYN' (Synthetic Image).
-'Study Date', 'Study Time' are defaulted to current Date and Time.
  
  
-1)2)3)
+1)3)
 'Media Storage SOP Class UID' (0x0002,0x0002)
 'SOP Class UID'               (0x0008,0x0016) are set to 
                                                [Secondary Capture Image Storage]
 'Media Storage SOP Class UID' (0x0002,0x0002)
 'SOP Class UID'               (0x0008,0x0016) are set to 
                                                [Secondary Capture Image Storage]
@@ -1244,14 +1292,11 @@ If 'SOP Class UID' exists in the native image  ('true DICOM' image)
           0008 1115 SQ 1 Referenced Series Sequence
           0008 1140 SQ 1 Referenced Image Sequence
        
           0008 1115 SQ 1 Referenced Series Sequence
           0008 1140 SQ 1 Referenced Image Sequence
        
-4) When user *knows* he didn't modified the pixels, he may ask the writer to keep some
-informations unchanged :
+4) When user *knows* he didn't modified the pixels, we keep some informations unchanged :
 'Media Storage SOP Class UID' (0x0002,0x0002)
 'SOP Class UID'               (0x0008,0x0016)
 'Image Type'                  (0x0008,0x0008)
 'Conversion Type'             (0x0008,0x0064)
 'Media Storage SOP Class UID' (0x0002,0x0002)
 'SOP Class UID'               (0x0008,0x0016)
 'Image Type'                  (0x0008,0x0008)
 'Conversion Type'             (0x0008,0x0064)
-He has to use gdcm::FileHelper::SetKeepMediaStorageSOPClassUID(true)
-(probabely name has to be changed)
 
 
 Bellow follows the full description (hope so !) of the consistency checks performed 
 
 
 Bellow follows the full description (hope so !) of the consistency checks performed 
@@ -1259,23 +1304,16 @@ by gdcm::FileHelper::CheckMandatoryElements()
 
 
 -->'Media Storage SOP Class UID' (0x0002,0x0002)
 
 
 -->'Media Storage SOP Class UID' (0x0002,0x0002)
--->'SOP Class UID'               (0x0008,0x0016) are set to 
+-->'SOP Class UID'               (0x0008,0x0016) are defaulted to 
                                                [Secondary Capture Image Storage]
                                                [Secondary Capture Image Storage]
-   (Potentialy, the image was modified by user, and post-processed; 
-    it's no longer a 'native' image)
-  Except if user told he wants to keep MediaStorageSOPClassUID,
-  when *he* knows he didn't modify the image (e.g. : he just anonymized the file)
-
 --> 'Image Type'  (0x0008,0x0008)
      is forced to  "DERIVED\PRIMARY"
      (The written image is no longer an 'ORIGINAL' one)
 --> 'Image Type'  (0x0008,0x0008)
      is forced to  "DERIVED\PRIMARY"
      (The written image is no longer an 'ORIGINAL' one)
-  Except if user told he wants to keep MediaStorageSOPClassUID,
-  when *he* knows he didn't modify the image (e.g. : he just anonymized the file)
+  Except if user knows he didn't modify the image (e.g. : he just anonymized the file)
    
  -->  Conversion Type (0x0008,0x0064)
    
  -->  Conversion Type (0x0008,0x0064)
-     is forced to 'SYN' (Synthetic Image)
-  Except if user told he wants to keep MediaStorageSOPClassUID,
-  when *he* knows he didn't modify the image (e.g. : he just anonymized the file)
+     is defaulted to 'SYN' (Synthetic Image)
+  when *he* knows he created his own image ex nihilo
             
 --> 'Modality' (0x0008,0x0060)   
     is defaulted to "OT" (other) if missing.   
             
 --> 'Modality' (0x0008,0x0060)   
     is defaulted to "OT" (other) if missing.   
@@ -1326,7 +1364,7 @@ by gdcm::FileHelper::CheckMandatoryElements()
     
 --> Patient ID, Patient's Birth Date, Patient's Sex, (Type 2)
 --> Referring Physician's Name  (Type 2)
     
 --> Patient ID, Patient's Birth Date, Patient's Sex, (Type 2)
 --> Referring Physician's Name  (Type 2)
-    are created, with empty value if there are missing.  
+    are created, with empty value if there are missing.
 
  -------------------------------------------------------------------------------------*/
 
 
  -------------------------------------------------------------------------------------*/
 
@@ -1334,6 +1372,7 @@ void FileHelper::CheckMandatoryElements()
 {
    std::string sop =  Util::CreateUniqueUID();
 
 {
    std::string sop =  Util::CreateUniqueUID();
 
+   // --------------------- For Meta Elements ---------------------
    // just to remember : 'official' 0002 group
    if ( WriteType != ACR && WriteType != ACR_LIBIDO )
    {
    // just to remember : 'official' 0002 group
    if ( WriteType != ACR && WriteType != ACR_LIBIDO )
    {
@@ -1353,7 +1392,7 @@ void FileHelper::CheckMandatoryElements()
    // Create them if not found
    // Always modify the value
    // Push the entries to the archive.
    // Create them if not found
    // Always modify the value
    // Push the entries to the archive.
-      CopyMandatoryEntry(0x0002,0x0000,"0");
+      CopyMandatoryEntry(0x0002,0x0000,"0","UL");
 
       DataEntry *e_0002_0001 = CopyDataEntry(0x0002,0x0001, "OB");
       e_0002_0001->SetBinArea((uint8_t*)Util::GetFileMetaInformationVersion(),
 
       DataEntry *e_0002_0001 = CopyDataEntry(0x0002,0x0001, "OB");
       e_0002_0001->SetBinArea((uint8_t*)Util::GetFileMetaInformationVersion(),
@@ -1362,40 +1401,117 @@ void FileHelper::CheckMandatoryElements()
       Archive->Push(e_0002_0001);
       e_0002_0001->Delete(); 
 
       Archive->Push(e_0002_0001);
       e_0002_0001->Delete(); 
 
-      if ( KeepMediaStorageSOPClassUID)      
-   // It up to the use to *know* whether he modified the pixels or not.
-   // he is allowed to keep the original 'Media Storage SOP Class UID'
-         CheckMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7");    
+      if ( ContentType == FILTERED_IMAGE || ContentType == UNMODIFIED_PIXELS_IMAGE)
+      {      
+   // we keep the original 'Media Storage SOP Class UID', we default it if missing
+         CheckMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7","UI"); 
+      }
       else
       else
-   // Potentialy this is a post-processed image 
+      {
+   // It's *not* an image comming straight from a source. We force
    // 'Media Storage SOP Class UID'  --> [Secondary Capture Image Storage]
    // 'Media Storage SOP Class UID'  --> [Secondary Capture Image Storage]
-         CopyMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7");    
-
+         CopyMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7","UI");
+      }
+      
    // 'Media Storage SOP Instance UID'   
    // 'Media Storage SOP Instance UID'   
-      CopyMandatoryEntry(0x0002,0x0003,sop);
+      CopyMandatoryEntry(0x0002,0x0003,sop,"UI");
       
    // 'Implementation Class UID'
    // FIXME : in all examples we have, 0x0002,0x0012 is not so long :
    //         seems to be Root UID + 4 digits (?)
       
    // 'Implementation Class UID'
    // FIXME : in all examples we have, 0x0002,0x0012 is not so long :
    //         seems to be Root UID + 4 digits (?)
-      CopyMandatoryEntry(0x0002,0x0012,Util::CreateUniqueUID());
+      CopyMandatoryEntry(0x0002,0x0012,Util::CreateUniqueUID(),"UI");
 
    // 'Implementation Version Name'
       std::string version = "GDCM ";
       version += Util::GetVersion();
 
    // 'Implementation Version Name'
       std::string version = "GDCM ";
       version += Util::GetVersion();
-      CopyMandatoryEntry(0x0002,0x0013,version);
+      CopyMandatoryEntry(0x0002,0x0013,version,"SH");
    }
 
    }
 
+   // --------------------- For DataSet ---------------------
+
+   if ( ContentType != USER_OWN_IMAGE) // when it's not a user made image
+   { 
+   
+      gdcmDebugMacro( "USER_OWN_IMAGE (1)");
+    // If 'SOP Class UID' exists ('true DICOM' image)
+   // we create the 'Source Image Sequence' SeqEntry
+   // to hold informations about the Source Image
+  
+      DataEntry *e_0008_0016 = FileInternal->GetDataEntry(0x0008, 0x0016);
+      if ( e_0008_0016 )
+      {
+      // Create 'Source Image Sequence' SeqEntry
+//     SeqEntry *sis = SeqEntry::New (
+//            Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x2112) );
+      SeqEntry *sis = SeqEntry::New (0x0008, 0x2112);
+      SQItem *sqi = SQItem::New(1);
+      // (we assume 'SOP Instance UID' exists too) 
+      // create 'Referenced SOP Class UID'
+//     DataEntry *e_0008_1150 = DataEntry::New(
+//            Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x1150) );
+      DataEntry *e_0008_1150 = DataEntry::New(0x0008, 0x1150, "UI");
+      e_0008_1150->SetString( e_0008_0016->GetString());
+      sqi->AddEntry(e_0008_1150);
+      e_0008_1150->Delete();
+      
+      // create 'Referenced SOP Instance UID'
+      DataEntry *e_0008_0018 = FileInternal->GetDataEntry(0x0008, 0x0018);
+//      DataEntry *e_0008_1155 = DataEntry::New(
+//            Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x1155) );
+      DataEntry *e_0008_1155 = DataEntry::New(0x0008, 0x1155, "UI");
+      e_0008_1155->SetString( e_0008_0018->GetString());
+      sqi->AddEntry(e_0008_1155);
+      e_0008_1155->Delete();
+
+      sis->AddSQItem(sqi,1);
+      sqi->Delete();
+
+      // temporarily replaces any previous 'Source Image Sequence' 
+      Archive->Push(sis);
+      sis->Delete();
+      // FIXME : is 'Image Type' *really* depending on the presence of 'SOP Class UID'?
+       if ( ContentType == FILTERED_IMAGE)      
+      // the user *knows* he just modified the pixels
+      // the image is no longer an 'Original' one
+         CopyMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY","CS");    
+      }
+   }
+      
+   if ( ContentType == FILTERED_IMAGE || ContentType == UNMODIFIED_PIXELS_IMAGE)
+   {      
+   // we keep the original 'Media Storage SOP Class UID', we default it if missing (it should be present !)
+         CheckMandatoryEntry(0x0008,0x0016,"1.2.840.10008.5.1.4.1.1.7","UI");      
+   }
+   else
+   {
+   // It's *not* an image comming straight from a source. We force
+   // 'Media Storage SOP Class UID'  --> [Secondary Capture Image Storage]
+         CopyMandatoryEntry(0x0008,0x0016,"1.2.840.10008.5.1.4.1.1.7", "UI");      
+   }
+     
+   Archive->Push(0x0028,0x005); // [Image Dimensions (RET)
    // Push out 'LibIDO-special' entries, if any
    Archive->Push(0x0028,0x0015);
    Archive->Push(0x0028,0x0016);
    Archive->Push(0x0028,0x0017);
    // Push out 'LibIDO-special' entries, if any
    Archive->Push(0x0028,0x0015);
    Archive->Push(0x0028,0x0016);
    Archive->Push(0x0028,0x0017);
-   Archive->Push(0x0028,0x00199);
+   Archive->Push(0x0028,0x0198);  // very old versions
+   Archive->Push(0x0028,0x0199);
+   // Replace deprecated 0028 0012 US Planes   
+   // by new             0028 0008 IS Number of Frames
+   DataEntry *e_0028_0012 = FileInternal->GetDataEntry(0x0028, 0x0012);
+   if ( e_0028_0012 )
+   {
+      CopyMandatoryEntry(0x0028, 0x0008,e_0028_0012->GetString(),"IS");
+      Archive->Push(0x0028,0x0012);      
+   }
 
    // Deal with the pb of (Bits Stored = 12)
    // - we're gonna write the image as Bits Stored = 16
    if ( FileInternal->GetEntryString(0x0028,0x0100) ==  "12")
    {
 
    // Deal with the pb of (Bits Stored = 12)
    // - we're gonna write the image as Bits Stored = 16
    if ( FileInternal->GetEntryString(0x0028,0x0100) ==  "12")
    {
-      CopyMandatoryEntry(0x0028,0x0100,"16");
+      CopyMandatoryEntry(0x0028,0x0100,"16","US");
    }
 
    // Check if user wasn't drunk ;-)
    }
 
    // Check if user wasn't drunk ;-)
@@ -1405,7 +1521,7 @@ void FileHelper::CheckMandatoryElements()
    int nbBitsAllocated = FileInternal->GetBitsAllocated();
    if ( nbBitsAllocated == 0 || nbBitsAllocated > 32)
    {
    int nbBitsAllocated = FileInternal->GetBitsAllocated();
    if ( nbBitsAllocated == 0 || nbBitsAllocated > 32)
    {
-      CopyMandatoryEntry(0x0028,0x0100,"16");
+      CopyMandatoryEntry(0x0028,0x0100,"16","US");
       gdcmWarningMacro("(0028,0100) changed from "
          << nbBitsAllocated << " to 16 for consistency purpose");
       nbBitsAllocated = 16; 
       gdcmWarningMacro("(0028,0100) changed from "
          << nbBitsAllocated << " to 16 for consistency purpose");
       nbBitsAllocated = 16; 
@@ -1416,7 +1532,7 @@ void FileHelper::CheckMandatoryElements()
    {
       s.str("");
       s << nbBitsAllocated;
    {
       s.str("");
       s << nbBitsAllocated;
-      CopyMandatoryEntry(0x0028,0x0101,s.str());
+      CopyMandatoryEntry(0x0028,0x0101,s.str(),"US");
       gdcmWarningMacro("(0028,0101) changed from "
                        << nbBitsStored << " to " << nbBitsAllocated
                        << " for consistency purpose" );
       gdcmWarningMacro("(0028,0101) changed from "
                        << nbBitsStored << " to " << nbBitsAllocated
                        << " for consistency purpose" );
@@ -1430,7 +1546,7 @@ void FileHelper::CheckMandatoryElements()
    {
       s.str("");
       s << nbBitsStored - 1; 
    {
       s.str("");
       s << nbBitsStored - 1; 
-      CopyMandatoryEntry(0x0028,0x0102,s.str());
+      CopyMandatoryEntry(0x0028,0x0102,s.str(),"US");
       gdcmWarningMacro("(0028,0102) changed from "
                        << highBitPosition << " to " << nbBitsAllocated-1
                        << " for consistency purpose");
       gdcmWarningMacro("(0028,0102) changed from "
                        << highBitPosition << " to " << nbBitsAllocated-1
                        << " for consistency purpose");
@@ -1441,95 +1557,29 @@ void FileHelper::CheckMandatoryElements()
    {
       pixelSpacing = "1.0\\1.0";
        // if missing, Pixel Spacing forced to "1.0\1.0"
    {
       pixelSpacing = "1.0\\1.0";
        // if missing, Pixel Spacing forced to "1.0\1.0"
-      CopyMandatoryEntry(0x0028,0x0030,pixelSpacing);
+      CopyMandatoryEntry(0x0028,0x0030,pixelSpacing,"DS");
    }
    
    // 'Imager Pixel Spacing' : defaulted to 'Pixel Spacing'
    // --> This one is the *legal* one !
    }
    
    // 'Imager Pixel Spacing' : defaulted to 'Pixel Spacing'
    // --> This one is the *legal* one !
-   // FIXME : we should write it only when we are *sure* the image comes from
+   if ( ContentType != USER_OWN_IMAGE)
+   //  we write it only when we are *sure* the image comes from
    //         an imager (see also 0008,0x0064)          
    //         an imager (see also 0008,0x0064)          
-   CheckMandatoryEntry(0x0018,0x1164,pixelSpacing);
+      CheckMandatoryEntry(0x0018,0x1164,pixelSpacing,"DS");
    
    // Samples Per Pixel (type 1) : default to grayscale 
    
    // Samples Per Pixel (type 1) : default to grayscale 
-   CheckMandatoryEntry(0x0028,0x0002,"1");
+   CheckMandatoryEntry(0x0028,0x0002,"1","US");
 
    // --- Check UID-related Entries ---
 
    // --- Check UID-related Entries ---
-
-   // If 'SOP Class UID' exists ('true DICOM' image)
-   // we create the 'Source Image Sequence' SeqEntry
-   // to hold informations about the Source Image
-
-   DataEntry *e_0008_0016 = FileInternal->GetDataEntry(0x0008, 0x0016);
-   if ( e_0008_0016 )
-   {
-      // Create 'Source Image Sequence' SeqEntry
-      SeqEntry *sis = SeqEntry::New (
-            Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x2112) );
-      SQItem *sqi = SQItem::New(1);
-      // (we assume 'SOP Instance UID' exists too) 
-      // create 'Referenced SOP Class UID'
-      DataEntry *e_0008_1150 = DataEntry::New(
-            Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x1150) );
-      e_0008_1150->SetString( e_0008_0016->GetString());
-      sqi->AddEntry(e_0008_1150);
-      e_0008_1150->Delete();
-      
-      // create 'Referenced SOP Instance UID'
-      DataEntry *e_0008_0018 = FileInternal->GetDataEntry(0x0008, 0x0018);
-      DataEntry *e_0008_1155 = DataEntry::New(
-            Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x1155) );
-      e_0008_1155->SetString( e_0008_0018->GetString());
-      sqi->AddEntry(e_0008_1155);
-      e_0008_1155->Delete();
-
-      sis->AddSQItem(sqi,1);
-      sqi->Delete();
-
-      // temporarily replaces any previous 'Source Image Sequence' 
-      Archive->Push(sis);
-      sis->Delete();
  
  
-      // FIXME : is 'Image Type' *really* depending on the presence of'SOP Class UID'?
-       if ( KeepMediaStorageSOPClassUID)      
-   // It up to the use to *know* whether he modified the pixels or not.
-   // he is allowed to keep the original 'Media Storage SOP Class UID'
-   // and 'Image Type' as well
-         CheckMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY");    
-      else
-   // Potentialy this is a post-processed image 
-   // (The written image is no longer an 'ORIGINAL' one)
-      CopyMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY");
-
-   }
-
    // At the end, not to overwrite the original ones,
    // needed by 'Referenced SOP Instance UID', 'Referenced SOP Class UID'   
    // 'SOP Instance UID'  
    // At the end, not to overwrite the original ones,
    // needed by 'Referenced SOP Instance UID', 'Referenced SOP Class UID'   
    // 'SOP Instance UID'  
-   CopyMandatoryEntry(0x0008,0x0018,sop);
-   
-   // the gdcm written image is a [Secondary Capture Image Storage]
-   // except if user told us he dind't modify the pixels, and, therefore
-   // he want to keep the 'Media Storage SOP Class UID'
-   
-      // 'Media Storage SOP Class UID' : [Secondary Capture Image Storage]
-   if ( KeepMediaStorageSOPClassUID)
-   {      
-      // It up to the use to *know* whether he modified the pixels or not.
-      // he is allowed to keep the original 'Media Storage SOP Class UID'
-      CheckMandatoryEntry(0x0008,0x0016,"1.2.840.10008.5.1.4.1.1.7");    
-   }
-   else
-   {
-       // Potentialy this is a post-processed image 
-       // 'Media Storage SOP Class UID'  --> [Secondary Capture Image Storage]
-      CopyMandatoryEntry(0x0008,0x0016,"1.2.840.10008.5.1.4.1.1.7");    
-
-       // FIXME : Must we Force Value, or Default value ?
-       // Is it Type 1 for any Modality ?
-       //    --> Answer seems to be NO :-(
-       // FIXME : we should write it only when we are *sure* the image 
-       //         *does not* come from an imager (see also 0018,0x1164)
+   CopyMandatoryEntry(0x0008,0x0018,sop,"UI");
 
 
+   if ( ContentType == USER_OWN_IMAGE)
+   {
+      gdcmDebugMacro( "USER_OWN_IMAGE (2)");   
        // Conversion Type.
        // Other possible values are :
        // See PS 3.3, Page 408
        // Conversion Type.
        // Other possible values are :
        // See PS 3.3, Page 408
@@ -1542,9 +1592,16 @@ void FileHelper::CheckMandatoryElements()
        // SI = Scanned Image
        // DRW = Drawing
        // SYN = Synthetic Image
        // SI = Scanned Image
        // DRW = Drawing
        // SYN = Synthetic Image
-     
-      CheckMandatoryEntry(0x0008,0x0064,"SYN");
-   }   
+           
+      CheckMandatoryEntry(0x0008,0x0064,"SYN","CS"); // Why not?
+   } 
+/*
+   if ( ContentType == CREATED_IMAGE)
+   {
+   /// \todo : find a trick to pass the Media Storage SOP Instance UID of the images used to create the current image
+   
+   }
+*/
            
    // ---- The user will never have to take any action on the following ----
 
            
    // ---- The user will never have to take any action on the following ----
 
@@ -1553,20 +1610,20 @@ void FileHelper::CheckMandatoryElements()
 
    // Instance Creation Date
    const std::string &date = Util::GetCurrentDate();
 
    // Instance Creation Date
    const std::string &date = Util::GetCurrentDate();
-   CopyMandatoryEntry(0x0008,0x0012,date);
+   CopyMandatoryEntry(0x0008,0x0012,date,"DA");
  
    // Instance Creation Time
    const std::string &time = Util::GetCurrentTime();
  
    // Instance Creation Time
    const std::string &time = Util::GetCurrentTime();
-   CopyMandatoryEntry(0x0008,0x0013,time);
+   CopyMandatoryEntry(0x0008,0x0013,time,"TM");
 
    // Study Date
 
    // Study Date
-   CheckMandatoryEntry(0x0008,0x0020,date);
+   CheckMandatoryEntry(0x0008,0x0020,date,"DA");
    // Study Time
    // Study Time
-   CheckMandatoryEntry(0x0008,0x0030,time);
+   CheckMandatoryEntry(0x0008,0x0030,time,"TM");
 
    // Accession Number
    //CopyMandatoryEntry(0x0008,0x0050,"");
 
    // Accession Number
    //CopyMandatoryEntry(0x0008,0x0050,"");
-   CheckMandatoryEntry(0x0008,0x0050,"");
+   CheckMandatoryEntry(0x0008,0x0050,"","SH");
    
 
    // ----- Add Mandatory Entries if missing ---
    
 
    // ----- Add Mandatory Entries if missing ---
@@ -1584,7 +1641,7 @@ void FileHelper::CheckMandatoryElements()
    //          keeping the same 'Study Instance UID' for various images
    // The user may add images to a 'Manufacturer Study',
    //          adding new Series to an already existing Study 
    //          keeping the same 'Study Instance UID' for various images
    // The user may add images to a 'Manufacturer Study',
    //          adding new Series to an already existing Study 
-   CheckMandatoryEntry(0x0020,0x000d,Util::CreateUniqueUID());
+   CheckMandatoryEntry(0x0020,0x000d,Util::CreateUniqueUID(),"UI");
 
    // 'Serie Instance UID'
    // Keep the value if exists
 
    // 'Serie Instance UID'
    // Keep the value if exists
@@ -1592,16 +1649,16 @@ void FileHelper::CheckMandatoryElements()
    // keeping the same 'Serie Instance UID' for various images
    // The user shouldn't add any image to a 'Manufacturer Serie'
    // but there is no way no to prevent him for doing that 
    // keeping the same 'Serie Instance UID' for various images
    // The user shouldn't add any image to a 'Manufacturer Serie'
    // but there is no way no to prevent him for doing that 
-   CheckMandatoryEntry(0x0020,0x000e,Util::CreateUniqueUID());
+   CheckMandatoryEntry(0x0020,0x000e,Util::CreateUniqueUID(),"UI");
 
    // Study ID
 
    // Study ID
-   CheckMandatoryEntry(0x0020,0x0010,"");
+   CheckMandatoryEntry(0x0020,0x0010,"","SH");
 
    // Series Number
 
    // Series Number
-   CheckMandatoryEntry(0x0020,0x0011,"");
+   CheckMandatoryEntry(0x0020,0x0011,"","IS");
 
    // Instance Number
 
    // Instance Number
-   CheckMandatoryEntry(0x0020,0x0013,"");
+   CheckMandatoryEntry(0x0020,0x0013,"","IS");
    
    // Patient Orientation
    // Can be computed from (0020|0037) :  Image Orientation (Patient)
    
    // Patient Orientation
    // Can be computed from (0020|0037) :  Image Orientation (Patient)
@@ -1609,37 +1666,41 @@ void FileHelper::CheckMandatoryElements()
    std::string ori = o->GetOrientation ( FileInternal );
    o->Delete();
    if (ori != "\\" && ori != GDCM_UNFOUND)
    std::string ori = o->GetOrientation ( FileInternal );
    o->Delete();
    if (ori != "\\" && ori != GDCM_UNFOUND)
-      CheckMandatoryEntry(0x0020,0x0020,ori);
+      CheckMandatoryEntry(0x0020,0x0020,ori,"CS");
    else   
    else   
-      CheckMandatoryEntry(0x0020,0x0020,"");
+      CheckMandatoryEntry(0x0020,0x0020,"","CS");
+
+   // Default Patient Position to HFS
+   CheckMandatoryEntry(0x0018,0x5100,"HFS","CS");
 
    // Modality : if missing we set it to 'OTher'
 
    // Modality : if missing we set it to 'OTher'
-   CheckMandatoryEntry(0x0008,0x0060,"OT");
+   CheckMandatoryEntry(0x0008,0x0060,"OT","CS");
 
    // Manufacturer : if missing we set it to 'GDCM Factory'
 
    // Manufacturer : if missing we set it to 'GDCM Factory'
-   CheckMandatoryEntry(0x0008,0x0070,"GDCM Factory");
+   CheckMandatoryEntry(0x0008,0x0070,"GDCM Factory","LO");
 
    // Institution Name : if missing we set it to 'GDCM Hospital'
 
    // Institution Name : if missing we set it to 'GDCM Hospital'
-   CheckMandatoryEntry(0x0008,0x0080,"GDCM Hospital");
+   CheckMandatoryEntry(0x0008,0x0080,"GDCM Hospital","LO");
 
    // Patient's Name : if missing, we set it to 'GDCM^Patient'
 
    // Patient's Name : if missing, we set it to 'GDCM^Patient'
-   CheckMandatoryEntry(0x0010,0x0010,"GDCM^Patient");
+   CheckMandatoryEntry(0x0010,0x0010,"GDCM^Patient","PN");
 
 
-   // Patient ID
-   CheckMandatoryEntry(0x0010,0x0020,"");
+   // Patient ID : some clinical softwares *demand* it although it's a 'type 2' entry.
+   CheckMandatoryEntry(0x0010,0x0020,"gdcm ID","LO");
 
    // Patient's Birth Date : 'type 2' entry -> must exist, value not mandatory
 
    // Patient's Birth Date : 'type 2' entry -> must exist, value not mandatory
-   CheckMandatoryEntry(0x0010,0x0030,"");
+   CheckMandatoryEntry(0x0010,0x0030,"","DA");
 
    // Patient's Sex :'type 2' entry -> must exist, value not mandatory
 
    // Patient's Sex :'type 2' entry -> must exist, value not mandatory
-   CheckMandatoryEntry(0x0010,0x0040,"");
+   CheckMandatoryEntry(0x0010,0x0040,"","CS");
 
    // Referring Physician's Name :'type 2' entry -> must exist, value not mandatory
 
    // Referring Physician's Name :'type 2' entry -> must exist, value not mandatory
-   CheckMandatoryEntry(0x0008,0x0090,"");
+   CheckMandatoryEntry(0x0008,0x0090,"","PN");
 
 
+ /*
    // Deal with element 0x0000 (group length) of each group.
    // First stage : get all the different Groups
    // Deal with element 0x0000 (group length) of each group.
    // First stage : get all the different Groups
- /*
+   
   GroupHT grHT;
   DocEntry *d = FileInternal->GetFirstEntry();
   while(d)
   GroupHT grHT;
   DocEntry *d = FileInternal->GetFirstEntry();
   while(d)
@@ -1653,32 +1714,36 @@ void FileHelper::CheckMandatoryElements()
       CheckMandatoryEntry(it->first, 0x0000, "0"); 
   }    
   // Third stage : update all 'zero level' groups length
       CheckMandatoryEntry(it->first, 0x0000, "0"); 
   }    
   // Third stage : update all 'zero level' groups length
-*/   
+*/ 
+
 } 
 
 } 
 
-void FileHelper::CheckMandatoryEntry(uint16_t group,uint16_t elem,std::string value)
+void FileHelper::CheckMandatoryEntry(uint16_t group,uint16_t elem,std::string value,const VRKey &vr )
 {
    DataEntry *entry = FileInternal->GetDataEntry(group,elem);
    if ( !entry )
    {
 {
    DataEntry *entry = FileInternal->GetDataEntry(group,elem);
    if ( !entry )
    {
-      entry = DataEntry::New(Global::GetDicts()->GetDefaultPubDict()->GetEntry(group,elem));
+      //entry = DataEntry::New(Global::GetDicts()->GetDefaultPubDict()->GetEntry(group,elem));
+      entry = DataEntry::New(group,elem,vr);
       entry->SetString(value);
       Archive->Push(entry);
       entry->Delete();
       entry->SetString(value);
       Archive->Push(entry);
       entry->Delete();
-   }
+   }    
 }
 
 }
 
-void FileHelper::SetMandatoryEntry(uint16_t group,uint16_t elem,std::string value)
+/// \todo : what is it used for ? (FileHelper::SetMandatoryEntry) 
+void FileHelper::SetMandatoryEntry(uint16_t group,uint16_t elem,std::string value,const VRKey &vr)
 {
 {
-   DataEntry *entry = DataEntry::New(Global::GetDicts()->GetDefaultPubDict()->GetEntry(group,elem));
+   //DataEntry *entry = DataEntry::New(Global::GetDicts()->GetDefaultPubDict()->GetEntry(group,elem));
+   DataEntry *entry = DataEntry::New(group,elem,vr);
    entry->SetString(value);
    Archive->Push(entry);
    entry->Delete();
 }
 
    entry->SetString(value);
    Archive->Push(entry);
    entry->Delete();
 }
 
-void FileHelper::CopyMandatoryEntry(uint16_t group,uint16_t elem,std::string value)
+void FileHelper::CopyMandatoryEntry(uint16_t group,uint16_t elem,std::string value,const VRKey &vr)
 {
 {
-   DataEntry *entry = CopyDataEntry(group,elem);
+   DataEntry *entry = CopyDataEntry(group,elem,vr);
    entry->SetString(value);
    Archive->Push(entry);
    entry->Delete();
    entry->SetString(value);
    Archive->Push(entry);
    entry->Delete();
@@ -1757,8 +1822,8 @@ void FileHelper::CallEndMethod()
 void FileHelper::Initialize()
 {
    UserFunction = 0;
 void FileHelper::Initialize()
 {
    UserFunction = 0;
-   KeepMediaStorageSOPClassUID = false;
-
+   ContentType = USER_OWN_IMAGE;
+   
    WriteMode = WMODE_RAW;
    WriteType = ExplicitVR;
 
    WriteMode = WMODE_RAW;
    WriteType = ExplicitVR;