]> Creatis software - gdcm.git/blobdiff - src/gdcmFileHelper.cxx
use GDCM_NAME_SPACE:: instead of gdcm::, even in Examples ...
[gdcm.git] / src / gdcmFileHelper.cxx
index fd2a84cc2eb03b22ae610caa5d33570ad1146c4a..f27d8d99a9ec899a3ddfa0a0aeb93a770a37f1a6 100644 (file)
@@ -4,8 +4,8 @@
   Module:    $RCSfile: gdcmFileHelper.cxx,v $
   Language:  C++
 
-  Date:      $Date: 2007/09/18 10:50:37 $
-  Version:   $Revision: 1.130 $
+  Date:      $Date: 2008/09/15 15:49:22 $
+  Version:   $Revision: 1.138 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
 #include "gdcmDocEntryArchive.h"
 #include "gdcmDictSet.h"
 #include "gdcmOrientation.h"
+
+
+
+#include <algorithm>  // for transform?
+
 #if defined(__BORLANDC__)
-   #include <mem.h> // for memset
+   #include <mem.h>   // for memset
+   #include <ctype.h> //for toupper
+   #include <math.h>
 #endif 
 
 #include <fstream>
 
 These lines will be moved to the document-to-be 'User's Guide'
 
-// To read an image, user needs a gdcm::File
-gdcm::File *f = new gdcm::File(fileName);
+// To read an image, user needs a GDCM_NAME_SPACE::File
+GDCM_NAME_SPACE::File *f = new GDCM_NAME_SPACE::File(fileName);
 // or (advanced) :
 // user may also decide he doesn't want to load some parts of the header
-gdcm::File *f = new gdcm::File();
+GDCM_NAME_SPACE::File *f = new GDCM_NAME_SPACE::File();
 f->SetFileName(fileName);
    f->SetLoadMode(LD_NOSEQ);               // or      
    f->SetLoadMode(LD_NOSHADOW);            // or
@@ -61,8 +67,8 @@ f->Load();
 // user can now check some values
 std::string v = f->GetEntryValue(groupNb,ElementNb);
 
-// to get the pixels, user needs a gdcm::FileHelper
-gdcm::FileHelper *fh = new gdcm::FileHelper(f);
+// to get the pixels, user needs a GDCM_NAME_SPACE::FileHelper
+GDCM_NAME_SPACE::FileHelper *fh = new GDCM_NAME_SPACE::FileHelper(f);
 
 // user may ask not to convert Palette (if any) to RGB
 uint8_t *pixels = fh->GetImageDataRaw();
@@ -71,8 +77,8 @@ int imageLength = fh->GetImageDataRawSize();
 // He can now use the pixels, create a new image, ...
 uint8_t *userPixels = ...
 
-//To re-write the image, user re-uses the gdcm::FileHelper
-gdcm::File *fh = new gdcm::FileHelper();
+//To re-write the image, user re-uses the GDCM_NAME_SPACE::FileHelper
+GDCM_NAME_SPACE::File *fh = new GDCM_NAME_SPACE::FileHelper();
 
 fh->SetTypeToRaw(); // Even if it was possible to convert Palette to RGB
                     // (WriteMode is set)
@@ -151,7 +157,7 @@ fh->Write(newFileName);
          ElementSet::WriteContent(fp, writetype);
             writes recursively all DataElements    
    RestoreWrite();
-         (moves back to the gdcm::File all the archived elements)
+         (moves back to the GDCM_NAME_SPACE::File all the archived elements)
 */
 
 
@@ -164,7 +170,7 @@ typedef std::map<uint16_t, int> GroupHT;    //  Hash Table
 // Constructor / Destructor
 /**
  * \brief Constructor dedicated to deal with the *pixels* area of a ACR/DICOMV3
- *        file (gdcm::File only deals with the ... header)
+ *        file (GDCM_NAME_SPACE::File only deals with the ... header)
  *        Opens (in read only and when possible) an existing file and checks
  *        for DICOM compliance. Returns NULL on failure.
  *        It will be up to the user to load the pixels into memory
@@ -210,7 +216,7 @@ FileHelper::FileHelper(File *header)
 
 /**
  * \brief canonical destructor
- * \note  If the header (gdcm::File) was created by the FileHelper constructor,
+ * \note  If the header (GDCM_NAME_SPACE::File) was created by the FileHelper constructor,
  *        it is destroyed by the FileHelper
  */
 FileHelper::~FileHelper()
@@ -235,7 +241,7 @@ FileHelper::~FileHelper()
 // Public
 
 /**
- * \brief Sets the LoadMode of the internal gdcm::File as a boolean string. 
+ * \brief Sets the LoadMode of the internal GDCM_NAME_SPACE::File as a boolean string. 
  *        NO_SEQ, NO_SHADOW, NO_SHADOWSEQ ... (nothing more, right now)
  *        WARNING : before using NO_SHADOW, be sure *all* your files
  *        contain accurate values in the 0x0000 element (if any) 
@@ -247,7 +253,7 @@ void FileHelper::SetLoadMode(int loadMode)
    GetFile()->SetLoadMode( loadMode ); 
 }
 /**
- * \brief Sets the LoadMode of the internal gdcm::File
+ * \brief Sets the LoadMode of the internal GDCM_NAME_SPACE::File
  * @param  fileName name of the file to be open  
  */
 void FileHelper::SetFileName(std::string const &fileName)
@@ -727,7 +733,6 @@ bool FileHelper::Write(std::string const &fileName)
 { 
    CheckMandatoryElements(); //called once, here !
    
-   bool flag = false;
    switch(WriteType)
    {
       case ImplicitVR:
@@ -870,7 +875,14 @@ bool FileHelper::CheckWriteIntegrity()
             if ( abs((long)(decSize-userDataSize))>1) // ignore padding zero
             {
                gdcmWarningMacro( "Data size (Raw) is incorrect. Should be " 
-                           << decSize << " / Found :" 
+                           << decSize << "(" 
+                           << FileInternal->GetXSize() << " * "
+                           << FileInternal->GetYSize() << " * "
+                           << FileInternal->GetZSize() << " * "
+                           << FileInternal->GetTSize() << " * "   
+                           << FileInternal->GetSamplesPerPixel() << " * "
+                           << numberBitsAllocated / 8   
+                           << ") / Found :" 
                            << userDataSize );
                return false;
             }
@@ -1316,7 +1328,7 @@ We have to deal with 4 *very* different cases :
 -Probabely some more to be added.
  --> Set it with FileHelper::SetContentType(int);
  
-gdcm::FileHelper::CheckMandatoryElements() deals automatically with these cases.
+GDCM_NAME_SPACE::FileHelper::CheckMandatoryElements() deals automatically with these cases.
 
 1)2)3)4)
 0008 0012 Instance Creation Date
@@ -1371,7 +1383,7 @@ If 'SOP Class UID' exists in the native image  ('true DICOM' image)
 
 
 Bellow follows the full description (hope so !) of the consistency checks performed 
-by gdcm::FileHelper::CheckMandatoryElements()
+by GDCM_NAME_SPACE::FileHelper::CheckMandatoryElements()
 
 
 -->'Media Storage SOP Class UID' (0x0002,0x0002)
@@ -1505,46 +1517,75 @@ void FileHelper::CheckMandatoryElements()
 
    // --------------------- For DataSet ---------------------
 
+   // check whether 0018|0015 [CS] [Body Part Examined] value is UPPER CASE
+   //      (avoid dciodvfy to complain!)
+   DataEntry *e_0018_0015 = FileInternal->GetDataEntry(0x0018, 0x0015);  
+   if ( e_0018_0015)
+   {
+      std::string bodyPartExamined = e_0018_0015->GetString();
+      std::transform(bodyPartExamined.begin(), bodyPartExamined.end(), bodyPartExamined.begin(), 
+                    (int(*)(int)) toupper);
+      CopyMandatoryEntry(0x0018,0x0015,bodyPartExamined,"CS");       
+   }
+
    if ( ContentType != USER_OWN_IMAGE) // when it's not a user made image
    { 
    // If 'SOP Class UID' and 'SOP Instance UID' exist ('true DICOM' image)
    // we create the 'Source Image Sequence' SeqEntry
    // to hold informations about the Source Image
-  
+      // 'SOP Instance UID' 
       DataEntry *e_0008_0016 = FileInternal->GetDataEntry(0x0008, 0x0016);
+      //
       DataEntry *e_0008_0018 = FileInternal->GetDataEntry(0x0008, 0x0018);
       if ( e_0008_0016 && e_0008_0018)
       {
-      // Create 'Source Image Sequence' SeqEntry
-      SeqEntry *sis = SeqEntry::New (0x0008, 0x2112);
-      SQItem *sqi = SQItem::New(1);
+         // Create 'Source Image Sequence' SeqEntry
+         SeqEntry *sis = SeqEntry::New (0x0008, 0x2112);
+         SQItem *sqi = SQItem::New(1);
       
-      // create 'Referenced SOP Class UID' from 'SOP Class UID'
+         // create 'Referenced SOP Class UID' from 'SOP Class UID'
 
-      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();
+         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' from 'SOP Instance UID'
-      DataEntry *e_0008_0018 = FileInternal->GetDataEntry(0x0008, 0x0018);
+         // create 'Referenced SOP Instance UID' from 'SOP Instance UID'
+        // DataEntry *e_0008_0018 = FileInternal->GetDataEntry(0x0008, 0x0018);
          
-      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();
+         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");    
+         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
+         { 
+            DataEntry *e_0008_0008 = FileInternal->GetDataEntry(0x0008, 0x0008);  
+            if ( e_0008_0008)
+            {
+               std::string imageType = e_0008_0008->GetString();
+               std::string::size_type p = imageType.find("ORIGINAL");
+               if (p == 0) // image is ORIGINAL one
+               {            
+                 // the image is no longer an 'Original' one
+                 CopyMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY","CS");
+               }
+               // if Image Type was not ORIGINAL\..., we keep it.
+             }
+             else // 0008_0008 was missing, wee add it.
+             {
+                 CopyMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY","CS");             
+             }  
+         }    
       }
    }
       
@@ -2118,7 +2159,7 @@ void FileHelper::Print(std::ostream &os, std::string const &)
 
 
 /* Probabely something to be added to use Rescale Slope/Intercept
-Have a look ,at ITK code !
+Have a look at ITK code !
 
 // Internal function to rescale pixel according to Rescale Slope/Intercept
 template<class TBuffer, class TSource>