]> Creatis software - gdcm.git/commitdiff
* src/*.[h|cxx] : coding style
authorregrain <regrain>
Tue, 13 Jan 2004 15:27:03 +0000 (15:27 +0000)
committerregrain <regrain>
Tue, 13 Jan 2004 15:27:03 +0000 (15:27 +0000)
     -- BeNours

32 files changed:
ChangeLog
src/gdcm.h
src/gdcmCommon.h
src/gdcmDict.cxx
src/gdcmDict.h
src/gdcmDictEntry.cxx
src/gdcmDictEntry.h
src/gdcmDictSet.cxx
src/gdcmDictSet.h
src/gdcmElValSet.cxx
src/gdcmElValSet.h
src/gdcmElValue.cxx
src/gdcmElValue.h
src/gdcmException.cxx
src/gdcmException.h
src/gdcmFile.cxx
src/gdcmFile.h
src/gdcmHeader.cxx
src/gdcmHeader.h
src/gdcmHeaderHelper.cxx
src/gdcmHeaderHelper.h
src/gdcmJpeg.cxx
src/gdcmJpeg12.cxx
src/gdcmJpeg2000.cxx
src/gdcmParse.cxx
src/gdcmRLE.cxx
src/gdcmTS.cxx
src/gdcmTS.h
src/gdcmUtil.cxx
src/gdcmUtil.h
src/gdcmVR.cxx
src/gdcmVR.h

index cdfae207fbc76ae3a1533c46b1d1e9cda1006de8..64caba12e82ef9a859fb3ebfbb0a6cd13d156f58 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2004-01-13 Benoit Regrain
+     * src/*.[h|cxx] : coding style
+
 2004-01-13 Benoit Regrain
      * gdcmPython/testSuite.py : test the readable flag of file for tests
      * src/gdcmDict.cxx, gdcmElValSet.cxx : bug fix under windows for prints.
index cd173d27a0568678a6e5dde7fff942ae7b5588e5..250b76e5da3e0aa29c661a29ab9359b1f2f9dd9d 100644 (file)
@@ -1,5 +1,5 @@
 // gdcm.h
-
+//-----------------------------------------------------------------------------
 #ifndef GDCM_H
 #define GDCM_H
 
@@ -27,8 +27,5 @@
 #include "gdcmHeaderHelper.h"
 #include "gdcmFile.h"
 
-//#include "gdcmTS.h"
-//#include "gdcmVR.h"
-//#include "gdcmUtil.h"
-
+//-----------------------------------------------------------------------------
 #endif // #ifndef GDCM_H
index 07d0eec61f12d68e0d6674fcd27be53dcd5f7078..3775c317f7ee3b926738de241e18032c36f9dc33 100644 (file)
@@ -1,5 +1,5 @@
 //gdcmCommon.h
-
+//-----------------------------------------------------------------------------
 #ifndef GDCMCOMMON_H
 #define GDCMCOMMON_H
 
@@ -26,6 +26,7 @@
 // Mmmmmm !
 // It reminds me the formerly well known LibIDO's idproto.h
 
+//-----------------------------------------------------------------------------
 #ifdef __GNUC__
 #ifndef HAVE_NO_STDINT_H
 #include <stdint.h>
@@ -74,4 +75,5 @@ enum FileType {
 //For now gdcm is not willing cmake, try to be more quiet
 //#cmakedefine GDCM_NO_ANSI_STRING_STREAM
 
+//-----------------------------------------------------------------------------
 #endif
index e362675dab70de9f96474a486a4a66b59e597c93..725d2d6c85d566f884de9b8acfc0a7f16fbad846 100644 (file)
@@ -1,5 +1,5 @@
 // gdcmDict.cxx
-
+//-----------------------------------------------------------------------------
 #include "gdcmDict.h"
 #include "gdcmUtil.h"
 #include <fstream>
@@ -10,6 +10,8 @@
 #  include <sstream>
 #endif
 
+//-----------------------------------------------------------------------------
+// Constructor / Destructor
 /**
  * \ingroup gdcmDict
  * \brief   Construtor
@@ -63,6 +65,8 @@ gdcmDict::~gdcmDict() {
    NameHt.clear();
 }
 
+//-----------------------------------------------------------------------------
+// Print
 /**
  * \brief   Print all the dictionary entries contained in this dictionary.
  *          Entries will be sorted by tag i.e. the couple (group, element).
@@ -114,49 +118,8 @@ void gdcmDict::PrintByName(std::ostream& os) {
    os << s.str();
 }
 
-/**
- * \ingroup gdcmDict
- * \brief   Get the dictionnary entry identified by a given tag (group,element)
- * @param   group   group of the entry to be found
- * @param   element element of the entry to be found
- * @return  the corresponding dictionnary entry when existing, NULL otherwise
- */
-gdcmDictEntry * gdcmDict::GetTagByNumber(guint16 group, guint16 element) {
-   TagKey key = gdcmDictEntry::TranslateToKey(group, element);
-   if ( ! KeyHt.count(key))
-      return (gdcmDictEntry*)0; 
-   return KeyHt.find(key)->second;
-}
-
-/**
- * \ingroup gdcmDict
- * \brief   Get the dictionnary entry identified by it's name.
- * @param   name element of the ElVal to modify
- * \warning : NEVER use it !
- *            the 'name' IS NOT an identifier within the Dicom Dicom Dictionary
- *            the name MAY CHANGE between two versions !
- * @return  the corresponding dictionnary entry when existing, NULL otherwise
- */
-gdcmDictEntry * gdcmDict::GetTagByName(TagName name) {
-   if ( ! NameHt.count(name))
-      return (gdcmDictEntry*)0; 
-   return NameHt.find(name)->second;
-}
-
-/**
- * \ingroup gdcmDict
- * \brief  replaces an already existing Dicom Element by a new one
- * @param   NewEntry
- * @return  false if Dicom Element doesn't exist
- */
-bool gdcmDict::ReplaceEntry(gdcmDictEntry* NewEntry) {
-   if ( RemoveEntry(NewEntry->gdcmDictEntry::GetKey()) ) {
-       KeyHt[ NewEntry->GetKey()] = NewEntry;
-       return (true);
-   } 
-   return (false);
-}
-
+//-----------------------------------------------------------------------------
+// Public
 /**
  * \ingroup gdcmDict
  * \brief  adds a new Dicom Dictionary Entry 
@@ -176,6 +139,20 @@ bool gdcmDict::ReplaceEntry(gdcmDictEntry* NewEntry) {
    }
 }
 
+/**
+ * \ingroup gdcmDict
+ * \brief  replaces an already existing Dicom Element by a new one
+ * @param   NewEntry
+ * @return  false if Dicom Element doesn't exist
+ */
+bool gdcmDict::ReplaceEntry(gdcmDictEntry* NewEntry) {
+   if ( RemoveEntry(NewEntry->gdcmDictEntry::GetKey()) ) {
+       KeyHt[ NewEntry->GetKey()] = NewEntry;
+       return (true);
+   } 
+   return (false);
+}
+
 /**
  * \ingroup gdcmDict
  * \brief  removes an already existing Dicom Dictionary Entry,
@@ -209,3 +186,39 @@ bool gdcmDict::RemoveEntry (guint16 group, guint16 element) {
        return( RemoveEntry(gdcmDictEntry::TranslateToKey(group, element)) );
 }
 
+/**
+ * \ingroup gdcmDict
+ * \brief   Get the dictionnary entry identified by a given tag (group,element)
+ * @param   group   group of the entry to be found
+ * @param   element element of the entry to be found
+ * @return  the corresponding dictionnary entry when existing, NULL otherwise
+ */
+gdcmDictEntry * gdcmDict::GetTagByNumber(guint16 group, guint16 element) {
+   TagKey key = gdcmDictEntry::TranslateToKey(group, element);
+   if ( ! KeyHt.count(key))
+      return (gdcmDictEntry*)0; 
+   return KeyHt.find(key)->second;
+}
+
+/**
+ * \ingroup gdcmDict
+ * \brief   Get the dictionnary entry identified by it's name.
+ * @param   name element of the ElVal to modify
+ * \warning : NEVER use it !
+ *            the 'name' IS NOT an identifier within the Dicom Dicom Dictionary
+ *            the name MAY CHANGE between two versions !
+ * @return  the corresponding dictionnary entry when existing, NULL otherwise
+ */
+gdcmDictEntry * gdcmDict::GetTagByName(TagName name) {
+   if ( ! NameHt.count(name))
+      return (gdcmDictEntry*)0; 
+   return NameHt.find(name)->second;
+}
+
+//-----------------------------------------------------------------------------
+// Protected
+
+//-----------------------------------------------------------------------------
+// Private
+
+//-----------------------------------------------------------------------------
index e91d68233c9d66f772fdc188a606763218da0b21..cf34024488841ec8ff7bdbebd896281bc2a3bb37 100644 (file)
@@ -1,5 +1,5 @@
 // gdcmDict.h
-
+//-----------------------------------------------------------------------------
 #ifndef GDCMDICT_H
 #define GDCMDICT_H
 
@@ -7,9 +7,11 @@
 #include "gdcmDictEntry.h"
 #include <map>
 
+//-----------------------------------------------------------------------------
 typedef std::map<TagKey,  gdcmDictEntry*> TagKeyHT;
 typedef std::map<TagName, gdcmDictEntry*> TagNameHT;
 
+//-----------------------------------------------------------------------------
 /*
  * \defgroup gdcmDict
  * \brief    gdcmDict acts a memory representation of a dicom dictionary i.e.
@@ -21,34 +23,40 @@ typedef std::map<TagName, gdcmDictEntry*> TagNameHT;
  * \see gdcmDictSet
  */
 class GDCM_EXPORT gdcmDict {
-   std::string name;
-   std::string filename;
-   /// Access through TagKey (see alternate access with NameHt)
-       TagKeyHT  KeyHt;
-   /// Access through TagName (see alternate access with KeyHt)
-       TagNameHT NameHt;
 public:
-       gdcmDict(std::string & FileName);
+   gdcmDict(std::string & FileName);
        ~gdcmDict();
-       bool AddNewEntry (gdcmDictEntry* NewEntry);
+
+       void Print(std::ostream&);
+       void PrintByKey(std::ostream&);
+       void PrintByName(std::ostream&);        
+
+   bool AddNewEntry (gdcmDictEntry* NewEntry);
        bool ReplaceEntry(gdcmDictEntry* NewEntry);
        bool RemoveEntry (TagKey key);
        bool RemoveEntry (guint16 group, guint16 element);
+
        gdcmDictEntry * GetTagByNumber(guint16 group, guint16 element);
        gdcmDictEntry * GetTagByName(TagName name);
-       void Print(std::ostream&);
-       void PrintByKey(std::ostream&);
-       void PrintByName(std::ostream&);        
 
- /**
- * \ingroup gdcmDict
- * \brief   returns a ref to the Dicom Dictionary H table (map)
- * return the Dicom Dictionary H table
- */
inline TagKeyHT &      gdcmDict::GetEntries(void)  {
  /**
   * \ingroup gdcmDict
   * \brief   returns a ref to the Dicom Dictionary H table (map)
   * return the Dicom Dictionary H table
   */
  inline TagKeyHT & gdcmDict::GetEntries(void)  {
     return KeyHt; 
- }
  }
  
+private:
+   std::string name;
+   std::string filename;
+   /// Access through TagKey (see alternate access with NameHt)
+       TagKeyHT  KeyHt;
+   /// Access through TagName (see alternate access with KeyHt)
+       TagNameHT NameHt;
+
 };
 
+//-----------------------------------------------------------------------------
 #endif
index ddef65335315a9cdf9a45473f65d968383be5c9d..7ad40bee7d9924c336d74836b6a5c0bfc8498598 100644 (file)
@@ -1,10 +1,12 @@
 // gdcmDictEntry.cxx
-
+//-----------------------------------------------------------------------------
 #include "gdcmDictEntry.h"
 
 #include <stdio.h>    // FIXME For sprintf
 #include "gdcmUtil.h"
 
+//-----------------------------------------------------------------------------
+// Constructor / Destructor
 /**
  * \ingroup gdcmDictEntry
  * \brief   Construtor
 gdcmDictEntry::gdcmDictEntry(guint16 InGroup, guint16 InElement,
                              std::string  InVr, std::string InFourth,
                              std::string  InName) {
-       group           = InGroup;
+       group   = InGroup;
        element         = InElement;
        vr              = InVr;
-       fourth          = InFourth;
+       fourth  = InFourth;
        name            = InName;
        key             = TranslateToKey(group, element);
 }
 
+//-----------------------------------------------------------------------------
+// Print
+
+//-----------------------------------------------------------------------------
+// Public
 /**
  * \ingroup gdcmDictEntry
  * \brief   concatenates 2 guint16 (supposed to be a Dicom group number 
@@ -54,10 +61,19 @@ TagKey gdcmDictEntry::TranslateToKey(guint16 group, guint16 element) {
  * @param NewVr New V(alue) R(epresentation) to be set.
  */
 void gdcmDictEntry::SetVR(std::string NewVr) {
-       if ( IsVrUnknown() )
+       if ( IsVRUnknown() )
                vr = NewVr;
        else {
                dbg.Error(true, "gdcmDictEntry::SetVR",
                          "Overwriting vr might compromise a dictionary");
        }
 }
+
+//-----------------------------------------------------------------------------
+// Protected
+
+//-----------------------------------------------------------------------------
+// Private
+
+//-----------------------------------------------------------------------------
+
index 6b21209977ce20947e7df07075831bae83969d9f..5c6abff303eae3c407bc89e06264bc78c845e9aa 100644 (file)
@@ -1,10 +1,11 @@
 // gdcmDictEntry.h
-
+//-----------------------------------------------------------------------------
 #ifndef GDCMDICTENTRY_H
 #define GDCMDICTENTRY_H
 
 #include "gdcmCommon.h"
 
+//-----------------------------------------------------------------------------
 /*
  * the gdcmDictEntry in an element contained by the gdcmDict.
  * It contains :
  *  - etc.
  */
 class GDCM_EXPORT gdcmDictEntry {
+public:
+   gdcmDictEntry(guint16 group, 
+                 guint16 element,
+                 std::string vr     = "Unknown",
+                 std::string fourth = "Unknown",
+                 std::string name   = "Unknown");
+       
+   static TagKey TranslateToKey(guint16 group, guint16 element);
+   void SetVR(std::string);
+
+   /**
+    * \ingroup     gdcmDictEntry
+    * \brief       tells if the V(alue) R(epresentation) is known (?!)
+    *              
+    * @return 
+    */
+   inline bool gdcmDictEntry::IsVRUnknown() {
+          if ( vr == "Unknown" )
+                  return true;
+          return false;
+   }
+
+   /**
+    * \ingroup gdcmDictEntry
+    * \brief   returns the Dicom Group Number of the current gdcmDictEntry
+    * return the Dicom Group Number
+    */
+   inline guint16 gdcmDictEntry::GetGroup(void)  {
+    return group; 
+   }
+  
+   /**
+    * \ingroup gdcmDictEntry
+    * \brief   returns the Dicom Element Number of the current gdcmDictEntry
+    * return the Dicom Element Number
+    */
+   inline guint16 gdcmDictEntry::GetElement(void)  {
+    return element; 
+   }
+   /**
+    * \ingroup gdcmDictEntry
+    * \brief   returns the Dicom Value Representation of the current gdcmDictEntry
+    * return the Dicom Value Representation
+    */
+   inline std::string gdcmDictEntry::GetVR(void)  {
+    return vr; 
+   }
+   /**
+    * \ingroup gdcmDictEntry
+    * \brief   sets the key of the current gdcmDictEntry
+    * @param k New key to be set.
+    */
+   inline void gdcmDictEntry::SetKey(std::string k)  {
+    key = k; 
+   }
+   /**
+    * \ingroup gdcmDictEntry
+    * \brief   returns the Fourth field of the current gdcmDictEntry
+    * \warning NOT part of the Dicom Standard
+    * \        May be REMOVED an any time
+    * \        NEVER use it
+    * return the Fourth field
+    */
+   inline std::string gdcmDictEntry::GetFourth(void)  {
+    return fourth; 
+   } 
+
+   /**
+    * \ingroup gdcmDictEntry
+    * \brief   returns the Dicom Name of the current gdcmDictEntry
+    * \        e.g. "Patient Name" for Dicom Tag (0x0010, 0x0010) 
+    * return the Dicom Name
+    */
+   inline std::string gdcmDictEntry::GetName(void)  {
+    return name; 
+   } 
+   /**
+    * \ingroup gdcmDictEntry
+    * \brief   Gets the key of the current gdcmDictEntry
+    * @return the key .
+    */
+   inline std::string gdcmDictEntry::GetKey(void)  {
+    return key; 
+   }
+
 private:
    // FIXME : were are the group and element used except from building up
    //         a TagKey. If the answer is nowhere then there is no need
@@ -43,109 +133,7 @@ private:
        //         DcmDictRangeRestriction groupRestriction;
        //         DcmDictRangeRestriction elementRestriction;
        //       };
-public:
-   gdcmDictEntry(guint16 group, 
-                 guint16 element,
-                 std::string vr     = "Unknown",
-                 std::string fourth = "Unknown",
-                 std::string name   = "Unknown");
-       
-   static TagKey TranslateToKey(guint16 group, guint16 element);
-
-//   bool         IsVrUnknown(void);
-       
-//   inline guint16      GetGroup(void);
-//   inline guint16      GetElement(void);
-//   inline std::string  GetVR(void);
-            void         SetVR(std::string);
-//   inline void         SetKey(std::string k);
-//   inline std::string  GetFourth(void);
-//   inline std::string  GetName(void);
-//   inline std::string  GetKey(void);
-
-
-
-/**
- * \ingroup     gdcmDictEntry
- * \brief       tells if the V(alue) R(epresentation) is known (?!)
- *              
- * @return 
- */
-inline bool gdcmDictEntry::IsVrUnknown() {
-       if ( vr == "Unknown" )
-               return true;
-       return false;
-}
-
-
-/**
- * \ingroup gdcmDictEntry
- * \brief   returns the Dicom Group Number of the current gdcmDictEntry
- * return the Dicom Group Number
- */
- inline guint16      gdcmDictEntry::GetGroup(void)  {
-    return group; 
- }
-  
-/**
- * \ingroup gdcmDictEntry
- * \brief   returns the Dicom Element Number of the current gdcmDictEntry
- * return the Dicom Element Number
- */
- inline guint16      gdcmDictEntry::GetElement(void)  {
-    return element; 
- }
- /**
- * \ingroup gdcmDictEntry
- * \brief   returns the Dicom Value Representation of the current gdcmDictEntry
- * return the Dicom Value Representation
- */
- inline std::string      gdcmDictEntry::GetVR(void)  {
-    return vr; 
- }
-/**
- * \ingroup gdcmDictEntry
- * \brief   sets the key of the current gdcmDictEntry
- * @param k New key to be set.
- */
- inline void      gdcmDictEntry::SetKey(std::string k)  {
-    key = k; 
- }
- /**
- * \ingroup gdcmDictEntry
- * \brief   returns the Fourth field of the current gdcmDictEntry
- * \warning NOT part of the Dicom Standard
- * \        May be REMOVED an any time
- * \        NEVER use it
- * return the Fourth field
- */
- inline std::string      gdcmDictEntry::GetFourth(void)  {
-    return fourth; 
- } 
-
- /**
- * \ingroup gdcmDictEntry
- * \brief   returns the Dicom Name of the current gdcmDictEntry
- * \        e.g. "Patient Name" for Dicom Tag (0x0010, 0x0010) 
- * return the Dicom Name
- */
- inline std::string      gdcmDictEntry::GetName(void)  {
-    return name; 
- } 
- /**
- * \ingroup gdcmDictEntry
- * \brief   Gets the key of the current gdcmDictEntry
- * @return the key .
- */
- inline std::string      gdcmDictEntry::GetKey(void)  {
-    return key; 
- }
-
-
 };
 
+//-----------------------------------------------------------------------------
 #endif
index 0db5964ad2266f0f2058fddff523a4d9be211fbd..ce08aa50142d21fb238198ed7702901128d26a64 100644 (file)
@@ -1,5 +1,5 @@
 // gdcmDictEntry
-
+//-----------------------------------------------------------------------------
 #include "gdcmDictSet.h"
 #include "gdcmUtil.h"
 #include <fstream>
 #endif
 #define PUB_DICT_FILENAME "dicomV3.dic"
 
+//-----------------------------------------------------------------------------
+// Constructor / Destructor
+/** 
+ * \ingroup gdcmDictSet
+ * \brief   The Dictionnary Set obtained with this constructor simply
+ *          contains the Default Public dictionnary.
+ */
+gdcmDictSet::gdcmDictSet(void) {
+   DictPath = BuildDictPath();
+   std::string PubDictFile = DictPath + PUB_DICT_FILENAME;
+   Dicts[PUB_DICT_NAME] = new gdcmDict(PubDictFile);
+}
+
+/**
+ * \ingroup gdcmDictSet
+ * \brief  Destructor 
+ */
+gdcmDictSet::~gdcmDictSet() {
+   for (DictSetHT::iterator tag = Dicts.begin(); tag != Dicts.end(); ++tag) {
+      gdcmDict* EntryToDelete = tag->second;
+      if ( EntryToDelete )
+         delete EntryToDelete;
+   }
+   Dicts.clear();
+}
+
+//-----------------------------------------------------------------------------
+// Print
+/**
+ * \ingroup gdcmDictSet
+ * \brief   Print, in an informal fashion, the list of all the dictionaries
+ *          contained is this gdcmDictSet, along with their respective content.
+ * @param   os Output stream used for printing.
+ */
+void gdcmDictSet::Print(std::ostream& os) {
+   for (DictSetHT::iterator dict = Dicts.begin(); dict != Dicts.end(); ++dict){
+      os << "Printing dictionary " << dict->first << std::endl;
+      dict->second->Print(os);
+   }
+}
+
+//-----------------------------------------------------------------------------
+// Public
 /** 
  * \ingroup gdcmDictSet
  * \brief   Consider all the entries of the public dicom dictionnary. 
@@ -39,7 +82,6 @@ std::list<std::string> * gdcmDictSet::GetPubDictTagNames(void) {
  *          A typical usage of this method would be to enable a dynamic
  *          configuration of a Dicom file browser: the admin/user can
  *          select in the interface which Dicom tags should be displayed.
  * \warning Dicom *doesn't* define any name for any 'categorie'
  *          (the dictionnary fourth field was formerly NIH defined
  *           - and no longer he is-
@@ -63,54 +105,6 @@ std::map<std::string, std::list<std::string> > * gdcmDictSet::GetPubDictTagNames
    return Result;
 }
 
-/**
- * \ingroup gdcmDictSet
- * \brief   Obtain from the GDCM_DICT_PATH environnement variable the
- *          path to directory containing the dictionnaries. When
- *          the environnement variable is absent the path is defaulted
- *          to "../Dicts/".
- * @return path to directory containing the dictionnaries
- */
-std::string gdcmDictSet::BuildDictPath(void) {
-   std::string ResultPath;
-   const char* EnvPath = (char*)0;
-   EnvPath = getenv("GDCM_DICT_PATH");
-   if (EnvPath && (strlen(EnvPath) != 0)) {
-      ResultPath = EnvPath;
-      if (ResultPath[ResultPath.length() -1] != '/' )
-         ResultPath += '/';
-      dbg.Verbose(1, "gdcmDictSet::BuildDictPath:",
-                     "Dictionary path set from environnement");
-   } else
-      ResultPath = PUB_DICT_PATH;
-   return ResultPath;
-}
-
-/** 
- * \ingroup gdcmDictSet
- * \brief   The Dictionnary Set obtained with this constructor simply
- *          contains the Default Public dictionnary.
- */
-gdcmDictSet::gdcmDictSet(void) {
-   DictPath = BuildDictPath();
-   std::string PubDictFile = DictPath + PUB_DICT_FILENAME;
-   Dicts[PUB_DICT_NAME] = new gdcmDict(PubDictFile);
-}
-
-
-/**
- * \ingroup gdcmDictSet
- * \brief  Destructor 
- */
-gdcmDictSet::~gdcmDictSet() {
-   for (DictSetHT::iterator tag = Dicts.begin(); tag != Dicts.end(); ++tag) {
-      gdcmDict* EntryToDelete = tag->second;
-      if ( EntryToDelete )
-         delete EntryToDelete;
-   }
-   Dicts.clear();
-}
-
 /**
  * \ingroup gdcmDictSet
  * \brief   Loads a dictionary from a specified file, and add it
@@ -122,20 +116,7 @@ gdcmDictSet::~gdcmDictSet() {
  */
 void gdcmDictSet::LoadDictFromFile(std::string FileName, DictKey Name) {
    gdcmDict *NewDict = new gdcmDict(FileName);
-   Dicts[Name] = NewDict;
-}
-
-/**
- * \ingroup gdcmDictSet
- * \brief   Print, in an informal fashion, the list of all the dictionaries
- *          contained is this gdcmDictSet, along with their respective content.
- * @param   os Output stream used for printing.
- */
-void gdcmDictSet::Print(std::ostream& os) {
-   for (DictSetHT::iterator dict = Dicts.begin(); dict != Dicts.end(); ++dict){
-      os << "Printing dictionary " << dict->first << std::endl;
-      dict->second->Print(os);
-   }
+   AppendDict(NewDict,Name);
 }
 
 /**
@@ -158,3 +139,41 @@ gdcmDict * gdcmDictSet::GetDict(DictKey DictName) {
 gdcmDict * gdcmDictSet::GetDefaultPubDict() {
    return GetDict(PUB_DICT_NAME);
 }
+
+/**
+ * \ingroup gdcmDictSet
+ * \brief   Obtain from the GDCM_DICT_PATH environnement variable the
+ *          path to directory containing the dictionnaries. When
+ *          the environnement variable is absent the path is defaulted
+ *          to "../Dicts/".
+ * @return path to directory containing the dictionnaries
+ */
+std::string gdcmDictSet::BuildDictPath(void) {
+   std::string ResultPath;
+   const char* EnvPath = (char*)0;
+   EnvPath = getenv("GDCM_DICT_PATH");
+   if (EnvPath && (strlen(EnvPath) != 0)) {
+      ResultPath = EnvPath;
+      if (ResultPath[ResultPath.length() -1] != '/' )
+         ResultPath += '/';
+      dbg.Verbose(1, "gdcmDictSet::BuildDictPath:",
+                     "Dictionary path set from environnement");
+   } else
+      ResultPath = PUB_DICT_PATH;
+   return ResultPath;
+}
+
+//-----------------------------------------------------------------------------
+// Protected
+bool gdcmDictSet::AppendDict(gdcmDict* NewDict,DictKey Name)
+{
+   Dicts[Name] = NewDict;
+   return(true);
+}
+
+//-----------------------------------------------------------------------------
+// Private
+
+//-----------------------------------------------------------------------------
+
+
index 578f72057b7880bfb573128e3c1028bd0f51bfe4..1fee82f95158b3c06f0559db18b292c5b79751ab 100644 (file)
@@ -1,5 +1,5 @@
 // gdcmDictSet.h
-
+//-----------------------------------------------------------------------------
 #ifndef GDCMDICTSET_H
 #define GDCMDICTSET_H
 
@@ -10,6 +10,7 @@
 typedef std::string DictKey;
 typedef std::map<DictKey, gdcmDict*> DictSetHT;
 
+//-----------------------------------------------------------------------------
 /*
  * \defgroup gdcmDictSet
  * \brief  Container for managing a set of loaded dictionaries.
@@ -19,20 +20,7 @@ typedef std::map<DictKey, gdcmDict*> DictSetHT;
  *        (saving memory).
  */
 class GDCM_EXPORT gdcmDictSet {
-private:
-   /// Hash table of all dictionaries contained in this gdcmDictSet
-       DictSetHT Dicts;
-   /// Directory path to dictionaries
-   std::string DictPath;
-
-       int AppendDict(gdcmDict* NewDict);
-       void LoadDictFromFile(std::string FileName, DictKey Name);
-
 public:
-   std::list<std::string> * GetPubDictTagNames(void);
-   std::map<std::string, std::list<std::string> >*
-       GetPubDictTagNamesByCategory(void);
-
        // TODO Swig int LoadDictFromFile(std::string filename);
    // QUESTION: the following function might not be thread safe !? Maybe
    //           we need some mutex here, to avoid concurent creation of
@@ -42,12 +30,29 @@ public:
        // TODO Swig std::string* GetAllDictNames();
        gdcmDictSet(void);
        ~gdcmDictSet(void);
+
        void Print(std::ostream& os);
 
-       gdcmDict* GetDict(DictKey DictName);
+   std::list<std::string> * GetPubDictTagNames(void);
+   std::map<std::string, std::list<std::string> >*
+       GetPubDictTagNamesByCategory(void);
+
+       void LoadDictFromFile(std::string FileName, DictKey Name);
+
+   gdcmDict* GetDict(DictKey DictName);
        gdcmDict* GetDefaultPubDict(void);
 
    static std::string BuildDictPath(void);
+
+protected:
+       bool AppendDict(gdcmDict* NewDict,DictKey Name);
+
+private:
+   /// Hash table of all dictionaries contained in this gdcmDictSet
+       DictSetHT Dicts;
+   /// Directory path to dictionaries
+   std::string DictPath;
 };
 
+//-----------------------------------------------------------------------------
 #endif
index 21c63c33f1f6e364a835f3e3b89a0ee2d06d2b8e..fb99ba162ba520f64605026592c75f082f6eca78 100644 (file)
@@ -1,5 +1,5 @@
 // gdcmElValSet.cxx
-
+//-----------------------------------------------------------------------------
 #include "gdcmUtil.h"
 #include "gdcmElValSet.h"
 #include "gdcmTS.h"
@@ -10,6 +10,8 @@
 #  include <sstream>
 #endif
 
+//-----------------------------------------------------------------------------
+// Constructor / Destructor
 /**
  * \ingroup gdcmElValSet
  * \brief  Destructor 
@@ -25,42 +27,13 @@ gdcmElValSet::~gdcmElValSet() {
    tagHt.clear();
 }
 
-/**
- * \ingroup gdcmElValSet
- * \brief  add a new Dicom Element pointer to 
- *         the H Table and to the chained List
- * @param   newElValue
- */
-void gdcmElValSet::Add(gdcmElValue * newElValue) {
-
-//     tagHt [newElValue->GetKey()]  = newElValue;
-
-   tagHt.insert( PairHT( newElValue->GetKey(),newElValue) );
-       
-// WARNING : push_bash in listElem ONLY during ParseHeader
-// TODO : something to allow further Elements addition 
-// position to be taken care of !      
-   listElem.push_back(newElValue); 
-}
-
-/**
- * \ingroup gdcmElValSet
- * \brief   Checks if a given Dicom Element exists
- * \        within the H table
- * @param   Group Group   number of the searched Dicom Element 
- * @param   Elem  Element number of the searched Dicom Element 
- * @return  number of occurences
- */
-int gdcmElValSet::CheckIfExistByNumber(guint16 Group, guint16 Elem ) {
-       std::string key = TranslateToKey(Group, Elem );
-       return (tagHt.count(key));
-}
-
+//-----------------------------------------------------------------------------
+// Print
 /**
  * \ingroup gdcmElValSet
  * \brief prints the Dicom Elements of the gdcmHeader
  *        using both H table and Chained List
 * @param   os The output stream to be written to.  
+ * @param   os The output stream to be written to.  
  */
 void gdcmElValSet::Print(std::ostream & os) {
 
@@ -69,11 +42,10 @@ void gdcmElValSet::Print(std::ostream & os) {
    TSKey v;
    std::string d2;
    gdcmTS * ts = gdcmGlobal::GetTS();
-   std::cout << "------------- using tagHt ---------------------" << std::endl; 
-      // Do not remove cout
    std::ostringstream s;
    
+   // Tag HT
+   s << "------------- using tagHt ---------------------" << std::endl; 
    for (TagElValueHT::iterator tag = tagHt.begin();
           tag != tagHt.end();
           ++tag){
@@ -104,13 +76,11 @@ void gdcmElValSet::Print(std::ostream & os) {
       s << std::endl;
    }
 
-   
+   // List element
    guint32 lgth;
    char greltag[10];  //group element tag
    
- std::cout << "------------ using listElem -------------------" << std::endl; 
-       // Do not remove cout
-   
+   s << "------------ using listElem -------------------" << std::endl; 
    for (ListTag::iterator i = listElem.begin();  
           i != listElem.end();
           ++i){
@@ -147,6 +117,26 @@ void gdcmElValSet::Print(std::ostream & os) {
    os<<s.str();
 } 
 
+//-----------------------------------------------------------------------------
+// Public
+/**
+ * \ingroup gdcmElValSet
+ * \brief  add a new Dicom Element pointer to 
+ *         the H Table and to the chained List
+ * @param   newElValue
+ */
+void gdcmElValSet::Add(gdcmElValue * newElValue) {
+
+//     tagHt [newElValue->GetKey()]  = newElValue;
+
+   tagHt.insert( PairHT( newElValue->GetKey(),newElValue) );
+       
+// WARNING : push_bash in listElem ONLY during ParseHeader
+// TODO : something to allow further Elements addition 
+// position to be taken care of !      
+   listElem.push_back(newElValue); 
+}
+
 /**
  * \ingroup gdcmElValSet
  * \brief  retrieves a Dicom Element (the first one) using (group, element)
@@ -179,7 +169,6 @@ std::string gdcmElValSet::GetElValueByNumber(guint16 group, guint16 element) {
    return tagHt.find(key)->second->GetValue();
 }
 
-
 /**
  * \ingroup gdcmElValSet
  * \brief  Sets the value (string) of the target Dicom Element
@@ -228,21 +217,25 @@ bool gdcmElValSet::SetElValueByNumber(std::string content,
    return true;
 }
 
-
 /**
  * \ingroup gdcmElValSet
- * \brief   Generate a free TagKey i.e. a TagKey that is not present
- *          in the TagHt dictionary.
- * @param   group The generated tag must belong to this group.  
- * @return  The element of tag with given group which is fee.
+ * \brief   Sets the value length of the Dicom Element
+ * \warning : use with caution !
+ * @param   length
+ * @param   group Group   number of the searched Dicom Element 
+ * @param   elem  Element number of the searched Dicom Element 
+ * @return  boolean
  */
-guint32 gdcmElValSet::GenerateFreeTagKeyInGroup(guint16 group) {
-   for (guint32 elem = 0; elem < UINT32_MAX; elem++) {
-      TagKey key = gdcmDictEntry::TranslateToKey(group, elem);
-      if (tagHt.count(key) == 0)
-         return elem;
-   }
-   return UINT32_MAX;
+bool gdcmElValSet::SetElValueLengthByNumber(guint32 length,
+                                           guint16 group, guint16 element) {
+   TagKey key = gdcmDictEntry::TranslateToKey(group, element);
+   if ( ! tagHt.count(key))
+      return false;
+   if (length%2) length++; // length must be even
+   //tagHt[key]->SetLength(length);
+   ( ((tagHt.equal_range(key)).first)->second )->SetLength(length);     
+        
+   return true ;               
 }
 
 /**
@@ -265,31 +258,69 @@ bool gdcmElValSet::SetVoidAreaByNumber(void * area,
 
 /**
  * \ingroup gdcmElValSet
- * \brief   Sets the value length of the Dicom Element
- * \warning : use with caution !
- * @param   length
- * @param   group Group   number of the searched Dicom Element 
- * @param   elem  Element number of the searched Dicom Element 
- * @return  boolean
+ * \brief   Generate a free TagKey i.e. a TagKey that is not present
+ *          in the TagHt dictionary.
+ * @param   group The generated tag must belong to this group.  
+ * @return  The element of tag with given group which is fee.
  */
-bool gdcmElValSet::SetElValueLengthByNumber(guint32 length,
-                                           guint16 group, guint16 element) {
-   TagKey key = gdcmDictEntry::TranslateToKey(group, element);
-   if ( ! tagHt.count(key))
-      return false;
-   if (length%2) length++; // length must be even
-   //tagHt[key]->SetLength(length);
-   ( ((tagHt.equal_range(key)).first)->second )->SetLength(length);     
-        
-   return true ;               
+guint32 gdcmElValSet::GenerateFreeTagKeyInGroup(guint16 group) {
+   for (guint32 elem = 0; elem < UINT32_MAX; elem++) {
+      TagKey key = gdcmDictEntry::TranslateToKey(group, elem);
+      if (tagHt.count(key) == 0)
+         return elem;
+   }
+   return UINT32_MAX;
 }
 
+/**
+ * \ingroup gdcmElValSet
+ * \brief   Checks if a given Dicom Element exists
+ * \        within the H table
+ * @param   Group Group   number of the searched Dicom Element 
+ * @param   Elem  Element number of the searched Dicom Element 
+ * @return  number of occurences
+ */
+int gdcmElValSet::CheckIfExistByNumber(guint16 Group, guint16 Elem ) {
+       std::string key = gdcmDictEntry::TranslateToKey(Group, Elem );
+       return (tagHt.count(key));
+}
 
 // ==============
 // TODO to be re-written using the chained list instead of the H table
 //      so we can remove the GroupHT from the gdcmHeader
 // =============
+/**
+ * \ingroup gdcmElValSet
+ * \brief   
+ * @param   _fp already open file pointer
+ * @param   type type of the File to be written 
+ *          (ACR-NEMA, ExplicitVR, ImplicitVR)
+ * @return  always "True" ?!
+ */
+bool gdcmElValSet::Write(FILE * _fp, FileType type) {
+
+       // Question :
+       // Comment pourrait-on savoir si le DcmHeader vient d'un fichier DicomV3 ou non
+       // (FileType est un champ de gdcmHeader ...)
+       // WARNING : Si on veut ecrire du DICOM V3 a partir d'un DcmHeader ACR-NEMA
+       // no way 
+        // a moins de se livrer a un tres complique ajout des champs manquants.
+        // faire un CheckAndCorrectHeader (?)
+
+   if ( (type == ImplicitVR) || (type == ExplicitVR) )
+      UpdateGroupLength(false,type);
+   if ( type == ACR)
+      UpdateGroupLength(true,ACR);
 
+   WriteElements(type, _fp);
+   return(true);
+}
+
+//-----------------------------------------------------------------------------
+// Protected
+
+//-----------------------------------------------------------------------------
+// Private
 /**
  * \ingroup gdcmElValSet
  * \brief   Re-computes the length of a ACR-NEMA/Dicom group from a DcmHeader
@@ -482,30 +513,4 @@ void gdcmElValSet::WriteElements(FileType type, FILE * _fp) {
    }
 }
 
-/**
- * \ingroup gdcmElValSet
- * \brief   
- * @param   _fp already open file pointer
- * @param   type type of the File to be written 
- *          (ACR-NEMA, ExplicitVR, ImplicitVR)
- * @return  always "True" ?!
- */
-bool gdcmElValSet::Write(FILE * _fp, FileType type) {
-
-       // Question :
-       // Comment pourrait-on savoir si le DcmHeader vient d'un fichier DicomV3 ou non
-       // (FileType est un champ de gdcmHeader ...)
-       // WARNING : Si on veut ecrire du DICOM V3 a partir d'un DcmHeader ACR-NEMA
-       // no way 
-        // a moins de se livrer a un tres complique ajout des champs manquants.
-        // faire un CheckAndCorrectHeader (?)
-
-   if ( (type == ImplicitVR) || (type == ExplicitVR) )
-      UpdateGroupLength(false,type);
-   if ( type == ACR)
-      UpdateGroupLength(true,ACR);
-
-   WriteElements(type, _fp);
-   return(true);
-}
-
+//-----------------------------------------------------------------------------
index 5dd8736cfd38bab9168957829953950af78f6083..07bea3ca6af464ede6af89848d9d1fa9d200368b 100644 (file)
@@ -1,5 +1,5 @@
-// $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.h,v 1.21 2004/01/13 11:32:30 jpr Exp $
-
+// gdcmElValSet.h
+//-----------------------------------------------------------------------------
 #ifndef GDCMELVALSET_H
 #define GDCMELVALSET_H
 
 #include <map>
 #include <list>       // for linking together *all* the Dicom Elements
 
-/*
- * Container for a set of successfully parsed ElValues (i.e. Dicom Elements).
- */
-
+//-----------------------------------------------------------------------------
 typedef std::multimap<TagKey, gdcmElValue*> TagElValueHT;
 typedef std::pair<TagKey, gdcmElValue*> PairHT;
 typedef std::pair<TagElValueHT::iterator,TagElValueHT::iterator> IterHT; 
@@ -25,57 +22,52 @@ typedef std::list<gdcmElValue*> ListTag; // for linking together the Elements
 typedef std::string GroupKey;
 typedef std::map<GroupKey, int> GroupHT;
 
-
+//-----------------------------------------------------------------------------
+/*
+ * Container for a set of successfully parsed ElValues (i.e. Dicom Elements).
+ */
 class GDCM_EXPORT gdcmElValSet {
-   TagElValueHT tagHt; // H Table (multimap), to provide fast access
-   ListTag listElem;   // chained list, to keep the 'spacial' ordering
-
 public:        
    ~gdcmElValSet();
-   void Add(gdcmElValue*);
-                       
+
    void Print(std::ostream &);
-   bool Write(FILE *fp, FileType type);
 
+   void Add(gdcmElValue*);
+                       
    gdcmElValue* GetElementByNumber(guint16 group, guint16 element);
-   //gdcmElValue* GetElementByName  (std::string); 
-   // moved to gdcmHeader
    std::string  GetElValueByNumber(guint16 group, guint16 element);
        
    bool SetElValueByNumber(std::string content, guint16 group, guint16 element);
- // bool SetElValueByName  (std::string content, std::string TagName);
- // moved to gdcmHeader
-       
    bool SetElValueLengthByNumber(guint32 l, guint16 group, guint16 element);
-   
    bool SetVoidAreaByNumber(void *a, guint16 Group, guint16 Elem );
 
    guint32 GenerateFreeTagKeyInGroup(guint16 group);
    int CheckIfExistByNumber(guint16 Group, guint16 Elem );  // int !
 
- /**
- * \ingroup gdcmElValSet
- * \brief   returns a ref to the Dicom Header H table (multimap)
- * return the Dicom Header H table
- */
-inline TagElValueHT & gdcmElValSet::GetTagHt(void)   {
-    return tagHt; 
- };
+   /**
+    * \ingroup gdcmElValSet
+    * \brief   returns a ref to the Dicom Header H table (multimap)
+    * return the Dicom Header H table
+    */
+   inline TagElValueHT & gdcmElValSet::GetTagHt(void) { return tagHt; };
+
+   /**
+    * \ingroup gdcmElValSet
+    * \brief   returns a ref to the Dicom Header chained list
+    * return the Dicom Header chained list
+    */
+   inline ListTag      & gdcmElValSet::GetListElem(void) { return listElem; };
+
+   bool Write(FILE *fp, FileType type);
 
- /**
- * \ingroup gdcmElValSet
- * \brief   returns a ref to the Dicom Header chained list
- * return the Dicom Header chained list
- */
- inline ListTag      & gdcmElValSet::GetListElem(void)  {
-      return listElem; 
- };
-       
 private:
    void UpdateGroupLength(bool SkipSequence = false, FileType type = ImplicitVR);
    void WriteElements(FileType type, FILE *);
    
-
+// Variables
+   TagElValueHT tagHt; // H Table (multimap), to provide fast access
+   ListTag listElem;   // chained list, to keep the 'spacial' ordering
 };
 
+//-----------------------------------------------------------------------------
 #endif
index ef00cd188f18712f532dd1a9ec4df8e3e10d26c9..64e3e247ef46f21066cf2331edf5f9a70870bc6c 100644 (file)
@@ -1,20 +1,33 @@
 // gdcmElValue.cxx
-
-
+//-----------------------------------------------------------------------------
 // TODO
 // A 'gdcmElValue' is actually a 'Dicom Element'.
 // WHY such a confusing name???
 //
 #include "gdcmElValue.h"
 
+//-----------------------------------------------------------------------------
+// Constructor / Destructor
 /**
  * \ingroup gdcmElValue
  * \brief   Constructor from a given gdcmDictEntry
  * @param   in Pointer to existing dictionary entry
  */
-
 gdcmElValue::gdcmElValue(gdcmDictEntry* in) {
        ImplicitVr = false;
        entry = in;
 }
 
+//-----------------------------------------------------------------------------
+// Print
+
+//-----------------------------------------------------------------------------
+// Public
+
+//-----------------------------------------------------------------------------
+// Protected
+
+//-----------------------------------------------------------------------------
+// Private
+
+//-----------------------------------------------------------------------------
index ed14eb2fce68de243c883d1327ba4d743cbd3720..7b4600a4aad273b8f72a49ab6ee7cb433ee30d34 100644 (file)
@@ -1,5 +1,5 @@
-// $Header: /cvs/public/gdcm/src/Attic/gdcmElValue.h,v 1.11 2004/01/13 11:32:30 jpr Exp $
-
+// gdcmElValue.h
+//-----------------------------------------------------------------------------
 #ifndef GDCMELVALUE_H
 #define GDCMELVALUE_H
 
@@ -8,49 +8,15 @@ class gdcmHeader;
 
 #include <stdio.h>
 
+//-----------------------------------------------------------------------------
 /*
  * The dicom header of a Dicom file contains a set of such ELement VALUES
  * (when successfuly parsed against a given Dicom dictionary)
  */
 class GDCM_EXPORT gdcmElValue {
-private:
-   gdcmDictEntry *entry;
-   guint32 UsableLength;  // Updated from ReadLength, by FixFoungLentgh()
-                          // for fixing a bug in the header or helping
-                          // the parser going on 
-                         
-   guint32 ReadLength;    // Length actually read on disk
-                          // (before FixFoundLength)
-                          // ReadLength will be updated only when
-                          // FixFoundLength actually fixes a bug in the header,
-                          // not when it performs a trick to help the Parser
-                          // going on.
-                          // *for internal* use only
-       
-   bool ImplicitVr;       // Even when reading explicit vr files, some
-                         // elements happen to be implicit. Flag them here
-                         // since we can't use the entry->vr without breaking
-                         // the underlying dictionary.
-                         
-   // FIXME: In fact we should be more specific and use :
-   // friend gdcmElValue * gdcmHeader::ReadNextElement(void);
-   friend class gdcmHeader;
-
 public:
-   std::string  value;
-   void * voidArea;  // unsecure memory area to hold 'non string' values 
-                     // (ie : Lookup Tables, overlays)
-   size_t Offset;    // Offset from the begining of file for direct user access
-       
    gdcmElValue(gdcmDictEntry*);
    
-   // inline void SetDictEntry(gdcmDictEntry *NewEntry);
-   // inline bool   IsVrUnknown(void);
-   // inline void SetImplicitVr(void);
-   // inline bool  IsImplicitVr(void);
-   // inline void SetOffset(size_t of);        
-   // inline gdcmDictEntry * GetDictEntry(void);
-   
    inline guint16      GetGroup(void)     { return entry->GetGroup();  };
    inline guint16      GetElement(void)   { return entry->GetElement();};
    inline std::string  GetKey(void)       { return entry->GetKey();    };
@@ -71,67 +37,88 @@ public:
    inline void         SetValue(std::string val) { value = val;      };
    inline void         SetVoidArea(void * area)  { voidArea = area;  };
    
-   
-  
-/**
- * \ingroup gdcmElValue
- * \brief   Sets the offset of the Dicom Element
- * \warning : use with caution !
- * @param   of offset to be set
- */
-inline void gdcmElValue::SetOffset(size_t of){ 
-   Offset = of; 
-};
+   /**
+    * \ingroup gdcmElValue
+    * \brief   Sets the offset of the Dicom Element
+    * \warning : use with caution !
+    * @param   of offset to be set
+    */
+   inline void gdcmElValue::SetOffset(size_t of) { Offset = of; };
 
-/**
- * \ingroup gdcmElValue
- * \brief   Sets the DicEntry of the current Dicom Element
- * @param   NewEntry pointer to the DictEntry
- */ 
+   /**
+    * \ingroup gdcmElValue
+    * \brief   Sets the DicEntry of the current Dicom Element
+    * @param   NewEntry pointer to the DictEntry
+    */ 
+   inline void gdcmElValue::SetDictEntry(gdcmDictEntry *NewEntry) { 
+      entry = NewEntry; 
+   };
 
-inline void gdcmElValue::SetDictEntry(gdcmDictEntry *NewEntry) { 
-   entry = NewEntry; 
-};
+   /**
+    * \ingroup gdcmElValue
+    * \brief   Sets to TRUE the ImplicitVr flag of the current Dicom Element
+    */
+   inline void gdcmElValue::SetImplicitVr(void) { 
+      ImplicitVr = true; 
+   };
+   /**
+    * \ingroup gdcmElValue
+    * \brief   tells us if the current Dicom Element was checked as ImplicitVr
+    * @return true if the current Dicom Element was checked as ImplicitVr
+    */ 
+   inline bool  gdcmElValue::IsImplicitVr(void) { 
+       return ImplicitVr; 
+    };
 
-/**
- * \ingroup gdcmElValue
- * \brief   tells us if the VR of the current Dicom Element is Unkonwn
- * @return true if the VR is unkonwn
- */ 
+   /**
+    * \ingroup gdcmElValue
+    * \brief   Gets the DicEntry of the current Dicom Element
+    * @return  the DicEntry of the current Dicom Element
+    */
+   gdcmDictEntry * gdcmElValue::GetDictEntry(void) { 
+      return entry;    
+   }; 
 
-inline bool   gdcmElValue::IsVrUnknown(void) { 
-   return entry->IsVrUnknown(); 
-};
+   /**
+    * \ingroup gdcmElValue
+    * \brief   tells us if the VR of the current Dicom Element is Unkonwn
+    * @return true if the VR is unkonwn
+    */ 
+   inline bool   gdcmElValue::IsVRUnknown(void) { 
+      return entry->IsVRUnknown(); 
+   };
 
-/**
- * \ingroup gdcmElValue
- * \brief   Sets to TRUE the ImplicitVr flag of the current Dicom Element
- */
-inline void gdcmElValue::SetImplicitVr(void) { 
-   ImplicitVr = true; 
-};
-/**
- * \ingroup gdcmElValue
- * \brief   tells us if the current Dicom Element was checked as ImplicitVr
- * @return true if the current Dicom Element was checked as ImplicitVr
- */ 
-inline bool  gdcmElValue::IsImplicitVr(void) { 
-    return ImplicitVr; 
- };
+private:
+   // FIXME: In fact we should be more specific and use :
+   // friend gdcmElValue * gdcmHeader::ReadNextElement(void);
+   friend class gdcmHeader;
 
-/**
- * \ingroup gdcmElValue
- * \brief   Gets the DicEntry of the current Dicom Element
- * @return  the DicEntry of the current Dicom Element
- */
-gdcmDictEntry * gdcmElValue::GetDictEntry(void) { 
-   return entry;    
-}; 
-       
+// Variables
+   gdcmDictEntry *entry;
+   guint32 UsableLength;  // Updated from ReadLength, by FixFoungLentgh()
+                          // for fixing a bug in the header or helping
+                          // the parser going on 
+                         
+   guint32 ReadLength;    // Length actually read on disk
+                          // (before FixFoundLength)
+                          // ReadLength will be updated only when
+                          // FixFoundLength actually fixes a bug in the header,
+                          // not when it performs a trick to help the Parser
+                          // going on.
+                          // *for internal* use only
+       
+   bool ImplicitVr;       // Even when reading explicit vr files, some
+                         // elements happen to be implicit. Flag them here
+                         // since we can't use the entry->vr without breaking
+                         // the underlying dictionary.
+                         
+
+   std::string  value;
+   void *voidArea;  // unsecure memory area to hold 'non string' values 
+                     // (ie : Lookup Tables, overlays)
+   size_t Offset;    // Offset from the begining of file for direct user access
 };
 
+//-----------------------------------------------------------------------------
 #endif
index d2d3d7cd030221b5c11ba898d5998cff8c5080eb..aeb15c0b5760038f875af775b81204be4e0fe3e8 100644 (file)
@@ -1,9 +1,12 @@
-
+// gdcmException.cxx
+//-----------------------------------------------------------------------------
 #include "gdcmException.h"
 
 #include <typeinfo>
 #include <stdio.h>
 
+//-----------------------------------------------------------------------------
+// gdcmException
 gdcmException::gdcmException(const std::string &f, const std::string& msg) throw()
 #ifdef __GNUC__
   try
@@ -17,7 +20,6 @@ catch(...) {
 #endif
 
 
-
 void gdcmException::fatal(const char *from) throw() {
   try {
     std::cerr << "Fatal: exception received in " << from 
@@ -36,7 +38,6 @@ void gdcmException::fatal(const char *from) throw() {
   }  
 }
 
-
 std::string gdcmException::getName() const throw() {
   try {
 #ifdef __GNUC__   // GNU C++ compiler class name demangling
@@ -68,12 +69,11 @@ std::string gdcmException::getName() const throw() {
   }
 }
 
-
 gdcmException::operator const char *() const throw() {
   return getName().c_str();
 }
 
-
+//-----------------------------------------------------------------------------
 std::ostream& operator<<(std::ostream &os, const gdcmException &e) {
   try {  
     os << "Exception " << e.getName() << " thrown: " << e.getError() << std::endl;
@@ -84,4 +84,4 @@ std::ostream& operator<<(std::ostream &os, const gdcmException &e) {
   return os;
 }
 
-  
+//-----------------------------------------------------------------------------
index 094cd5682b9e55fd3651c447cb1e81ccf9335cde..436d664a3dfd412d372f6ead94806655a8d430e3 100644 (file)
@@ -1,3 +1,5 @@
+// gdcmException.h
+//-----------------------------------------------------------------------------
 #ifndef GDCM_EXCEPTION_H
 #define GDCM_EXCEPTION_H
 
 #include <iostream>
 #include <exception>
 
+//-----------------------------------------------------------------------------
 /*
  * Any exception thrown in the gdcm library
  */
 class GDCM_EXPORT gdcmException : public std::exception {
- protected:
-  /// error message
-  std::string from;
-  /// error message
-  std::string error;
-
- public:
-  /*
-   * Builds an exception with minimal information: name of the thrower
-   * method and error message
-   *
-   * @param from name of the thrower
-   * @param error error description string
-   */
-  explicit gdcmException(const std::string &from, const std::string &error = "")
+public:
+   /*
+    * Builds an exception with minimal information: name of the thrower
+    * method and error message
+    *
+    * @param from name of the thrower
+    * @param error error description string
+    */
+   explicit gdcmException(const std::string &from, const std::string &error = "")
     throw();
-  
-
-  /*
-   * virtual destructor makes this class dynamic
-   */
-  virtual ~gdcmException() throw() {
-  }
-  
-  /// returns error message
-  const std::string &getError(void) const throw() {
-    return error;
-  }
 
-  /// returns exception name string
-  operator const char *() const throw();
+   /*
+    * virtual destructor makes this class dynamic
+    */
+   virtual ~gdcmException() throw() {
+   }
 
-  /// returns exception name string (overloads std::exception::what)
-  virtual const char *what() const throw() {
-    return (const char *) *this;
-  }
+   // exception caught within exception class: print error message and die
+   static void fatal(const char *from) throw();
 
+   // returns error message
+   const std::string &getError(void) const throw() {
+    return error;
+   }
 
-  /// exception caught within exception class: print error message and die
-  static void fatal(const char *from) throw();
+   // try to discover this (dynamic) class name
+   virtual std::string getName() const throw();
 
-  /// try to discover this (dynamic) class name
-  virtual std::string getName() const throw();
+   // returns exception name string (overloads std::exception::what)
+   virtual const char *what() const throw() {
+    return (const char *) *this;
+   }
 
-  friend std::ostream& operator<<(std::ostream &os, const gdcmException &e);
-  
-};
+   // returns exception name string
+   operator const char *() const throw();
 
+   friend std::ostream& operator<<(std::ostream &os, const gdcmException &e);
 
-/* prints exception stack on output stream
- * @param os output stream
- * @param e exception to print
- * @returns output stream os
- */
-std::ostream& operator<<(std::ostream &os, const gdcmException &e);
+protected:
+   // error message
+   std::string from;
+   // error message
+   std::string error;
+};
 
 
+//-----------------------------------------------------------------------------
 /*
  * File error exception thrown in the gdcm library
  */
 class GDCM_EXPORT gdcmFileError : public gdcmException {
- public:
-  /*
-   * Builds an file-related exception with minimal information: name of
-   * the thrower method and error message
-   *
-   * @param from name of the thrower
-   * @param error error description string
-   */
-  explicit gdcmFileError(const std::string &from,
-                        const std::string &error = "File error")
-    throw() : gdcmException(from, error) {
-  }
+public:
+   /*
+    * Builds an file-related exception with minimal information: name of
+    * the thrower method and error message
+    *
+    * @param from name of the thrower
+    * @param error error description string
+    */
+   explicit gdcmFileError(const std::string &from,
+                          const std::string &error = "File error")
+      throw() : gdcmException(from, error) {
+   }
 };
 
 
+//-----------------------------------------------------------------------------
 /*
  * Invalid file format exception
  */
 class GDCM_EXPORT gdcmFormatError : public gdcmException {
- public:
-  /*
-   * Builds an file-related exception with minimal information: name of
-   * the thrower method and error message
-   *
-   * @param from name of the thrower
-   * @param error error description string
-   */
-  explicit gdcmFormatError(const std::string &from,
-                          const std::string &error = "Invalid file format error")
-    throw() : gdcmException(from, error) {
-  }
+public:
+   /*
+    * Builds an file-related exception with minimal information: name of
+    * the thrower method and error message
+    *
+    * @param from name of the thrower
+    * @param error error description string
+    */
+   explicit gdcmFormatError(const std::string &from,
+                            const std::string &error = "Invalid file format error")
+      throw() : gdcmException(from, error) {
+   }
 };
 
+//-----------------------------------------------------------------------------
+/* prints exception stack on output stream
+ * @param os output stream
+ * @param e exception to print
+ * @returns output stream os
+ */
+std::ostream& operator<<(std::ostream &os, const gdcmException &e);
 
+//-----------------------------------------------------------------------------
 #endif // GDCM_EXCEPTION_H
index eb34b461e9d2926ba0458f1b527e8a8664083e58..fb042163f66476c3d17f6457a19230f262d19a6a 100644 (file)
@@ -1,10 +1,11 @@
 // gdcmFile.cxx
-
+//-----------------------------------------------------------------------------
 #include "gdcmFile.h"
 #include "gdcmUtil.h"
 #include "jpeg/ljpg/jpegless.h"
 
-/////////////////////////////////////////////////////////////////
+//-----------------------------------------------------------------------------
+// Constructor / Destructor
 /**
  * \ingroup   gdcmFile
  * \brief Constructor dedicated to writing a new DICOMV3 part10 compliant
@@ -31,7 +32,6 @@ gdcmFile::gdcmFile(gdcmHeader *header)
       SetPixelDataSizeFromHeader();
 }
 
-/////////////////////////////////////////////////////////////////
 /**
  * \ingroup   gdcmFile
  * \brief Constructor dedicated to writing a new DICOMV3 part10 compliant
@@ -66,7 +66,6 @@ gdcmFile::gdcmFile(const char * filename)
       SetPixelDataSizeFromHeader();
 }
 
-/////////////////////////////////////////////////////////////////
 /**
  * \ingroup   gdcmFile
  * \brief Destructor dedicated to writing a new DICOMV3 part10 compliant
@@ -84,7 +83,11 @@ gdcmFile::~gdcmFile(void)
    Header=NULL;
 }
 
+//-----------------------------------------------------------------------------
+// Print
 
+//-----------------------------------------------------------------------------
+// Public
 /**
  * \ingroup   gdcmFile
  * \brief     
@@ -106,6 +109,32 @@ gdcmHeader *gdcmFile::GetHeader(void)
  * @return     longueur a allouer 
  */
 void gdcmFile::SetPixelDataSizeFromHeader(void) {
+   // see PS 3.3-2003 : C.7.6.3.2.1  
+   // 
+   //   MONOCHROME1
+   //   MONOCHROME2
+   //   PALETTE COLOR
+   //   RGB
+   //   HSV  (Retired)
+   //   ARGB (Retired)
+   //   CMYK (Retired)
+   //   YBR_FULL
+   //   YBR_FULL_422 (no LUT, no Palette)
+   //   YBR_PARTIAL_422
+   //   YBR_ICT
+   //   YBR_RCT
+
+   // LUT's
+   // ex : gdcm-US-ALOKA-16.dcm
+   // 0028|1221 [OW]   [Segmented Red Palette Color Lookup Table Data]
+   // 0028|1222 [OW]   [Segmented Green Palette Color Lookup Table Data]  
+   // 0028|1223 [OW]   [Segmented Blue Palette Color Lookup Table Data]
+
+   // ex  : OT-PAL-8-face.dcm
+   // 0028|1201 [US]   [Red Palette Color Lookup Table Data]
+   // 0028|1202 [US]   [Green Palette Color Lookup Table Data]
+   // 0028|1203 [US]   [Blue Palette Color Lookup Table Data]
+
    int nb;
    std::string str_nb;
    str_nb=Header->GetPubElValByNumber(0x0028,0x0100);
@@ -128,240 +157,27 @@ void gdcmFile::SetPixelDataSizeFromHeader(void) {
    }
 }
 
-   // see PS 3.3-2003 : C.7.6.3.2.1  
-   // 
-   //   MONOCHROME1
-   //   MONOCHROME2
-   //   PALETTE COLOR
-   //   RGB
-   //   HSV  (Retired)
-   //   ARGB (Retired)
-   //   CMYK (Retired)
-   //   YBR_FULL
-   //   YBR_FULL_422 (no LUT, no Palette)
-   //   YBR_PARTIAL_422
-   //   YBR_ICT
-   //   YBR_RCT
-
-  // LUT's
-  // ex : gdcm-US-ALOKA-16.dcm
-  // 0028|1221 [OW]   [Segmented Red Palette Color Lookup Table Data]
-  // 0028|1222 [OW]   [Segmented Green Palette Color Lookup Table Data]  
-  // 0028|1223 [OW]   [Segmented Blue Palette Color Lookup Table Data]
-
-  // ex  : OT-PAL-8-face.dcm
-  // 0028|1201 [US]   [Red Palette Color Lookup Table Data]
-  // 0028|1202 [US]   [Green Palette Color Lookup Table Data]
-  // 0028|1203 [US]   [Blue Palette Color Lookup Table Data]
-
-
-/////////////////////////////////////////////////////////////////
-/**
- * \ingroup   gdcmFile
- * \brief     Returns the size (in bytes) of required memory to hold
- * \          the pixel data represented in this file, when user DOESN'T want 
- * \          to get RGB pixels image when it's stored as a PALETTE COLOR image
- * \          - the (vtk) user is supposed to know how deal with LUTs - 
- * \          warning to be used with GetImagePixelsRaw()
- * @return    The size of pixel data in bytes.
- */
-
-size_t gdcmFile::GetImageDataSizeRaw(void) {
-   return (lgrTotaleRaw);
-}
-
-/////////////////////////////////////////////////////////////////
 /**
  * \ingroup   gdcmFile
  * \brief     Returns the size (in bytes) of required memory to hold
  *            the pixel data represented in this file.
  * @return    The size of pixel data in bytes.
  */
-
 size_t gdcmFile::GetImageDataSize(void) {
    return (lgrTotale);
 }
 
-
-/////////////////////////////////////////////////////////////////
 /**
- * \ingroup gdcmFile
- * \brief   Read pixel data from disk (optionaly decompressing) into the
- *          caller specified memory location.
- * @param   destination where the pixel data should be stored.
- *
+ * \ingroup   gdcmFile
+ * \brief     Returns the size (in bytes) of required memory to hold
+ * \          the pixel data represented in this file, when user DOESN'T want 
+ * \          to get RGB pixels image when it's stored as a PALETTE COLOR image
+ * \          - the (vtk) user is supposed to know how deal with LUTs - 
+ * \          warning to be used with GetImagePixelsRaw()
+ * @return    The size of pixel data in bytes.
  */
-bool gdcmFile::ReadPixelData(void* destination) {
-
-   FILE *fp;
-
-   if ( !(fp=Header->OpenFile()))
-      return false;
-      
-   if ( fseek(fp, Header->GetPixelOffset(), SEEK_SET) == -1 ) {
-      Header->CloseFile();
-      return false;
-   }
-   
-
-   // ----------------------  Compacted File (12 Bits Per Pixel)
-
-   /* unpack 12 Bits pixels into 16 Bits pixels */
-   /* 2 pixels 12bit =     [0xABCDEF]           */
-   /* 2 pixels 16bit = [0x0ABD] + [0x0FCE]      */
-
-   if (Header->GetBitsAllocated()==12) {
-      int nbPixels = Header->GetXSize() * Header->GetYSize();
-      unsigned char b0, b1, b2;
-      
-      unsigned short int* pdestination = (unsigned short int*)destination;    
-      for(int p=0;p<nbPixels;p+=2) {
-         fread(&b0,1,1,fp);
-         fread(&b1,1,1,fp);
-         fread(&b2,1,1,fp);      
-         //Two steps is necessary to please VC++
-         *pdestination++ =  ((b0 >> 4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f);
-                       /* A */          /* B */            /* D */
-         *pdestination++ =  ((b2 & 0x0f) << 8) + ((b1 >> 4) << 4) + (b2 >> 4);
-                       /* F */          /* C */            /* E */
-                 
-       // Troubles expected on Big-Endian processors ?       
-      }
-      return(true);
-   }        
-
-   // ----------------------  Uncompressed File
-    
-   if ( !Header->IsDicomV3()                             ||
-        Header->IsImplicitVRLittleEndianTransferSyntax() ||
-        Header->IsExplicitVRLittleEndianTransferSyntax() ||
-        Header->IsExplicitVRBigEndianTransferSyntax()    ||
-        Header->IsDeflatedExplicitVRLittleEndianTransferSyntax() ) {
-
-      size_t ItemRead = fread(destination, Header->GetPixelAreaLength(), 1, fp);
-      
-      if ( ItemRead != 1 ) {
-         Header->CloseFile();
-         return false;
-      } else {
-         Header->CloseFile();
-         return true;
-      }
-   } 
-
-   // ---------------------- Run Length Encoding
-
-   if (Header->IsRLELossLessTransferSyntax()) {
-         bool res = (bool)gdcm_read_RLE_file (fp,destination);
-         return res; 
-   }  
-    
-   // --------------- SingleFrame/Multiframe JPEG Lossless/Lossy/2000 
-       
-   int nb;
-   std::string str_nb=Header->GetPubElValByNumber(0x0028,0x0100);
-   if (str_nb == GDCM_UNFOUND ) {
-      nb = 16;
-   } else {
-      nb = atoi(str_nb.c_str() );
-      if (nb == 12) nb =16;  // ?? 12 should be ACR-NEMA only ?
-   }
-
-   int nBytes= nb/8;
-   
-   int taille = Header->GetXSize() * Header->GetYSize()  
-               * Header->GetSamplesPerPixel();    
-   long fragmentBegining; // for ftell, fseek
-   
-   bool jpg2000 =     Header->IsJPEG2000();
-   bool jpgLossless = Header->IsJPEGLossless();
-    
-   bool res = true;
-   guint16 ItemTagGr,ItemTagEl;
-   int ln;  
-   
-      //  Position on begining of Jpeg Pixels
-   
-   fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
-   fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
-   if(Header->GetSwapCode()) {
-      ItemTagGr=Header->SwapShort(ItemTagGr); 
-      ItemTagEl=Header->SwapShort(ItemTagEl);            
-   }
-   fread(&ln,4,1,fp); 
-   if(Header->GetSwapCode()) 
-      ln=Header->SwapLong(ln);    // Basic Offset Table Item length
-      
-   if (ln != 0) {
-      // What is it used for ?!?
-      char *BasicOffsetTableItemValue = (char *)malloc(ln+1);        
-      fread(BasicOffsetTableItemValue,ln,1,fp); 
-   }
-   
-   // first Fragment initialisation
-   fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
-   fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
-   if(Header->GetSwapCode()) {
-      ItemTagGr=Header->SwapShort(ItemTagGr); 
-      ItemTagEl=Header->SwapShort(ItemTagEl);            
-   }
-           
-   // parsing fragments until Sequence Delim. Tag found
-                           
-   while (  ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) { 
-      // --- for each Fragment
-
-      fread(&ln,4,1,fp); 
-      if(Header->GetSwapCode()) 
-         ln=Header->SwapLong(ln);    // Fragment Item length
-   
-      fragmentBegining=ftell(fp);   
-
-      if (jpg2000) {          // JPEG 2000 :    call to ???
-         res = (bool)gdcm_read_JPEG2000_file (fp,destination);  // Not Yet written 
-
-      } // ------------------------------------- endif (JPEG2000)
-       
-      else if (jpgLossless) { // JPEG LossLess : call to xmedcom JPEG
-                  
-         JPEGLosslessDecodeImage (fp,  // Reading Fragment pixels
-                                    (unsigned short *)destination,
-                                    Header->GetPixelSize()*8* Header->GetSamplesPerPixel(),
-                                     ln);                                                         
-         res=1; // in order not to break the loop
-  
-      } // ------------------------------------- endif (JPEGLossless)
-               
-      else {                   // JPEG Lossy : call to IJG 6b
-
-         if  (Header->GetBitsStored() == 8) {
-            res = (bool)gdcm_read_JPEG_file (fp,destination);  // Reading Fragment pixels         
-         } else {
-            res = (bool)gdcm_read_JPEG_file12 (fp,destination);// Reading Fragment pixels  
-         } 
-      }  // ------------------------------------- endif (JPEGLossy)    
-         
-      if (!res) break;
-               
-      destination = (char *)destination + taille * nBytes; // location in user's memory 
-                                                           // for next fragment (if any) 
-      
-      fseek(fp,fragmentBegining,SEEK_SET); // To be sure we start 
-      fseek(fp,ln,SEEK_CUR);               // at the begining of next fragment
-      
-      ItemTagGr = ItemTagEl =0;
-      fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
-      fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
-      if(Header->GetSwapCode()) {
-         ItemTagGr=Header->SwapShort(ItemTagGr); 
-         ItemTagEl=Header->SwapShort(ItemTagEl);            
-      } 
-   
-   }     // endWhile parsing fragments until Sequence Delim. Tag found    
-   Header->CloseFile();
-   return res;
+size_t gdcmFile::GetImageDataSizeRaw(void) {
+   return (lgrTotaleRaw);
 }
 
 /**
@@ -381,27 +197,6 @@ void * gdcmFile::GetImageData (void) {
    return(PixelData);
 }
 
-/**
- * \ingroup gdcmFile
- * \brief   Allocates necessary memory, copies the pixel data
- *          (image[s]/volume[s]) to newly allocated zone.
- *          Transforms YBR pixels into RGB pixels if any
-            Transforms 3 planes R, G, B into a single RGB Plane
-           DOES NOT transform Grey plane + 3 Palettes into a RGB Plane
- * @return  Pointer to newly allocated pixel data.
- * \        NULL if alloc fails 
- */
-void * gdcmFile::GetImageDataRaw (void) {
-   if (Header->HasLUT())
-      lgrTotale /= 3;  // TODO Let gdcmHeadar user a chance 
-                       // to get the right value
-                      // Create a member lgrTotaleRaw ???
-   PixelData = (void *) malloc(lgrTotale);
-   if (PixelData)
-      GetImageDataIntoVectorRaw(PixelData, lgrTotale);
-   return(PixelData);
-}
-
 /**
  * \ingroup gdcmFile
  * \brief   Copies at most MaxSize bytes of pixel data to caller's
@@ -423,16 +218,13 @@ void * gdcmFile::GetImageDataRaw (void) {
  * @return  On success, the number of bytes actually copied. Zero on
  *          failure e.g. MaxSize is lower than necessary.
  */
-
 size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) {
-
    size_t l = GetImageDataIntoVectorRaw (destination, MaxSize);
    
    if (!Header->HasLUT())
       return lgrTotale; 
                             
-         //       from Lut R + Lut G + Lut B
-         
+   // from Lut R + Lut G + Lut B
    unsigned char * newDest = (unsigned char *)malloc(lgrTotale);
    unsigned char * a       = (unsigned char *)destination;      
    unsigned char * lutRGBA =                  Header->GetLUTRGBA();
@@ -459,8 +251,7 @@ size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) {
    Header->SetPubElValByNumber(rgb,0x0028,0x0004);
    std::string planConfig = "0"; // Planar Configuration
    Header->SetPubElValByNumber(planConfig,0x0028,0x0006);
-       
-               
+
    } else { 
             // need to make RGB Pixels (?)
              //    from grey Pixels (?!)
@@ -483,7 +274,26 @@ size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) {
    return lgrTotale; 
 }
 
-
+/**
+ * \ingroup gdcmFile
+ * \brief   Allocates necessary memory, copies the pixel data
+ *          (image[s]/volume[s]) to newly allocated zone.
+ *          Transforms YBR pixels into RGB pixels if any
+            Transforms 3 planes R, G, B into a single RGB Plane
+           DOES NOT transform Grey plane + 3 Palettes into a RGB Plane
+ * @return  Pointer to newly allocated pixel data.
+ * \        NULL if alloc fails 
+ */
+void * gdcmFile::GetImageDataRaw (void) {
+   if (Header->HasLUT())
+      lgrTotale /= 3;  // TODO Let gdcmHeadar user a chance 
+                       // to get the right value
+                      // Create a member lgrTotaleRaw ???
+   PixelData = (void *) malloc(lgrTotale);
+   if (PixelData)
+      GetImageDataIntoVectorRaw(PixelData, lgrTotale);
+   return(PixelData);
+}
 
 /**
  * \ingroup gdcmFile
@@ -497,7 +307,7 @@ size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) {
  *          (for some axis related reasons?). Hence he will have 
  *          to load the image line by line, starting from the end.
  *          VTK users hace to call GetImageData
 * \warning DOES NOT transform the Grey Plane + Palette Color (if any) 
+ * \warning DOES NOT transform the Grey Plane + Palette Color (if any) 
  *                   into a single RGB Pixels Plane
  *          the (VTK) user will manage the palettes
  *     
@@ -509,7 +319,6 @@ size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) {
  * @return  On success, the number of bytes actually copied. Zero on
  *          failure e.g. MaxSize is lower than necessary.
  */
-
 size_t gdcmFile::GetImageDataIntoVectorRaw (void* destination, size_t MaxSize) {
 
    int nb, nbu, highBit, signe;
@@ -640,13 +449,13 @@ size_t gdcmFile::GetImageDataIntoVectorRaw (void* destination, size_t MaxSize) {
          {
          if (str_PhotometricInterpretation == "YBR_FULL") { 
         
-        // Warning : YBR_FULL_422 acts as RGB
-         //         : we need to make RGB Pixels from Planes Y,cB,cR
-         // see http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf
-         // for code optimisation
+   // Warning : YBR_FULL_422 acts as RGB
+   //         : we need to make RGB Pixels from Planes Y,cB,cR
+   // see http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf
+   // for code optimisation
         
         // to see the tricks about YBR_FULL, YBR_FULL_422, 
-         // YBR_PARTIAL_422, YBR_ICT, YBR_RCT have a look at :
+    // YBR_PARTIAL_422, YBR_ICT, YBR_RCT have a look at :
         //   ftp://medical.nema.org/medical/dicom/final/sup61_ft.pdf
         // and be *very* affraid
         //
@@ -688,7 +497,7 @@ size_t gdcmFile::GetImageDataIntoVectorRaw (void* destination, size_t MaxSize) {
         } else {
          
          //       need to make RGB Pixels from R,G,B Planes
-        //       (all the Frames at a time)
+         //       (all the Frames at a time)
 
             int l = Header->GetXSize()*Header->GetYSize()*Header->GetZSize();
 
@@ -713,15 +522,13 @@ size_t gdcmFile::GetImageDataIntoVectorRaw (void* destination, size_t MaxSize) {
      
        case 2:                      
          //       Palettes were found
-        //       Let the user deal with them !
-         return lgrTotale;        
+         //       Let the user deal with them !
+         return lgrTotale;        
    } 
-            // now, it's an RGB image
-            // Lets's write it in the Header
-
-         // CreateOrReplaceIfExist ?
-        
+   // now, it's an RGB image
+   // Lets's write it in the Header
 
+   // CreateOrReplaceIfExist ?
 
    std::string spp = "3";        // Samples Per Pixel
    Header->SetPubElValByNumber(spp,0x0028,0x0002);
@@ -732,92 +539,9 @@ size_t gdcmFile::GetImageDataIntoVectorRaw (void* destination, size_t MaxSize) {
    Header->SetPubElValByNumber(planConfig,0x0028,0x0006);
         
         // TODO : Drop Palette Color out of the Header? 
-            
    return lgrTotale; 
 }
 
-
-
-/**
- * \ingroup gdcmFile
- * \brief   Swap the bytes, according to swap code.
- * \warning not end user intended
- * @param   im area to deal with
- * @param   swap swap code
- * @param   lgr Area Length
- * @param   nb Pixels Bit number 
- */
-
-void gdcmFile::SwapZone(void* im, int swap, int lgr, int nb) {
-guint32 s32;
-guint16 fort,faible;
-int i;
-
-if(nb == 16)  
-   switch(swap) {
-      case 0:
-      case 12:
-      case 1234:
-         break;
-               
-      case 21:
-      case 3412:
-      case 2143:
-      case 4321:
-
-         for(i=0;i<lgr;i++)
-            ((unsigned short int*)im)[i]= ((((unsigned short int*)im)[i])>>8)
-                                        | ((((unsigned short int*)im)[i])<<8);
-         break;
-                       
-      default:
-         printf("valeur de SWAP (16 bits) not allowed : %d\n", swap);
-   } 
-if( nb == 32 )
-   switch (swap) {
-      case 0:
-      case 1234:
-         break;
-
-      case 4321:
-         for(i=0;i<lgr;i++) {
-            faible=  ((unsigned long int*)im)[i]&0x0000ffff;    /* 4321 */
-            fort  =((unsigned long int*)im)[i]>>16;
-            fort=  (fort>>8)   | (fort<<8);
-            faible=(faible>>8) | (faible<<8);
-            s32=faible;
-            ((unsigned long int*)im)[i]=(s32<<16)|fort;
-         }
-         break;
-
-      case 2143:
-         for(i=0;i<lgr;i++) {
-            faible=  ((unsigned long int*)im)[i]&0x0000ffff;    /* 2143 */
-            fort=((unsigned long int*)im)[i]>>16;
-            fort=  (fort>>8)   | (fort<<8);
-            faible=(faible>>8) | (faible<<8);
-            s32=fort; 
-            ((unsigned long int*)im)[i]=(s32<<16)|faible;
-         }
-         break;
-  
-      case 3412:
-         for(i=0;i<lgr;i++) {
-            faible=  ((unsigned long int*)im)[i]&0x0000ffff;    /* 3412 */
-            fort=((unsigned long int*)im)[i]>>16;                  
-            s32=faible; 
-            ((unsigned long int*)im)[i]=(s32<<16)|fort;
-         }                 
-         break; 
-                               
-      default:
-         printf(" SWAP value (32 bits) not allowed : %d\n", swap);
-   } 
-return;
-}
-
-/////////////////////////////////////////////////////////////////
 /**
  * \ingroup   gdcmFile
  * \brief TODO JPR
@@ -836,8 +560,6 @@ bool gdcmFile::SetImageData(void * inData, size_t ExpectedSize) {
    return(true);
 }
 
-
-/////////////////////////////////////////////////////////////////
 /**
  * \ingroup   gdcmFile
  * \brief Ecrit sur disque les pixels d'UNE image
@@ -861,7 +583,6 @@ bool gdcmFile::WriteRawData (std::string fileName) {
    return(true);
 }
 
-/////////////////////////////////////////////////////////////////
 /**
  * \ingroup   gdcmFile
  * \brief Ecrit sur disque UNE image Dicom
@@ -877,7 +598,6 @@ bool gdcmFile::WriteDcmImplVR (std::string fileName) {
    return WriteBase(fileName, ImplicitVR);
 }
 
-/////////////////////////////////////////////////////////////////
 /**
  * \ingroup   gdcmFile
  * \brief  
@@ -889,7 +609,6 @@ bool gdcmFile::WriteDcmImplVR (const char* fileName) {
    return WriteDcmImplVR (std::string (fileName));
 }
        
-/////////////////////////////////////////////////////////////////
 /**
  * \ingroup   gdcmFile
  * \brief  
@@ -901,7 +620,6 @@ bool gdcmFile::WriteDcmExplVR (std::string fileName) {
    return WriteBase(fileName, ExplicitVR);
 }
        
-/////////////////////////////////////////////////////////////////
 /**
  * \ingroup   gdcmFile
  * \brief  Ecrit au format ACR-NEMA sur disque l'entete et les pixels
@@ -921,7 +639,8 @@ bool gdcmFile::WriteAcr (std::string fileName) {
    return WriteBase(fileName, ACR);
 }
 
-/////////////////////////////////////////////////////////////////
+//-----------------------------------------------------------------------------
+// Protected
 /**
  * \ingroup   gdcmFile
  *
@@ -981,3 +700,258 @@ bool gdcmFile::WriteBase (std::string FileName, FileType type) {
    fclose (fp1);
    return(true);
 }
+
+//-----------------------------------------------------------------------------
+// Private
+/**
+ * \ingroup gdcmFile
+ * \brief   Swap the bytes, according to swap code.
+ * \warning not end user intended
+ * @param   im area to deal with
+ * @param   swap swap code
+ * @param   lgr Area Length
+ * @param   nb Pixels Bit number 
+ */
+void gdcmFile::SwapZone(void* im, int swap, int lgr, int nb) {
+guint32 s32;
+guint16 fort,faible;
+int i;
+
+if(nb == 16)  
+   switch(swap) {
+      case 0:
+      case 12:
+      case 1234:
+         break;
+               
+      case 21:
+      case 3412:
+      case 2143:
+      case 4321:
+
+         for(i=0;i<lgr;i++)
+            ((unsigned short int*)im)[i]= ((((unsigned short int*)im)[i])>>8)
+                                        | ((((unsigned short int*)im)[i])<<8);
+         break;
+                       
+      default:
+         printf("valeur de SWAP (16 bits) not allowed : %d\n", swap);
+   } 
+if( nb == 32 )
+   switch (swap) {
+      case 0:
+      case 1234:
+         break;
+
+      case 4321:
+         for(i=0;i<lgr;i++) {
+            faible=  ((unsigned long int*)im)[i]&0x0000ffff;    /* 4321 */
+            fort  =((unsigned long int*)im)[i]>>16;
+            fort=  (fort>>8)   | (fort<<8);
+            faible=(faible>>8) | (faible<<8);
+            s32=faible;
+            ((unsigned long int*)im)[i]=(s32<<16)|fort;
+         }
+         break;
+
+      case 2143:
+         for(i=0;i<lgr;i++) {
+            faible=  ((unsigned long int*)im)[i]&0x0000ffff;    /* 2143 */
+            fort=((unsigned long int*)im)[i]>>16;
+            fort=  (fort>>8)   | (fort<<8);
+            faible=(faible>>8) | (faible<<8);
+            s32=fort; 
+            ((unsigned long int*)im)[i]=(s32<<16)|faible;
+         }
+         break;
+  
+      case 3412:
+         for(i=0;i<lgr;i++) {
+            faible=  ((unsigned long int*)im)[i]&0x0000ffff;    /* 3412 */
+            fort=((unsigned long int*)im)[i]>>16;                  
+            s32=faible; 
+            ((unsigned long int*)im)[i]=(s32<<16)|fort;
+         }                 
+         break; 
+                               
+      default:
+         printf(" SWAP value (32 bits) not allowed : %d\n", swap);
+   } 
+return;
+}
+
+/**
+ * \ingroup gdcmFile
+ * \brief   Read pixel data from disk (optionaly decompressing) into the
+ *          caller specified memory location.
+ * @param   destination where the pixel data should be stored.
+ *
+ */
+bool gdcmFile::ReadPixelData(void* destination) {
+
+   FILE *fp;
+
+   if ( !(fp=Header->OpenFile()))
+      return false;
+      
+   if ( fseek(fp, Header->GetPixelOffset(), SEEK_SET) == -1 ) {
+      Header->CloseFile();
+      return false;
+   }
+   
+
+   // ----------------------  Compacted File (12 Bits Per Pixel)
+   /* unpack 12 Bits pixels into 16 Bits pixels */
+   /* 2 pixels 12bit =     [0xABCDEF]           */
+   /* 2 pixels 16bit = [0x0ABD] + [0x0FCE]      */
+   if (Header->GetBitsAllocated()==12) {
+      int nbPixels = Header->GetXSize() * Header->GetYSize();
+      unsigned char b0, b1, b2;
+      
+      unsigned short int* pdestination = (unsigned short int*)destination;    
+      for(int p=0;p<nbPixels;p+=2) {
+         fread(&b0,1,1,fp);
+         fread(&b1,1,1,fp);
+         fread(&b2,1,1,fp);      
+         //Two steps is necessary to please VC++
+         *pdestination++ =  ((b0 >> 4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f);
+                       /* A */          /* B */            /* D */
+         *pdestination++ =  ((b2 & 0x0f) << 8) + ((b1 >> 4) << 4) + (b2 >> 4);
+                       /* F */          /* C */            /* E */
+                 
+       // Troubles expected on Big-Endian processors ?       
+      }
+      return(true);
+   }        
+
+   // ----------------------  Uncompressed File
+   if ( !Header->IsDicomV3()                             ||
+        Header->IsImplicitVRLittleEndianTransferSyntax() ||
+        Header->IsExplicitVRLittleEndianTransferSyntax() ||
+        Header->IsExplicitVRBigEndianTransferSyntax()    ||
+        Header->IsDeflatedExplicitVRLittleEndianTransferSyntax() ) {
+
+      size_t ItemRead = fread(destination, Header->GetPixelAreaLength(), 1, fp);
+      
+      if ( ItemRead != 1 ) {
+         Header->CloseFile();
+         return false;
+      } else {
+         Header->CloseFile();
+         return true;
+      }
+   } 
+
+   // ---------------------- Run Length Encoding
+   if (Header->IsRLELossLessTransferSyntax()) {
+         bool res = (bool)gdcm_read_RLE_file (fp,destination);
+         return res; 
+   }  
+    
+   // --------------- SingleFrame/Multiframe JPEG Lossless/Lossy/2000 
+   int nb;
+   std::string str_nb=Header->GetPubElValByNumber(0x0028,0x0100);
+   if (str_nb == GDCM_UNFOUND ) {
+      nb = 16;
+   } else {
+      nb = atoi(str_nb.c_str() );
+      if (nb == 12) nb =16;  // ?? 12 should be ACR-NEMA only ?
+   }
+
+   int nBytes= nb/8;
+   
+   int taille = Header->GetXSize() * Header->GetYSize()  
+               * Header->GetSamplesPerPixel();    
+   long fragmentBegining; // for ftell, fseek
+   
+   bool jpg2000 =     Header->IsJPEG2000();
+   bool jpgLossless = Header->IsJPEGLossless();
+    
+   bool res = true;
+   guint16 ItemTagGr,ItemTagEl;
+   int ln;  
+   
+      //  Position on begining of Jpeg Pixels
+   
+   fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
+   fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
+   if(Header->GetSwapCode()) {
+      ItemTagGr=Header->SwapShort(ItemTagGr); 
+      ItemTagEl=Header->SwapShort(ItemTagEl);            
+   }
+   fread(&ln,4,1,fp); 
+   if(Header->GetSwapCode()) 
+      ln=Header->SwapLong(ln);    // Basic Offset Table Item length
+      
+   if (ln != 0) {
+      // What is it used for ?!?
+      char *BasicOffsetTableItemValue = (char *)malloc(ln+1);        
+      fread(BasicOffsetTableItemValue,ln,1,fp); 
+   }
+   
+   // first Fragment initialisation
+   fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
+   fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
+   if(Header->GetSwapCode()) {
+      ItemTagGr=Header->SwapShort(ItemTagGr); 
+      ItemTagEl=Header->SwapShort(ItemTagEl);            
+   }
+           
+   // parsing fragments until Sequence Delim. Tag found
+   while (  ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) { 
+      // --- for each Fragment
+
+      fread(&ln,4,1,fp); 
+      if(Header->GetSwapCode()) 
+         ln=Header->SwapLong(ln);    // Fragment Item length
+   
+      fragmentBegining=ftell(fp);   
+
+      if (jpg2000) {          // JPEG 2000 :    call to ???
+         res = (bool)gdcm_read_JPEG2000_file (fp,destination);  // Not Yet written 
+
+      } // ------------------------------------- endif (JPEG2000)
+       
+      else if (jpgLossless) { // JPEG LossLess : call to xmedcom JPEG
+                  
+         JPEGLosslessDecodeImage (fp,  // Reading Fragment pixels
+                                    (unsigned short *)destination,
+                                    Header->GetPixelSize()*8* Header->GetSamplesPerPixel(),
+                                     ln);                                                         
+         res=1; // in order not to break the loop
+  
+      } // ------------------------------------- endif (JPEGLossless)
+               
+      else {                   // JPEG Lossy : call to IJG 6b
+
+         if  (Header->GetBitsStored() == 8) {
+            res = (bool)gdcm_read_JPEG_file (fp,destination);  // Reading Fragment pixels         
+         } else {
+            res = (bool)gdcm_read_JPEG_file12 (fp,destination);// Reading Fragment pixels  
+         } 
+      }  // ------------------------------------- endif (JPEGLossy)    
+         
+      if (!res) break;
+               
+      destination = (char *)destination + taille * nBytes; // location in user's memory 
+                                                           // for next fragment (if any) 
+      
+      fseek(fp,fragmentBegining,SEEK_SET); // To be sure we start 
+      fseek(fp,ln,SEEK_CUR);               // at the begining of next fragment
+      
+      ItemTagGr = ItemTagEl =0;
+      fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
+      fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
+      if(Header->GetSwapCode()) {
+         ItemTagGr=Header->SwapShort(ItemTagGr); 
+         ItemTagEl=Header->SwapShort(ItemTagEl);            
+      } 
+   
+   }     // endWhile parsing fragments until Sequence Delim. Tag found    
+   Header->CloseFile();
+   return res;
+}
+//-----------------------------------------------------------------------------
index fb2cbc419563d31fda18f0a7663c00f092b9a5cc..6773662c46f08f9d47ec7a75682d508d63239b9d 100644 (file)
@@ -1,11 +1,12 @@
 // gdcmFile.h
-
+//-----------------------------------------------------------------------------
 #ifndef GDCMFILE_H
 #define GDCMFILE_H
 
 #include "gdcmCommon.h"
 #include "gdcmHeader.h"
 
+//-----------------------------------------------------------------------------
 /*
  * In addition to Dicom header exploration, this class is designed
  * for accessing the image/volume content. One can also use it to
  */
 class GDCM_EXPORT gdcmFile
 {
-private:
-   gdcmHeader *Header;   // Header to use to load the file
-   bool SelfHeader;
-
-   void* PixelData;
-   size_t lgrTotaleRaw;  // Area length to receive the pixels
-   size_t lgrTotale;     // Area length to receive the RGB pixels
-                         // from Grey Plane + Palette Color
-
-   int Parsed;               // weather already parsed
-   std::string OrigFileName; // To avoid file overwrite
-   void SwapZone(void* im, int swap, int lgr, int nb);
-   
-   bool ReadPixelData(void * destination);
-   
-   bool gdcm_read_JPEG_file     (FILE *fp,void * image_buffer); // For JPEG 8 Bits
-   bool gdcm_read_JPEG_file12   (FILE *fp,void * image_buffer); // For JPEG 12 Bits
-   bool gdcm_read_JPEG2000_file (FILE *fp,void * image_buffer); // For JPEG 2000 (TODO)
-
-// For Run Length Encoding (TOCHECK)
-   bool gdcm_read_RLE_file      (FILE *fp,void * image_buffer); 
-
-protected:
-   bool WriteBase(std::string FileName, FileType type);
-
 public:
    gdcmFile(gdcmHeader *header);
    gdcmFile(std::string & filename);
@@ -58,6 +34,7 @@ public:
    void   SetPixelDataSizeFromHeader(void);
    size_t GetImageDataSize();
    size_t GetImageDataSizeRaw();
+
    void * GetImageData();
    size_t GetImageDataIntoVector(void* destination, size_t MaxSize);
    void * GetImageDataRaw();
@@ -79,17 +56,50 @@ public:
        // incohérente avec l'ordre des octets en mémoire ? 
        // TODO Swig int Write();
        
-       // Ecrit sur disque les pixels d'UNE image
-       // Aucun test n'est fait sur l'"Endiannerie" du processeur.
-       // Ca sera Ã  l'utilisateur d'appeler son Reader correctement
-               
+   // Write pixels of ONE image on hard drive
+   // No test is made on processor "stupidity"
+   // The user must call his reader correctly
    bool WriteRawData  (std::string fileName);
    bool WriteDcmImplVR(std::string fileName);
    bool WriteDcmImplVR(const char * fileName);
    bool WriteDcmExplVR(std::string fileName);
    bool WriteAcr      (std::string fileName);
    
+protected:
+   bool WriteBase(std::string FileName, FileType type);
+
+   // Body in file gdcmParse.cxx
    bool ParsePixelData(void);
+
+private:
+   void SwapZone(void* im, int swap, int lgr, int nb);
+   
+   bool ReadPixelData(void * destination);
+   
+   // For JPEG 8 Bits, body in file gdcmJpeg.cxx
+   bool gdcm_read_JPEG_file     (FILE *fp,void * image_buffer); 
+   static int gdcm_read_RLE_fragment(char **areaToRead, long lengthToDecode, 
+                                     long uncompressedSegmentSize,FILE *fp);
+   // For JPEG 12 Bits, body in file gdcmJpeg12.cxx
+   bool gdcm_read_JPEG_file12   (FILE *fp,void * image_buffer);
+   // For JPEG 2000, body in file gdcmJpeg2000.cxx
+   bool gdcm_read_JPEG2000_file (FILE *fp,void * image_buffer);
+
+   // For Run Length Encoding (TOCHECK)
+   bool gdcm_read_RLE_file      (FILE *fp,void * image_buffer); 
+
+// Variables
+   gdcmHeader *Header;   // Header to use to load the file
+   bool SelfHeader;
+
+   void* PixelData;
+   size_t lgrTotaleRaw;  // Area length to receive the pixels
+   size_t lgrTotale;     // Area length to receive the RGB pixels
+                         // from Grey Plane + Palette Color
+
+   int Parsed;               // weather already parsed
+   std::string OrigFileName; // To avoid file overwrite
 };
 
+//-----------------------------------------------------------------------------
 #endif
index a6f4c58eb49e9bbaf289066f9f05564a0fca9d50..cbe330c01823c36c7d54dbd8e49483dcf1e4b990 100644 (file)
@@ -1,5 +1,5 @@
-// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.cxx,v 1.123 2004/01/13 11:32:30 jpr Exp $
-
+// gdcmHeader.cxx
+//-----------------------------------------------------------------------------
 #include "gdcmHeader.h"
 
 #include <stdio.h>
 #include "gdcmUtil.h"
 #include "gdcmTS.h"
 
+//-----------------------------------------------------------------------------
 // Refer to gdcmHeader::CheckSwap()
-#define HEADER_LENGTH_TO_READ       256
+const unsigned int gdcmHeader::HEADER_LENGTH_TO_READ = 256;
+
 // Refer to gdcmHeader::SetMaxSizeLoadElementValue()
-#define _MaxSizeLoadElementValue_   4096
-/**
- * \ingroup gdcmHeader
- * \brief   
- */
-void gdcmHeader::Initialise(void) {
-   dicom_vr = gdcmGlobal::GetVR();
-   dicom_ts = gdcmGlobal::GetTS();
-   Dicts    = gdcmGlobal::GetDicts();
-   RefPubDict = Dicts->GetDefaultPubDict();
-   RefShaDict = (gdcmDict*)0;
-}
+const unsigned int gdcmHeader::MAX_SIZE_LOAD_ELEMENT_VALUE = 4096;
 
+//-----------------------------------------------------------------------------
+// Constructor / Destructor
 /**
  * \ingroup gdcmHeader
  * \brief   
@@ -45,8 +38,7 @@ void gdcmHeader::Initialise(void) {
  * @param   exception_on_error
  * @param   enable_sequences = true to allow the header 
  *          to be parsed *inside* the SeQuences, 
- *          when they have an actual length
- the 
+ *          when they have an actual length 
  */
 gdcmHeader::gdcmHeader(const char *InFilename, 
                        bool exception_on_error,
@@ -56,7 +48,7 @@ gdcmHeader::gdcmHeader(const char *InFilename,
    else
       enableSequences = 0;
    
-   SetMaxSizeLoadElementValue(_MaxSizeLoadElementValue_);
+   SetMaxSizeLoadElementValue(MAX_SIZE_LOAD_ELEMENT_VALUE);
    filename = InFilename;
    Initialise();
    if ( !OpenFile(exception_on_error))
@@ -72,373 +64,192 @@ gdcmHeader::gdcmHeader(const char *InFilename,
  * @param   exception_on_error
  */
 gdcmHeader::gdcmHeader(bool exception_on_error) {
-  SetMaxSizeLoadElementValue(_MaxSizeLoadElementValue_);
+  SetMaxSizeLoadElementValue(MAX_SIZE_LOAD_ELEMENT_VALUE);
   Initialise();
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   
- * @param   exception_on_error
- * @return  
+ * \brief   Canonical destructor.
  */
-FILE *gdcmHeader::OpenFile(bool exception_on_error)
-  throw(gdcmFileError) {
-  fp=fopen(filename.c_str(),"rb");
-  if(exception_on_error) {
-    if(!fp)
-      throw gdcmFileError("gdcmHeader::gdcmHeader(const char *, bool)");
-  }
+gdcmHeader::~gdcmHeader (void) {
+  dicom_vr =   (gdcmVR*)0; 
+  Dicts    =   (gdcmDictSet*)0;
+  RefPubDict = (gdcmDict*)0;
+  RefShaDict = (gdcmDict*)0;
+  return;
+}
 
-  if ( fp ) {
-     guint16 zero;
-     fread(&zero,  (size_t)2, (size_t)1, fp);
+//-----------------------------------------------------------------------------
+// Print
+/**
+  * \ingroup gdcmHeader
+  * \brief
+  * @return
+  */ 
+void gdcmHeader::PrintPubElVal(std::ostream & os) {
+   PubElValSet.Print(os);
+}
 
-    //ACR -- or DICOM with no Preamble
-    if( zero == 0x0008 || zero == 0x0800 || zero == 0x0002 || zero == 0x0200)
-       return(fp);
+/**
+  * \ingroup gdcmHeader
+  * \brief 
+  * @return
+  */  
+void gdcmHeader::PrintPubDict(std::ostream & os) {
+   RefPubDict->Print(os);
+}
 
-    //DICOM
-    fseek(fp, 126L, SEEK_CUR);
-    char dicm[4];
-    fread(dicm,  (size_t)4, (size_t)1, fp);
-    if( memcmp(dicm, "DICM", 4) == 0 )
-       return(fp);
+//-----------------------------------------------------------------------------
+// Public
+/**
+ * \ingroup gdcmHeader
+ * \brief  This predicate, based on hopefully reasonable heuristics,
+ *         decides whether or not the current gdcmHeader was properly parsed
+ *         and contains the mandatory information for being considered as
+ *         a well formed and usable image.
+ * @return true when gdcmHeader is the one of a reasonable Dicom file,
+ *         false otherwise. 
+ */
+bool gdcmHeader::IsReadable(void) {
+   std::string res = GetPubElValByNumber(0x0028, 0x0005);
+   if (       res != GDCM_UNFOUND
+      && atoi(res.c_str()) > 4 ) {
+      return false; // Image Dimensions
+   }
+   if ( GetPubElValByNumber(0x0028, 0x0100) == GDCM_UNFOUND )
+      return false; // "Bits Allocated"
+   if ( GetPubElValByNumber(0x0028, 0x0101) == GDCM_UNFOUND )
+      return false; // "Bits Stored"
+   if ( GetPubElValByNumber(0x0028, 0x0102) == GDCM_UNFOUND )
+      return false; // "High Bit"
+   if ( GetPubElValByNumber(0x0028, 0x0103) == GDCM_UNFOUND )
+      return false; // "Pixel Representation"
+   return true;
+}
 
-    fclose(fp);
-    dbg.Verbose(0, "gdcmHeader::gdcmHeader not DICOM/ACR", filename.c_str());
-  }
-  else {
-    dbg.Verbose(0, "gdcmHeader::gdcmHeader cannot open file", filename.c_str());
-  }
-  return(NULL);
+/**
+ * \ingroup gdcmHeader
+ * \brief   Determines if the Transfer Syntax was already encountered
+ *          and if it corresponds to a ImplicitVRLittleEndian one.
+ *
+ * @return  True when ImplicitVRLittleEndian found. False in all other cases.
+ */
+bool gdcmHeader::IsImplicitVRLittleEndianTransferSyntax(void) {
+   gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
+   if ( !Element )
+      return false;
+   LoadElementValueSafe(Element);
+   std::string Transfer = Element->GetValue();
+   if ( Transfer == "1.2.840.10008.1.2" )
+      return true;
+   return false;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   
- * @return  TRUE if the close was successfull 
+ * \brief   Determines if the Transfer Syntax was already encountered
+ *          and if it corresponds to a ExplicitVRLittleEndian one.
+ *
+ * @return  True when ExplicitVRLittleEndian found. False in all other cases.
  */
-bool gdcmHeader::CloseFile(void) {
-  int closed = fclose(fp);
-  fp = (FILE *)0;
-  if (! closed)
-     return false;
-  return true;
+bool gdcmHeader::IsExplicitVRLittleEndianTransferSyntax(void) {
+   gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
+   if ( !Element )
+      return false;
+   LoadElementValueSafe(Element);
+   std::string Transfer = Element->GetValue();
+   if ( Transfer == "1.2.840.10008.1.2.1" )
+      return true;
+   return false;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Canonical destructor.
+ * \brief   Determines if the Transfer Syntax was already encountered
+ *          and if it corresponds to a DeflatedExplicitVRLittleEndian one.
+ *
+ * @return  True when DeflatedExplicitVRLittleEndian found. False in all other cases.
  */
-gdcmHeader::~gdcmHeader (void) {
-  dicom_vr =   (gdcmVR*)0; 
-  Dicts    =   (gdcmDictSet*)0;
-  RefPubDict = (gdcmDict*)0;
-  RefShaDict = (gdcmDict*)0;
+bool gdcmHeader::IsDeflatedExplicitVRLittleEndianTransferSyntax(void) {
+   gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
+   if ( !Element )
+      return false;
+   LoadElementValueSafe(Element);
+   std::string Transfer = Element->GetValue();
+   if ( Transfer == "1.2.840.10008.1.2.1.99" )
+      return true;
+   return false;
+}
 
+/**
+ * \ingroup gdcmHeader
+ * \brief   Determines if the Transfer Syntax was already encountered
+ *          and if it corresponds to a Explicit VR Big Endian one.
+ *
+ * @return  True when big endian found. False in all other cases.
+ */
+bool gdcmHeader::IsExplicitVRBigEndianTransferSyntax(void) {
+   gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
+   if ( !Element )
+      return false;
+   LoadElementValueSafe(Element);
+   std::string Transfer = Element->GetValue();
+   if ( Transfer == "1.2.840.10008.1.2.2" )  //1.2.2 ??? A verifier !
+      return true;
+   return false;
+}
 
-  return;
+/**
+ * \ingroup gdcmHeader
+ * \brief   Determines if the Transfer Syntax was already encountered
+ *          and if it corresponds to a JPEGBaseLineProcess1 one.
+ *
+ * @return  True when JPEGBaseLineProcess1found. False in all other cases.
+ */
+bool gdcmHeader::IsJPEGBaseLineProcess1TransferSyntax(void) {
+   gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
+   if ( !Element )
+      return false;
+   LoadElementValueSafe(Element);
+   std::string Transfer = Element->GetValue();
+   if ( Transfer == "1.2.840.10008.1.2.4.50" )
+      return true;
+   return false;
 }
 
-// Fourth semantics:
-//
-// ---> Warning : This fourth field is NOT part 
-//                of the 'official' Dicom Dictionnary
-//                and should NOT be used.
-//                (Not defined for all the groups
-//                 may be removed in a future release)
-//
-// CMD      Command        
-// META     Meta Information 
-// DIR      Directory
-// ID
-// PAT      Patient
-// ACQ      Acquisition
-// REL      Related
-// IMG      Image
-// SDY      Study
-// VIS      Visit 
-// WAV      Waveform
-// PRC
-// DEV      Device
-// NMI      Nuclear Medicine
-// MED
-// BFS      Basic Film Session
-// BFB      Basic Film Box
-// BIB      Basic Image Box
-// BAB
-// IOB
-// PJ
-// PRINTER
-// RT       Radio Therapy
-// DVH   
-// SSET
-// RES      Results
-// CRV      Curve
-// OLY      Overlays
-// PXL      Pixels
-// DL       Delimiters
-//
+/**
+ * \ingroup gdcmHeader
+ * \brief   Determines if the Transfer Syntax was already encountered
+ *          and if it corresponds to a JPEGExtendedProcess2-4 one.
+ *
+ * @return  True when JPEGExtendedProcess2-4 found. False in all other cases.
+ */
+bool gdcmHeader::IsJPEGExtendedProcess2_4TransferSyntax(void) {
+   gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
+   if ( !Element )
+      return false;
+   LoadElementValueSafe(Element);
+   std::string Transfer = Element->GetValue();
+   if ( Transfer == "1.2.840.10008.1.2.4.51" )
+      return true;
+   return false;
+}
 
 /**
  * \ingroup gdcmHeader
- * \brief   Discover what the swap code is (among little endian, big endian,
- *          bad little endian, bad big endian).
+ * \brief   Determines if the Transfer Syntax was already encountered
+ *          and if it corresponds to a JPEGExtendeProcess3-5 one.
  *
+ * @return  True when JPEGExtendedProcess3-5 found. False in all other cases.
  */
-void gdcmHeader::CheckSwap()
-{
-   // The only guaranted way of finding the swap code is to find a
-   // group tag since we know it's length has to be of four bytes i.e.
-   // 0x00000004. Finding the swap code in then straigthforward. Trouble
-   // occurs when we can't find such group...
-   guint32  s;
-   guint32  x=4;  // x : for ntohs
-   bool net2host; // true when HostByteOrder is the same as NetworkByteOrder
-    
-   int lgrLue;
-   char * entCur;
-   char deb[HEADER_LENGTH_TO_READ];
-    
-   // First, compare HostByteOrder and NetworkByteOrder in order to
-   // determine if we shall need to swap bytes (i.e. the Endian type).
-   if (x==ntohs(x))
-      net2host = true;
-   else
-      net2host = false; 
-    //cout << net2host << endl;
-         
-   // The easiest case is the one of a DICOM header, since it possesses a
-   // file preamble where it suffice to look for the string "DICM".
-   lgrLue = fread(deb, 1, HEADER_LENGTH_TO_READ, fp);
-   
-   entCur = deb + 128;
-   if(memcmp(entCur, "DICM", (size_t)4) == 0) {
-      dbg.Verbose(1, "gdcmHeader::CheckSwap:", "looks like DICOM Version3");
-      // Next, determine the value representation (VR). Let's skip to the
-      // first element (0002, 0000) and check there if we find "UL" 
-      // - or "OB" if the 1st one is (0002,0001) -,
-      // in which case we (almost) know it is explicit VR.
-      // WARNING: if it happens to be implicit VR then what we will read
-      // is the length of the group. If this ascii representation of this
-      // length happens to be "UL" then we shall believe it is explicit VR.
-      // FIXME: in order to fix the above warning, we could read the next
-      // element value (or a couple of elements values) in order to make
-      // sure we are not commiting a big mistake.
-      // We need to skip :
-      // * the 128 bytes of File Preamble (often padded with zeroes),
-      // * the 4 bytes of "DICM" string,
-      // * the 4 bytes of the first tag (0002, 0000),or (0002, 0001)
-      // i.e. a total of  136 bytes.
-      entCur = deb + 136;
-      // FIXME
-      // Use gdcmHeader::dicom_vr to test all the possibilities
-      // instead of just checking for UL, OB and UI !?
-      if(  (memcmp(entCur, "UL", (size_t)2) == 0) ||
-          (memcmp(entCur, "OB", (size_t)2) == 0) ||
-          (memcmp(entCur, "UI", (size_t)2) == 0) )   
-      {
-         filetype = ExplicitVR;
-         dbg.Verbose(1, "gdcmHeader::CheckSwap:",
-                     "explicit Value Representation");
-      } else {
-         filetype = ImplicitVR;
-         dbg.Verbose(1, "gdcmHeader::CheckSwap:",
-                     "not an explicit Value Representation");
-      }
-      if (net2host) {
-         sw = 4321;
-         dbg.Verbose(1, "gdcmHeader::CheckSwap:",
-                        "HostByteOrder != NetworkByteOrder");
-      } else {
-         sw = 0;
-         dbg.Verbose(1, "gdcmHeader::CheckSwap:",
-                        "HostByteOrder = NetworkByteOrder");
-      }
-      
-      // Position the file position indicator at first tag (i.e.
-      // after the file preamble and the "DICM" string).
-      rewind(fp);
-      fseek (fp, 132L, SEEK_SET);
-      return;
-   } // End of DicomV3
-
-   // Alas, this is not a DicomV3 file and whatever happens there is no file
-   // preamble. We can reset the file position indicator to where the data
-   // is (i.e. the beginning of the file).
-    dbg.Verbose(1, "gdcmHeader::CheckSwap:", "not a DICOM Version3 file");
-   rewind(fp);
-
-   // Our next best chance would be to be considering a 'clean' ACR/NEMA file.
-   // By clean we mean that the length of the first tag is written down.
-   // If this is the case and since the length of the first group HAS to be
-   // four (bytes), then determining the proper swap code is straightforward.
-
-   entCur = deb + 4;
-   // We assume the array of char we are considering contains the binary
-   // representation of a 32 bits integer. Hence the following dirty
-   // trick :
-   s = *((guint32 *)(entCur));
-   
-   switch (s) {
-   case 0x00040000 :
-      sw = 3412;
-      filetype = ACR;
-      return;
-   case 0x04000000 :
-      sw = 4321;
-      filetype = ACR;
-      return;
-   case 0x00000400 :
-      sw = 2143;
-      filetype = ACR;
-      return;
-   case 0x00000004 :
-      sw = 0;
-      filetype = ACR;
-      return;
-   default :
-      dbg.Verbose(0, "gdcmHeader::CheckSwap:",
-                     "ACR/NEMA unfound swap info (time to raise bets)");
-   }
-
-   // We are out of luck. It is not a DicomV3 nor a 'clean' ACR/NEMA file.
-   // It is time for despaired wild guesses. So, let's assume this file
-   // happens to be 'dirty' ACR/NEMA, i.e. the length of the group is
-   // not present. Then the only info we have is the net2host one.
-   filetype = Unknown;
-   if (! net2host )
-      sw = 0;
-   else
-      sw = 4321;
-   return;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief   
- */
-void gdcmHeader::SwitchSwapToBigEndian(void) {
-   dbg.Verbose(1, "gdcmHeader::SwitchSwapToBigEndian",
-                  "Switching to BigEndian mode.");
-   if ( sw == 0    ) {
-      sw = 4321;
-      return;
-   }
-   if ( sw == 4321 ) {
-      sw = 0;
-      return;
-   }
-   if ( sw == 3412 ) {
-      sw = 2143;
-      return;
-   }
-   if ( sw == 2143 )
-      sw = 3412;
-}
-
-/**
- * \ingroup   gdcmHeader
- * \brief     Find the value representation of the current tag.
- * @param ElVal
- */
-void gdcmHeader::FindVR( gdcmElValue *ElVal) {
-   if (filetype != ExplicitVR)
-      return;
-
-   char VR[3];
-   std::string vr;
-   int lgrLue;
-   char msg[100]; // for sprintf. Sorry
-
-   long PositionOnEntry = ftell(fp);
-   // Warning: we believe this is explicit VR (Value Representation) because
-   // we used a heuristic that found "UL" in the first tag. Alas this
-   // doesn't guarantee that all the tags will be in explicit VR. In some
-   // cases (see e-film filtered files) one finds implicit VR tags mixed
-   // within an explicit VR file. Hence we make sure the present tag
-   // is in explicit VR and try to fix things if it happens not to be
-   // the case.
-   bool RealExplicit = true;
-   
-   lgrLue=fread (&VR, (size_t)2,(size_t)1, fp);
-   VR[2]=0;
-   vr = std::string(VR);
-      
-   // Assume we are reading a falsely explicit VR file i.e. we reached
-   // a tag where we expect reading a VR but are in fact we read the
-   // first to bytes of the length. Then we will interogate (through find)
-   // the dicom_vr dictionary with oddities like "\004\0" which crashes
-   // both GCC and VC++ implementations of the STL map. Hence when the
-   // expected VR read happens to be non-ascii characters we consider
-   // we hit falsely explicit VR tag.
-
-   if ( (!isalpha(VR[0])) && (!isalpha(VR[1])) )
-      RealExplicit = false;
-
-   // CLEANME searching the dicom_vr at each occurence is expensive.
-   // PostPone this test in an optional integrity check at the end
-   // of parsing or only in debug mode.
-   if ( RealExplicit && !dicom_vr->Count(vr) )
-      RealExplicit= false;
-
-   if ( RealExplicit ) {
-      if ( ElVal->IsVrUnknown() ) {
-         // When not a dictionary entry, we can safely overwrite the vr.
-         ElVal->SetVR(vr);
-         return; 
-      }
-      if ( ElVal->GetVR() == vr ) {
-         // The vr we just read and the dictionary agree. Nothing to do.
-         return;
-      }
-      // The vr present in the file and the dictionary disagree. We assume
-      // the file writer knew best and use the vr of the file. Since it would
-      // be unwise to overwrite the vr of a dictionary (since it would
-      // compromise it's next user), we need to clone the actual DictEntry
-      // and change the vr for the read one.
-      gdcmDictEntry* NewTag = new gdcmDictEntry(ElVal->GetGroup(),
-                                 ElVal->GetElement(),
-                                 vr,
-                                 "FIXME",
-                                 ElVal->GetName());
-      ElVal->SetDictEntry(NewTag);
-      return; 
-   }
-   
-   // We thought this was explicit VR, but we end up with an
-   // implicit VR tag. Let's backtrack.   
-   
-      sprintf(msg,"Falsely explicit vr file (%04x,%04x)\n", 
-                   ElVal->GetGroup(),ElVal->GetElement());
-      dbg.Verbose(1, "gdcmHeader::FindVR: ",msg);
-   
-   fseek(fp, PositionOnEntry, SEEK_SET);
-   // When this element is known in the dictionary we shall use, e.g. for
-   // the semantics (see the usage of IsAnInteger), the vr proposed by the
-   // dictionary entry. Still we have to flag the element as implicit since
-   // we know now our assumption on expliciteness is not furfilled.
-   // avoid  .
-   if ( ElVal->IsVrUnknown() )
-      ElVal->SetVR("Implicit");
-   ElVal->SetImplicitVr();
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief   Determines if the Transfer Syntax was already encountered
- *          and if it corresponds to a ImplicitVRLittleEndian one.
- *
- * @return  True when ImplicitVRLittleEndian found. False in all other cases.
- */
-bool gdcmHeader::IsImplicitVRLittleEndianTransferSyntax(void) {
+bool gdcmHeader::IsJPEGExtendedProcess3_5TransferSyntax(void) {
    gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
    if ( !Element )
       return false;
    LoadElementValueSafe(Element);
    std::string Transfer = Element->GetValue();
-   if ( Transfer == "1.2.840.10008.1.2" )
+   if ( Transfer == "1.2.840.10008.1.2.4.52" )
       return true;
    return false;
 }
@@ -446,17 +257,18 @@ bool gdcmHeader::IsImplicitVRLittleEndianTransferSyntax(void) {
 /**
  * \ingroup gdcmHeader
  * \brief   Determines if the Transfer Syntax was already encountered
- *          and if it corresponds to a ExplicitVRLittleEndian one.
+ *          and if it corresponds to a JPEGSpectralSelectionProcess6-8 one.
  *
- * @return  True when ExplicitVRLittleEndian found. False in all other cases.
+ * @return  True when JPEGSpectralSelectionProcess6-8 found. False in all
+ *          other cases.
  */
-bool gdcmHeader::IsExplicitVRLittleEndianTransferSyntax(void) {
+bool gdcmHeader::IsJPEGSpectralSelectionProcess6_8TransferSyntax(void) {
    gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
    if ( !Element )
       return false;
    LoadElementValueSafe(Element);
    std::string Transfer = Element->GetValue();
-   if ( Transfer == "1.2.840.10008.1.2.1" )
+   if ( Transfer == "1.2.840.10008.1.2.4.53" )
       return true;
    return false;
 }
@@ -464,1266 +276,1108 @@ bool gdcmHeader::IsExplicitVRLittleEndianTransferSyntax(void) {
 /**
  * \ingroup gdcmHeader
  * \brief   Determines if the Transfer Syntax was already encountered
- *          and if it corresponds to a DeflatedExplicitVRLittleEndian one.
+ *          and if it corresponds to a RLE Lossless one.
  *
- * @return  True when DeflatedExplicitVRLittleEndian found. False in all other cases.
+ * @return  True when RLE Lossless found. False in all
+ *          other cases.
  */
-bool gdcmHeader::IsDeflatedExplicitVRLittleEndianTransferSyntax(void) {
+bool gdcmHeader::IsRLELossLessTransferSyntax(void) {
    gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
    if ( !Element )
       return false;
    LoadElementValueSafe(Element);
    std::string Transfer = Element->GetValue();
-   if ( Transfer == "1.2.840.10008.1.2.1.99" )
+   if ( Transfer == "1.2.840.10008.1.2.5" )
       return true;
    return false;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Determines if the Transfer Syntax was already encountered
- *          and if it corresponds to a Explicit VR Big Endian one.
+ * \brief   
  *
- * @return  True when big endian found. False in all other cases.
+ * @return 
  */
-bool gdcmHeader::IsExplicitVRBigEndianTransferSyntax(void) {
+bool gdcmHeader::IsJPEGLossless(void) {
    gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
+    // faire qq chose d'intelligent a la place de Ã§a
    if ( !Element )
       return false;
    LoadElementValueSafe(Element);
-   std::string Transfer = Element->GetValue();
-   if ( Transfer == "1.2.840.10008.1.2.2" )  //1.2.2 ??? A verifier !
-      return true;
+   const char * Transfert = Element->GetValue().c_str();
+   if ( memcmp(Transfert+strlen(Transfert)-2 ,"70",2)==0) return true;
+   if ( memcmp(Transfert+strlen(Transfert)-2 ,"55",2)==0) return true;
+   if (Element->GetValue() == "1.2.840.10008.1.2.4.57")   return true;
+
    return false;
 }
 
 /**
  * \ingroup gdcmHeader
  * \brief   Determines if the Transfer Syntax was already encountered
- *          and if it corresponds to a JPEGBaseLineProcess1 one.
+ *          and if it corresponds to a JPEG200 one.0
  *
- * @return  True when JPEGBaseLineProcess1found. False in all other cases.
+ * @return  True when JPEG2000 (Lossly or LossLess) found. False in all
+ *          other cases.
  */
-bool gdcmHeader::IsJPEGBaseLineProcess1TransferSyntax(void) {
+bool gdcmHeader::IsJPEG2000(void) {
    gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
    if ( !Element )
       return false;
    LoadElementValueSafe(Element);
    std::string Transfer = Element->GetValue();
-   if ( Transfer == "1.2.840.10008.1.2.4.50" )
+   if (    (Transfer == "1.2.840.10008.1.2.4.90") 
+        || (Transfer == "1.2.840.10008.1.2.4.91") )
       return true;
    return false;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   
- *
+ * \brief   Predicate for dicom version 3 file.
+ * @return  True when the file is a dicom version 3.
+ */
+bool gdcmHeader::IsDicomV3(void) {
+   if (   (filetype == ExplicitVR)
+       || (filetype == ImplicitVR) )
+      return true;
+   return false;
+}
+
+/**
+ * \ingroup gdcmHeader
+ * \brief  
  * @return 
  */
-bool gdcmHeader::IsJPEGLossless(void) {
-   gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
-    // faire qq chose d'intelligent a la place de Ã§a
-   if ( !Element )
-      return false;
-   LoadElementValueSafe(Element);
-   const char * Transfert = Element->GetValue().c_str();
-   if ( memcmp(Transfert+strlen(Transfert)-2 ,"70",2)==0) return true;
-   if ( memcmp(Transfert+strlen(Transfert)-2 ,"55",2)==0) return true;
-   if (Element->GetValue() == "1.2.840.10008.1.2.4.57")   return true;
-
-   return false;
+FileType gdcmHeader::GetFileType(void)
+{
+   return(filetype);
 }
 
-
 /**
  * \ingroup gdcmHeader
- * \brief   Determines if the Transfer Syntax was already encountered
- *          and if it corresponds to a JPEGExtendedProcess2-4 one.
- *
- * @return  True when JPEGExtendedProcess2-4 found. False in all other cases.
+ * \brief   Retrieve the number of columns of image.
+ * @return  The encountered size when found, 0 by default.
  */
-bool gdcmHeader::IsJPEGExtendedProcess2_4TransferSyntax(void) {
-   gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
-   if ( !Element )
-      return false;
-   LoadElementValueSafe(Element);
-   std::string Transfer = Element->GetValue();
-   if ( Transfer == "1.2.840.10008.1.2.4.51" )
-      return true;
-   return false;
+int gdcmHeader::GetXSize(void) {
+   // We cannot check for "Columns" because the "Columns" tag is present
+   // both in IMG (0028,0011) and OLY (6000,0011) sections of the dictionary.
+   std::string StrSize = GetPubElValByNumber(0x0028,0x0011);
+   if (StrSize == GDCM_UNFOUND)
+      return 0;
+   return atoi(StrSize.c_str());
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Determines if the Transfer Syntax was already encountered
- *          and if it corresponds to a JPEGExtendeProcess3-5 one.
- *
- * @return  True when JPEGExtendedProcess3-5 found. False in all other cases.
+ * \brief   Retrieve the number of lines of image.
+ * \warning The defaulted value is 1 as opposed to gdcmHeader::GetXSize()
+ * @return  The encountered size when found, 1 by default.
  */
-bool gdcmHeader::IsJPEGExtendedProcess3_5TransferSyntax(void) {
-   gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
-   if ( !Element )
-      return false;
-   LoadElementValueSafe(Element);
-   std::string Transfer = Element->GetValue();
-   if ( Transfer == "1.2.840.10008.1.2.4.52" )
-      return true;
-   return false;
+int gdcmHeader::GetYSize(void) {
+   // We cannot check for "Rows" because the "Rows" tag is present
+   // both in IMG (0028,0010) and OLY (6000,0010) sections of the dictionary.
+   std::string StrSize = GetPubElValByNumber(0x0028,0x0010);
+   if (StrSize != GDCM_UNFOUND)
+      return atoi(StrSize.c_str());
+   if ( IsDicomV3() )
+      return 0;
+   else
+      // The Rows (0028,0010) entry is optional for ACR/NEMA. It might
+      // hence be a signal (1d image). So we default to 1:
+      return 1;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Determines if the Transfer Syntax was already encountered
- *          and if it corresponds to a JPEGSpectralSelectionProcess6-8 one.
- *
- * @return  True when JPEGSpectralSelectionProcess6-8 found. False in all
- *          other cases.
+ * \brief   Retrieve the number of planes of volume or the number
+ *          of frames of a multiframe.
+ * \warning When present we consider the "Number of Frames" as the third
+ *          dimension. When absent we consider the third dimension as
+ *          being the "Planes" tag content.
+ * @return  The encountered size when found, 1 by default.
  */
-bool gdcmHeader::IsJPEGSpectralSelectionProcess6_8TransferSyntax(void) {
-   gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
-   if ( !Element )
-      return false;
-   LoadElementValueSafe(Element);
-   std::string Transfer = Element->GetValue();
-   if ( Transfer == "1.2.840.10008.1.2.4.53" )
-      return true;
-   return false;
+int gdcmHeader::GetZSize(void) {
+   // Both  DicomV3 and ACR/Nema consider the "Number of Frames"
+   // as the third dimension.
+   std::string StrSize = GetPubElValByNumber(0x0028,0x0008);
+   if (StrSize != GDCM_UNFOUND)
+      return atoi(StrSize.c_str());
+
+   // We then consider the "Planes" entry as the third dimension [we
+   // cannot retrieve by name since "Planes tag is present both in
+   // IMG (0028,0012) and OLY (6000,0012) sections of the dictionary]. 
+   StrSize = GetPubElValByNumber(0x0028,0x0012);
+   if (StrSize != GDCM_UNFOUND)
+      return atoi(StrSize.c_str());
+   return 1;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Determines if the Transfer Syntax was already encountered
- *          and if it corresponds to a RLE Lossless one.
- *
- * @return  True when RLE Lossless found. False in all
- *          other cases.
+ * \brief   Retrieve the number of Bits Stored
+ *          (as opposite to number of Bits Allocated)
+ * 
+ * @return  The encountered number of Bits Stored, 0 by default.
  */
-bool gdcmHeader::IsRLELossLessTransferSyntax(void) {
-   gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
-   if ( !Element )
-      return false;
-   LoadElementValueSafe(Element);
-   std::string Transfer = Element->GetValue();
-   if ( Transfer == "1.2.840.10008.1.2.5" )
-      return true;
-   return false;
+int gdcmHeader::GetBitsStored(void) { 
+   std::string StrSize = GetPubElValByNumber(0x0028,0x0101);
+   if (StrSize == GDCM_UNFOUND)
+      return 1;
+   return atoi(StrSize.c_str());
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Determines if the Transfer Syntax was already encountered
- *          and if it corresponds to a JPEG200 one.0
- *
- * @return  True when JPEG2000 (Lossly or LossLess) found. False in all
- *          other cases.
+ * \brief   Retrieve the number of Bits Allocated
+ *          (8, 12 -compacted ACR-NEMA files, 16, ...)
+ * 
+ * @return  The encountered number of Bits Allocated, 0 by default.
  */
-bool gdcmHeader::IsJPEG2000(void) {
-   gdcmElValue* Element = PubElValSet.GetElementByNumber(0x0002, 0x0010);
-   if ( !Element )
-      return false;
-   LoadElementValueSafe(Element);
-   std::string Transfer = Element->GetValue();
-   if (    (Transfer == "1.2.840.10008.1.2.4.90") 
-        || (Transfer == "1.2.840.10008.1.2.4.91") )
-      return true;
-   return false;
+int gdcmHeader::GetBitsAllocated(void) { 
+   std::string StrSize = GetPubElValByNumber(0x0028,0x0100);
+   if (StrSize == GDCM_UNFOUND)
+      return 1;
+   return atoi(StrSize.c_str());
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Predicate for dicom version 3 file.
- * @return  True when the file is a dicom version 3.
+ * \brief   Retrieve the number of Samples Per Pixel
+ *          (1 : gray level, 3 : RGB -1 or 3 Planes-)
+ * 
+ * @return  The encountered number of Samples Per Pixel, 1 by default.
  */
-bool gdcmHeader::IsDicomV3(void) {
-   if (   (filetype == ExplicitVR)
-       || (filetype == ImplicitVR) )
-      return true;
-   return false;
+int gdcmHeader::GetSamplesPerPixel(void) { 
+   std::string StrSize = GetPubElValByNumber(0x0028,0x0002);
+   if (StrSize == GDCM_UNFOUND)
+      return 1; // Well, it's supposed to be mandatory ...
+   return atoi(StrSize.c_str());
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   When the length of an element value is obviously wrong (because
- *          the parser went Jabberwocky) one can hope improving things by
- *          applying this heuristic.
+ * \brief   Retrieve the Planar Configuration for RGB images
+ *          (0 : RGB Pixels , 1 : R Plane + G Plane + B Plane)
+ * 
+ * @return  The encountered Planar Configuration, 0 by default.
  */
-void gdcmHeader::FixFoundLength(gdcmElValue * ElVal, guint32 FoundLength) {
-
-   ElVal->SetReadLength(FoundLength); // will be updated only if a bug is found
-                    
-   if ( FoundLength == 0xffffffff) {  
-      FoundLength = 0;
-   }
-      
-      // Sorry for the patch!  
-      // XMedCom did the trick to read some nasty GE images ...
-   else if (FoundLength == 13) {
-      // The following 'if' will be removed when there is no more
-      // images on Creatis HDs with a 13 length for Manufacturer...
-      if ( (ElVal->GetGroup() != 0x0008) ||  
-           ( (ElVal->GetElement() != 0x0070) && (ElVal->GetElement() != 0x0080) ) ) {
-      // end of remove area
-         FoundLength =10;
-        ElVal->SetReadLength(10); // a bug is to be fixed
-      }
-   } 
-     // to fix some garbage 'Leonardo' Siemens images
-     // May be commented out to avoid overhead
-   else if ( (ElVal->GetGroup() == 0x0009) 
-       &&
-       ( (ElVal->GetElement() == 0x1113) || (ElVal->GetElement() == 0x1114) ) ){
-        FoundLength =4;
-       ElVal->SetReadLength(4); // a bug is to be fixed 
-   } 
-     // end of fix
-        
-    // to try to 'go inside' SeQuences (with length), and not to skip them        
-    else if ( ElVal->GetVR() == "SQ") { 
-       if (enableSequences)    // only if the user does want to !
-         FoundLength =0;        
-    } 
-    
-    // a SeQuence Element is beginning
-    // Let's forget it's length
-    // (we want to 'go inside')
-    else if(ElVal->GetGroup() == 0xfffe){
-         FoundLength =0;            
-    }
-                 
-   ElVal->SetUsableLength(FoundLength);
+int gdcmHeader::GetPlanarConfiguration(void) { 
+   std::string StrSize = GetPubElValByNumber(0x0028,0x0006);
+   if (StrSize == GDCM_UNFOUND)
+      return 0;
+   return atoi(StrSize.c_str());
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   
+ * \brief   Return the size (in bytes) of a single pixel of data.
+ * @return  The size in bytes of a single pixel of data.
  *
- * @return 
  */
- guint32 gdcmHeader::FindLengthOB(void) {
-   // See PS 3.5-2001, section A.4 p. 49 on encapsulation of encoded pixel data.
-   guint16 g;
-   guint16 n; 
-   long PositionOnEntry = ftell(fp);
-   bool FoundSequenceDelimiter = false;
-   guint32 TotalLength = 0;
-   guint32 ItemLength;
-
-   while ( ! FoundSequenceDelimiter) {
-      g = ReadInt16();
-      n = ReadInt16();   
-      if (errno == 1)
-         return 0;
-      TotalLength += 4;  // We even have to decount the group and element 
-     
-      if ( g != 0xfffe && g!=0xb00c ) /*for bogus header */ {
-         char msg[100]; // for sprintf. Sorry
-         sprintf(msg,"wrong group (%04x) for an item sequence (%04x,%04x)\n",g, g,n);
-         dbg.Verbose(1, "gdcmHeader::FindLengthOB: ",msg); 
-         errno = 1;
-         return 0;
-      }
-      if ( n == 0xe0dd || ( g==0xb00c && n==0x0eb6 ) ) /* for bogus header  */ 
-         FoundSequenceDelimiter = true;
-      else if ( n != 0xe000 ){
-         char msg[100];  // for sprintf. Sorry
-         sprintf(msg,"wrong element (%04x) for an item sequence (%04x,%04x)\n",
-                      n, g,n);
-        dbg.Verbose(1, "gdcmHeader::FindLengthOB: ",msg);
-         errno = 1;
-         return 0;
-      }
-      ItemLength = ReadInt32();
-      TotalLength += ItemLength + 4;  // We add 4 bytes since we just read
-                                      // the ItemLength with ReadInt32                                     
-      SkipBytes(ItemLength);
-   }
-   fseek(fp, PositionOnEntry, SEEK_SET);
-   return TotalLength;
+int gdcmHeader::GetPixelSize(void) {
+   std::string PixelType = GetPixelType();
+   if (PixelType == "8U"  || PixelType == "8S")
+      return 1;
+   if (PixelType == "16U" || PixelType == "16S")
+      return 2;
+   if (PixelType == "32U" || PixelType == "32S")
+      return 4;
+   dbg.Verbose(0, "gdcmHeader::GetPixelSize: Unknown pixel type");
+   return 0;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   
- *
- * @return 
+ * \brief   Build the Pixel Type of the image.
+ *          Possible values are:
+ *          - 8U  unsigned  8 bit,
+ *          - 8S    signed  8 bit,
+ *          - 16U unsigned 16 bit,
+ *          - 16S   signed 16 bit,
+ *          - 32U unsigned 32 bit,
+ *          - 32S   signed 32 bit,
+ * \warning 12 bit images appear as 16 bit.
+ * \        24 bit images appear as 8 bit
+ * @return  
  */
- void gdcmHeader::FindLength (gdcmElValue * ElVal) {
-   guint16 element = ElVal->GetElement();
-   guint16 group   = ElVal->GetGroup();
-   std::string  vr = ElVal->GetVR();
-   guint16 length16;
-   if( (element == 0x0010) && (group == 0x7fe0) ) {
-      dbg.SetDebug(-1);
-      dbg.Verbose(2, "gdcmHeader::FindLength: ",
-                     "we reached 7fe0 0010");
-   }   
-   
-   if ( (filetype == ExplicitVR) && ! ElVal->IsImplicitVr() ) {
-      if ( (vr=="OB") || (vr=="OW") || (vr=="SQ") || (vr=="UN") ) {
-      
-         // The following reserved two bytes (see PS 3.5-2001, section
-         // 7.1.2 Data element structure with explicit vr p27) must be
-         // skipped before proceeding on reading the length on 4 bytes.
-         fseek(fp, 2L, SEEK_CUR);
-
-         guint32 length32 = ReadInt32();
-
-         if ( (vr == "OB") && (length32 == 0xffffffff) ) {
-            ElVal->SetLength(FindLengthOB());
-            return;
-         }
-         FixFoundLength(ElVal, length32); 
-         return;
-      }
-
-      // Length is encoded on 2 bytes.
-      length16 = ReadInt16();
-      
-      // We can tell the current file is encoded in big endian (like
-      // Data/US-RGB-8-epicard) when we find the "Transfer Syntax" tag
-      // and it's value is the one of the encoding of a big endian file.
-      // In order to deal with such big endian encoded files, we have
-      // (at least) two strategies:
-      // * when we load the "Transfer Syntax" tag with value of big endian
-      //   encoding, we raise the proper flags. Then we wait for the end
-      //   of the META group (0x0002) among which is "Transfer Syntax",
-      //   before switching the swap code to big endian. We have to postpone
-      //   the switching of the swap code since the META group is fully encoded
-      //   in little endian, and big endian coding only starts at the next
-      //   group. The corresponding code can be hard to analyse and adds
-      //   many additional unnecessary tests for regular tags.
-      // * the second strategy consists in waiting for trouble, that shall
-      //   appear when we find the first group with big endian encoding. This
-      //   is easy to detect since the length of a "Group Length" tag (the
-      //   ones with zero as element number) has to be of 4 (0x0004). When we
-      //   encounter 1024 (0x0400) chances are the encoding changed and we
-      //   found a group with big endian encoding.
-      // We shall use this second strategy. In order to make sure that we
-      // can interpret the presence of an apparently big endian encoded
-      // length of a "Group Length" without committing a big mistake, we
-      // add an additional check: we look in the already parsed elements
-      // for the presence of a "Transfer Syntax" whose value has to be "big
-      // endian encoding". When this is the case, chances are we have got our
-      // hands on a big endian encoded file: we switch the swap code to
-      // big endian and proceed...
-      if ( (element  == 0x0000) && (length16 == 0x0400) ) {
-         if ( ! IsExplicitVRBigEndianTransferSyntax() ) {
-            dbg.Verbose(0, "gdcmHeader::FindLength", "not explicit VR");
-            errno = 1;
-            return;
-         }
-         length16 = 4;
-         SwitchSwapToBigEndian();
-         // Restore the unproperly loaded values i.e. the group, the element
-         // and the dictionary entry depending on them.
-         guint16 CorrectGroup   = SwapShort(ElVal->GetGroup());
-         guint16 CorrectElem    = SwapShort(ElVal->GetElement());
-         gdcmDictEntry * NewTag = GetDictEntryByNumber(CorrectGroup,
-                                                       CorrectElem);
-         if (!NewTag) {
-            // This correct tag is not in the dictionary. Create a new one.
-            NewTag = new gdcmDictEntry(CorrectGroup, CorrectElem);
-         }
-         // FIXME this can create a memory leaks on the old entry that be
-         // left unreferenced.
-         ElVal->SetDictEntry(NewTag);
-      }
-       
-      // Heuristic: well some files are really ill-formed.
-      if ( length16 == 0xffff) {
-         length16 = 0;
-         //dbg.Verbose(0, "gdcmHeader::FindLength",
-         //            "Erroneous element length fixed.");
-         // Actually, length= 0xffff means that we deal with
-         // Unknown Sequence Length 
-      }
-
-      FixFoundLength(ElVal, (guint32)length16);
-      return;
+std::string gdcmHeader::GetPixelType(void) {
+   std::string BitsAlloc;
+   BitsAlloc = GetPubElValByNumber(0x0028, 0x0100); // Bits Allocated
+   if (BitsAlloc == GDCM_UNFOUND) {
+      dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated");
+      BitsAlloc = std::string("16");
+   }
+   if (BitsAlloc == "12")            // It will be unpacked
+      BitsAlloc = std::string("16");
+   else if (BitsAlloc == "24")       // (in order no to be messed up
+      BitsAlloc = std::string("8");  // by old RGB images)
+     
+   std::string Signed;
+   Signed = GetPubElValByNumber(0x0028, 0x0103); // "Pixel Representation"
+   if (Signed == GDCM_UNFOUND) {
+      dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Pixel Representation");
+      BitsAlloc = std::string("0");
    }
+   if (Signed == "0")
+      Signed = std::string("U");
+   else
+      Signed = std::string("S");
 
-   // Either implicit VR or a non DICOM conformal (see not below) explicit
-   // VR that ommited the VR of (at least) this element. Farts happen.
-   // [Note: according to the part 5, PS 3.5-2001, section 7.1 p25
-   // on Data elements "Implicit and Explicit VR Data Elements shall
-   // not coexist in a Data Set and Data Sets nested within it".]
-   // Length is on 4 bytes.
-   FixFoundLength(ElVal, ReadInt32());
-   return;
+   return( BitsAlloc + Signed);
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Swaps back the bytes of 4-byte long integer accordingly to
- *          processor order.
- * @return  The properly swaped 32 bits integer.
+ * \brief   Recover the offset (from the beginning of the file) of the pixels.
  */
-guint32 gdcmHeader::SwapLong(guint32 a) {
-   switch (sw) {
-   case    0 :
-      break;
-   case 4321 :
-      a=(   ((a<<24) & 0xff000000) | ((a<<8)  & 0x00ff0000)    | 
-            ((a>>8)  & 0x0000ff00) | ((a>>24) & 0x000000ff) );
-      break;
-   
-   case 3412 :
-      a=(   ((a<<16) & 0xffff0000) | ((a>>16) & 0x0000ffff) );
-      break;
-   
-   case 2143 :
-      a=(    ((a<<8) & 0xff00ff00) | ((a>>8) & 0x00ff00ff)  );
-      break;
-   default :
-      dbg.Error(" gdcmHeader::SwapLong : unset swap code");
-      a=0;
+size_t gdcmHeader::GetPixelOffset(void) {
+   // If this file complies with the norm we should encounter the
+   // "Image Location" tag (0x0028,  0x0200). This tag contains the
+   // the group that contains the pixel data (hence the "Pixel Data"
+   // is found by indirection through the "Image Location").
+   // Inside the group pointed by "Image Location" the searched element
+   // is conventionally the element 0x0010 (when the norm is respected).
+   // When the "Image Location" is absent we default to group 0x7fe0.
+   guint16 grPixel;
+   guint16 numPixel;
+   std::string ImageLocation = GetPubElValByNumber(0x0028, 0x0200);
+   if ( ImageLocation == GDCM_UNFOUND ) { // Image Location
+      grPixel = 0x7fe0;
+   } else {
+      grPixel = (guint16) atoi( ImageLocation.c_str() );
    }
-   return(a);
+   if (grPixel != 0x7fe0)
+      // This is a kludge for old dirty Philips imager.
+      numPixel = 0x1010;
+   else
+      numPixel = 0x0010;
+         
+   gdcmElValue* PixelElement = PubElValSet.GetElementByNumber(grPixel,
+                                                              numPixel);
+   if (PixelElement)
+      return PixelElement->GetOffset();
+   else
+      return 0;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Swaps the bytes so they agree with the processor order
- * @return  The properly swaped 16 bits integer.
+ * \brief   Recover the pixel area length (in Bytes) .
  */
-guint16 gdcmHeader::SwapShort(guint16 a) {
-   if ( (sw==4321)  || (sw==2143) )
-      a =(((a<<8) & 0x0ff00) | ((a>>8)&0x00ff));
-   return (a);
+size_t gdcmHeader::GetPixelAreaLength(void) {
+   // If this file complies with the norm we should encounter the
+   // "Image Location" tag (0x0028,  0x0200). This tag contains the
+   // the group that contains the pixel data (hence the "Pixel Data"
+   // is found by indirection through the "Image Location").
+   // Inside the group pointed by "Image Location" the searched element
+   // is conventionally the element 0x0010 (when the norm is respected).
+   // When the "Image Location" is absent we default to group 0x7fe0.
+   guint16 grPixel;
+   guint16 numPixel;
+   std::string ImageLocation = GetPubElValByNumber(0x0028, 0x0200);
+   if ( ImageLocation == GDCM_UNFOUND ) {
+      grPixel = 0x7fe0;
+   } else {
+      grPixel = (guint16) atoi( ImageLocation.c_str() );
+   }
+   if (grPixel != 0x7fe0)
+      // This is a kludge for old dirty Philips imager.
+      numPixel = 0x1010;
+   else
+      numPixel = 0x0010;
+         
+   gdcmElValue* PixelElement = PubElValSet.GetElementByNumber(grPixel,
+                                                              numPixel);
+   if (PixelElement)
+      return PixelElement->GetLength();
+   else
+      return 0;
 }
 
 /**
- * \ingroup gdcmHeader
- * \brief   
- *
- * @return 
- */
- void gdcmHeader::SkipBytes(guint32 NBytes) {
-   //FIXME don't dump the returned value
-   (void)fseek(fp, (long)NBytes, SEEK_CUR);
+  * \ingroup gdcmHeader
+  * \brief tells us if LUT are used
+  * \warning Right now, Segmented xxx Palette Color Lookup Table Data
+  * \        are NOT considered as LUT, since nobody knows
+  *\         how to deal with them
+  * @return int acts as a Boolean 
+  */
+bool gdcmHeader::HasLUT(void) {
+
+   // Check the presence of the LUT Descriptors 
+   if (GetPubElValByNumber(0x0028,0x1101) == GDCM_UNFOUND)
+      return false;
+   // LutDescriptorGreen 
+   if (GetPubElValByNumber(0x0028,0x1102) == GDCM_UNFOUND)
+      return false;
+   // LutDescriptorBlue 
+   if (GetPubElValByNumber(0x0028,0x1103) == GDCM_UNFOUND)
+      return false;
+   //  It is not enough
+   // we check also 
+   if (GetPubElValByNumber(0x0028,0x1201) == GDCM_UNFOUND)
+      return false;  
+   if (GetPubElValByNumber(0x0028,0x1202) == GDCM_UNFOUND)
+      return false;
+   if (GetPubElValByNumber(0x0028,0x1203) == GDCM_UNFOUND)
+      return false;   
+   return true;
 }
 
 /**
- * \ingroup gdcmHeader
- * \brief   
- * @param ElVal 
- * @return 
- */
- void gdcmHeader::SkipElementValue(gdcmElValue * ElVal) {
-    SkipBytes(ElVal->GetLength());
+  * \ingroup gdcmHeader
+  * \brief gets the info from 0028,1101 : Lookup Table Desc-Red
+  * \           else 0
+  * @return Lookup Table nBit 
+  * \       when (0028,0004),Photometric Interpretation = [PALETTE COLOR ] 
+  */
+int gdcmHeader::GetLUTNbits(void) {
+   std::vector<std::string> tokens;
+   //int LutLength;
+   //int LutDepth;
+   int LutNbits;
+   //Just hope Lookup Table Desc-Red = Lookup Table Desc-Red = Lookup Table Desc-Blue
+   // Consistency already checked in GetLUTLength
+   std::string LutDescription = GetPubElValByNumber(0x0028,0x1101);
+   if (LutDescription == GDCM_UNFOUND)
+      return 0;
+   tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
+   Tokenize (LutDescription, tokens, "\\");
+   //LutLength=atoi(tokens[0].c_str());
+   //LutDepth=atoi(tokens[1].c_str());
+   LutNbits=atoi(tokens[2].c_str());
+   tokens.clear();
+   return LutNbits;
 }
 
+/**
+  * \ingroup gdcmHeader
+  * \brief builts Red/Green/Blue/Alpha LUT from Header
+  * \       when (0028,0004),Photometric Interpretation = [PALETTE COLOR ]
+  * \        and (0028,1101),(0028,1102),(0028,1102)  
+  * \          - xxx Palette Color Lookup Table Descriptor - are found
+  * \        and (0028,1201),(0028,1202),(0028,1202) 
+  * \          - xxx Palette Color Lookup Table Data - are found 
+  * \warning does NOT deal with :
+  * \ 0028 1100 Gray Lookup Table Descriptor (Retired)
+  * \ 0028 1221 Segmented Red Palette Color Lookup Table Data
+  * \ 0028 1222 Segmented Green Palette Color Lookup Table Data
+  * \ 0028 1223 Segmented Blue Palette Color Lookup Table Data 
+  * \ no known Dicom reader deails with them :-(
+  * @return Lookup Table RGBA
+  */ 
+unsigned char * gdcmHeader::GetLUTRGBA(void) {
+// Not so easy : see 
+// http://www.barre.nom.fr/medical/dicom2/limitations.html#Color%20Lookup%20Tables
+// and  OT-PAL-8-face.dcm
+
+//  if Photometric Interpretation # PALETTE COLOR, no LUT to be done
+   if (gdcmHeader::GetPubElValByNumber(0x0028,0x0004) != "PALETTE COLOR ") {
+       return NULL;
+   }  
+
+   int lengthR, debR, nbitsR;
+   int lengthG, debG, nbitsG;
+   int lengthB, debB, nbitsB;
+   
+// Get info from Lut Descriptors
+// (the 3 LUT descriptors may be different)    
+   std::string LutDescriptionR = GetPubElValByNumber(0x0028,0x1101);
+   if (LutDescriptionR == GDCM_UNFOUND)
+      return NULL;
+   std::string LutDescriptionG = GetPubElValByNumber(0x0028,0x1102);
+   if (LutDescriptionG == GDCM_UNFOUND)
+      return NULL;   
+   std::string LutDescriptionB = GetPubElValByNumber(0x0028,0x1103);
+   if (LutDescriptionB == GDCM_UNFOUND)
+      return NULL;
+      
+   std::vector<std::string> tokens;
+      
+   tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
+   Tokenize (LutDescriptionR, tokens, "\\");
+   lengthR=atoi(tokens[0].c_str()); // Red LUT length in Bytes
+   debR   =atoi(tokens[1].c_str()); // subscript of the first Lut Value
+   nbitsR =atoi(tokens[2].c_str()); // Lut item size (in Bits)
+   tokens.clear();
+   
+   tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
+   Tokenize (LutDescriptionG, tokens, "\\");
+   lengthG=atoi(tokens[0].c_str()); // Green LUT length in Bytes
+   debG   =atoi(tokens[1].c_str());
+   nbitsG =atoi(tokens[2].c_str());
+   tokens.clear();  
+   
+   tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
+   Tokenize (LutDescriptionB, tokens, "\\");
+   lengthB=atoi(tokens[0].c_str()); // Blue LUT length in Bytes
+   debB   =atoi(tokens[1].c_str());
+   nbitsB =atoi(tokens[2].c_str());
+   tokens.clear();
+// Load LUTs into memory, (as they were stored on disk)
+   unsigned char *lutR = (unsigned char *)
+                                   GetPubElValVoidAreaByNumber(0x0028,0x1201);
+   unsigned char *lutG = (unsigned char *)
+                                   GetPubElValVoidAreaByNumber(0x0028,0x1202);
+   unsigned char *lutB = (unsigned char *)
+                                   GetPubElValVoidAreaByNumber(0x0028,0x1203); 
+   
+   if (!lutR || !lutG || !lutB ) {
+       return NULL;
+   } 
+ // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT 
+   
+  unsigned char *LUTRGBA = (unsigned char *)calloc(1024,1); // 256 * 4 (R, G, B, Alpha) 
+  if (!LUTRGBA) {
+     return NULL;
+  }
+  memset(LUTRGBA, 0, 1024);
+       // Bits Allocated
+   int nb;
+   std::string str_nb = GetPubElValByNumber(0x0028,0x0100);
+   if (str_nb == GDCM_UNFOUND ) {
+      nb = 16;
+   } else {
+      nb = atoi(str_nb.c_str() );
+   }  
+  int mult;
+  
+  if (nbitsR==16 && nb==8) // when LUT item size is different than pixel size
+     mult=2;               // high byte must be = low byte 
+  else                     // See PS 3.3-2003 C.11.1.1.2 p 619
+     mult=1; 
+   // if we get a black image, let's just remove the '+1'
+   // from 'i*mult+1' and check again 
+   // if it works, we shall have to check the 3 Palettes
+   // to see which byte is ==0 (first one, or second one)
+   // and fix the code
+   // We give up the checking to avoid some overhead 
+  unsigned char *a;      
+  int i;
+
+  a = LUTRGBA+0;
+  for(i=0;i<lengthR;i++) {
+     *a = lutR[i*mult+1]; 
+     a+=4;       
+  }        
+  a = LUTRGBA+1;
+  for(i=0;i<lengthG;i++) {
+     *a = lutG[i*mult+1]; 
+     a+=4;       
+  }  
+  a = LUTRGBA+2;
+  for(i=0;i<lengthB;i++) {
+     *a = lutB[i*mult+1]; 
+     a+=4;       
+  }  
+  a = LUTRGBA+3;
+  for(i=0;i<256;i++) {
+     *a = 1; // Alpha component
+     a+=4; 
+  } 
+      
+//How to free the now useless LUTs?
+
+//free(LutR); free(LutB); free(LutG);
+  return(LUTRGBA);   
+} 
+
 /**
  * \ingroup gdcmHeader
- * \brief   
- * @param NewSize
- * @return 
+ * \brief gets the info from 0002,0010 : Transfert Syntax
+ * \      else 1.
+ * @return Transfert Syntax Name (as oposite to Transfert Syntax UID)
  */
- void gdcmHeader::SetMaxSizeLoadElementValue(long NewSize) {
-   if (NewSize < 0)
-      return;
-   if ((guint32)NewSize >= (guint32)0xffffffff) {
-      MaxSizeLoadElementValue = 0xffffffff;
-      return;
+std::string gdcmHeader::GetTransfertSyntaxName(void) { 
+   // use the gdcmTS (TS : Transfert Syntax)
+   std::string TransfertSyntax = GetPubElValByNumber(0x0002,0x0010);
+   if (TransfertSyntax == GDCM_UNFOUND) {
+      dbg.Verbose(0, "gdcmHeader::GetTransferSyntaxName: unfound Transfert Syntax (0002,0010)");
+      return "Uncompressed ACR-NEMA";
    }
-   MaxSizeLoadElementValue = NewSize;
+   // we do it only when we need it
+   gdcmTS * ts = gdcmGlobal::GetTS();
+   std::string tsName=ts->GetValue(TransfertSyntax);
+   //delete ts; // Seg Fault when deleted ?!
+   return tsName;
 }
 
 /**
- * \ingroup       gdcmHeader
- * \brief         Loads the element content if it's length is not bigger
- *                than the value specified with
- *                gdcmHeader::SetMaxSizeLoadElementValue()
+ * \ingroup gdcmHeader
+ * \brief   Searches within the public dictionary for element value of
+ *          a given tag.
+ * @param   tagName name of the searched element.
+ * @return  Corresponding element value when it exists, and the string
+ *          GDCM_UNFOUND ("gdcm::Unfound") otherwise.
  */
-void gdcmHeader::LoadElementValue(gdcmElValue * ElVal) {
-   size_t item_read;
-   guint16 group  = ElVal->GetGroup();
-   std::string  vr= ElVal->GetVR();
-   guint32 length = ElVal->GetLength();
-   bool SkipLoad  = false;
-
-   fseek(fp, (long)ElVal->GetOffset(), SEEK_SET);
-   
-   // FIXME Sequences not treated yet !
-   //
-   // Ne faudrait-il pas au contraire trouver immediatement
-   // une maniere 'propre' de traiter les sequences (vr = SQ)
-   // car commencer par les ignorer risque de conduire a qq chose
-   // qui pourrait ne pas etre generalisable
-   // Well, I'm expecting your code !!!
-   
-   // the test was commented out to 'go inside' the SeQuences
-   // we don't any longer skip them !
-    
-  // if( vr == "SQ" )  
-  //    SkipLoad = true;
-
-   // A SeQuence "contains" a set of Elements.  
-   //          (fffe e000) tells us an Element is beginning
-   //          (fffe e00d) tells us an Element just ended
-   //          (fffe e0dd) tells us the current SeQuence just ended
-  
-   if( group == 0xfffe )
-      SkipLoad = true;
+std::string gdcmHeader::GetPubElValByName(std::string tagName) {
+   gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); 
+   if( dictEntry == NULL)
+      return GDCM_UNFOUND;
+   return(PubElValSet.GetElValueByNumber(dictEntry->GetGroup(),
+                                         dictEntry->GetElement()));  
+}
 
-   if ( SkipLoad ) {
-      ElVal->SetLength(0);
-      ElVal->SetValue("gdcm::Skipped");
-      return;
-   }
+/**
+ * \ingroup gdcmHeader
+ * \brief   Searches within the elements parsed with the public dictionary for
+ *          the element value representation of a given tag.
+ *
+ *          Obtaining the VR (Value Representation) might be needed by caller
+ *          to convert the string typed content to caller's native type 
+ *          (think of C++ vs Python). The VR is actually of a higher level
+ *          of semantics than just the native C++ type.
+ * @param   tagName name of the searched element.
+ * @return  Corresponding element value representation when it exists,
+ *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
+ */
+std::string gdcmHeader::GetPubElValRepByName(std::string tagName) {
+   gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); 
+   if( dictEntry == NULL)
+      return GDCM_UNFOUND;   
+   gdcmElValue* elem =  PubElValSet.GetElementByNumber(
+                                         dictEntry->GetGroup(),
+                                         dictEntry->GetElement());                                     
+   return elem->GetVR();
+}
 
-   // When the length is zero things are easy:
-   if ( length == 0 ) {
-      ElVal->SetValue("");
-      return;
-   }
-
-   // The elements whose length is bigger than the specified upper bound
-   // are not loaded. Instead we leave a short notice of the offset of
-   // the element content and it's length.
-   if (length > MaxSizeLoadElementValue) {
-      std::ostringstream s;
-      s << "gdcm::NotLoaded.";
-      s << " Address:" << (long)ElVal->GetOffset();
-      s << " Length:"  << ElVal->GetLength();
-      s << " x(" << std::hex << ElVal->GetLength() << ")";
-      ElVal->SetValue(s.str());
-      return;
-   }
-   
-   // When an integer is expected, read and convert the following two or
-   // four bytes properly i.e. as an integer as opposed to a string.
-       
-       // Actually, elements with Value Multiplicity > 1
-       // contain a set of integers (not a single one)         
-       // Any compacter code suggested (?)
-               
-   if ( IsAnInteger(ElVal) ) {
-      guint32 NewInt;
-      std::ostringstream s;
-      int nbInt;
-      if (vr == "US" || vr == "SS") {
-         nbInt = length / 2;
-         NewInt = ReadInt16();
-         s << NewInt;
-         if (nbInt > 1) {
-            for (int i=1; i < nbInt; i++) {
-               s << '\\';
-               NewInt = ReadInt16();
-               s << NewInt;
-            }
-         }
-                       
-      } else if (vr == "UL" || vr == "SL") {
-         nbInt = length / 4;
-         NewInt = ReadInt32();
-         s << NewInt;
-         if (nbInt > 1) {
-            for (int i=1; i < nbInt; i++) {
-               s << '\\';
-               NewInt = ReadInt32();
-               s << NewInt;
-            }
-         }
-      }                                        
-#ifdef GDCM_NO_ANSI_STRING_STREAM
-      s << std::ends; // to avoid oddities on Solaris
-#endif //GDCM_NO_ANSI_STRING_STREAM
-      ElVal->SetValue(s.str());
-      return;  
-   }
-   
-   // We need an additional byte for storing \0 that is not on disk
-   char* NewValue = (char*)malloc(length+1);
-   if( !NewValue) {
-      dbg.Verbose(1, "LoadElementValue: Failed to allocate NewValue");
-      return;
-   }
-   NewValue[length]= 0;
-   
-   item_read = fread(NewValue, (size_t)length, (size_t)1, fp);
-   if ( item_read != 1 ) {
-      free(NewValue);
-      dbg.Verbose(1, "gdcmHeader::LoadElementValue","unread element value");
-      ElVal->SetValue("gdcm::UnRead");
-      return;
-   }
-   ElVal->SetValue(NewValue);
-   free(NewValue);
-}
+/**
+ * \ingroup gdcmHeader
+ * \brief   Searches within the public dictionary for element value of
+ *          a given tag.
+ * @param   group Group of the researched tag.
+ * @param   element Element of the researched tag.
+ * @return  Corresponding element value when it exists, and the string
+ *          GDCM_UNFOUND ("gdcm::Unfound") otherwise.
+ */
+std::string gdcmHeader::GetPubElValByNumber(guint16 group, guint16 element) {
+   return PubElValSet.GetElValueByNumber(group, element);
+}
 
 /**
- * \ingroup       gdcmHeader
- * \brief         Loads the element while preserving the current
- *                underlying file position indicator as opposed to
- *                to LoadElementValue that modifies it.
- * @param ElVal   Element whose value shall be loaded. 
- * @return  
+ * \ingroup gdcmHeader
+ * \brief   Searches within the public dictionary for element value
+ *          representation of a given tag.
+ *
+ *          Obtaining the VR (Value Representation) might be needed by caller
+ *          to convert the string typed content to caller's native type 
+ *          (think of C++ vs Python). The VR is actually of a higher level
+ *          of semantics than just the native C++ type.
+ * @param   group Group of the researched tag.
+ * @param   element Element of the researched tag.
+ * @return  Corresponding element value representation when it exists,
+ *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
  */
-void gdcmHeader::LoadElementValueSafe(gdcmElValue * ElVal) {
-   long PositionOnEntry = ftell(fp);
-   LoadElementValue(ElVal);
-   fseek(fp, PositionOnEntry, SEEK_SET);
+std::string gdcmHeader::GetPubElValRepByNumber(guint16 group, guint16 element) {
+   gdcmElValue* elem =  PubElValSet.GetElementByNumber(group, element);
+   if ( !elem )
+      return GDCM_UNFOUND;
+   return elem->GetVR();
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief Reads a supposed to be 16 Bits integer
- * \     (swaps it depending on processor endianity) 
- *
- * @return integer acts as a boolean
+ * \brief   Accesses an existing gdcmElValue in the PubElValSet of this instance
+ *          through tag name and modifies it's content with the given value.
+ * @param   content new value to substitute with
+ * @param   tagName name of the tag to be modified
  */
-guint16 gdcmHeader::ReadInt16(void) {
-   guint16 g;
-   size_t item_read;
-   item_read = fread (&g, (size_t)2,(size_t)1, fp);
-   if ( item_read != 1 ) {
-      // dbg.Verbose(0, "gdcmHeader::ReadInt16", " Failed to read :");
-      // if(feof(fp)) 
-      //    dbg.Verbose(0, "gdcmHeader::ReadInt16", " End of File encountered");
-      if(ferror(fp)) 
-         dbg.Verbose(0, "gdcmHeader::ReadInt16", " File Error");
-      errno = 1;
-      return 0;
-   }
-   errno = 0;
-   g = SwapShort(g);
-   return g;
+bool gdcmHeader::SetPubElValByName(std::string content, std::string tagName) {
+   //return (  PubElValSet.SetElValueByName (content, tagName) );
+   gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); 
+   if( dictEntry == NULL)
+      return false;       
+   return(PubElValSet.SetElValueByNumber(content,
+                                         dictEntry->GetGroup(),
+                                         dictEntry->GetElement()));   
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief  Reads a supposed to be 32 Bits integer
- * \       (swaps it depending on processor endianity)  
- *
- * @return 
+ * \brief   Accesses an existing gdcmElValue (i.e. a Dicom Element)
+ *          in the PubElValSet of this instance
+ *          through it's (group, element) and modifies it's content with
+ *          the given value.
+ * @param   content new value to substitute with
+ * @param   group   group of the Dicom Element to modify
+ * @param   element element of the Dicom Element to modify
  */
-guint32 gdcmHeader::ReadInt32(void) {
-   guint32 g;
-   size_t item_read;
-   item_read = fread (&g, (size_t)4,(size_t)1, fp);
-   if ( item_read != 1 ) { 
-      //dbg.Verbose(0, "gdcmHeader::ReadInt32", " Failed to read :");
-      //if(feof(fp)) 
-      //   dbg.Verbose(0, "gdcmHeader::ReadInt32", " End of File encountered");
-     if(ferror(fp)) 
-         dbg.Verbose(0, "gdcmHeader::ReadInt32", " File Error");   
-      errno = 1;
-      return 0;
-   }
-   errno = 0;   
-   g = SwapLong(g);
-   return g;
+bool gdcmHeader::SetPubElValByNumber(std::string content, guint16 group,
+                                    guint16 element)
+                                    
+//TODO  : homogeneiser les noms : SetPubElValByNumber   
+//                    qui appelle PubElValSet.SetElValueByNumber 
+//        pourquoi pas            SetPubElValueByNumber ??
+{
+   return (  PubElValSet.SetElValueByNumber (content, group, element) );
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   
- *
- * @return 
+ * \brief   Accesses an existing gdcmElValue in the PubElValSet of this instance
+ *          through it's (group, element) and modifies it's length with
+ *          the given value.
+ * \warning Use with extreme caution.
+ * @param   length new length to substitute with
+ * @param   group   group of the ElVal to modify
+ * @param   element element of the ElVal to modify
+ * @return  1 on success, 0 otherwise.
  */
- gdcmElValue* gdcmHeader::GetElValueByNumber(guint16 Group, guint16 Elem) {
 
-   gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);  
-   if (!elValue) {
-      dbg.Verbose(1, "gdcmHeader::GetElValueByNumber",
-                  "failed to Locate gdcmElValue");
-      return (gdcmElValue*)0;
-   }
-   return elValue;
+bool gdcmHeader::SetPubElValLengthByNumber(guint32 length, guint16 group,
+                                    guint16 element) {
+       return (  PubElValSet.SetElValueLengthByNumber (length, group, element) );
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Build a new Element Value from all the low level arguments. 
- *          Check for existence of dictionary entry, and build
- *          a default one when absent.
- * @param   Group group   of the underlying DictEntry
- * @param   Elem  element of the underlying DictEntry
+ * \brief   Searches within elements parsed with the public dictionary 
+ *          and then within the elements parsed with the shadow dictionary
+ *          for the element value of a given tag.
+ * @param   tagName name of the searched element.
+ * @return  Corresponding element value when it exists,
+ *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
  */
-gdcmElValue* gdcmHeader::NewElValueByNumber(guint16 Group, guint16 Elem) {
-   // Find out if the tag we encountered is in the dictionaries:
-   gdcmDictEntry * NewTag = GetDictEntryByNumber(Group, Elem);
-   if (!NewTag)
-      NewTag = new gdcmDictEntry(Group, Elem);
-
-   gdcmElValue* NewElVal = new gdcmElValue(NewTag);
-   if (!NewElVal) {
-      dbg.Verbose(1, "gdcmHeader::NewElValueByNumber",
-                  "failed to allocate gdcmElValue");
-      return (gdcmElValue*)0;
-   }
-   return NewElVal;
+std::string gdcmHeader::GetElValByName(std::string tagName) {
+   std::string pub = GetPubElValByName(tagName);
+      return pub;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   TODO
- * @param   Value
- * @param   Group
- * @param   Elem
- * \return integer acts as a boolean
+ * \brief   Searches within elements parsed with the public dictionary 
+ *          and then within the elements parsed with the shadow dictionary
+ *          for the element value representation of a given tag.
+ *
+ *          Obtaining the VR (Value Representation) might be needed by caller
+ *          to convert the string typed content to caller's native type 
+ *          (think of C++ vs Python). The VR is actually of a higher level
+ *          of semantics than just the native C++ type.
+ * @param   tagName name of the searched element.
+ * @return  Corresponding element value representation when it exists,
+ *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
  */
-bool gdcmHeader::ReplaceOrCreateByNumber(std::string Value, 
-                                        guint16 Group, guint16 Elem ) {
-       // TODO : FIXME JPRx
-       // curieux, non ?
-       // on (je) cree une Elvalue ne contenant pas de valeur
-       // on l'ajoute au ElValSet
-       // on affecte une valeur a cette ElValue a l'interieur du ElValSet
-       // --> devrait pouvoir etre fait + simplement ???
-   if (CheckIfExistByNumber(Group, Elem) == 0) {
-      gdcmElValue* a =NewElValueByNumber(Group, Elem);
-      if (a == NULL) 
-         return false;
-      PubElValSet.Add(a);
-   }   
-   PubElValSet.SetElValueByNumber(Value, Group, Elem);
-   return(true);
-}   
-
+std::string gdcmHeader::GetElValRepByName(std::string tagName) {
+   std::string pub = GetPubElValRepByName(tagName);
+      return pub;
+}
 
 /**
  * \ingroup gdcmHeader
- * \brief   Modify (or Creates if not found) an element
- * @param   Value new value
- * @param   Group
- * @param   Elem
- * \return integer acts as a boolean 
- * 
+ * \brief   Searches within elements parsed with the public dictionary 
+ *          and then within the elements parsed with the shadow dictionary
+ *          for the element value of a given tag.
+ * @param   group Group of the searched tag.
+ * @param   element Element of the searched tag.
+ * @return  Corresponding element value representation when it exists,
+ *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
  */
-bool gdcmHeader::ReplaceOrCreateByNumber(char* Value, guint16 Group, guint16 Elem ) {
-
-   gdcmElValue* nvElValue=NewElValueByNumber(Group, Elem);
-   // TODO : check if fails
-   PubElValSet.Add(nvElValue);
-   std::string v = Value;      
-   PubElValSet.SetElValueByNumber(v, Group, Elem);
-   return(true);
-}  
-
+std::string gdcmHeader::GetElValByNumber(guint16 group, guint16 element) {
+   std::string pub = GetPubElValByNumber(group, element);
+      return pub;
+}
 
 /**
  * \ingroup gdcmHeader
- * \brief   Set a new value if the invoked element exists
- *          Seems to be useless !!!
- * @param   Value
- * @param   Group
- * @param   Elem
- * \return integer acts as a boolean 
+ * \brief   Searches within elements parsed with the public dictionary 
+ *          and then within the elements parsed with the shadow dictionary
+ *          for the element value representation of a given tag.
+ *
+ *          Obtaining the VR (Value Representation) might be needed by caller
+ *          to convert the string typed content to caller's native type 
+ *          (think of C++ vs Python). The VR is actually of a higher level
+ *          of semantics than just the native C++ type.
+ * @param   group Group of the searched tag.
+ * @param   element Element of the searched tag.
+ * @return  Corresponding element value representation when it exists,
+ *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
  */
-bool gdcmHeader::ReplaceIfExistByNumber(char* Value, guint16 Group, guint16 Elem ) {
+std::string gdcmHeader::GetElValRepByNumber(guint16 group, guint16 element) {
+   std::string pub = GetPubElValRepByNumber(group, element);
+      return pub;
+}
 
-   //gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);
-   std::string v = Value;      
-   PubElValSet.SetElValueByNumber(v, Group, Elem);
+/**
+ * \ingroup gdcmElValSet
+ * \brief  Sets the value (string) of the target Dicom Element
+ * @param   content string value of the Dicom Element
+ * @param   tagName name of the searched Dicom Element.
+ * @return  true when found
+ */
+bool gdcmHeader::SetElValueByName(std::string content,
+                                  std::string tagName) {
+                                   
+   gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); 
+   if( dictEntry == NULL)
+      return false;                                
+                                                                                                   
+                                   
+   TagKey key = gdcmDictEntry::TranslateToKey(dictEntry->GetGroup(), 
+                                              dictEntry->GetElement());
+   if ( ! PubElValSet.GetTagHt().count(key))
+      return false;
+   int l = content.length();
+   if(l%2) {  // Odd length are padded with a space (020H).
+      l++;
+      content = content + '\0';
+   }
+      
+   //tagHt[key]->SetValue(content);   
+   gdcmElValue * a;
+   IterHT p;
+   TagElValueHT::iterator p2;
+   // DO NOT remove the following lines : they explain the stuff   
+   //p= tagHt.equal_range(key); // get a pair of iterators first-last synonym
+   //p2=p.first;                // iterator on the first synonym 
+   //a=p2->second;              // H Table target column (2-nd col)
+    
+   // or, easier :
+   a = ((PubElValSet.GetTagHt().equal_range(key)).first)->second; 
+       
+   a-> SetValue(content); 
+   
+   //std::string vr = tagHt[key]->GetVR();
+   std::string vr = a->GetVR();
+   
+   guint32 lgr;
+   if( (vr == "US") || (vr == "SS") ) 
+      lgr = 2;
+   else if( (vr == "UL") || (vr == "SL") )
+      lgr = 4;
+   else
+      lgr = l;    
+   //tagHt[key]->SetLength(lgr);
+   a->SetLength(lgr);   
    return true;
-} 
-
+}
 
 /**
  * \ingroup gdcmHeader
- * \brief   Checks if a given ElValue (group,number) 
- * \ exists in the Public ElValSet
- * @param   Group
- * @param   Elem
- * @return  integer acts as a boolean  
+ * \brief   
+ * @param   exception_on_error
+ * @return  
  */
-bool gdcmHeader::CheckIfExistByNumber(guint16 Group, guint16 Elem ) {
-   return (PubElValSet.CheckIfExistByNumber(Group, Elem));
- }
-  
+FILE *gdcmHeader::OpenFile(bool exception_on_error)
+  throw(gdcmFileError) {
+  fp=fopen(filename.c_str(),"rb");
+  if(exception_on_error) {
+    if(!fp)
+      throw gdcmFileError("gdcmHeader::gdcmHeader(const char *, bool)");
+  }
+
+  if ( fp ) {
+     guint16 zero;
+     fread(&zero,  (size_t)2, (size_t)1, fp);
+
+    //ACR -- or DICOM with no Preamble
+    if( zero == 0x0008 || zero == 0x0800 || zero == 0x0002 || zero == 0x0200)
+       return(fp);
+
+    //DICOM
+    fseek(fp, 126L, SEEK_CUR);
+    char dicm[4];
+    fread(dicm,  (size_t)4, (size_t)1, fp);
+    if( memcmp(dicm, "DICM", 4) == 0 )
+       return(fp);
+
+    fclose(fp);
+    dbg.Verbose(0, "gdcmHeader::gdcmHeader not DICOM/ACR", filename.c_str());
+  }
+  else {
+    dbg.Verbose(0, "gdcmHeader::gdcmHeader cannot open file", filename.c_str());
+  }
+  return(NULL);
+}
+
 /**
  * \ingroup gdcmHeader
- * \brief   Build a new Element Value from all the low level arguments. 
- *          Check for existence of dictionary entry, and build
- *          a default one when absent.
- * @param   Name    Name of the underlying DictEntry
+ * \brief   
+ * @return  TRUE if the close was successfull 
  */
-gdcmElValue* gdcmHeader::NewElValueByName(std::string Name) {
-
-   gdcmDictEntry * NewTag = GetDictEntryByName(Name);
-   if (!NewTag)
-      NewTag = new gdcmDictEntry(0xffff, 0xffff, "LO", "Unknown", Name);
-
-   gdcmElValue* NewElVal = new gdcmElValue(NewTag);
-   if (!NewElVal) {
-      dbg.Verbose(1, "gdcmHeader::ObtainElValueByName",
-                  "failed to allocate gdcmElValue");
-      return (gdcmElValue*)0;
-   }
-   return NewElVal;
-}  
+bool gdcmHeader::CloseFile(void) {
+  int closed = fclose(fp);
+  fp = (FILE *)0;
+  if (! closed)
+     return false;
+  return true;
+}
 
 /**
  * \ingroup gdcmHeader
- * \brief   Read the next tag but WITHOUT loading it's value
- * @return  On succes the newly created ElValue, NULL on failure.      
+ * \brief   Parses the header of the file but WITHOUT loading element values.
  */
-gdcmElValue * gdcmHeader::ReadNextElement(void) {
-  
-   guint16 g,n;
-   gdcmElValue * NewElVal;
-   
-   g = ReadInt16();
-   n = ReadInt16();
-      
-   if (errno == 1)
-      // We reached the EOF (or an error occured) and header parsing
-      // has to be considered as finished.
-      return (gdcmElValue *)0;
+void gdcmHeader::ParseHeader(bool exception_on_error) throw(gdcmFormatError) {
+   gdcmElValue * newElValue = (gdcmElValue *)0;
    
-   NewElVal = NewElValueByNumber(g, n);
-   FindVR(NewElVal);
-   FindLength(NewElVal);
-       
-   if (errno == 1) {
-      // Call it quits
-      return (gdcmElValue *)0;
+   rewind(fp);
+   CheckSwap();
+   while ( (newElValue = ReadNextElement()) ) { 
+      SkipElementValue(newElValue);
+      PubElValSet.Add(newElValue);
    }
-   NewElVal->SetOffset(ftell(fp));  
-   //if ( (g==0x7fe0) && (n==0x0010) ) 
-   return NewElVal;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Apply some heuristics to predict wether the considered 
- *          element value contains/represents an integer or not.
- * @param   ElVal The element value on which to apply the predicate.
- * @return  The result of the heuristical predicate.
- */
-bool gdcmHeader::IsAnInteger(gdcmElValue * ElVal) {
-   guint16 element = ElVal->GetElement();
-   guint16 group   = ElVal->GetGroup();
-   std::string  vr = ElVal->GetVR();
-   guint32 length  = ElVal->GetLength();
+ * \brief
+ * @return integer, acts as a Boolean
+ */ 
+bool gdcmHeader::Write(FILE * fp, FileType type) {
 
-         cout << "Found :" << std::hex 
-             << group << " , " << element << std::endl;
-             
-   // When we have some semantics on the element we just read, and if we
-   // a priori know we are dealing with an integer, then we shall be
-   // able to swap it's element value properly.
-   if ( element == 0 )  {  // This is the group length of the group
-      if (length == 4)
-         return true;
-      else {
-         cout << "Error on :" << std::hex 
-             << group << " , " << element << std::endl;
-         dbg.Error("gdcmHeader::IsAnInteger",
-            "Erroneous Group Length element length.");     
-      }
+   // TODO : move the following lines (and a lot of others, to be written)
+   // to a future function CheckAndCorrectHeader
+
+   if (type == ImplicitVR) {
+      std::string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
+      ReplaceOrCreateByNumber(implicitVRTransfertSyntax,0x0002, 0x0010);
+      
+      //FIXME Refer to standards on page 21, chapter 6.2 "Value representation":
+      //      values with a VR of UI shall be padded with a single trailing null
+      //      Dans le cas suivant on doit pader manuellement avec un 0
+      
+      PubElValSet.SetElValueLengthByNumber(18, 0x0002, 0x0010);
+   } 
+
+   if (type == ExplicitVR) {
+      std::string explicitVRTransfertSyntax = "1.2.840.10008.1.2.1";
+      ReplaceOrCreateByNumber(explicitVRTransfertSyntax,0x0002, 0x0010);
+      
+      //FIXME Refer to standards on page 21, chapter 6.2 "Value representation":
+      //      values with a VR of UI shall be padded with a single trailing null
+      //      Dans le cas suivant on doit pader manuellement avec un 0
+      
+      PubElValSet.SetElValueLengthByNumber(20, 0x0002, 0x0010);
    }
-   if ( (vr == "UL") || (vr == "US") || (vr == "SL") || (vr == "SS") )
-      return true;
-   
-   return false;
+
+   return PubElValSet.Write(fp, type);
 }
 
 /**
- * \ingroup gdcmHeader
- * \brief   Recover the offset (from the beginning of the file) of the pixels.
+ * \ingroup   gdcmFile
+ * \brief Sets the Pixel Area size in the Header
+ *        --> not-for-rats function
+ * 
+ * \warning WARNING doit-etre etre publique ? 
+ * TODO : y aurait il un inconvenient Ã  fusionner ces 2 fonctions
+ *
+ * @param ImageDataSize new Pixel Area Size
+ *        warning : nothing else is checked
  */
-size_t gdcmHeader::GetPixelOffset(void) {
-   // If this file complies with the norm we should encounter the
-   // "Image Location" tag (0x0028,  0x0200). This tag contains the
-   // the group that contains the pixel data (hence the "Pixel Data"
-   // is found by indirection through the "Image Location").
-   // Inside the group pointed by "Image Location" the searched element
-   // is conventionally the element 0x0010 (when the norm is respected).
-   // When the "Image Location" is absent we default to group 0x7fe0.
-   guint16 grPixel;
-   guint16 numPixel;
-   std::string ImageLocation = GetPubElValByNumber(0x0028, 0x0200);
-   if ( ImageLocation == GDCM_UNFOUND ) { // Image Location
-      grPixel = 0x7fe0;
-   } else {
-      grPixel = (guint16) atoi( ImageLocation.c_str() );
-   }
-   if (grPixel != 0x7fe0)
-      // This is a kludge for old dirty Philips imager.
-      numPixel = 0x1010;
-   else
-      numPixel = 0x0010;
-         
-   gdcmElValue* PixelElement = PubElValSet.GetElementByNumber(grPixel,
-                                                              numPixel);
-   if (PixelElement)
-      return PixelElement->GetOffset();
-   else
-      return 0;
+void gdcmHeader::SetImageDataSize(size_t ImageDataSize) {
+   std::string content1;
+   char car[20];       
+   // Assumes ElValue (0x7fe0, 0x0010) exists ...      
+   sprintf(car,"%d",ImageDataSize);
+   gdcmElValue *a = GetElValueByNumber(0x7fe0, 0x0010);
+   a->SetLength(ImageDataSize);
+               
+   ImageDataSize+=8;
+   sprintf(car,"%d",ImageDataSize);
+   content1=car;       
+   SetPubElValByNumber(content1, 0x7fe0, 0x0000);
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Recover the pixel area length (in Bytes) .
+ * \brief   Swaps back the bytes of 4-byte long integer accordingly to
+ *          processor order.
+ * @return  The properly swaped 32 bits integer.
  */
-size_t gdcmHeader::GetPixelAreaLength(void) {
-   // If this file complies with the norm we should encounter the
-   // "Image Location" tag (0x0028,  0x0200). This tag contains the
-   // the group that contains the pixel data (hence the "Pixel Data"
-   // is found by indirection through the "Image Location").
-   // Inside the group pointed by "Image Location" the searched element
-   // is conventionally the element 0x0010 (when the norm is respected).
-   // When the "Image Location" is absent we default to group 0x7fe0.
-   guint16 grPixel;
-   guint16 numPixel;
-   std::string ImageLocation = GetPubElValByNumber(0x0028, 0x0200);
-   if ( ImageLocation == GDCM_UNFOUND ) {
-      grPixel = 0x7fe0;
-   } else {
-      grPixel = (guint16) atoi( ImageLocation.c_str() );
+guint32 gdcmHeader::SwapLong(guint32 a) {
+   switch (sw) {
+   case    0 :
+      break;
+   case 4321 :
+      a=(   ((a<<24) & 0xff000000) | ((a<<8)  & 0x00ff0000)    | 
+            ((a>>8)  & 0x0000ff00) | ((a>>24) & 0x000000ff) );
+      break;
+   
+   case 3412 :
+      a=(   ((a<<16) & 0xffff0000) | ((a>>16) & 0x0000ffff) );
+      break;
+   
+   case 2143 :
+      a=(    ((a<<8) & 0xff00ff00) | ((a>>8) & 0x00ff00ff)  );
+      break;
+   default :
+      dbg.Error(" gdcmHeader::SwapLong : unset swap code");
+      a=0;
    }
-   if (grPixel != 0x7fe0)
-      // This is a kludge for old dirty Philips imager.
-      numPixel = 0x1010;
-   else
-      numPixel = 0x0010;
-         
-   gdcmElValue* PixelElement = PubElValSet.GetElementByNumber(grPixel,
-                                                              numPixel);
-   if (PixelElement)
-      return PixelElement->GetLength();
-   else
-      return 0;
+   return(a);
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Searches both the public and the shadow dictionary (when they
- *          exist) for the presence of the DictEntry with given
- *          group and element. The public dictionary has precedence on the
- *          shadow one.
- * @param   group   group of the searched DictEntry
- * @param   element element of the searched DictEntry
- * @return  Corresponding DictEntry when it exists, NULL otherwise.
+ * \brief   Swaps the bytes so they agree with the processor order
+ * @return  The properly swaped 16 bits integer.
  */
-gdcmDictEntry * gdcmHeader::GetDictEntryByNumber(guint16 group,
-                                                 guint16 element) {
-   gdcmDictEntry * found = (gdcmDictEntry*)0;
-   if (!RefPubDict && !RefShaDict) {
-      dbg.Verbose(0, "gdcmHeader::GetDictEntry",
-                     "we SHOULD have a default dictionary");
-   }
-   if (RefPubDict) {
-      found = RefPubDict->GetTagByNumber(group, element);
-      if (found)
-         return found;
-   }
-   if (RefShaDict) {
-      found = RefShaDict->GetTagByNumber(group, element);
-      if (found)
-         return found;
-   }
-   return found;
+guint16 gdcmHeader::SwapShort(guint16 a) {
+   if ( (sw==4321)  || (sw==2143) )
+      a =(((a<<8) & 0x0ff00) | ((a>>8)&0x00ff));
+   return (a);
 }
 
+//-----------------------------------------------------------------------------
+// Protected
 /**
  * \ingroup gdcmHeader
- * \brief   Searches both the public and the shadow dictionary (when they
- *          exist) for the presence of the DictEntry with given name.
- *          The public dictionary has precedence on the shadow one.
- * @param   Name name of the searched DictEntry
- * @return  Corresponding DictEntry when it exists, NULL otherwise.
+ * \brief   
+ *
+ * @return 
  */
-gdcmDictEntry * gdcmHeader::GetDictEntryByName(std::string Name) {
-   gdcmDictEntry * found = (gdcmDictEntry*)0;
-   if (!RefPubDict && !RefShaDict) {
-      dbg.Verbose(0, "gdcmHeader::GetDictEntry",
-                     "we SHOULD have a default dictionary");
-   }
-   if (RefPubDict) {
-      found = RefPubDict->GetTagByName(Name);
-      if (found)
-         return found;
-   }
-   if (RefShaDict) {
-      found = RefShaDict->GetTagByName(Name);
-      if (found)
-         return found;
+gdcmElValue* gdcmHeader::GetElValueByNumber(guint16 Group, guint16 Elem) {
+
+   gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);  
+   if (!elValue) {
+      dbg.Verbose(1, "gdcmHeader::GetElValueByNumber",
+                  "failed to Locate gdcmElValue");
+      return (gdcmElValue*)0;
    }
-   return found;
+   return elValue;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Searches within the public dictionary for element value of
- *          a given tag.
- * @param   group Group of the researched tag.
- * @param   element Element of the researched tag.
- * @return  Corresponding element value when it exists, and the string
- *          GDCM_UNFOUND ("gdcm::Unfound") otherwise.
+ * \brief   Checks if a given ElValue (group,number) 
+ * \ exists in the Public ElValSet
+ * @param   Group
+ * @param   Elem
+ * @return  integer acts as a boolean  
  */
-std::string gdcmHeader::GetPubElValByNumber(guint16 group, guint16 element) {
-   return PubElValSet.GetElValueByNumber(group, element);
+bool gdcmHeader::CheckIfExistByNumber(guint16 Group, guint16 Elem ) {
+   return (PubElValSet.CheckIfExistByNumber(Group, Elem));
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Searches within the public dictionary for element value
- *          representation of a given tag.
- *
- *          Obtaining the VR (Value Representation) might be needed by caller
- *          to convert the string typed content to caller's native type 
- *          (think of C++ vs Python). The VR is actually of a higher level
- *          of semantics than just the native C++ type.
- * @param   group Group of the researched tag.
- * @param   element Element of the researched tag.
- * @return  Corresponding element value representation when it exists,
- *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
+ * \brief   Gets (from Header) the offset  of a 'non string' element value 
+ * \        (LoadElementValue has already be executed)
+ * @param   Group
+ * @param   Elem
+ * @return File Offset of the Element Value 
  */
-std::string gdcmHeader::GetPubElValRepByNumber(guint16 group, guint16 element) {
-   gdcmElValue* elem =  PubElValSet.GetElementByNumber(group, element);
-   if ( !elem )
-      return GDCM_UNFOUND;
-   return elem->GetVR();
+size_t gdcmHeader::GetPubElValOffsetByNumber(guint16 Group, guint16 Elem) {
+   gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);  
+   if (!elValue) {
+      dbg.Verbose(1, "gdcmHeader::GetElValueByNumber",
+                      "failed to Locate gdcmElValue");
+      return (size_t)0;
+   }
+   return elValue->GetOffset();
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Searches within the public dictionary for element value of
- *          a given tag.
- * @param   tagName name of the searched element.
- * @return  Corresponding element value when it exists, and the string
- *          GDCM_UNFOUND ("gdcm::Unfound") otherwise.
+ * \brief   Gets (from Header) a 'non string' element value 
+ * \        (LoadElementValue has already be executed)  
+ * @param   Group
+ * @param   Elem
+ * @return Pointer to the 'non string' area
  */
-std::string gdcmHeader::GetPubElValByName(std::string tagName) {
-   gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); 
-   if( dictEntry == NULL)
-      return GDCM_UNFOUND;
-  return(PubElValSet.GetElValueByNumber(dictEntry->GetGroup(),
-                                        dictEntry->GetElement()));  
+void * gdcmHeader::GetPubElValVoidAreaByNumber(guint16 Group, guint16 Elem) {
+   gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);  
+   if (!elValue) {
+      dbg.Verbose(1, "gdcmHeader::GetElValueByNumber",
+                  "failed to Locate gdcmElValue");
+      return (NULL);
+   }
+   return elValue->GetVoidArea();
 }
 
 /**
- * \ingroup gdcmHeader
- * \brief   Searches within the elements parsed with the public dictionary for
- *          the element value representation of a given tag.
- *
- *          Obtaining the VR (Value Representation) might be needed by caller
- *          to convert the string typed content to caller's native type 
- *          (think of C++ vs Python). The VR is actually of a higher level
- *          of semantics than just the native C++ type.
- * @param   tagName name of the searched element.
- * @return  Corresponding element value representation when it exists,
- *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
+ * \ingroup       gdcmHeader
+ * \brief         Loads (from disk) the element content 
+ *                when a string is not suitable
  */
-std::string gdcmHeader::GetPubElValRepByName(std::string tagName) {
-   gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); 
-   if( dictEntry == NULL)
-      return GDCM_UNFOUND;   
-   gdcmElValue* elem =  PubElValSet.GetElementByNumber(
-                                         dictEntry->GetGroup(),
-                                         dictEntry->GetElement());                                     
-   return elem->GetVR();
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief   Searches within elements parsed with the public dictionary 
- *          and then within the elements parsed with the shadow dictionary
- *          for the element value of a given tag.
- * @param   group Group of the searched tag.
- * @param   element Element of the searched tag.
- * @return  Corresponding element value representation when it exists,
- *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
- */
-std::string gdcmHeader::GetElValByNumber(guint16 group, guint16 element) {
-   std::string pub = GetPubElValByNumber(group, element);
-      return pub;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief   Searches within elements parsed with the public dictionary 
- *          and then within the elements parsed with the shadow dictionary
- *          for the element value representation of a given tag.
- *
- *          Obtaining the VR (Value Representation) might be needed by caller
- *          to convert the string typed content to caller's native type 
- *          (think of C++ vs Python). The VR is actually of a higher level
- *          of semantics than just the native C++ type.
- * @param   group Group of the searched tag.
- * @param   element Element of the searched tag.
- * @return  Corresponding element value representation when it exists,
- *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
- */
-std::string gdcmHeader::GetElValRepByNumber(guint16 group, guint16 element) {
-   std::string pub = GetPubElValRepByNumber(group, element);
-      return pub;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief   Searches within elements parsed with the public dictionary 
- *          and then within the elements parsed with the shadow dictionary
- *          for the element value of a given tag.
- * @param   tagName name of the searched element.
- * @return  Corresponding element value when it exists,
- *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
- */
-std::string gdcmHeader::GetElValByName(std::string tagName) {
-   std::string pub = GetPubElValByName(tagName);
-      return pub;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief   Searches within elements parsed with the public dictionary 
- *          and then within the elements parsed with the shadow dictionary
- *          for the element value representation of a given tag.
- *
- *          Obtaining the VR (Value Representation) might be needed by caller
- *          to convert the string typed content to caller's native type 
- *          (think of C++ vs Python). The VR is actually of a higher level
- *          of semantics than just the native C++ type.
- * @param   tagName name of the searched element.
- * @return  Corresponding element value representation when it exists,
- *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
- */
-std::string gdcmHeader::GetElValRepByName(std::string tagName) {
-   std::string pub = GetPubElValRepByName(tagName);
-      return pub;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief   Accesses an existing gdcmElValue (i.e. a Dicom Element)
- *          in the PubElValSet of this instance
- *          through it's (group, element) and modifies it's content with
- *          the given value.
- * @param   content new value to substitute with
- * @param   group   group of the Dicom Element to modify
- * @param   element element of the Dicom Element to modify
- */
-bool gdcmHeader::SetPubElValByNumber(std::string content, guint16 group,
-                                    guint16 element)
-                                    
-//TODO  : homogeneiser les noms : SetPubElValByNumber   
-//                    qui appelle PubElValSet.SetElValueByNumber 
-//        pourquoi pas            SetPubElValueByNumber ??
-{
-   return (  PubElValSet.SetElValueByNumber (content, group, element) );
+void * gdcmHeader::LoadElementVoidArea(guint16 Group, guint16 Elem) {
+   gdcmElValue * Element= PubElValSet.GetElementByNumber(Group, Elem);
+   if ( !Element )
+      return NULL;
+   size_t o =(size_t)Element->GetOffset();
+   fseek(fp, o, SEEK_SET);
+   int l=Element->GetLength();
+   void * a = malloc(l);
+   if(!a) {
+       return NULL;
+   }  
+   /* int res = */ PubElValSet.SetVoidAreaByNumber(a, Group, Elem);
+   // TODO check the result 
+   size_t l2 = fread(a, 1, l ,fp);
+   if(l != l2) {
+       free(a);
+       return NULL;
+   }
+   return a;  
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Accesses an existing gdcmElValue in the PubElValSet of this instance
- *          through tag name and modifies it's content with the given value.
- * @param   content new value to substitute with
- * @param   tagName name of the tag to be modified
+ * \brief   TODO
+ * @param   Value
+ * @param   Group
+ * @param   Elem
+ * \return integer acts as a boolean
  */
-bool gdcmHeader::SetPubElValByName(std::string content, std::string tagName) {
-   //return (  PubElValSet.SetElValueByName (content, tagName) );
-   gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); 
-   if( dictEntry == NULL)
-      return false;       
-   return(PubElValSet.SetElValueByNumber(content,
-                                         dictEntry->GetGroup(),
-                                         dictEntry->GetElement()));   
-}
+bool gdcmHeader::ReplaceOrCreateByNumber(std::string Value, 
+                                        guint16 Group, guint16 Elem ) {
+       // TODO : FIXME JPRx
+       // curieux, non ?
+       // on (je) cree une Elvalue ne contenant pas de valeur
+       // on l'ajoute au ElValSet
+       // on affecte une valeur a cette ElValue a l'interieur du ElValSet
+       // --> devrait pouvoir etre fait + simplement ???
+   if (CheckIfExistByNumber(Group, Elem) == 0) {
+      gdcmElValue* a =NewElValueByNumber(Group, Elem);
+      if (a == NULL) 
+         return false;
+      PubElValSet.Add(a);
+   }   
+   PubElValSet.SetElValueByNumber(Value, Group, Elem);
+   return(true);
+}   
 
 /**
  * \ingroup gdcmHeader
- * \brief   Accesses an existing gdcmElValue in the PubElValSet of this instance
- *          through it's (group, element) and modifies it's length with
- *          the given value.
- * \warning Use with extreme caution.
- * @param   length new length to substitute with
- * @param   group   group of the ElVal to modify
- * @param   element element of the ElVal to modify
- * @return  1 on success, 0 otherwise.
+ * \brief   Modify (or Creates if not found) an element
+ * @param   Value new value
+ * @param   Group
+ * @param   Elem
+ * \return integer acts as a boolean 
+ * 
  */
+bool gdcmHeader::ReplaceOrCreateByNumber(char* Value, guint16 Group, guint16 Elem ) {
 
-bool gdcmHeader::SetPubElValLengthByNumber(guint32 length, guint16 group,
-                                    guint16 element) {
-       return (  PubElValSet.SetElValueLengthByNumber (length, group, element) );
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief   Parses the header of the file but WITHOUT loading element values.
- */
-void gdcmHeader::ParseHeader(bool exception_on_error) throw(gdcmFormatError) {
-   gdcmElValue * newElValue = (gdcmElValue *)0;
-   
-   rewind(fp);
-   CheckSwap();
-   while ( (newElValue = ReadNextElement()) ) { 
-      SkipElementValue(newElValue);
-      PubElValSet.Add(newElValue);
-   }
-}
+   gdcmElValue* nvElValue=NewElValueByNumber(Group, Elem);
+   // TODO : check if fails
+   PubElValSet.Add(nvElValue);
+   std::string v = Value;      
+   PubElValSet.SetElValueByNumber(v, Group, Elem);
+   return(true);
+}  
 
 /**
  * \ingroup gdcmHeader
- * \brief  
- * @return 
+ * \brief   Set a new value if the invoked element exists
+ *          Seems to be useless !!!
+ * @param   Value
+ * @param   Group
+ * @param   Elem
+ * \return integer acts as a boolean 
  */
-FileType gdcmHeader::GetFileType(void)
-{
-   return(filetype);
-}
+bool gdcmHeader::ReplaceIfExistByNumber(char* Value, guint16 Group, guint16 Elem ) {
 
-/**
- * \ingroup gdcmHeader
- * \brief  This predicate, based on hopefully reasonable heuristics,
- *         decides whether or not the current gdcmHeader was properly parsed
- *         and contains the mandatory information for being considered as
- *         a well formed and usable image.
- * @return true when gdcmHeader is the one of a reasonable Dicom file,
- *         false otherwise. 
- */
-bool gdcmHeader::IsReadable(void) {
-   std::string res = GetPubElValByNumber(0x0028, 0x0005);
-   if (       res != GDCM_UNFOUND
-      && atoi(res.c_str()) > 4 ) {
-      return false; // Image Dimensions
-   }
-   if ( GetPubElValByNumber(0x0028, 0x0100) == GDCM_UNFOUND )
-      return false; // "Bits Allocated"
-   if ( GetPubElValByNumber(0x0028, 0x0101) == GDCM_UNFOUND )
-      return false; // "Bits Stored"
-   if ( GetPubElValByNumber(0x0028, 0x0102) == GDCM_UNFOUND )
-      return false; // "High Bit"
-   if ( GetPubElValByNumber(0x0028, 0x0103) == GDCM_UNFOUND )
-      return false; // "Pixel Representation"
+   //gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);
+   std::string v = Value;      
+   PubElValSet.SetElValueByNumber(v, Group, Elem);
    return true;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief   Small utility function that creates a new manually crafted
- *          (as opposed as read from the file) gdcmElValue with user
- *          specified name and adds it to the public tag hash table.
- * \note    A fake TagKey is generated so the PubDict can keep it's coherence.
- * @param   NewTagName The name to be given to this new tag.
- * @param   VR The Value Representation to be given to this new tag.
- * @ return The newly hand crafted Element Value.
- */
-gdcmElValue* gdcmHeader::NewManualElValToPubDict(std::string NewTagName, 
-                                                 std::string VR) {
-   gdcmElValue* NewElVal = (gdcmElValue*)0;
-   guint32 StuffGroup = 0xffff;   // Group to be stuffed with additional info
-   guint32 FreeElem = 0;
-   gdcmDictEntry* NewEntry = (gdcmDictEntry*)0;
-
-   FreeElem = PubElValSet.GenerateFreeTagKeyInGroup(StuffGroup);
-   if (FreeElem == UINT32_MAX) {
-      dbg.Verbose(1, "gdcmHeader::NewManualElValToPubDict",
-                     "Group 0xffff in Public Dict is full");
-      return (gdcmElValue*)0;
-   }
-   NewEntry = new gdcmDictEntry(StuffGroup, FreeElem,
-                                VR, "GDCM", NewTagName);
-   NewElVal = new gdcmElValue(NewEntry);
-   PubElValSet.Add(NewElVal);
-   return NewElVal;
-}
+} 
 
+//-----------------------------------------------------------------------------
+// Private
 /**
  * \ingroup gdcmHeader
  * \brief   Loads the element values of all the elements present in the
@@ -1740,8 +1394,8 @@ void gdcmHeader::LoadElements(void) {
    //     LoadElementValue(tag->second);
    //}
    
-     for (ListTag::iterator i = GetListElem().begin();  
-          i != GetListElem().end();
+     for (ListTag::iterator i = GetPubListElem().begin();  
+          i != GetPubListElem().end();
           ++i){
         LoadElementValue(*i);   
      }    
@@ -1781,560 +1435,891 @@ void gdcmHeader::LoadElements(void) {
 }
 
 /**
-  * \ingroup gdcmHeader
-  * \brief
-  * @return
-  */ 
-void gdcmHeader::PrintPubElVal(std::ostream & os) {
-   PubElValSet.Print(os);
-}
-
-/**
-  * \ingroup gdcmHeader
-  * \brief 
-  * @return
-  */  
-void gdcmHeader::PrintPubDict(std::ostream & os) {
-   RefPubDict->Print(os);
-}
-
-/**
-  * \ingroup gdcmHeader
-  * \brief
-  * @return integer, acts as a Boolean
-  */ 
-bool gdcmHeader::Write(FILE * fp, FileType type) {
+ * \ingroup       gdcmHeader
+ * \brief         Loads the element content if it's length is not bigger
+ *                than the value specified with
+ *                gdcmHeader::SetMaxSizeLoadElementValue()
+ */
+void gdcmHeader::LoadElementValue(gdcmElValue * ElVal) {
+   size_t item_read;
+   guint16 group  = ElVal->GetGroup();
+   std::string  vr= ElVal->GetVR();
+   guint32 length = ElVal->GetLength();
+   bool SkipLoad  = false;
 
-   // TODO : move the following lines (and a lot of others, to be written)
-   // to a future function CheckAndCorrectHeader
+   fseek(fp, (long)ElVal->GetOffset(), SEEK_SET);
+   
+   // FIXME Sequences not treated yet !
+   //
+   // Ne faudrait-il pas au contraire trouver immediatement
+   // une maniere 'propre' de traiter les sequences (vr = SQ)
+   // car commencer par les ignorer risque de conduire a qq chose
+   // qui pourrait ne pas etre generalisable
+   // Well, I'm expecting your code !!!
+   
+   // the test was commented out to 'go inside' the SeQuences
+   // we don't any longer skip them !
+    
+   // if( vr == "SQ" )  
+   //    SkipLoad = true;
 
-   if (type == ImplicitVR) {
-      std::string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
-      ReplaceOrCreateByNumber(implicitVRTransfertSyntax,0x0002, 0x0010);
-      
-      //FIXME Refer to standards on page 21, chapter 6.2 "Value representation":
-      //      values with a VR of UI shall be padded with a single trailing null
-      //      Dans le cas suivant on doit pader manuellement avec un 0
-      
-      PubElValSet.SetElValueLengthByNumber(18, 0x0002, 0x0010);
-   } 
+   // A SeQuence "contains" a set of Elements.  
+   //          (fffe e000) tells us an Element is beginning
+   //          (fffe e00d) tells us an Element just ended
+   //          (fffe e0dd) tells us the current SeQuence just ended
+   if( group == 0xfffe )
+      SkipLoad = true;
 
-   if (type == ExplicitVR) {
-      std::string explicitVRTransfertSyntax = "1.2.840.10008.1.2.1";
-      ReplaceOrCreateByNumber(explicitVRTransfertSyntax,0x0002, 0x0010);
-      
-      //FIXME Refer to standards on page 21, chapter 6.2 "Value representation":
-      //      values with a VR of UI shall be padded with a single trailing null
-      //      Dans le cas suivant on doit pader manuellement avec un 0
-      
-      PubElValSet.SetElValueLengthByNumber(20, 0x0002, 0x0010);
+   if ( SkipLoad ) {
+      ElVal->SetLength(0);
+      ElVal->SetValue("gdcm::Skipped");
+      return;
    }
 
-   return PubElValSet.Write(fp, type);
-}
-
-//
-// ------------------------ 'non string' elements related functions
-//
+   // When the length is zero things are easy:
+   if ( length == 0 ) {
+      ElVal->SetValue("");
+      return;
+   }
 
-/**
- * \ingroup       gdcmHeader
- * \brief         Loads (from disk) the element content 
- *                when a string is not suitable
- */
-void * gdcmHeader::LoadElementVoidArea(guint16 Group, guint16 Elem) {
-   gdcmElValue * Element= PubElValSet.GetElementByNumber(Group, Elem);
-   if ( !Element )
-      return NULL;
-   size_t o =(size_t)Element->GetOffset();
-   fseek(fp, o, SEEK_SET);
-   int l=Element->GetLength();
-   void * a = malloc(l);
-   if(!a) {
-       return NULL;
-   }  
-   /* int res = */ PubElValSet.SetVoidAreaByNumber(a, Group, Elem);
-   // TODO check the result 
-   size_t l2 = fread(a, 1, l ,fp);
-   if(l != l2) {
-       free(a);
-       return NULL;
+   // The elements whose length is bigger than the specified upper bound
+   // are not loaded. Instead we leave a short notice of the offset of
+   // the element content and it's length.
+   if (length > MaxSizeLoadElementValue) {
+      std::ostringstream s;
+      s << "gdcm::NotLoaded.";
+      s << " Address:" << (long)ElVal->GetOffset();
+      s << " Length:"  << ElVal->GetLength();
+      s << " x(" << std::hex << ElVal->GetLength() << ")";
+      ElVal->SetValue(s.str());
+      return;
    }
-   return a;  
+   
+   // When an integer is expected, read and convert the following two or
+   // four bytes properly i.e. as an integer as opposed to a string.
+       
+       // Actually, elements with Value Multiplicity > 1
+       // contain a set of integers (not a single one)         
+       // Any compacter code suggested (?)
+   if ( IsAnInteger(ElVal) ) {
+      guint32 NewInt;
+      std::ostringstream s;
+      int nbInt;
+      if (vr == "US" || vr == "SS") {
+         nbInt = length / 2;
+         NewInt = ReadInt16();
+         s << NewInt;
+         if (nbInt > 1) {
+            for (int i=1; i < nbInt; i++) {
+               s << '\\';
+               NewInt = ReadInt16();
+               s << NewInt;
+            }
+         }
+                       
+      } else if (vr == "UL" || vr == "SL") {
+         nbInt = length / 4;
+         NewInt = ReadInt32();
+         s << NewInt;
+         if (nbInt > 1) {
+            for (int i=1; i < nbInt; i++) {
+               s << '\\';
+               NewInt = ReadInt32();
+               s << NewInt;
+            }
+         }
+      }                                        
+#ifdef GDCM_NO_ANSI_STRING_STREAM
+      s << std::ends; // to avoid oddities on Solaris
+#endif //GDCM_NO_ANSI_STRING_STREAM
+      ElVal->SetValue(s.str());
+      return;  
+   }
+   
+   // We need an additional byte for storing \0 that is not on disk
+   char* NewValue = (char*)malloc(length+1);
+   if( !NewValue) {
+      dbg.Verbose(1, "LoadElementValue: Failed to allocate NewValue");
+      return;
+   }
+   NewValue[length]= 0;
+   
+   item_read = fread(NewValue, (size_t)length, (size_t)1, fp);
+   if ( item_read != 1 ) {
+      free(NewValue);
+      dbg.Verbose(1, "gdcmHeader::LoadElementValue","unread element value");
+      ElVal->SetValue("gdcm::UnRead");
+      return;
+   }
+   ElVal->SetValue(NewValue);
+   free(NewValue);
 }
 
 /**
- * \ingroup gdcmHeader
- * \brief   Gets (from Header) the offset  of a 'non string' element value 
- * \        (LoadElementValue has already be executed)
- * @param   Group
- * @param   Elem
- * @return File Offset of the Element Value 
+ * \ingroup       gdcmHeader
+ * \brief         Loads the element while preserving the current
+ *                underlying file position indicator as opposed to
+ *                to LoadElementValue that modifies it.
+ * @param ElVal   Element whose value shall be loaded. 
+ * @return  
  */
- size_t gdcmHeader::GetPubElValOffsetByNumber(guint16 Group, guint16 Elem) {
-   gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);  
-   if (!elValue) {
-      dbg.Verbose(1, "gdcmHeader::GetElValueByNumber",
-                      "failed to Locate gdcmElValue");
-      return (size_t)0;
-   }
-   return elValue->GetOffset();
+void gdcmHeader::LoadElementValueSafe(gdcmElValue * ElVal) {
+   long PositionOnEntry = ftell(fp);
+   LoadElementValue(ElVal);
+   fseek(fp, PositionOnEntry, SEEK_SET);
 }
 
 /**
  * \ingroup gdcmHeader
-* \brief   Gets (from Header) a 'non string' element value 
- * \        (LoadElementValue has already be executed)  
- * @param   Group
- * @param   Elem
- * @return Pointer to the 'non string' area
+ * \brief   
+ *
+ * @return 
  */
- void * gdcmHeader::GetPubElValVoidAreaByNumber(guint16 Group, guint16 Elem) {
-   gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);  
-   if (!elValue) {
-      dbg.Verbose(1, "gdcmHeader::GetElValueByNumber",
-                  "failed to Locate gdcmElValue");
-      return (NULL);
-   }
-   return elValue->GetVoidArea();
-}
-
-
-//
-// =============================================================================
-//   Heuristics based accessors
-//==============================================================================
-//
-
-// TODO : move to an other file.
+ void gdcmHeader::FindLength (gdcmElValue * ElVal) {
+   guint16 element = ElVal->GetElement();
+   guint16 group   = ElVal->GetGroup();
+   std::string  vr = ElVal->GetVR();
+   guint16 length16;
+   if( (element == 0x0010) && (group == 0x7fe0) ) {
+      dbg.SetDebug(-1);
+      dbg.Verbose(2, "gdcmHeader::FindLength: ",
+                     "we reached 7fe0 0010");
+   }   
+   
+   if ( (filetype == ExplicitVR) && ! ElVal->IsImplicitVr() ) {
+      if ( (vr=="OB") || (vr=="OW") || (vr=="SQ") || (vr=="UN") ) {
+      
+         // The following reserved two bytes (see PS 3.5-2001, section
+         // 7.1.2 Data element structure with explicit vr p27) must be
+         // skipped before proceeding on reading the length on 4 bytes.
+         fseek(fp, 2L, SEEK_CUR);
 
+         guint32 length32 = ReadInt32();
 
-/**
- * \ingroup gdcmHeader
- * \brief   Retrieve the number of columns of image.
- * @return  The encountered size when found, 0 by default.
- */
-int gdcmHeader::GetXSize(void) {
-   // We cannot check for "Columns" because the "Columns" tag is present
-   // both in IMG (0028,0011) and OLY (6000,0011) sections of the dictionary.
-   std::string StrSize = GetPubElValByNumber(0x0028,0x0011);
-   if (StrSize == GDCM_UNFOUND)
-      return 0;
-   return atoi(StrSize.c_str());
-}
+         if ( (vr == "OB") && (length32 == 0xffffffff) ) {
+            ElVal->SetLength(FindLengthOB());
+            return;
+         }
+         FixFoundLength(ElVal, length32); 
+         return;
+      }
 
-/**
- * \ingroup gdcmHeader
- * \brief   Retrieve the number of lines of image.
- * \warning The defaulted value is 1 as opposed to gdcmHeader::GetXSize()
- * @return  The encountered size when found, 1 by default.
- */
-int gdcmHeader::GetYSize(void) {
-   // We cannot check for "Rows" because the "Rows" tag is present
-   // both in IMG (0028,0010) and OLY (6000,0010) sections of the dictionary.
-   std::string StrSize = GetPubElValByNumber(0x0028,0x0010);
-   if (StrSize != GDCM_UNFOUND)
-      return atoi(StrSize.c_str());
-   if ( IsDicomV3() )
-      return 0;
-   else
-      // The Rows (0028,0010) entry is optional for ACR/NEMA. It might
-      // hence be a signal (1d image). So we default to 1:
-      return 1;
+      // Length is encoded on 2 bytes.
+      length16 = ReadInt16();
+      
+      // We can tell the current file is encoded in big endian (like
+      // Data/US-RGB-8-epicard) when we find the "Transfer Syntax" tag
+      // and it's value is the one of the encoding of a big endian file.
+      // In order to deal with such big endian encoded files, we have
+      // (at least) two strategies:
+      // * when we load the "Transfer Syntax" tag with value of big endian
+      //   encoding, we raise the proper flags. Then we wait for the end
+      //   of the META group (0x0002) among which is "Transfer Syntax",
+      //   before switching the swap code to big endian. We have to postpone
+      //   the switching of the swap code since the META group is fully encoded
+      //   in little endian, and big endian coding only starts at the next
+      //   group. The corresponding code can be hard to analyse and adds
+      //   many additional unnecessary tests for regular tags.
+      // * the second strategy consists in waiting for trouble, that shall
+      //   appear when we find the first group with big endian encoding. This
+      //   is easy to detect since the length of a "Group Length" tag (the
+      //   ones with zero as element number) has to be of 4 (0x0004). When we
+      //   encounter 1024 (0x0400) chances are the encoding changed and we
+      //   found a group with big endian encoding.
+      // We shall use this second strategy. In order to make sure that we
+      // can interpret the presence of an apparently big endian encoded
+      // length of a "Group Length" without committing a big mistake, we
+      // add an additional check: we look in the already parsed elements
+      // for the presence of a "Transfer Syntax" whose value has to be "big
+      // endian encoding". When this is the case, chances are we have got our
+      // hands on a big endian encoded file: we switch the swap code to
+      // big endian and proceed...
+      if ( (element  == 0x0000) && (length16 == 0x0400) ) {
+         if ( ! IsExplicitVRBigEndianTransferSyntax() ) {
+            dbg.Verbose(0, "gdcmHeader::FindLength", "not explicit VR");
+            errno = 1;
+            return;
+         }
+         length16 = 4;
+         SwitchSwapToBigEndian();
+         // Restore the unproperly loaded values i.e. the group, the element
+         // and the dictionary entry depending on them.
+         guint16 CorrectGroup   = SwapShort(ElVal->GetGroup());
+         guint16 CorrectElem    = SwapShort(ElVal->GetElement());
+         gdcmDictEntry * NewTag = GetDictEntryByNumber(CorrectGroup,
+                                                       CorrectElem);
+         if (!NewTag) {
+            // This correct tag is not in the dictionary. Create a new one.
+            NewTag = new gdcmDictEntry(CorrectGroup, CorrectElem);
+         }
+         // FIXME this can create a memory leaks on the old entry that be
+         // left unreferenced.
+         ElVal->SetDictEntry(NewTag);
+      }
+       
+      // Heuristic: well some files are really ill-formed.
+      if ( length16 == 0xffff) {
+         length16 = 0;
+         //dbg.Verbose(0, "gdcmHeader::FindLength",
+         //            "Erroneous element length fixed.");
+         // Actually, length= 0xffff means that we deal with
+         // Unknown Sequence Length 
+      }
+
+      FixFoundLength(ElVal, (guint32)length16);
+      return;
+   }
+
+   // Either implicit VR or a non DICOM conformal (see not below) explicit
+   // VR that ommited the VR of (at least) this element. Farts happen.
+   // [Note: according to the part 5, PS 3.5-2001, section 7.1 p25
+   // on Data elements "Implicit and Explicit VR Data Elements shall
+   // not coexist in a Data Set and Data Sets nested within it".]
+   // Length is on 4 bytes.
+   FixFoundLength(ElVal, ReadInt32());
+   return;
 }
 
 /**
- * \ingroup gdcmHeader
- * \brief   Retrieve the number of planes of volume or the number
- *          of frames of a multiframe.
- * \warning When present we consider the "Number of Frames" as the third
- *          dimension. When absent we consider the third dimension as
- *          being the "Planes" tag content.
- * @return  The encountered size when found, 1 by default.
+ * \ingroup   gdcmHeader
+ * \brief     Find the value representation of the current tag.
+ * @param ElVal
  */
-int gdcmHeader::GetZSize(void) {
-   // Both  DicomV3 and ACR/Nema consider the "Number of Frames"
-   // as the third dimension.
-   std::string StrSize = GetPubElValByNumber(0x0028,0x0008);
-   if (StrSize != GDCM_UNFOUND)
-      return atoi(StrSize.c_str());
+void gdcmHeader::FindVR( gdcmElValue *ElVal) {
+   if (filetype != ExplicitVR)
+      return;
 
-   // We then consider the "Planes" entry as the third dimension [we
-   // cannot retrieve by name since "Planes tag is present both in
-   // IMG (0028,0012) and OLY (6000,0012) sections of the dictionary]. 
-   StrSize = GetPubElValByNumber(0x0028,0x0012);
-   if (StrSize != GDCM_UNFOUND)
-      return atoi(StrSize.c_str());
-   return 1;
+   char VR[3];
+   std::string vr;
+   int lgrLue;
+   char msg[100]; // for sprintf. Sorry
+
+   long PositionOnEntry = ftell(fp);
+   // Warning: we believe this is explicit VR (Value Representation) because
+   // we used a heuristic that found "UL" in the first tag. Alas this
+   // doesn't guarantee that all the tags will be in explicit VR. In some
+   // cases (see e-film filtered files) one finds implicit VR tags mixed
+   // within an explicit VR file. Hence we make sure the present tag
+   // is in explicit VR and try to fix things if it happens not to be
+   // the case.
+   bool RealExplicit = true;
+   
+   lgrLue=fread (&VR, (size_t)2,(size_t)1, fp);
+   VR[2]=0;
+   vr = std::string(VR);
+      
+   // Assume we are reading a falsely explicit VR file i.e. we reached
+   // a tag where we expect reading a VR but are in fact we read the
+   // first to bytes of the length. Then we will interogate (through find)
+   // the dicom_vr dictionary with oddities like "\004\0" which crashes
+   // both GCC and VC++ implementations of the STL map. Hence when the
+   // expected VR read happens to be non-ascii characters we consider
+   // we hit falsely explicit VR tag.
+
+   if ( (!isalpha(VR[0])) && (!isalpha(VR[1])) )
+      RealExplicit = false;
+
+   // CLEANME searching the dicom_vr at each occurence is expensive.
+   // PostPone this test in an optional integrity check at the end
+   // of parsing or only in debug mode.
+   if ( RealExplicit && !dicom_vr->Count(vr) )
+      RealExplicit= false;
+
+   if ( RealExplicit ) {
+      if ( ElVal->IsVRUnknown() ) {
+         // When not a dictionary entry, we can safely overwrite the vr.
+         ElVal->SetVR(vr);
+         return; 
+      }
+      if ( ElVal->GetVR() == vr ) {
+         // The vr we just read and the dictionary agree. Nothing to do.
+         return;
+      }
+      // The vr present in the file and the dictionary disagree. We assume
+      // the file writer knew best and use the vr of the file. Since it would
+      // be unwise to overwrite the vr of a dictionary (since it would
+      // compromise it's next user), we need to clone the actual DictEntry
+      // and change the vr for the read one.
+      gdcmDictEntry* NewTag = new gdcmDictEntry(ElVal->GetGroup(),
+                                 ElVal->GetElement(),
+                                 vr,
+                                 "FIXME",
+                                 ElVal->GetName());
+      ElVal->SetDictEntry(NewTag);
+      return; 
+   }
+   
+   // We thought this was explicit VR, but we end up with an
+   // implicit VR tag. Let's backtrack.   
+   
+      sprintf(msg,"Falsely explicit vr file (%04x,%04x)\n", 
+                   ElVal->GetGroup(),ElVal->GetElement());
+      dbg.Verbose(1, "gdcmHeader::FindVR: ",msg);
+   
+   fseek(fp, PositionOnEntry, SEEK_SET);
+   // When this element is known in the dictionary we shall use, e.g. for
+   // the semantics (see the usage of IsAnInteger), the vr proposed by the
+   // dictionary entry. Still we have to flag the element as implicit since
+   // we know now our assumption on expliciteness is not furfilled.
+   // avoid  .
+   if ( ElVal->IsVRUnknown() )
+      ElVal->SetVR("Implicit");
+   ElVal->SetImplicitVr();
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Retrieve the number of Bits Stored
- *          (as opposite to number of Bits Allocated)
- * 
- * @return  The encountered number of Bits Stored, 0 by default.
+ * \brief   
+ *
+ * @return 
  */
-int gdcmHeader::GetBitsStored(void) { 
-   std::string StrSize = GetPubElValByNumber(0x0028,0x0101);
-   if (StrSize == GDCM_UNFOUND)
-      return 1;
-   return atoi(StrSize.c_str());
+ guint32 gdcmHeader::FindLengthOB(void) {
+   // See PS 3.5-2001, section A.4 p. 49 on encapsulation of encoded pixel data.
+   guint16 g;
+   guint16 n; 
+   long PositionOnEntry = ftell(fp);
+   bool FoundSequenceDelimiter = false;
+   guint32 TotalLength = 0;
+   guint32 ItemLength;
+
+   while ( ! FoundSequenceDelimiter) {
+      g = ReadInt16();
+      n = ReadInt16();   
+      if (errno == 1)
+         return 0;
+      TotalLength += 4;  // We even have to decount the group and element 
+     
+      if ( g != 0xfffe && g!=0xb00c ) /*for bogus header */ {
+         char msg[100]; // for sprintf. Sorry
+         sprintf(msg,"wrong group (%04x) for an item sequence (%04x,%04x)\n",g, g,n);
+         dbg.Verbose(1, "gdcmHeader::FindLengthOB: ",msg); 
+         errno = 1;
+         return 0;
+      }
+      if ( n == 0xe0dd || ( g==0xb00c && n==0x0eb6 ) ) /* for bogus header  */ 
+         FoundSequenceDelimiter = true;
+      else if ( n != 0xe000 ){
+         char msg[100];  // for sprintf. Sorry
+         sprintf(msg,"wrong element (%04x) for an item sequence (%04x,%04x)\n",
+                      n, g,n);
+        dbg.Verbose(1, "gdcmHeader::FindLengthOB: ",msg);
+         errno = 1;
+         return 0;
+      }
+      ItemLength = ReadInt32();
+      TotalLength += ItemLength + 4;  // We add 4 bytes since we just read
+                                      // the ItemLength with ReadInt32                                     
+      SkipBytes(ItemLength);
+   }
+   fseek(fp, PositionOnEntry, SEEK_SET);
+   return TotalLength;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Retrieve the number of Bits Allocated
- *          (8, 12 -compacted ACR-NEMA files, 16, ...)
- * 
- * @return  The encountered number of Bits Allocated, 0 by default.
+ * \brief   
+ * @param ElVal 
+ * @return 
  */
-int gdcmHeader::GetBitsAllocated(void) { 
-   std::string StrSize = GetPubElValByNumber(0x0028,0x0100);
-   if (StrSize == GDCM_UNFOUND)
-      return 1;
-   return atoi(StrSize.c_str());
+void gdcmHeader::SkipElementValue(gdcmElValue * ElVal) {
+    SkipBytes(ElVal->GetLength());
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Retrieve the number of Samples Per Pixel
- *          (1 : gray level, 3 : RGB -1 or 3 Planes-)
- * 
- * @return  The encountered number of Samples Per Pixel, 1 by default.
- */
-int gdcmHeader::GetSamplesPerPixel(void) { 
-   std::string StrSize = GetPubElValByNumber(0x0028,0x0002);
-   if (StrSize == GDCM_UNFOUND)
-      return 1; // Well, it's supposed to be mandatory ...
-   return atoi(StrSize.c_str());
+ * \brief   When the length of an element value is obviously wrong (because
+ *          the parser went Jabberwocky) one can hope improving things by
+ *          applying this heuristic.
+ */
+void gdcmHeader::FixFoundLength(gdcmElValue * ElVal, guint32 FoundLength) {
+
+   ElVal->SetReadLength(FoundLength); // will be updated only if a bug is found
+                    
+   if ( FoundLength == 0xffffffff) {  
+      FoundLength = 0;
+   }
+      
+      // Sorry for the patch!  
+      // XMedCom did the trick to read some nasty GE images ...
+   else if (FoundLength == 13) {
+      // The following 'if' will be removed when there is no more
+      // images on Creatis HDs with a 13 length for Manufacturer...
+      if ( (ElVal->GetGroup() != 0x0008) ||  
+           ( (ElVal->GetElement() != 0x0070) && (ElVal->GetElement() != 0x0080) ) ) {
+      // end of remove area
+         FoundLength =10;
+         ElVal->SetReadLength(10); // a bug is to be fixed
+      }
+   } 
+     // to fix some garbage 'Leonardo' Siemens images
+     // May be commented out to avoid overhead
+   else if ( (ElVal->GetGroup() == 0x0009) &&
+       ( (ElVal->GetElement() == 0x1113) || (ElVal->GetElement() == 0x1114) ) ){
+      FoundLength =4;
+      ElVal->SetReadLength(4); // a bug is to be fixed 
+   } 
+     // end of fix
+        
+   // to try to 'go inside' SeQuences (with length), and not to skip them        
+   else if ( ElVal->GetVR() == "SQ") { 
+      if (enableSequences)    // only if the user does want to !
+         FoundLength =0;        
+   } 
+    
+   ElVal->SetUsableLength(FoundLength);
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Retrieve the Planar Configuration for RGB images
- *          (0 : RGB Pixels , 1 : R Plane + G Plane + B Plane)
- * 
- * @return  The encountered Planar Configuration, 0 by default.
+ * \brief   Apply some heuristics to predict wether the considered 
+ *          element value contains/represents an integer or not.
+ * @param   ElVal The element value on which to apply the predicate.
+ * @return  The result of the heuristical predicate.
  */
-int gdcmHeader::GetPlanarConfiguration(void) { 
-   std::string StrSize = GetPubElValByNumber(0x0028,0x0006);
-   if (StrSize == GDCM_UNFOUND)
-      return 0;
-   return atoi(StrSize.c_str());
+bool gdcmHeader::IsAnInteger(gdcmElValue * ElVal) {
+   guint16 element = ElVal->GetElement();
+   guint16 group   = ElVal->GetGroup();
+   std::string  vr = ElVal->GetVR();
+   guint32 length  = ElVal->GetLength();
+
+   // When we have some semantics on the element we just read, and if we
+   // a priori know we are dealing with an integer, then we shall be
+   // able to swap it's element value properly.
+   if ( element == 0 )  {  // This is the group length of the group
+      if (length == 4)
+         return true;
+      else {
+         std::ostringstream s;
+         s << "Erroneous Group Length element length  on :" \
+           << std::hex << group << " , " << element;
+         dbg.Error("gdcmHeader::IsAnInteger",
+            s.str().c_str());     
+      }
+   }
+   if ( (vr == "UL") || (vr == "US") || (vr == "SL") || (vr == "SS") )
+      return true;
+   
+   return false;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Return the size (in bytes) of a single pixel of data.
- * @return  The size in bytes of a single pixel of data.
+ * \brief Reads a supposed to be 16 Bits integer
+ * \     (swaps it depending on processor endianity) 
  *
+ * @return integer acts as a boolean
  */
-int gdcmHeader::GetPixelSize(void) {
-   std::string PixelType = GetPixelType();
-   if (PixelType == "8U"  || PixelType == "8S")
-      return 1;
-   if (PixelType == "16U" || PixelType == "16S")
-      return 2;
-   if (PixelType == "32U" || PixelType == "32S")
-      return 4;
-   dbg.Verbose(0, "gdcmHeader::GetPixelSize: Unknown pixel type");
-   return 0;
+guint16 gdcmHeader::ReadInt16(void) {
+   guint16 g;
+   size_t item_read;
+   item_read = fread (&g, (size_t)2,(size_t)1, fp);
+   if ( item_read != 1 ) {
+      // dbg.Verbose(0, "gdcmHeader::ReadInt16", " Failed to read :");
+      // if(feof(fp)) 
+      //    dbg.Verbose(0, "gdcmHeader::ReadInt16", " End of File encountered");
+      if(ferror(fp)) 
+         dbg.Verbose(0, "gdcmHeader::ReadInt16", " File Error");
+      errno = 1;
+      return 0;
+   }
+   errno = 0;
+   g = SwapShort(g);
+   return g;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   Build the Pixel Type of the image.
- *          Possible values are:
- *          - 8U  unsigned  8 bit,
- *          - 8S    signed  8 bit,
- *          - 16U unsigned 16 bit,
- *          - 16S   signed 16 bit,
- *          - 32U unsigned 32 bit,
- *          - 32S   signed 32 bit,
- * \warning 12 bit images appear as 16 bit.
- * \        24 bit images appear as 8 bit
- * @return  
+ * \brief  Reads a supposed to be 32 Bits integer
+ * \       (swaps it depending on processor endianity)  
+ *
+ * @return 
  */
-std::string gdcmHeader::GetPixelType(void) {
-   std::string BitsAlloc;
-   BitsAlloc = GetPubElValByNumber(0x0028, 0x0100); // Bits Allocated
-   if (BitsAlloc == GDCM_UNFOUND) {
-      dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated");
-      BitsAlloc = std::string("16");
-   }
-   if (BitsAlloc == "12")            // It will be unpacked
-      BitsAlloc = std::string("16");
-   else if (BitsAlloc == "24")       // (in order no to be messed up
-      BitsAlloc = std::string("8");  // by old RGB images)
-     
-   std::string Signed;
-   Signed = GetPubElValByNumber(0x0028, 0x0103); // "Pixel Representation"
-   if (Signed == GDCM_UNFOUND) {
-      dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Pixel Representation");
-      BitsAlloc = std::string("0");
-   }
-   if (Signed == "0")
-      Signed = std::string("U");
-   else
-      Signed = std::string("S");
-
-   return( BitsAlloc + Signed);
-}
-
-/**
-  * \ingroup gdcmHeader
-  * \brief gets the info from 0002,0010 : Transfert Syntax
-  * \           else 1.
-  * @return Transfert Syntax Name (as oposite to Transfert Syntax UID)
-  */
-std::string gdcmHeader::GetTransferSyntaxName(void) { 
-   std::string TransfertSyntax = GetPubElValByNumber(0x0002,0x0010);
-   if (TransfertSyntax == GDCM_UNFOUND) {
-      dbg.Verbose(0, "gdcmHeader::GetTransferSyntaxName: unfound Transfert Syntax (0002,0010)");
-      return "Uncompressed ACR-NEMA";
+guint32 gdcmHeader::ReadInt32(void) {
+   guint32 g;
+   size_t item_read;
+   item_read = fread (&g, (size_t)4,(size_t)1, fp);
+   if ( item_read != 1 ) { 
+      //dbg.Verbose(0, "gdcmHeader::ReadInt32", " Failed to read :");
+      //if(feof(fp)) 
+      //   dbg.Verbose(0, "gdcmHeader::ReadInt32", " End of File encountered");
+     if(ferror(fp)) 
+         dbg.Verbose(0, "gdcmHeader::ReadInt32", " File Error");   
+      errno = 1;
+      return 0;
    }
-   // we do it only when we need it
-   gdcmTS * ts = gdcmGlobal::GetTS();
-   std::string tsName=ts->GetValue(TransfertSyntax);
-   //delete ts; // Seg Fault when deleted ?!
-   return tsName;
+   errno = 0;   
+   g = SwapLong(g);
+   return g;
 }
 
-// -------------------------------- Lookup Table related functions ------------
-
 /**
-  * \ingroup gdcmHeader
-  * \brief tells us if LUT are used
-  * \warning Right now, Segmented xxx Palette Color Lookup Table Data
-  * \        are NOT considered as LUT, since nobody knows
-  *\         how to deal with them
-  * @return int acts as a Boolean 
-  */
-  
-bool gdcmHeader::HasLUT(void) {
-
-   // Check the presence of the LUT Descriptors 
-   if (GetPubElValByNumber(0x0028,0x1101) == GDCM_UNFOUND)
-      return false;
-   // LutDescriptorGreen 
-   if (GetPubElValByNumber(0x0028,0x1102) == GDCM_UNFOUND)
-      return false;
-   // LutDescriptorBlue 
-   if (GetPubElValByNumber(0x0028,0x1103) == GDCM_UNFOUND)
-      return false;
-   //  It is not enough
-   // we check also 
-   if (GetPubElValByNumber(0x0028,0x1201) == GDCM_UNFOUND)
-      return false;  
-   if (GetPubElValByNumber(0x0028,0x1202) == GDCM_UNFOUND)
-      return false;
-   if (GetPubElValByNumber(0x0028,0x1203) == GDCM_UNFOUND)
-      return false;   
-   return true;
+ * \ingroup gdcmHeader
+ * \brief   
+ *
+ * @return 
+ */
+void gdcmHeader::SkipBytes(guint32 NBytes) {
+   //FIXME don't dump the returned value
+   (void)fseek(fp, (long)NBytes, SEEK_CUR);
 }
 
 /**
-  * \ingroup gdcmHeader
-  * \brief gets the info from 0028,1101 : Lookup Table Desc-Red
-  * \           else 0
-  * @return Lookup Table nBit 
-  * \       when (0028,0004),Photometric Interpretation = [PALETTE COLOR ] 
-  */
-  
-int gdcmHeader::GetLUTNbits(void) {
-   std::vector<std::string> tokens;
-   //int LutLength;
-   //int LutDepth;
-   int LutNbits;
-   //Just hope Lookup Table Desc-Red = Lookup Table Desc-Red = Lookup Table Desc-Blue
-   // Consistency already checked in GetLUTLength
-   std::string LutDescription = GetPubElValByNumber(0x0028,0x1101);
-   if (LutDescription == GDCM_UNFOUND)
-      return 0;
-   tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
-   Tokenize (LutDescription, tokens, "\\");
-   //LutLength=atoi(tokens[0].c_str());
-   //LutDepth=atoi(tokens[1].c_str());
-   LutNbits=atoi(tokens[2].c_str());
-   tokens.clear();
-   return LutNbits;
+ * \ingroup gdcmHeader
+ * \brief   
+ */
+void gdcmHeader::Initialise(void) {
+   dicom_vr = gdcmGlobal::GetVR();
+   dicom_ts = gdcmGlobal::GetTS();
+   Dicts    = gdcmGlobal::GetDicts();
+   RefPubDict = Dicts->GetDefaultPubDict();
+   RefShaDict = (gdcmDict*)0;
 }
 
 /**
-  * \ingroup gdcmHeader
-  * \brief builts Red/Green/Blue/Alpha LUT from Header
-  * \       when (0028,0004),Photometric Interpretation = [PALETTE COLOR ]
-  * \        and (0028,1101),(0028,1102),(0028,1102)  
-  * \          - xxx Palette Color Lookup Table Descriptor - are found
-  * \        and (0028,1201),(0028,1202),(0028,1202) 
-  * \          - xxx Palette Color Lookup Table Data - are found 
-  * \warning does NOT deal with :
-  * \ 0028 1100 Gray Lookup Table Descriptor (Retired)
-  * \ 0028 1221 Segmented Red Palette Color Lookup Table Data
-  * \ 0028 1222 Segmented Green Palette Color Lookup Table Data
-  * \ 0028 1223 Segmented Blue Palette Color Lookup Table Data 
-  * \ no known Dicom reader deails with them :-(
-  * @return Lookup Table RGBA
-  */ 
-  
-unsigned char * gdcmHeader::GetLUTRGBA(void) {
-// Not so easy : see 
-// http://www.barre.nom.fr/medical/dicom2/limitations.html#Color%20Lookup%20Tables
-// and  OT-PAL-8-face.dcm
-
-//  if Photometric Interpretation # PALETTE COLOR, no LUT to be done
-                
-   if (gdcmHeader::GetPubElValByNumber(0x0028,0x0004) != "PALETTE COLOR ") {
-       return NULL;
-   }  
+ * \ingroup gdcmHeader
+ * \brief   Discover what the swap code is (among little endian, big endian,
+ *          bad little endian, bad big endian).
+ *
+ */
+void gdcmHeader::CheckSwap()
+{
+   // Fourth semantics:
+   //
+   // ---> Warning : This fourth field is NOT part 
+   //                of the 'official' Dicom Dictionnary
+   //                and should NOT be used.
+   //                (Not defined for all the groups
+   //                 may be removed in a future release)
+   //
+   // CMD      Command        
+   // META     Meta Information 
+   // DIR      Directory
+   // ID
+   // PAT      Patient
+   // ACQ      Acquisition
+   // REL      Related
+   // IMG      Image
+   // SDY      Study
+   // VIS      Visit 
+   // WAV      Waveform
+   // PRC
+   // DEV      Device
+   // NMI      Nuclear Medicine
+   // MED
+   // BFS      Basic Film Session
+   // BFB      Basic Film Box
+   // BIB      Basic Image Box
+   // BAB
+   // IOB
+   // PJ
+   // PRINTER
+   // RT       Radio Therapy
+   // DVH   
+   // SSET
+   // RES      Results
+   // CRV      Curve
+   // OLY      Overlays
+   // PXL      Pixels
+   // DL       Delimiters
+   //
 
-   int lengthR, debR, nbitsR;
-   int lengthG, debG, nbitsG;
-   int lengthB, debB, nbitsB;
-   
-// Get info from Lut Descriptors
-// (the 3 LUT descriptors may be different)    
+   // The only guaranted way of finding the swap code is to find a
+   // group tag since we know it's length has to be of four bytes i.e.
+   // 0x00000004. Finding the swap code in then straigthforward. Trouble
+   // occurs when we can't find such group...
+   guint32  s;
+   guint32  x=4;  // x : for ntohs
+   bool net2host; // true when HostByteOrder is the same as NetworkByteOrder
+    
+   int lgrLue;
+   char * entCur;
+   char deb[HEADER_LENGTH_TO_READ];
+    
+   // First, compare HostByteOrder and NetworkByteOrder in order to
+   // determine if we shall need to swap bytes (i.e. the Endian type).
+   if (x==ntohs(x))
+      net2host = true;
+   else
+      net2host = false; 
+    //cout << net2host << endl;
+         
+   // The easiest case is the one of a DICOM header, since it possesses a
+   // file preamble where it suffice to look for the string "DICM".
+   lgrLue = fread(deb, 1, HEADER_LENGTH_TO_READ, fp);
    
-   std::string LutDescriptionR = GetPubElValByNumber(0x0028,0x1101);
-   if (LutDescriptionR == GDCM_UNFOUND)
-      return NULL;
-   std::string LutDescriptionG = GetPubElValByNumber(0x0028,0x1102);
-   if (LutDescriptionG == GDCM_UNFOUND)
-      return NULL;   
-   std::string LutDescriptionB = GetPubElValByNumber(0x0028,0x1103);
-   if (LutDescriptionB == GDCM_UNFOUND)
-      return NULL;
-      
-   std::vector<std::string> tokens;
+   entCur = deb + 128;
+   if(memcmp(entCur, "DICM", (size_t)4) == 0) {
+      dbg.Verbose(1, "gdcmHeader::CheckSwap:", "looks like DICOM Version3");
+      // Next, determine the value representation (VR). Let's skip to the
+      // first element (0002, 0000) and check there if we find "UL" 
+      // - or "OB" if the 1st one is (0002,0001) -,
+      // in which case we (almost) know it is explicit VR.
+      // WARNING: if it happens to be implicit VR then what we will read
+      // is the length of the group. If this ascii representation of this
+      // length happens to be "UL" then we shall believe it is explicit VR.
+      // FIXME: in order to fix the above warning, we could read the next
+      // element value (or a couple of elements values) in order to make
+      // sure we are not commiting a big mistake.
+      // We need to skip :
+      // * the 128 bytes of File Preamble (often padded with zeroes),
+      // * the 4 bytes of "DICM" string,
+      // * the 4 bytes of the first tag (0002, 0000),or (0002, 0001)
+      // i.e. a total of  136 bytes.
+      entCur = deb + 136;
+      // FIXME
+      // Use gdcmHeader::dicom_vr to test all the possibilities
+      // instead of just checking for UL, OB and UI !?
+      if(  (memcmp(entCur, "UL", (size_t)2) == 0) ||
+          (memcmp(entCur, "OB", (size_t)2) == 0) ||
+          (memcmp(entCur, "UI", (size_t)2) == 0) )   
+      {
+         filetype = ExplicitVR;
+         dbg.Verbose(1, "gdcmHeader::CheckSwap:",
+                     "explicit Value Representation");
+      } else {
+         filetype = ImplicitVR;
+         dbg.Verbose(1, "gdcmHeader::CheckSwap:",
+                     "not an explicit Value Representation");
+      }
+      if (net2host) {
+         sw = 4321;
+         dbg.Verbose(1, "gdcmHeader::CheckSwap:",
+                        "HostByteOrder != NetworkByteOrder");
+      } else {
+         sw = 0;
+         dbg.Verbose(1, "gdcmHeader::CheckSwap:",
+                        "HostByteOrder = NetworkByteOrder");
+      }
       
-   tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
-   Tokenize (LutDescriptionR, tokens, "\\");
-   lengthR=atoi(tokens[0].c_str()); // Red LUT length in Bytes
-   debR   =atoi(tokens[1].c_str()); // subscript of the first Lut Value
-   nbitsR =atoi(tokens[2].c_str()); // Lut item size (in Bits)
-   tokens.clear();
-   
-   tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
-   Tokenize (LutDescriptionG, tokens, "\\");
-   lengthG=atoi(tokens[0].c_str()); // Green LUT length in Bytes
-   debG   =atoi(tokens[1].c_str());
-   nbitsG =atoi(tokens[2].c_str());
-   tokens.clear();  
-   
-   tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
-   Tokenize (LutDescriptionB, tokens, "\\");
-   lengthB=atoi(tokens[0].c_str()); // Blue LUT length in Bytes
-   debB   =atoi(tokens[1].c_str());
-   nbitsB =atoi(tokens[2].c_str());
-   tokens.clear();
-// Load LUTs into memory, (as they were stored on disk)
-   
-   unsigned char *lutR =(unsigned char *)
-                                   GetPubElValVoidAreaByNumber(0x0028,0x1201);
-   unsigned char *lutG =(unsigned char *)
-                                   GetPubElValVoidAreaByNumber(0x0028,0x1202);
-   unsigned char *lutB =(unsigned char *)
-                                   GetPubElValVoidAreaByNumber(0x0028,0x1203); 
-   
-   if (!lutR || !lutG || !lutB ) {
-       return NULL;
-   } 
- // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT 
+      // Position the file position indicator at first tag (i.e.
+      // after the file preamble and the "DICM" string).
+      rewind(fp);
+      fseek (fp, 132L, SEEK_SET);
+      return;
+   } // End of DicomV3
+
+   // Alas, this is not a DicomV3 file and whatever happens there is no file
+   // preamble. We can reset the file position indicator to where the data
+   // is (i.e. the beginning of the file).
+    dbg.Verbose(1, "gdcmHeader::CheckSwap:", "not a DICOM Version3 file");
+   rewind(fp);
+
+   // Our next best chance would be to be considering a 'clean' ACR/NEMA file.
+   // By clean we mean that the length of the first tag is written down.
+   // If this is the case and since the length of the first group HAS to be
+   // four (bytes), then determining the proper swap code is straightforward.
+
+   entCur = deb + 4;
+   // We assume the array of char we are considering contains the binary
+   // representation of a 32 bits integer. Hence the following dirty
+   // trick :
+   s = *((guint32 *)(entCur));
    
-  unsigned char *LUTRGBA = (unsigned char *)calloc(1024,1); // 256 * 4 (R, G, B, Alpha) 
-  if (!LUTRGBA) {
-     return NULL;
-  }
-  memset(LUTRGBA, 0, 1024);
-       // Bits Allocated
-   int nb;
-   std::string str_nb = GetPubElValByNumber(0x0028,0x0100);
-   if (str_nb == GDCM_UNFOUND ) {
-      nb = 16;
-   } else {
-      nb = atoi(str_nb.c_str() );
-   }  
-  int mult;
-  
-  if (nbitsR==16 && nb==8) // when LUT item size is different than pixel size
-     mult=2;               // high byte must be = low byte 
-  else                     // See PS 3.3-2003 C.11.1.1.2 p 619
-     mult=1; 
-            // if we get a black image, let's just remove the '+1'
-            // from 'i*mult+1' and check again 
-            // if it works, we shall have to check the 3 Palettes
-            // to see which byte is ==0 (first one, or second one)
-           // and fix the code
-           // We give up the checking to avoid some overhead 
-           
-  unsigned char *a;      
-  int i;
-  a= LUTRGBA+0;
-  for(i=0;i<lengthR;i++) {
-     *a = lutR[i*mult+1]; 
-     a+=4;       
-  }        
-  a= LUTRGBA+1;
-  for(i=0;i<lengthG;i++) {
-     *a = lutG[i*mult+1]; 
-     a+=4;       
-  }  
-  a= LUTRGBA+2;
-  for(i=0;i<lengthB;i++) {
-     *a = lutB[i*mult+1]; 
-     a+=4;       
-  }  
-  a= LUTRGBA+3;
-  for(i=0;i<256;i++) {
-     *a = 1; // Alpha component
-     a+=4; 
-  } 
-      
-//How to free the now useless LUTs?
-//
-//free(LutR); free(LutB); free(LutG);
+   switch (s) {
+   case 0x00040000 :
+      sw = 3412;
+      filetype = ACR;
+      return;
+   case 0x04000000 :
+      sw = 4321;
+      filetype = ACR;
+      return;
+   case 0x00000400 :
+      sw = 2143;
+      filetype = ACR;
+      return;
+   case 0x00000004 :
+      sw = 0;
+      filetype = ACR;
+      return;
+   default :
+      dbg.Verbose(0, "gdcmHeader::CheckSwap:",
+                     "ACR/NEMA unfound swap info (time to raise bets)");
+   }
+
+   // We are out of luck. It is not a DicomV3 nor a 'clean' ACR/NEMA file.
+   // It is time for despaired wild guesses. So, let's assume this file
+   // happens to be 'dirty' ACR/NEMA, i.e. the length of the group is
+   // not present. Then the only info we have is the net2host one.
+   filetype = Unknown;
+   if (! net2host )
+      sw = 0;
+   else
+      sw = 4321;
+   return;
+}
+
+/**
+ * \ingroup gdcmHeader
+ * \brief   
+ */
+void gdcmHeader::SwitchSwapToBigEndian(void) {
+   dbg.Verbose(1, "gdcmHeader::SwitchSwapToBigEndian",
+                  "Switching to BigEndian mode.");
+   if ( sw == 0    ) {
+      sw = 4321;
+      return;
+   }
+   if ( sw == 4321 ) {
+      sw = 0;
+      return;
+   }
+   if ( sw == 3412 ) {
+      sw = 2143;
+      return;
+   }
+   if ( sw == 2143 )
+      sw = 3412;
+}
 
-  return(LUTRGBA);   
-} 
-/////////////////////////////////////////////////////////////////
 /**
- * \ingroup   gdcmFile
- * \brief Sets the Pixel Area size in the Header
- *        --> not-for-rats function
- * 
- * \warning WARNING doit-etre etre publique ? 
- * TODO : y aurait il un inconvenient Ã  fusionner ces 2 fonctions
- *
- * @param ImageDataSize new Pixel Area Size
- *        warning : nothing else is checked
+ * \ingroup gdcmHeader
+ * \brief   
+ * @param NewSize
+ * @return 
  */
+void gdcmHeader::SetMaxSizeLoadElementValue(long NewSize) {
+   if (NewSize < 0)
+      return;
+   if ((guint32)NewSize >= (guint32)0xffffffff) {
+      MaxSizeLoadElementValue = 0xffffffff;
+      return;
+   }
+   MaxSizeLoadElementValue = NewSize;
+}
 
-void gdcmHeader::SetImageDataSize(size_t ImageDataSize) {
-   std::string content1;
-   char car[20];       
-   // Assumes ElValue (0x7fe0, 0x0010) exists ...      
-   sprintf(car,"%d",ImageDataSize);
-   gdcmElValue *a = GetElValueByNumber(0x7fe0, 0x0010);
-   a->SetLength(ImageDataSize);
-               
-   ImageDataSize+=8;
-   sprintf(car,"%d",ImageDataSize);
-   content1=car;       
-   SetPubElValByNumber(content1, 0x7fe0, 0x0000);
+/**
+ * \ingroup gdcmHeader
+ * \brief   Searches both the public and the shadow dictionary (when they
+ *          exist) for the presence of the DictEntry with given
+ *          group and element. The public dictionary has precedence on the
+ *          shadow one.
+ * @param   group   group of the searched DictEntry
+ * @param   element element of the searched DictEntry
+ * @return  Corresponding DictEntry when it exists, NULL otherwise.
+ */
+gdcmDictEntry * gdcmHeader::GetDictEntryByNumber(guint16 group,
+                                                 guint16 element) {
+   gdcmDictEntry * found = (gdcmDictEntry*)0;
+   if (!RefPubDict && !RefShaDict) {
+      dbg.Verbose(0, "gdcmHeader::GetDictEntry",
+                     "we SHOULD have a default dictionary");
+   }
+   if (RefPubDict) {
+      found = RefPubDict->GetTagByNumber(group, element);
+      if (found)
+         return found;
+   }
+   if (RefShaDict) {
+      found = RefShaDict->GetTagByNumber(group, element);
+      if (found)
+         return found;
+   }
+   return found;
 }
 
+/**
+ * \ingroup gdcmHeader
+ * \brief   Searches both the public and the shadow dictionary (when they
+ *          exist) for the presence of the DictEntry with given name.
+ *          The public dictionary has precedence on the shadow one.
+ * @param   Name name of the searched DictEntry
+ * @return  Corresponding DictEntry when it exists, NULL otherwise.
+ */
+gdcmDictEntry * gdcmHeader::GetDictEntryByName(std::string Name) {
+   gdcmDictEntry * found = (gdcmDictEntry*)0;
+   if (!RefPubDict && !RefShaDict) {
+      dbg.Verbose(0, "gdcmHeader::GetDictEntry",
+                     "we SHOULD have a default dictionary");
+   }
+   if (RefPubDict) {
+      found = RefPubDict->GetTagByName(Name);
+      if (found)
+         return found;
+   }
+   if (RefShaDict) {
+      found = RefShaDict->GetTagByName(Name);
+      if (found)
+         return found;
+   }
+   return found;
+}
 
+/**
+ * \ingroup gdcmHeader
+ * \brief   Read the next tag but WITHOUT loading it's value
+ * @return  On succes the newly created ElValue, NULL on failure.      
+ */
+gdcmElValue * gdcmHeader::ReadNextElement(void) {
+  
+   guint16 g,n;
+   gdcmElValue * NewElVal;
+   
+   g = ReadInt16();
+   n = ReadInt16();
+      
+   if (errno == 1)
+      // We reached the EOF (or an error occured) and header parsing
+      // has to be considered as finished.
+      return (gdcmElValue *)0;
+   
+   NewElVal = NewElValueByNumber(g, n);
+   FindVR(NewElVal);
+   FindLength(NewElVal);
+       
+   if (errno == 1) {
+      // Call it quits
+      return (gdcmElValue *)0;
+   }
+   NewElVal->SetOffset(ftell(fp));  
+   //if ( (g==0x7fe0) && (n==0x0010) ) 
+   return NewElVal;
+}
 
+/**
+ * \ingroup gdcmHeader
+ * \brief   Build a new Element Value from all the low level arguments. 
+ *          Check for existence of dictionary entry, and build
+ *          a default one when absent.
+ * @param   Name    Name of the underlying DictEntry
+ */
+gdcmElValue* gdcmHeader::NewElValueByName(std::string Name) {
 
+   gdcmDictEntry * NewTag = GetDictEntryByName(Name);
+   if (!NewTag)
+      NewTag = new gdcmDictEntry(0xffff, 0xffff, "LO", "Unknown", Name);
 
+   gdcmElValue* NewElVal = new gdcmElValue(NewTag);
+   if (!NewElVal) {
+      dbg.Verbose(1, "gdcmHeader::ObtainElValueByName",
+                  "failed to allocate gdcmElValue");
+      return (gdcmElValue*)0;
+   }
+   return NewElVal;
+}  
 
+/**
+ * \ingroup gdcmHeader
+ * \brief   Build a new Element Value from all the low level arguments. 
+ *          Check for existence of dictionary entry, and build
+ *          a default one when absent.
+ * @param   Group group   of the underlying DictEntry
+ * @param   Elem  element of the underlying DictEntry
+ */
+gdcmElValue* gdcmHeader::NewElValueByNumber(guint16 Group, guint16 Elem) {
+   // Find out if the tag we encountered is in the dictionaries:
+   gdcmDictEntry * NewTag = GetDictEntryByNumber(Group, Elem);
+   if (!NewTag)
+      NewTag = new gdcmDictEntry(Group, Elem);
 
+   gdcmElValue* NewElVal = new gdcmElValue(NewTag);
+   if (!NewElVal) {
+      dbg.Verbose(1, "gdcmHeader::NewElValueByNumber",
+                  "failed to allocate gdcmElValue");
+      return (gdcmElValue*)0;
+   }
+   return NewElVal;
+}
 
 /**
  * \ingroup gdcmHeader
@@ -2352,58 +2337,34 @@ void gdcmHeader::SetImageDataSize(size_t ImageDataSize) {
                                         dictEntry->GetElement()));  
 }
 
-
-
 /**
- * \ingroup gdcmElValSet
- * \brief  Sets the value (string) of the target Dicom Element
- * @param   content string value of the Dicom Element
- * @param   tagName name of the searched Dicom Element.
- * @return  true when found
+ * \ingroup gdcmHeader
+ * \brief   Small utility function that creates a new manually crafted
+ *          (as opposed as read from the file) gdcmElValue with user
+ *          specified name and adds it to the public tag hash table.
+ * \note    A fake TagKey is generated so the PubDict can keep it's coherence.
+ * @param   NewTagName The name to be given to this new tag.
+ * @param   VR The Value Representation to be given to this new tag.
+ * @ return The newly hand crafted Element Value.
  */
-bool gdcmHeader::SetElValueByName(std::string content,
-                                  std::string tagName) {
-                                   
-   gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); 
-   if( dictEntry == NULL)
-      return false;                                
-                                                                                                   
-                                   
-   TagKey key = gdcmDictEntry::TranslateToKey(dictEntry->GetGroup(), 
-                                              dictEntry->GetElement());
-   if ( ! PubElValSet.GetTagHt().count(key))
-      return false;
-   int l = content.length();
-   if(l%2) {  // Odd length are padded with a space (020H).
-      l++;
-      content = content + '\0';
+gdcmElValue* gdcmHeader::NewManualElValToPubDict(std::string NewTagName, 
+                                                 std::string VR) {
+   gdcmElValue* NewElVal = (gdcmElValue*)0;
+   guint32 StuffGroup = 0xffff;   // Group to be stuffed with additional info
+   guint32 FreeElem = 0;
+   gdcmDictEntry* NewEntry = (gdcmDictEntry*)0;
+
+   FreeElem = PubElValSet.GenerateFreeTagKeyInGroup(StuffGroup);
+   if (FreeElem == UINT32_MAX) {
+      dbg.Verbose(1, "gdcmHeader::NewManualElValToPubDict",
+                     "Group 0xffff in Public Dict is full");
+      return (gdcmElValue*)0;
    }
-      
-   //tagHt[key]->SetValue(content);   
-   gdcmElValue * a;
-   IterHT p;
-   TagElValueHT::iterator p2;
-   // DO NOT remove the following lines : they explain the stuff   
-   //p= tagHt.equal_range(key); // get a pair of iterators first-last synonym
-   //p2=p.first;                // iterator on the first synonym 
-   //a=p2->second;              // H Table target column (2-nd col)
-    
-   // or, easier :
-   a = ((PubElValSet.GetTagHt().equal_range(key)).first)->second; 
-       
-   a-> SetValue(content); 
-   
-   //std::string vr = tagHt[key]->GetVR();
-   std::string vr = a->GetVR();
-   
-   guint32 lgr;
-   if( (vr == "US") || (vr == "SS") ) 
-      lgr = 2;
-   else if( (vr == "UL") || (vr == "SL") )
-      lgr = 4;
-   else
-      lgr = l;    
-   //tagHt[key]->SetLength(lgr);
-   a->SetLength(lgr);   
-   return true;
+   NewEntry = new gdcmDictEntry(StuffGroup, FreeElem,
+                                VR, "GDCM", NewTagName);
+   NewElVal = new gdcmElValue(NewEntry);
+   PubElValSet.Add(NewElVal);
+   return NewElVal;
 }
+
+//-----------------------------------------------------------------------------
index dff360a72725ae6cc816838dec53d07f5011d7b2..23df5390bcb490ef551b0b348857ff45140db0f5 100644 (file)
@@ -1,5 +1,5 @@
-// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.h,v 1.47 2004/01/13 11:32:30 jpr Exp $
-
+// gdcmHeader.h
+//-----------------------------------------------------------------------------
 #ifndef GDCMHEADER_H
 #define GDCMHEADER_H
 
 #include "gdcmElValSet.h"
 #include <map>
 
+//-----------------------------------------------------------------------------
 typedef std::string VRKey;
 typedef std::string VRAtr;
 typedef std::map<VRKey, VRAtr> VRHT;    // Value Representation Hash Table
 
+//-----------------------------------------------------------------------------
 /*
  * The purpose of an instance of gdcmHeader is to act as a container of
  * all the DICOM elements and their corresponding values (and
@@ -35,96 +37,16 @@ typedef std::map<VRKey, VRAtr> VRHT;    // Value Representation Hash Table
  *        gdcmFile and gdcmHeader.
  */
 class GDCM_EXPORT gdcmHeader {
-private:
-   /// Pointer to the Value Representation Hash Table which contains all
-   /// the VR of the DICOM version3 public dictionary. 
-   gdcmVR *dicom_vr;     // Not a class member for thread-safety reasons
-   
-   /// Pointer to the Transfert Syntax Hash Table which contains all
-   /// the TS of the DICOM version3 public dictionary. 
-   gdcmTS *dicom_ts;     // Not a class member for thread-safety reasons 
-     
-   /// Pointer to global dictionary container
-   gdcmDictSet *Dicts;   // Not a class member for thread-safety reasons
-   
-   /// Public dictionary used to parse this header
-   gdcmDict *RefPubDict;
-   
-   /// Optional "shadow dictionary" (private elements) used to parse this
-   /// header
-   gdcmDict *RefShaDict;
-
-   /// ELement VALueS parsed with the PUBlic dictionary.
-   gdcmElValSet PubElValSet;
-   
-   /// Refering underlying filename.
-   std::string filename; 
-  
-   int enableSequences;
-
-   // FIXME sw should be an enum e.g.
-   //enum EndianType {
-      //LittleEndian, 
-      //BadLittleEndian,
-      //BigEndian, 
-      //BadBigEndian};
-   /// Swap code e.g. little, big, bad-big, bad-little endian). Warning:
-   /// this code is not fixed during header parsing.
-   int sw;
-
-   /// Size treshold above which an element value will NOT be loaded in 
-   /// memory (to avoid loading the image/volume itself). By default,
-   /// this upper bound is fixed to 1024 bytes (which might look reasonable
-   /// when one considers the definition of the various VR contents).
-   guint32 MaxSizeLoadElementValue;
-
-   guint16 ReadInt16(void);
-   guint32 ReadInt32(void);
-   guint32 FindLengthOB(void);
-   void Initialise(void);
-   void CheckSwap(void);
-   void SwitchSwapToBigEndian(void);
-   // CLEAN ME: NewManualElValToPubDict is NOT called any more.
-   gdcmElValue *NewManualElValToPubDict(std::string NewTagName,
-                                         std::string VR);
-   void SetMaxSizeLoadElementValue(long);
-
-   gdcmDictEntry *GetDictEntryByNumber(guint16, guint16);
-   gdcmDictEntry *GetDictEntryByName  (std::string Name);
-
-   // ElValue related utilities
-   gdcmElValue *ReadNextElement(void);
-   gdcmElValue *NewElValueByNumber(guint16 group, guint16 element);
-   gdcmElValue *NewElValueByName  (std::string Name);
-   
-   gdcmElValue* GetElementByName  (std::string Name);
-   // moved from gdcmElValSet
-
-   void FindLength          (gdcmElValue *);
-   void FindVR              (gdcmElValue *);
-   void LoadElementValue    (gdcmElValue *);
-   void LoadElementValueSafe(gdcmElValue *);
-   void SkipElementValue    (gdcmElValue *);
-   void FixFoundLength      (gdcmElValue *, guint32);
-   bool IsAnInteger         (gdcmElValue *);
-   void LoadElements(void);
-   void SkipBytes(guint32);
-
-protected:
-   FILE * fp;
-   FileType filetype; // ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown
-   
-   gdcmElValue * GetElValueByNumber(guint16 group, guint16 element);
-   bool CheckIfExistByNumber(guint16 Group, guint16 Elem );
-
-   int write(std::ostream&);   
-   int anonymize(std::ostream&);  // FIXME : anonymize should be a friend ?
-
 public:
-   FILE *OpenFile(bool exception_on_error = false)
-     throw(gdcmFileError);
-   bool CloseFile(void);
-   FileType GetFileType(void);
+   gdcmHeader(bool exception_on_error = false);
+   gdcmHeader(const char *filename, 
+              bool  exception_on_error = false, 
+              bool  enable_sequences   = false);
+             
+   virtual ~gdcmHeader();
+
+// Standard values and informations contained in the header
+   inline std::string GetFileName(void) {return filename;}
 
    bool IsReadable(void);
    bool IsImplicitVRLittleEndianTransferSyntax(void);
@@ -139,24 +61,29 @@ public:
    bool IsJPEGLossless(void); 
    bool IsJPEG2000(void); 
    bool IsDicomV3(void); 
-      
-   virtual void ParseHeader(bool exception_on_error = false)
-     throw(gdcmFormatError);
-     
-   gdcmHeader(bool exception_on_error = false);
-   gdcmHeader(const char *filename, 
-              bool  exception_on_error = false, 
-              bool  enable_sequences   = false);
-             
-   virtual ~gdcmHeader();
+   FileType GetFileType(void);
 
-   inline std::string GetFileName(void) {return filename;}
-   
+   // Some heuristic based accessors, end user intended 
+   // (to be move to gdcmHeaderHelper?) 
+   int GetXSize(void);  
+   int GetYSize(void);
+   int GetZSize(void);
+   int GetBitsStored(void);
+   int GetBitsAllocated(void);
+   int GetSamplesPerPixel(void);   
+   int GetPlanarConfiguration(void);
+
+   int GetPixelSize(void);   
+   std::string GetPixelType(void);  
    size_t GetPixelOffset(void);
    size_t GetPixelAreaLength(void);
 
-   inline int    GetSwapCode(void) { return sw; }
-  
+   bool   HasLUT(void);
+   int    GetLUTNbits(void);
+   unsigned char * GetLUTRGBA(void);
+
+   std::string GetTransfertSyntaxName(void);
+
    // When some proprietary shadow groups are disclosed, we can set up
    // an additional specific dictionary to access extra information.
    
@@ -167,64 +94,150 @@ public:
    // TODO Swig int SetShaDict(std::string filename);
    // TODO Swig int SetPubDict(std::string filename);
 
+// Public element value
    std::string GetPubElValByName     (std::string tagName);
    std::string GetPubElValRepByName  (std::string tagName);
    std::string GetPubElValByNumber   (guint16 group, guint16 element);
    std::string GetPubElValRepByNumber(guint16 group, guint16 element);
    
-   size_t GetPubElValOffsetByNumber  (guint16 Group, guint16 Elem);
-   void * GetPubElValVoidAreaByNumber(guint16 Group, guint16 Elem);   
-   void * LoadElementVoidArea        (guint16 Group, guint16 Element);
-   
-   inline ListTag      & GetListElem(void) { return PubElValSet.GetListElem();};
-   inline TagElValueHT & GetPubElVal(void) { return PubElValSet.GetTagHt();   };
-   
-   void   PrintPubElVal(std::ostream & os = std::cout);
-   void   PrintPubDict (std::ostream & os = std::cout);
-
    bool SetPubElValByName  (std::string content, std::string tagName); 
    bool SetPubElValByNumber(std::string content, guint16 group, guint16 element);  
    bool SetPubElValLengthByNumber(guint32 lgr, guint16 group, guint16 element); 
-      
+
+   inline ListTag      & GetPubListElem(void) { return PubElValSet.GetListElem();};
+   inline TagElValueHT & GetPubElVal(void) { return PubElValSet.GetTagHt();   };
+
+   void PrintPubElVal(std::ostream & os = std::cout);
+   void PrintPubDict (std::ostream & os = std::cout);
+
+// Element value
    std::string GetElValByName     (std::string tagName);
    std::string GetElValRepByName  (std::string tagName);
    std::string GetElValByNumber   (guint16 group, guint16 element);
-   std::string GetElValRepByNumber(guint16 group, guint16 element);                                  
+   std::string GetElValRepByNumber(guint16 group, guint16 element);
 
    bool SetElValueByName(std::string content,std::string tagName); 
-   // moved from ElValSet
-                                    
+//   bool SetElValueByNumber(std::string content,guint16 group, guint16 element);
+
+//   inline ListTag      & GetListElem(void) { return PubElValSet.GetListElem();};
+//   inline TagElValueHT & GetElVal(void) { return PubElValSet.GetTagHt();   };
+
+// Read (used in gdcmFile)
+   FILE *OpenFile(bool exception_on_error = false) throw(gdcmFileError);
+   bool CloseFile(void);
+   virtual void ParseHeader(bool exception_on_error = false) throw(gdcmFormatError);
+
+// Write (used in gdcmFile)
+   bool Write(FILE *, FileType);
+   void SetImageDataSize(size_t ExpectedSize);
+
+// System access
+   inline int GetSwapCode(void) { return sw; }
+   guint16 SwapShort(guint16); // needed by gdcmFile
+   guint32 SwapLong(guint32);  // for JPEG Files
+
+protected:
+   gdcmElValue * GetElValueByNumber(guint16 group, guint16 element);
+   bool CheckIfExistByNumber(guint16 Group, guint16 Elem );
+
+   int write(std::ostream&);   
+   int anonymize(std::ostream&);  // FIXME : anonymize should be a friend ?
+
+   size_t GetPubElValOffsetByNumber  (guint16 Group, guint16 Elem);
+   void * GetPubElValVoidAreaByNumber(guint16 Group, guint16 Elem);   
+   void * LoadElementVoidArea        (guint16 Group, guint16 Element);
+
    bool ReplaceOrCreateByNumber(std::string Value, guint16 Group, guint16 Elem); 
    bool ReplaceOrCreateByNumber(     char * Value, guint16 Group, guint16 Elem);                                
    bool ReplaceIfExistByNumber (     char * Value, guint16 Group, guint16 Elem);
-                                  
-   bool Write(FILE *, FileType);
+
+// Variables
+   FILE * fp;
+   FileType filetype; // ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown
    
- // Some heuristic based accessors, end user intended 
- // (to be move to gdcmHeaderHelper?) 
-  
-   int GetXSize(void);  
-   int GetYSize(void);
-   int GetZSize(void);
-   int GetBitsStored(void);
-   int GetBitsAllocated(void);
-   int GetSamplesPerPixel(void);   
-   int GetPlanarConfiguration(void);
-   int GetPixelSize(void);   
-       
-   std::string GetPixelType(void);  
+private:
+   // Read
+   void LoadElements        (void);
+   void LoadElementValue    (gdcmElValue *);
+   void LoadElementValueSafe(gdcmElValue *);
+   void FindLength          (gdcmElValue *);
+   void FindVR              (gdcmElValue *);
+
+   guint32 FindLengthOB(void);
+
+   void SkipElementValue    (gdcmElValue *);
+   void FixFoundLength      (gdcmElValue *, guint32);
+   bool IsAnInteger         (gdcmElValue *);
+
+   guint16 ReadInt16(void);
+   guint32 ReadInt32(void);
+   void    SkipBytes(guint32);
+
+   void Initialise(void);
+   void CheckSwap(void);
+   void SwitchSwapToBigEndian(void);
+   void SetMaxSizeLoadElementValue(long);
+
+   // Dict
+   gdcmDictEntry *GetDictEntryByName  (std::string Name);
+   gdcmDictEntry *GetDictEntryByNumber(guint16, guint16);
+
+   // ElValue related utilities
+   gdcmElValue *ReadNextElement   (void);
+   gdcmElValue *NewElValueByNumber(guint16 group, guint16 element);
+   gdcmElValue *NewElValueByName  (std::string Name);
+   gdcmElValue* GetElementByName  (std::string Name);
+
+   // Deprecated
+   gdcmElValue *NewManualElValToPubDict(std::string NewTagName,
+                                        std::string VR);
+
+// Variables
+   // Pointer to the Value Representation Hash Table which contains all
+   // the VR of the DICOM version3 public dictionary. 
+   gdcmVR *dicom_vr;     // Not a class member for thread-safety reasons
    
-   std::string GetTransferSyntaxName(void);
-   bool   HasLUT(void);
-   int    GetLUTNbits(void);
-   unsigned char * GetLUTRGBA(void);
+   // Pointer to the Transfert Syntax Hash Table which contains all
+   // the TS of the DICOM version3 public dictionary. 
+   gdcmTS *dicom_ts;     // Not a class member for thread-safety reasons 
+     
+   // Pointer to global dictionary container
+   gdcmDictSet *Dicts;   // Not a class member for thread-safety reasons
+   
+   // Public dictionary used to parse this header
+   gdcmDict *RefPubDict;
+   
+   // Optional "shadow dictionary" (private elements) used to parse this
+   // header
+   gdcmDict *RefShaDict;
+
+   /// ELement VALueS parsed with the PUBlic dictionary.
+   gdcmElValSet PubElValSet;
+   
+   // Refering underlying filename.
+   std::string filename; 
   
-  // voir gdcmFile::SetImageData ?!?         
-   void SetImageDataSize (size_t ExpectedSize);
+   int enableSequences;
 
-// System access
-   guint16 SwapShort(guint16); // needed by gdcmFile
-   guint32 SwapLong(guint32);  // for JPEG Files
+   // FIXME sw should be an enum e.g.
+   //enum EndianType {
+      //LittleEndian, 
+      //BadLittleEndian,
+      //BigEndian, 
+      //BadBigEndian};
+   // Swap code e.g. little, big, bad-big, bad-little endian). Warning:
+   // this code is not fixed during header parsing.
+   int sw;
+
+   // Size treshold above which an element value will NOT be loaded in 
+   // memory (to avoid loading the image/volume itself). By default,
+   // this upper bound is fixed to 1024 bytes (which might look reasonable
+   // when one considers the definition of the various VR contents).
+   guint32 MaxSizeLoadElementValue;
+
+   static const unsigned int HEADER_LENGTH_TO_READ; 
+   static const unsigned int MAX_SIZE_LOAD_ELEMENT_VALUE;
 };
 
+//-----------------------------------------------------------------------------
 #endif
index 60e1fbee2e8775be786332f0cbe3dae105506916..15f0927528fe2c2a1eba36e6cb541a5aa1fc2a23 100644 (file)
@@ -1,60 +1,61 @@
-// $Header: /cvs/public/gdcm/src/Attic/gdcmHeaderHelper.cxx,v 1.18 2004/01/13 11:32:30 jpr Exp $
-
+// gdcmHeaderHelper.cxx
+//-----------------------------------------------------------------------------
 #include "gdcmHeaderHelper.h"
 
 #include "gdcmUtil.h" //for debug
 #include <math.h>
 #include <algorithm>
-//#include <string.h> //for bzero
 
-//directory manipulation (os indep).
-//cygwin ???? -> _WIN32 ??
 #ifdef _MSC_VER 
-#include <windows.h> 
-int GetDir(std::string dPath, std::list<std::string> &filenames)
-{
-  //For now dPath should have an ending "\"
-  WIN32_FIND_DATA FileData; 
-  HANDLE hFile; 
-  hFile = FindFirstFile((dPath+"*").c_str(), &FileData); 
-  if ( hFile == INVALID_HANDLE_VALUE ) 
-  { 
-    //No files !
-    return false; 
-  } 
+   #include <windows.h> 
+
+   int GetDir(std::string dPath, std::list<std::string> &filenames)
+   {
+     //For now dPath should have an ending "\"
+     WIN32_FIND_DATA FileData; 
+     HANDLE hFile; 
+     hFile = FindFirstFile((dPath+"*").c_str(), &FileData); 
+     if ( hFile == INVALID_HANDLE_VALUE ) 
+     { 
+       //No files !
+       return false; 
+     } 
   
-  if( strncmp(FileData.cFileName, ".", 1) != 0 )
-    filenames.push_back( dPath+FileData.cFileName );
-  while( FindNextFile(hFile, &FileData ) != 0)
-  { 
-    if( strncmp(FileData.cFileName, ".", 1) != 0 )
-      filenames.push_back( dPath+FileData.cFileName );
-  }
-  return true;
-}
+     if( strncmp(FileData.cFileName, ".", 1) != 0 )
+       filenames.push_back( dPath+FileData.cFileName );
+     while( FindNextFile(hFile, &FileData ) != 0)
+     
+       if( strncmp(FileData.cFileName, ".", 1) != 0 )
+         filenames.push_back( dPath+FileData.cFileName );
+     }
+     return true;
+   }
 
 #else
-#include <dirent.h>
+   #include <dirent.h>
 
-int GetDir(std::string dPath, std::list<std::string> &filenames)
-{
- DIR *dir = opendir( dPath.c_str() );
- struct dirent *entry;
- while((entry = readdir(dir)) != NULL)
- {
-//   if( strncmp(entry->d_name, ".", 1) != 0 && strncmp(entry->d_name, "..", 2) != 0)
-   if( strncmp(entry->d_name, ".", 1) != 0 )
+   int GetDir(std::string dPath, std::list<std::string> &filenames)
    {
-      filenames.push_back( dPath + "/" + entry->d_name );
+    DIR *dir = opendir( dPath.c_str() );
+    struct dirent *entry;
+    while((entry = readdir(dir)) != NULL)
+    {
+   //   if( strncmp(entry->d_name, ".", 1) != 0 && strncmp(entry->d_name, "..", 2) != 0)
+      if( strncmp(entry->d_name, ".", 1) != 0 )
+      {
+         filenames.push_back( dPath + "/" + entry->d_name );
+      }
+    }
+    closedir(dir);
+    return true;
    }
- }
- closedir(dir);
- return true;
-}
 
 #endif
 
-//----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// gdcmHeaderHelper
+//-----------------------------------------------------------------------------
+// Constructor / Destructor
 /**
  * \ingroup gdcmHeaderHelper
  * \brief   cstor
@@ -62,7 +63,7 @@ int GetDir(std::string dPath, std::list<std::string> &filenames)
 gdcmHeaderHelper::gdcmHeaderHelper() : gdcmHeader( )
 {
 }
-//----------------------------------------------------------------------------
+
 /**
  * \ingroup gdcmHeaderHelper
  * \brief   cstor
@@ -71,7 +72,12 @@ gdcmHeaderHelper::gdcmHeaderHelper(const char *InFilename,
     bool exception_on_error) : gdcmHeader( InFilename , exception_on_error)
 {
 }
-//----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Print
+
+//-----------------------------------------------------------------------------
+// Public
 /**
  * \ingroup gdcmHeaderHelper
  * \brief   Return the size (in bytes) of a single pixel of data.
@@ -96,69 +102,6 @@ int gdcmHeaderHelper::GetPixelSize() {
    return 0;
 }
 
-//----------------------------------------------------------------------------
-/**
-  * \ingroup gdcmHeaderHelper
-  * \brief This function is intended to user who doesn't whan 
-  * \ to have to manage a LUT and expects to get an RBG Pixel image
-  * \ (or a monochrome one ...) 
-  * \warning to be used with GetImagePixels()
-  * @return 1 if Gray level, 3 if Color (RGB, YBR or PALETTE COLOR)
-  */
-int gdcmHeaderHelper::GetNumberOfScalarComponents() {
-
-   if (GetSamplesPerPixel() ==3)
-      return 3;
-      
-     // 0028 0100 US IMG Bits Allocated
-     // (in order no to be messed up by old RGB images)
-   if (gdcmHeader::GetPubElValByNumber(0x0028,0x0100) == "24")
-      return 3;
-       
-   std::string PhotometricInterpretation = 
-                  gdcmHeader::GetPubElValByNumber(0x0028,0x0004);
-
-   if ( ( PhotometricInterpretation == "PALETTE COLOR ") ) {
-      if (HasLUT())   // PALETTE COLOR is NOT enough
-         return 3;
-      else
-         return 1;      
-   }   
-                 
-      //beware of trailing space at end of string                                              
-   if (PhotometricInterpretation.find(GDCM_UNFOUND) < 
-                           PhotometricInterpretation.length() || 
-       PhotometricInterpretation.find("MONOCHROME1") < 
-                           PhotometricInterpretation.length() || 
-       PhotometricInterpretation.find("MONOCHROME2") < 
-                           PhotometricInterpretation.length() ) 
-       return 1;
-    else
-    // we assume that *all* kinds of YBR are dealt with
-      return 3;
-}
-
-//----------------------------------------------------------------------------
-/**
-  * \ingroup gdcmHeaderHelper
-  * \brief This function is intended to user that DOESN'T want 
-  * \to get RGB pixels image when it's stored as a PALETTE COLOR image
-  * \ - the (vtk) user is supposed to know how deal with LUTs - 
-  * \warning to be used with GetImagePixelsRaw()
-  * @return 1 if Gray level, 3 if Color (RGB or YBR - NOT 'PALETTE COLOR' -)
-  */
-int gdcmHeaderHelper::GetNumberOfScalarComponentsRaw() {
-      
-     // 0028 0100 US IMG Bits Allocated
-     // (in order no to be messed up by old RGB images)
-   if (gdcmHeader::GetPubElValByNumber(0x0028,0x0100) == "24")
-      return 3;
-
-    // we assume that *all* kinds of YBR are dealt with
-      return GetSamplesPerPixel();
-}
-
-//----------------------------------------------------------------------------
 /**
  * \ingroup gdcmHeaderHelper
  * \brief   Build the Pixel Type of the image.
@@ -198,7 +141,7 @@ std::string gdcmHeaderHelper::GetPixelType() {
 
    return( BitsAlloc + Signed);
 }
-//----------------------------------------------------------------------------
+
 /**
   * \ingroup gdcmHeaderHelper
   * \brief gets the info from 0028,0030 : Pixel Spacing
@@ -222,7 +165,7 @@ float gdcmHeaderHelper::GetXSpacing() {
   }
   return xspacing;
 }
-//----------------------------------------------------------------------------
+
 /**
   * \ingroup gdcmHeaderHelper
   * \brief gets the info from 0028,0030 : Pixel Spacing
@@ -247,7 +190,6 @@ float gdcmHeaderHelper::GetYSpacing() {
   return yspacing;
 } 
 
-//----------------------------------------------------------------------------
 /**
   *\ingroup gdcmHeaderHelper
   *\brief gets the info from 0018,0088 : Space Between Slices
@@ -284,8 +226,112 @@ float gdcmHeaderHelper::GetZSpacing() {
    }
 }
 
-//----------------------------------------------------------------------------
-//
+float gdcmHeaderHelper::GetRescaleIntercept()
+{
+  float resInter = 0.;
+  std::string StrRescInter = GetPubElValByNumber(0x0028,0x1052); //0028 1052 DS IMG Rescale Intercept
+  if (StrRescInter != GDCM_UNFOUND) {
+      if( sscanf( StrRescInter.c_str(), "%f", &resInter) != 1) {
+         dbg.Verbose(0, "gdcmHeader::GetRescaleIntercept: Rescale Slope is empty");
+           // bug in the element 0x0028,0x1052
+      }    
+   }
+  return resInter;
+}
+
+float gdcmHeaderHelper::GetRescaleSlope()
+{
+  float resSlope = 1.;
+  std::string StrRescSlope = GetPubElValByNumber(0x0028,0x1053); //0028 1053 DS IMG Rescale Slope
+  if (StrRescSlope != GDCM_UNFOUND) {
+      if( sscanf( StrRescSlope.c_str(), "%f", &resSlope) != 1) {
+         dbg.Verbose(0, "gdcmHeader::GetRescaleSlope: Rescale Slope is empty");
+           // bug in the element 0x0028,0x1053
+      }    
+   }  
+       return resSlope;
+}
+
+/**
+  * \ingroup gdcmHeaderHelper
+  * \brief This function is intended to user who doesn't whan 
+  * \ to have to manage a LUT and expects to get an RBG Pixel image
+  * \ (or a monochrome one ...) 
+  * \warning to be used with GetImagePixels()
+  * @return 1 if Gray level, 3 if Color (RGB, YBR or PALETTE COLOR)
+  */
+int gdcmHeaderHelper::GetNumberOfScalarComponents() {
+
+   if (GetSamplesPerPixel() ==3)
+      return 3;
+      
+     // 0028 0100 US IMG Bits Allocated
+     // (in order no to be messed up by old RGB images)
+   if (gdcmHeader::GetPubElValByNumber(0x0028,0x0100) == "24")
+      return 3;
+       
+   std::string PhotometricInterpretation = 
+                  gdcmHeader::GetPubElValByNumber(0x0028,0x0004);
+
+   if ( ( PhotometricInterpretation == "PALETTE COLOR ") ) {
+      if (HasLUT())   // PALETTE COLOR is NOT enough
+         return 3;
+      else
+         return 1;      
+   }   
+                 
+      //beware of trailing space at end of string                                              
+   if (PhotometricInterpretation.find(GDCM_UNFOUND) < 
+                           PhotometricInterpretation.length() || 
+       PhotometricInterpretation.find("MONOCHROME1") < 
+                           PhotometricInterpretation.length() || 
+       PhotometricInterpretation.find("MONOCHROME2") < 
+                           PhotometricInterpretation.length() ) 
+       return 1;
+    else
+    // we assume that *all* kinds of YBR are dealt with
+      return 3;
+}
+
+/**
+  * \ingroup gdcmHeaderHelper
+  * \brief This function is intended to user that DOESN'T want 
+  * \to get RGB pixels image when it's stored as a PALETTE COLOR image
+  * \ - the (vtk) user is supposed to know how deal with LUTs - 
+  * \warning to be used with GetImagePixelsRaw()
+  * @return 1 if Gray level, 3 if Color (RGB or YBR - NOT 'PALETTE COLOR' -)
+  */
+int gdcmHeaderHelper::GetNumberOfScalarComponentsRaw() {
+      
+     // 0028 0100 US IMG Bits Allocated
+     // (in order no to be messed up by old RGB images)
+   if (gdcmHeader::GetPubElValByNumber(0x0028,0x0100) == "24")
+      return 3;
+
+    // we assume that *all* kinds of YBR are dealt with
+      return GetSamplesPerPixel();
+}
+
+std::string gdcmHeaderHelper::GetStudyUID()
+{
+  return GetPubElValByNumber(0x0020,0x000d); //0020 000d UI REL Study Instance UID
+}
+
+std::string gdcmHeaderHelper::GetSeriesUID()
+{
+  return GetPubElValByNumber(0x0020,0x000e); //0020 000e UI REL Series Instance UID
+}
+
+std::string gdcmHeaderHelper::GetClassUID()
+{
+  return GetPubElValByNumber(0x0008,0x0016); //0008 0016 UI ID SOP Class UID
+}
+
+std::string gdcmHeaderHelper::GetInstanceUID()
+{
+  return GetPubElValByNumber(0x0008,0x0018); //0008 0018 UI ID SOP Instance UID
+}
+
 // Image Position Patient                              (0020,0032):
 // If not found (ACR_NEMA) we try Image Position       (0020,0030)
 // If not found (ACR-NEMA), we consider Slice Location (0020,1041)
@@ -295,7 +341,6 @@ float gdcmHeaderHelper::GetZSpacing() {
 
 // TODO : find a way to inform the caller nothing was found
 // TODO : How to tell the caller a wrong number of values was found?
-
 /**
   * \ingroup gdcmHeaderHelper
   * \brief gets the info from 0020,0032 : Image Position Patient
@@ -320,7 +365,7 @@ float gdcmHeaderHelper::GetXOrigin() {
      return 0.;
    return xImPos;
 }
-//----------------------------------------------------------------------------
+
 /**
   * \ingroup gdcmHeaderHelper
   * \brief gets the info from 0020,0032 : Image Position Patient
@@ -345,7 +390,7 @@ float gdcmHeaderHelper::GetYOrigin() {
      return 0.;
    return yImPos;
 }
-//----------------------------------------------------------------------------
+
 /**
   * \ingroup gdcmHeaderHelper
   * \brief gets the info from 0020,0032 : Image Position Patient
@@ -397,7 +442,7 @@ float gdcmHeaderHelper::GetZOrigin() {
    dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Location (0020,0050)");  
    return 0.; // Hopeless
 }
-//----------------------------------------------------------------------------
+
 /**
   * \ingroup gdcmHeaderHelper
   * \brief gets the info from 0020,0013 : Image Number
@@ -416,7 +461,7 @@ int gdcmHeaderHelper::GetImageNumber() {
   }
   return 0;   //Hopeless
 }
-//----------------------------------------------------------------------------
+
 /**
   * \ingroup gdcmHeaderHelper
   * \brief gets the info from 0008,0060 : Modality
@@ -476,72 +521,6 @@ ModalityType gdcmHeaderHelper::GetModality(void) {
   return Unknow;
 }
 
-//----------------------------------------------------------------------------
-std::string gdcmHeaderHelper::GetStudyUID()
-{
-  return GetPubElValByNumber(0x0020,0x000d); //0020 000d UI REL Study Instance UID
-}
-//----------------------------------------------------------------------------
-std::string gdcmHeaderHelper::GetSeriesUID()
-{
-  return GetPubElValByNumber(0x0020,0x000e); //0020 000e UI REL Series Instance UID
-}
-//----------------------------------------------------------------------------
-std::string gdcmHeaderHelper::GetClassUID()
-{
-  return GetPubElValByNumber(0x0008,0x0016); //0008 0016 UI ID SOP Class UID
-}
-//----------------------------------------------------------------------------
-std::string gdcmHeaderHelper::GetInstanceUID()
-{
-  return GetPubElValByNumber(0x0008,0x0018); //0008 0018 UI ID SOP Instance UID
-}
-//----------------------------------------------------------------------------
-float gdcmHeaderHelper::GetRescaleIntercept()
-{
-  float resInter = 0.;
-  std::string StrRescInter = GetPubElValByNumber(0x0028,0x1052); //0028 1052 DS IMG Rescale Intercept
-  if (StrRescInter != GDCM_UNFOUND) {
-      if( sscanf( StrRescInter.c_str(), "%f", &resInter) != 1) {
-         dbg.Verbose(0, "gdcmHeader::GetRescaleIntercept: Rescale Slope is empty");
-           // bug in the element 0x0028,0x1052
-      }    
-   }
-  return resInter;
-}
-//----------------------------------------------------------------------------
-float gdcmHeaderHelper::GetRescaleSlope()
-{
-  float resSlope = 1.;
-  std::string StrRescSlope = GetPubElValByNumber(0x0028,0x1053); //0028 1053 DS IMG Rescale Slope
-  if (StrRescSlope != GDCM_UNFOUND) {
-      if( sscanf( StrRescSlope.c_str(), "%f", &resSlope) != 1) {
-         dbg.Verbose(0, "gdcmHeader::GetRescaleSlope: Rescale Slope is empty");
-           // bug in the element 0x0028,0x1053
-      }    
-   }  
-       return resSlope;
-}
-
-
-
-
-
-
-
-
-
-gdcmSerieHeaderHelper::~gdcmSerieHeaderHelper()
-{
-  //! \todo
-  for (std::list<gdcmHeaderHelper*>::iterator it  = CoherentGdcmFileList.begin();
-        it != CoherentGdcmFileList.end(); it++)
-  {
-    delete *it;
-  }
-  CoherentGdcmFileList.clear();
-}
-//----------------------------------------------------------------------------
 /**
   * \ingroup gdcmHeaderHelper
   * \brief gets the info from 0020,0037 : Image Orientation Patient
@@ -576,30 +555,59 @@ void gdcmHeaderHelper::GetImageOrientationPatient( float* iop ) {
   }
 }
 
-//----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// Protected
+
+//-----------------------------------------------------------------------------
+// Private
+
+//-----------------------------------------------------------------------------
+
+
+
+//-----------------------------------------------------------------------------
+// gdcmSerieHeaderHelper
+//-----------------------------------------------------------------------------
+// Constructor / Destructor
+gdcmSerieHeaderHelper::~gdcmSerieHeaderHelper()
+{
+  //! \todo
+  for (std::list<gdcmHeaderHelper*>::iterator it  = CoherentGdcmFileList.begin();
+        it != CoherentGdcmFileList.end(); it++)
+  {
+    delete *it;
+  }
+  CoherentGdcmFileList.clear();
+}
+
+//-----------------------------------------------------------------------------
+// Print
+
+//-----------------------------------------------------------------------------
+// Public
 /**
 * \ingroup gdcmHeaderHelper
 * \brief add a gdcmFile to the list based on file name
 */
+ * \ingroup gdcmHeaderHelper
+ * \brief add a gdcmFile to the list based on file name
+ */
 void gdcmSerieHeaderHelper::AddFileName(std::string filename)
 {
   gdcmHeaderHelper *GdcmFile = new gdcmHeaderHelper( filename.c_str() );
   this->CoherentGdcmFileList.push_back( GdcmFile );
 }
-//----------------------------------------------------------------------------
+
 /**
 * \ingroup gdcmHeaderHelper
 * \brief add a gdcmFile to the list
 */
+ * \ingroup gdcmHeaderHelper
+ * \brief add a gdcmFile to the list
+ */
 void gdcmSerieHeaderHelper::AddGdcmFile(gdcmHeaderHelper *file)
 {
   this->CoherentGdcmFileList.push_back( file );
 }
-//----------------------------------------------------------------------------
+
 /**
 * \ingroup gdcmHeaderHelper
 * \brief \todo
 */
+ * \ingroup gdcmHeaderHelper
+ * \brief \todo
+ */
 void gdcmSerieHeaderHelper::SetDirectory(std::string dir)
 {
   std::list<std::string> filenames_list;
@@ -612,7 +620,7 @@ void gdcmSerieHeaderHelper::SetDirectory(std::string dir)
     this->CoherentGdcmFileList.push_back( file );
   }
 }
-//----------------------------------------------------------------------------
+
 //This could be implemented in a 'Strategy Pattern' approach
 //But as I don't know how to do it, I leave it this way
 //BTW, this is also a Strategy, I don't know this is the best approach :)
@@ -631,17 +639,27 @@ void gdcmSerieHeaderHelper::OrderGdcmFileList()
     FileNameOrdering();
   }
 }
-//----------------------------------------------------------------------------
+
+std::list<gdcmHeaderHelper*> &gdcmSerieHeaderHelper::GetGdcmFileList()
+{
+  return CoherentGdcmFileList;
+}
+
+//-----------------------------------------------------------------------------
+// Protected
+
+//-----------------------------------------------------------------------------
+// Private
 /**
-  * \ingroup gdcmHeaderHelper
-  * \brief 
-    We may order, considering :
-      -# Image Number
-      -# Image Position Patient
-      -# More to come :)
-*/
-//based on Jolinda's algorithm
+ * \ingroup gdcmHeaderHelper
+ * \brief 
+ *  We may order, considering :
+ *   -# Image Number
+ *   -# Image Position Patient
+ *   -# More to come :)
+ */
 bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering()
+//based on Jolinda's algorithm
 {
   //iop is calculated based on the file file
   float *cosines = new float[6];
@@ -748,7 +766,7 @@ bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering()
   
   return true;
 }
-//----------------------------------------------------------------------------
+
 //Based on Image Number
 bool gdcmSerieHeaderHelper::ImageNumberOrdering()
 {
@@ -800,16 +818,12 @@ bool gdcmSerieHeaderHelper::ImageNumberOrdering()
   delete[] partition;
   return mult;
 }
-//----------------------------------------------------------------------------
+
 bool gdcmSerieHeaderHelper::FileNameOrdering()
 {
   //using the sort
   //sort(CoherentGdcmFileList.begin(), CoherentGdcmFileList.end());
   return true;
 }
-//----------------------------------------------------------------------------
-std::list<gdcmHeaderHelper*> &gdcmSerieHeaderHelper::GetGdcmFileList()
-{
-  return CoherentGdcmFileList;
-}
-//----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
index 0fdb046209a9685eed7d098225f4d32b5532d3e7..8f44170724c5a2550b4627f4a5f72e842148c670 100644 (file)
@@ -1,56 +1,58 @@
-// $Header: /cvs/public/gdcm/src/Attic/gdcmHeaderHelper.h,v 1.10 2004/01/13 11:32:30 jpr Exp $
-
+// gdcmHeaderHelper.h
+//-----------------------------------------------------------------------------
 #ifndef GDCMHEADERHELPER_H
 #define GDCMHEADERHELPER_H
 
 #include "gdcmHeader.h"
 
-   // Dicom Part 3.3 Compliant
-   enum ModalityType {
-      Unknow,
-      AU,       // Voice Audio
-      AS,       // Angioscopy
-      BI,       // Biomagnetic Imaging
-      CF,       // Cinefluorography
-      CP,       // Culposcopy
-      CR,       // Computed Radiography
-      CS,       // Cystoscopy
-      CT,       // Computed Tomography
-      DD,       // Duplex Dopler
-      DF,       // Digital Fluoroscopy
-      DG,       // Diaphanography
-      DM,       // Digital Microscopy
-      DS,       // Digital Substraction Angiography
-      DX,       // Digital Radiography
-      ECG,      // Echocardiography
-      EPS,      // Basic Cardiac EP
-      ES,       // Endoscopy
-      FA,       // Fluorescein Angiography
-      FS,       // Fundoscopy
-      HC,       // Hard Copy
-      HD,       // Hemodynamic
-      LP,       // Laparoscopy
-      LS,       // Laser Surface Scan
-      MA,       // Magnetic Resonance Angiography
-      MR,       // Magnetic Resonance
-      NM,       // Nuclear Medicine
-      OT,       // Other
-      PT,       // Positron Emission Tomography
-      RF,       // Radio Fluoroscopy
-      RG,       // Radiographic Imaging
-      RTDOSE,   // Radiotherapy Dose
-      RTIMAGE,  // Radiotherapy Image
-      RTPLAN,   // Radiotherapy Plan
-      RTSTRUCT, // Radiotherapy Structure Set
-      SM,       // Microscopic Imaging
-      ST,       // Single-photon Emission Computed Tomography
-      TG,       // Thermography
-      US,       // Ultrasound
-      VF,       // Videofluorography
-      XA,       // X-Ray Angiography
-      XC        // Photographic Imaging
-    };
+//-----------------------------------------------------------------------------
+// Dicom Part 3.3 Compliant
+enum ModalityType {
+   Unknow,
+   AU,       // Voice Audio
+   AS,       // Angioscopy
+   BI,       // Biomagnetic Imaging
+   CF,       // Cinefluorography
+   CP,       // Culposcopy
+   CR,       // Computed Radiography
+   CS,       // Cystoscopy
+   CT,       // Computed Tomography
+   DD,       // Duplex Dopler
+   DF,       // Digital Fluoroscopy
+   DG,       // Diaphanography
+   DM,       // Digital Microscopy
+   DS,       // Digital Substraction Angiography
+   DX,       // Digital Radiography
+   ECG,      // Echocardiography
+   EPS,      // Basic Cardiac EP
+   ES,       // Endoscopy
+   FA,       // Fluorescein Angiography
+   FS,       // Fundoscopy
+   HC,       // Hard Copy
+   HD,       // Hemodynamic
+   LP,       // Laparoscopy
+   LS,       // Laser Surface Scan
+   MA,       // Magnetic Resonance Angiography
+   MR,       // Magnetic Resonance
+   NM,       // Nuclear Medicine
+   OT,       // Other
+   PT,       // Positron Emission Tomography
+   RF,       // Radio Fluoroscopy
+   RG,       // Radiographic Imaging
+   RTDOSE,   // Radiotherapy Dose
+   RTIMAGE,  // Radiotherapy Image
+   RTPLAN,   // Radiotherapy Plan
+   RTSTRUCT, // Radiotherapy Structure Set
+   SM,       // Microscopic Imaging
+   ST,       // Single-photon Emission Computed Tomography
+   TG,       // Thermography
+   US,       // Ultrasound
+   VF,       // Videofluorography
+   XA,       // X-Ray Angiography
+   XC        // Photographic Imaging
+};
       
+//-----------------------------------------------------------------------------
 /*
  * This class is meant to *interpret* data given from gdcmHeader
  * That is to say :
@@ -61,7 +63,6 @@
  *  - ...
  */
 class GDCM_EXPORT gdcmHeaderHelper : public gdcmHeader {
-
 public:
    gdcmHeaderHelper::gdcmHeaderHelper();
    gdcmHeaderHelper::gdcmHeaderHelper(const char *filename, 
@@ -74,7 +75,7 @@ public:
    float GetYSpacing();
    float GetZSpacing();
    
-   //Usefull for rescaling graylevel:
+   // Usefull for rescaling graylevel:
    float GetRescaleIntercept();
    float GetRescaleSlope();
 
@@ -86,12 +87,12 @@ public:
    std::string GetClassUID();
    std::string GetInstanceUID();
    
-    /**
-    change GetXImagePosition -> GetXOrigin in order not to confused reader
-      -# GetXOrigin can return default value (=0) if it was not ImagePosition
-      -# Image Position is different in dicomV3 <> ACR NEMA -> better use generic
-      name
-    */
+   /**
+    change GetXImagePosition -> GetXOrigin in order not to confused reader
+    * -# GetXOrigin can return default value (=0) if it was not ImagePosition
+    * -# Image Position is different in dicomV3 <> ACR NEMA -> better use generic
+    * name
+   */
    float GetXOrigin();
    float GetYOrigin();
    float GetZOrigin();
@@ -100,16 +101,14 @@ public:
    ModalityType GetModality();
    
    void GetImageOrientationPatient( float* iop );
-  
-
 };
 
+//-----------------------------------------------------------------------------
 /**
 This class should be used for a stack of 2D dicom images.
 For a multiframe dicom image better use directly gdcmHeaderHelper
 */
 class GDCM_EXPORT gdcmSerieHeaderHelper {
-
 public:
     gdcmSerieHeaderHelper::gdcmSerieHeaderHelper() {};
     gdcmSerieHeaderHelper::~gdcmSerieHeaderHelper();
@@ -119,7 +118,7 @@ public:
    void SetDirectory(std::string dir);
    void OrderGdcmFileList();
    
-   gdcmHeaderHelper *GetGdcmHeader()
+   inline gdcmHeaderHelper *GetGdcmHeader()
    {
       //Assume all element in the list have the same global infos
       return CoherentGdcmFileList.front();
@@ -133,7 +132,7 @@ private:
    bool FileNameOrdering();
    
    std::list<gdcmHeaderHelper*> CoherentGdcmFileList;
-
 };
 
+//-----------------------------------------------------------------------------
 #endif
index 76f04c23b834a962fc14e59e75958123277773a0..15bdd1a17b3926d1fc14b29bc3766f6eb79a435c 100644 (file)
@@ -1,4 +1,5 @@
-
+// gdcmJpeg.cxx
+//-----------------------------------------------------------------------------
 #include <stdio.h>
 #include "gdcmFile.h"
 
@@ -117,74 +118,70 @@ extern "C" {
  * Here's the extended error handler struct:
  */
 
+//-----------------------------------------------------------------------------
 struct my_error_mgr {
-  struct jpeg_error_mgr pub;   /* "public" fields */
-  jmp_buf setjmp_buffer;       /* for return to caller */
+   struct jpeg_error_mgr pub;  /* "public" fields */
+   jmp_buf setjmp_buffer;      /* for return to caller */
 };
 
+//-----------------------------------------------------------------------------
 typedef struct my_error_mgr * my_error_ptr;
 
 /*
  * Here's the routine that will replace the standard error_exit method:
  */
+METHODDEF(void) my_error_exit (j_common_ptr cinfo) {
+   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
+   my_error_ptr myerr = (my_error_ptr) cinfo->err;
 
-METHODDEF(void)
-my_error_exit (j_common_ptr cinfo) {
-  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
-  my_error_ptr myerr = (my_error_ptr) cinfo->err;
-
-  /* Always display the message. */
-  /* We could postpone this until after returning, if we chose. */
-  (*cinfo->err->output_message) (cinfo);
+   /* Always display the message. */
+   /* We could postpone this until after returning, if we chose. */
+   (*cinfo->err->output_message) (cinfo);
 
-  /* Return control to the setjmp point */
-  longjmp(myerr->setjmp_buffer, 1);
+   /* Return control to the setjmp point */
+   longjmp(myerr->setjmp_buffer, 1);
 }
 
-
+//-----------------------------------------------------------------------------
 /*
  * Sample routine for JPEG decompression.  We assume that the source file name
  * is passed in.  We want to return 1 on success, 0 on error.
  */
 //GLOBAL(bool)
 bool gdcmFile::gdcm_read_JPEG_file (FILE *fp,void * image_buffer) {
+   char *pimage;
 
-char *pimage;
-
-  /* This struct contains the JPEG decompression parameters and pointers to
+   /* This struct contains the JPEG decompression parameters and pointers to
    * working space (which is allocated as needed by the JPEG library).
    */
-   
-  struct jpeg_decompress_struct cinfo;
-  
-  /* -------------- inside, we found :
-  JDIMENSION image_width;      // input image width 
-  JDIMENSION image_height;     // input image height 
-  int input_components;                // nb of color components in input image 
-  J_COLOR_SPACE in_color_space;        // colorspace of input image 
-  double input_gamma;          // image gamma of input image 
+   struct jpeg_decompress_struct cinfo;
+
+   /* -------------- inside, we found :
+   JDIMENSION image_width;     // input image width 
+   JDIMENSION image_height;    // input image height 
+   int input_components;               // nb of color components in input image 
+   J_COLOR_SPACE in_color_space;       // colorspace of input image 
+   double input_gamma;         // image gamma of input image 
      -------------- */
-  
-  /* We use our private extension JPEG error handler.
+
+   /* We use our private extension JPEG error handler.
    * Note that this struct must live as long as the main JPEG parameter
    * struct, to avoid dangling-pointer problems.
    */
-  struct my_error_mgr jerr;
-  /* More stuff */
-  JSAMPARRAY buffer;           /* Output row buffer */
-  
-  // rappel :
-  // ------
-  // typedef unsigned char JSAMPLE;
-  // typedef JSAMPLE FAR *JSAMPROW;    /* ptr to one image row of pixel samples. */
-  // typedef JSAMPROW *JSAMPARRAY;     /* ptr to some rows (a 2-D sample array) */
-  // typedef JSAMPARRAY *JSAMPIMAGE;   /* a 3-D sample array: top index is color */
+   struct my_error_mgr jerr;
+   /* More stuff */
+
+   JSAMPARRAY buffer;          /* Output row buffer */
   
-  int row_stride;              /* physical row width in output buffer */
+   // rappel :
+   // ------
+   // typedef unsigned char JSAMPLE;
+   // typedef JSAMPLE FAR *JSAMPROW;   /* ptr to one image row of pixel samples. */
+   // typedef JSAMPROW *JSAMPARRAY;    /* ptr to some rows (a 2-D sample array) */
+   // typedef JSAMPARRAY *JSAMPIMAGE;  /* a 3-D sample array: top index is color */
+   int row_stride;             /* physical row width in output buffer */
   
- if (DEBUG) printf("entree dans gdcmFile::gdcm_read_JPEG_file, depuis gdcmJpeg\n");
  if (DEBUG) printf("entree dans gdcmFile::gdcm_read_JPEG_file, depuis gdcmJpeg\n");
 
 
   /* In this example we want to open the input file before doing anything else,
@@ -214,33 +211,31 @@ char *pimage;
   /* Now we can initialize the JPEG decompression object. */
   jpeg_create_decompress(&cinfo);
 
-  /* Step 2: specify data source (eg, a file) */
-  
-if (DEBUG) printf("Entree Step 2\n");
-
-  jpeg_stdio_src(&cinfo, fp);
+   /* Step 2: specify data source (eg, a file) */
+   if (DEBUG) printf("Entree Step 2\n");
 
-  /* Step 3: read file parameters with jpeg_read_header() */
+   jpeg_stdio_src(&cinfo, fp);
 
- if (DEBUG) printf("Entree Step 3\n");
+   /* Step 3: read file parameters with jpeg_read_header() */
+   if (DEBUG) printf("Entree Step 3\n");
 
-  (void) jpeg_read_header(&cinfo, TRUE);
+   (void) jpeg_read_header(&cinfo, TRUE);
    
-  /* We can ignore the return value from jpeg_read_header since
-   *   (a) suspension is not possible with the stdio data source, and
-   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
-   * See libjpeg.doc for more info.
-   */
-
-if (DEBUG) {   
-       printf("--------------Header contents :----------------\n");
-       printf("image_width %d image_height %d\n", 
-                               cinfo.image_width , cinfo.image_height);
-       printf("bits of precision in image data  %d \n", 
-                               cinfo.output_components);
-       printf("nb of color components returned  %d \n", 
-                               cinfo.data_precision);
-}
+   /* We can ignore the return value from jpeg_read_header since
+    *   (a) suspension is not possible with the stdio data source, and
+    *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
+    * See libjpeg.doc for more info.
+    */
+
+   if (DEBUG) {   
+      printf("--------------Header contents :----------------\n");
+      printf("image_width %d image_height %d\n", 
+              cinfo.image_width , cinfo.image_height);
+      printf("bits of precision in image data  %d \n", 
+              cinfo.output_components);
+      printf("nb of color components returned  %d \n", 
+              cinfo.data_precision);
+   }
 
 
 /*
@@ -253,17 +248,14 @@ if (DEBUG) {
  
 */
 
-  /* Step 4: set parameters for decompression */
-  
- if (DEBUG) printf("Entree Step 4\n");
-
-  /* In this example, we don't need to change any of the defaults set by
-   * jpeg_read_header(), so we do nothing here.
-   */
+   /* Step 4: set parameters for decompression */
+   if (DEBUG) printf("Entree Step 4\n");
+   /* In this example, we don't need to change any of the defaults set by
+    * jpeg_read_header(), so we do nothing here.
+    */
 
-  /* Step 5: Start decompressor */
-  
- if (DEBUG) printf("Entree Step 5\n");
+   /* Step 5: Start decompressor */
+   if (DEBUG) printf("Entree Step 5\n");
 
   (void) jpeg_start_decompress(&cinfo);
   /* We can ignore the return value since suspension is not possible
@@ -280,30 +272,28 @@ if (DEBUG) {
   /* JSAMPLEs per row in output buffer */
   row_stride = cinfo.output_width * cinfo.output_components;
   
- if (DEBUG) printf ("cinfo.output_width %d cinfo.output_components %d  row_stride %d\n",
-       cinfo.output_width, cinfo.output_components,row_stride);
  if (DEBUG) printf ("cinfo.output_width %d cinfo.output_components %d  row_stride %d\n",
+      cinfo.output_width, cinfo.output_components,row_stride);
        
-  /* Make a one-row-high sample array that will go away when done with image */
-  buffer = (*cinfo.mem->alloc_sarray)
-               ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
+   /* Make a one-row-high sample array that will go away when done with image */
+   buffer = (*cinfo.mem->alloc_sarray)
+            ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
 
-  /* Step 6: while (scan lines remain to be read) */
-  
- if (DEBUG)  printf("Entree Step 6\n"); 
+   /* Step 6: while (scan lines remain to be read) */
+   if (DEBUG)  printf("Entree Step 6\n"); 
 
-  /*           jpeg_read_scanlines(...); */
+   /*           jpeg_read_scanlines(...); */
 
-  /* Here we use the library's state variable cinfo.output_scanline as the
-   * loop counter, so that we don't have to keep track ourselves.
-   */
-   
if (DEBUG)  printf ("cinfo.output_height %d  cinfo.output_width %d\n",
-                       cinfo.output_height,cinfo.output_width);
+   /* Here we use the library's state variable cinfo.output_scanline as the
+    * loop counter, so that we don't have to keep track ourselves.
+    */
+   if (DEBUG)  
     printf ("cinfo.output_height %d  cinfo.output_width %d\n",
+               cinfo.output_height,cinfo.output_width);
  
-  pimage=(char *)image_buffer;
-  
+   pimage=(char *)image_buffer;
   
-  while (cinfo.output_scanline < cinfo.output_height) {
+   while (cinfo.output_scanline < cinfo.output_height) {
     /* jpeg_read_scanlines expects an array of pointers to scanlines.
      * Here the array is only one element long, but you could ask for
      * more than one scanline at a time if that's more convenient.
@@ -327,35 +317,34 @@ if (DEBUG) {
   }
  
   /* Step 7: Finish decompression */
-  
-if (DEBUG)  printf("Entree Step 7\n");
+   if (DEBUG)  printf("Entree Step 7\n");
 
-  (void) jpeg_finish_decompress(&cinfo);
-  /* We can ignore the return value since suspension is not possible
-   * with the stdio data source.
-   */
+   (void) jpeg_finish_decompress(&cinfo);
+   /* We can ignore the return value since suspension is not possible
+    * with the stdio data source.
+    */
 
-  /* Step 8: Release JPEG decompression object */
-  
-if (DEBUG) printf("Entree Step 8\n");
+   /* Step 8: Release JPEG decompression object */
 
-  /* This is an important step since it will release a good deal of memory. */
-  
-  jpeg_destroy_decompress(&cinfo);
+   if (DEBUG) printf("Entree Step 8\n");
 
-  /* After finish_decompress, we can close the input file.
-   * Here we postpone it until after no more JPEG errors are possible,
-   * so as to simplify the setjmp error logic above.  (Actually, I don't
-   * think that jpeg_destroy can do an error exit, but why assume anything...)
-   */
+   /* This is an important step since it will release a good deal of memory. */
 
-  /* At this point you may want to check to see whether any corrupt-data
-   * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
-   */
+   jpeg_destroy_decompress(&cinfo);
 
-  /* And we're done! */
-  
-  return 1;
+   /* After finish_decompress, we can close the input file.
+    * Here we postpone it until after no more JPEG errors are possible,
+    * so as to simplify the setjmp error logic above.  (Actually, I don't
+    * think that jpeg_destroy can do an error exit, but why assume anything...)
+    */
+
+   /* At this point you may want to check to see whether any corrupt-data
+    * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
+    */
+
+   /* And we're done! */
+
+   return 1;
 }
 
 /*
@@ -383,9 +372,4 @@ if (DEBUG) printf("Entree Step 8\n");
  * temporary files are deleted if the program is interrupted.  See libjpeg.doc.
  */
  
-
-
-
-
-
+//-----------------------------------------------------------------------------
index 8a9a4bd853cbaddfffc4dfd902db66c9379a4dee..da5be5d8af30efdde3c21466637aff37181615b6 100644 (file)
@@ -1,4 +1,5 @@
-
+// gdcmJpeg12.cxx
+//-----------------------------------------------------------------------------
 #include <stdio.h>
 #include "gdcmFile.h"
 
 #define jpeg_destroy           jDestroy
 #define jpeg_resync_to_restart jResyncRestart
 
-// -----------------
-
 #define DEBUG 0
 
-
 /*
  * <setjmp.h> is used for the optional error recovery mechanism shown in
  * the second part of the example.
@@ -132,6 +130,7 @@ extern "C" {
  * Here's the extended error handler struct:
  */
 
+//-----------------------------------------------------------------------------
 struct my_error_mgr {
   struct jpeg_error_mgr pub;   /* "public" fields */
   jmp_buf setjmp_buffer;       /* for return to caller */
@@ -139,10 +138,10 @@ struct my_error_mgr {
 
 typedef struct my_error_mgr * my_error_ptr;
 
+//-----------------------------------------------------------------------------
 /*
  * Here's the routine that will replace the standard error_exit method:
  */
-
 METHODDEF(void)
 my_error_exit (j_common_ptr cinfo) {
   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
@@ -157,216 +156,200 @@ my_error_exit (j_common_ptr cinfo) {
 }
 
 
+//-----------------------------------------------------------------------------
 /*
  * Sample routine for JPEG decompression.  We assume that the source file name
  * is passed in.  We want to return 1 on success, 0 on error.
  */
-
-
-//GLOBAL(bool)
 bool gdcmFile::gdcm_read_JPEG_file12 (FILE *fp,void * image_buffer) {
+   char *pimage;
 
-char *pimage;
+   /* This struct contains the JPEG decompression parameters and pointers to
+    * working space (which is allocated as needed by the JPEG library).
+    */
 
-  /* This struct contains the JPEG decompression parameters and pointers to
-   * working space (which is allocated as needed by the JPEG library).
-   */
-   
-  struct jpeg_decompress_struct cinfo;
-  
-  /* -------------- inside, we found :
-  JDIMENSION image_width;      // input image width 
-  JDIMENSION image_height;     // input image height 
-  int input_components;                // nb of color components in input image 
-  J_COLOR_SPACE in_color_space;        // colorspace of input image 
-  double input_gamma;          // image gamma of input image 
-     -------------- */
-  
-  /* We use our private extension JPEG error handler.
-   * Note that this struct must live as long as the main JPEG parameter
-   * struct, to avoid dangling-pointer problems.
-   */
-  struct my_error_mgr jerr;
-  /* More stuff */
-  JSAMPARRAY buffer;           /* Output row buffer */
-  
-  // rappel :
-  // ------
-  // typedef unsigned char JSAMPLE;
-  // typedef JSAMPLE FAR *JSAMPROW;    /* ptr to one image row of pixel samples. */
-  // typedef JSAMPROW *JSAMPARRAY;     /* ptr to some rows (a 2-D sample array) */
-  // typedef JSAMPARRAY *JSAMPIMAGE;   /* a 3-D sample array: top index is color */
+   struct jpeg_decompress_struct cinfo;
   
-  int row_stride;              /* physical row width in output buffer */
+   /* -------------- inside, we found :
+    * JDIMENSION image_width;  // input image width 
+    * JDIMENSION image_height; // input image height 
+    * int input_components;            // nb of color components in input image 
+    * J_COLOR_SPACE in_color_space;    // colorspace of input image 
+    * double input_gamma;              // image gamma of input image 
+    * -------------- */
   
- if (DEBUG) printf("entree dans gdcmFile::gdcm_read_JPEG_file12, depuis gdcmJpeg\n");
+   /* We use our private extension JPEG error handler.
+    * Note that this struct must live as long as the main JPEG parameter
+    * struct, to avoid dangling-pointer problems.
+    */
+   struct my_error_mgr jerr;
+   /* More stuff */
 
+   JSAMPARRAY buffer;          /* Output row buffer */
 
-  /* In this example we want to open the input file before doing anything else,
-   * so that the setjmp() error recovery below can assume the file is open.
-   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
-   * requires it in order to read binary files.
-   */
+   // rappel :
+   // ------
+   // typedef unsigned char JSAMPLE;
+   // typedef JSAMPLE FAR *JSAMPROW;   /* ptr to one image row of pixel samples. */
+   // typedef JSAMPROW *JSAMPARRAY;    /* ptr to some rows (a 2-D sample array) */
+   // typedef JSAMPARRAY *JSAMPIMAGE;  /* a 3-D sample array: top index is color */
 
-  /* Step 1: allocate and initialize JPEG decompression object */
-  
-  if (DEBUG)printf("Entree Step 1\n");
 
-  /* We set up the normal JPEG error routines, then override error_exit. */
-  
-  cinfo.err = jpeg_std_error(&jerr.pub);
-  jerr.pub.error_exit = my_error_exit;
+   int row_stride;             /* physical row width in output buffer */
   
-  /* Establish the setjmp return context for my_error_exit to use. */
+   if (DEBUG) printf("entree dans gdcmFile::gdcm_read_JPEG_file12, depuis gdcmJpeg\n");
+
+
+   /* In this example we want to open the input file before doing anything else,
+    * so that the setjmp() error recovery below can assume the file is open.
+    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
+    * requires it in order to read binary files.
+    */
+
+   /* Step 1: allocate and initialize JPEG decompression object */
+   if (DEBUG)printf("Entree Step 1\n");
+
+   /* We set up the normal JPEG error routines, then override error_exit. */
+
+   cinfo.err = jpeg_std_error(&jerr.pub);
+   jerr.pub.error_exit = my_error_exit;
+
+   /* Establish the setjmp return context for my_error_exit to use. */
+   if (setjmp(jerr.setjmp_buffer)) {
+      /* If we get here, the JPEG code has signaled an error.
+       * We need to clean up the JPEG object, close the input file, and return.
+       */
+      jpeg_destroy_decompress(&cinfo);
+      return(false);
+   }
+
+   /* Now we can initialize the JPEG decompression object. */
+   jpeg_create_decompress(&cinfo);
+
+   /* Step 2: specify data source (eg, a file) */
+   if (DEBUG) printf("Entree Step 2\n");
+   jpeg_stdio_src(&cinfo, fp);
+
+   /* Step 3: read file parameters with jpeg_read_header() */
+   if (DEBUG) printf("Entree Step 3\n");
+   (void) jpeg_read_header(&cinfo, TRUE);
+
+   /* We can ignore the return value from jpeg_read_header since
+    *   (a) suspension is not possible with the stdio data source, and
+    *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
+    * See libjpeg.doc for more info.
+    */
+
+   if (DEBUG) {   
+      printf("--------------Header contents :----------------\n");
+      printf("image_width %d image_height %d\n", 
+                             cinfo.image_width , cinfo.image_height);
+      printf("bits of precision in image data  %d \n", 
+                             cinfo.output_components);
+      printf("nb of color components returned  %d \n", 
+                             cinfo.data_precision);
+   }
+
+
+   /*
+    * JDIMENSION image_width;  // input image width 
+    * JDIMENSION image_height; // input image height 
+    * int output_components;   // # of color components returned 
+    * J_COLOR_SPACE in_color_space;    // colorspace of input image 
+    * double input_gamma;              // image gamma of input image
+    * int data_precision;              // bits of precision in image data 
+    */
+
+   /* Step 4: set parameters for decompression */
+   if (DEBUG) printf("Entree Step 4\n");
+
+   /* In this example, we don't need to change any of the defaults set by
+    * jpeg_read_header(), so we do nothing here.
+    */
+
+   /* Step 5: Start decompressor */
+   if (DEBUG) printf("Entree Step 5\n");
+
+   (void) jpeg_start_decompress(&cinfo);
+   /* We can ignore the return value since suspension is not possible
+    * with the stdio data source.
+    */
+
+   /* We may need to do some setup of our own at this point before reading
+    * the data.  After jpeg_start_decompress() we have the correct scaled
+    * output image dimensions available, as well as the output colormap
+    * if we asked for color quantization.
+    * In this example, we need to make an output work buffer of the right size.
+    */ 
+
+   /* JSAMPLEs per row in output buffer */
+   row_stride = cinfo.output_width * cinfo.output_components;
   
-  if (setjmp(jerr.setjmp_buffer)) {
-    /* If we get here, the JPEG code has signaled an error.
-     * We need to clean up the JPEG object, close the input file, and return.
-     */
-    jpeg_destroy_decompress(&cinfo);
-    return(false);
-  }
-  /* Now we can initialize the JPEG decompression object. */
-  jpeg_create_decompress(&cinfo);
-
-  /* Step 2: specify data source (eg, a file) */
-  
-if (DEBUG) printf("Entree Step 2\n");
-
-  jpeg_stdio_src(&cinfo, fp);
-
-  /* Step 3: read file parameters with jpeg_read_header() */
-
- if (DEBUG) printf("Entree Step 3\n");
-
-  (void) jpeg_read_header(&cinfo, TRUE);
-   
-  /* We can ignore the return value from jpeg_read_header since
-   *   (a) suspension is not possible with the stdio data source, and
-   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
-   * See libjpeg.doc for more info.
-   */
-
-if (DEBUG) {   
-       printf("--------------Header contents :----------------\n");
-       printf("image_width %d image_height %d\n", 
-                               cinfo.image_width , cinfo.image_height);
-       printf("bits of precision in image data  %d \n", 
-                               cinfo.output_components);
-       printf("nb of color components returned  %d \n", 
-                               cinfo.data_precision);
-
-}
+   if (DEBUG) 
+      printf ("cinfo.output_width %d cinfo.output_components %d  row_stride %d\n",
+              cinfo.output_width, cinfo.output_components,row_stride);
+       
+   /* Make a one-row-high sample array that will go away when done with image */
+   buffer = (*cinfo.mem->alloc_sarray)
+          ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
 
+   /* Step 6: while (scan lines remain to be read) */
+   if (DEBUG)  printf("Entree Step 6\n"); 
 
-/*
-  JDIMENSION image_width;      // input image width 
-  JDIMENSION image_height;     // input image height 
-  int output_components;       // # of color components returned 
-  J_COLOR_SPACE in_color_space;        // colorspace of input image 
-  double input_gamma;          // image gamma of input image
-  int data_precision;          // bits of precision in image data 
-*/
+   /*           jpeg_read_scanlines(...); */
 
-  /* Step 4: set parameters for decompression */
-  
- if (DEBUG) printf("Entree Step 4\n");
+   /* Here we use the library's state variable cinfo.output_scanline as the
+    * loop counter, so that we don't have to keep track ourselves.
+    */
 
-  /* In this example, we don't need to change any of the defaults set by
-   * jpeg_read_header(), so we do nothing here.
-   */
+   if (DEBUG)  printf ("cinfo.output_height %d  cinfo.output_width %d\n",
+                  cinfo.output_height,cinfo.output_width);
 
-  /* Step 5: Start decompressor */
-  
- if (DEBUG) printf("Entree Step 5\n");
-
-  (void) jpeg_start_decompress(&cinfo);
-  /* We can ignore the return value since suspension is not possible
-   * with the stdio data source.
-   */
-   
-  /* We may need to do some setup of our own at this point before reading
-   * the data.  After jpeg_start_decompress() we have the correct scaled
-   * output image dimensions available, as well as the output colormap
-   * if we asked for color quantization.
-   * In this example, we need to make an output work buffer of the right size.
-   */ 
-   
-  /* JSAMPLEs per row in output buffer */
-  row_stride = cinfo.output_width * cinfo.output_components;
-  
- if (DEBUG) printf ("cinfo.output_width %d cinfo.output_components %d  row_stride %d\n",
-       cinfo.output_width, cinfo.output_components,row_stride);
-       
-  /* Make a one-row-high sample array that will go away when done with image */
-  buffer = (*cinfo.mem->alloc_sarray)
-               ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
+   pimage=(char *)image_buffer;
 
-  /* Step 6: while (scan lines remain to be read) */
-  
- if (DEBUG)  printf("Entree Step 6\n"); 
+   while (cinfo.output_scanline < cinfo.output_height) {
+      /* jpeg_read_scanlines expects an array of pointers to scanlines.
+       * Here the array is only one element long, but you could ask for
+       * more than one scanline at a time if that's more convenient.
+       */
 
-  /*           jpeg_read_scanlines(...); */
+      (void) jpeg_read_scanlines(&cinfo, buffer, 1);
 
-  /* Here we use the library's state variable cinfo.output_scanline as the
-   * loop counter, so that we don't have to keep track ourselves.
-   */
-   
- if (DEBUG)  printf ("cinfo.output_height %d  cinfo.output_width %d\n",
-                       cinfo.output_height,cinfo.output_width);
-  pimage=(char *)image_buffer;
-   
-  while (cinfo.output_scanline < cinfo.output_height) {
-    /* jpeg_read_scanlines expects an array of pointers to scanlines.
-     * Here the array is only one element long, but you could ask for
-     * more than one scanline at a time if that's more convenient.
-     */
-    
-     (void) jpeg_read_scanlines(&cinfo, buffer, 1);
-      
-     if ( BITS_IN_JSAMPLE == 8) {
+      if ( BITS_IN_JSAMPLE == 8) {
          memcpy( pimage, buffer[0],row_stride); 
          pimage+=row_stride;
-     } else {
+      } else {
          memcpy( pimage, buffer[0],row_stride*2 ); // FIXME : *2  car 16 bits?!?
          pimage+=row_stride*2;                     // FIXME : *2 car 16 bits?!?     
-     }
-  }
+      }
+   }
  
   /* Step 7: Finish decompression */
-  
-if (DEBUG)  printf("Entree Step 7\n");
-
+   if (DEBUG)  printf("Entree Step 7\n");
   (void) jpeg_finish_decompress(&cinfo);
-  /* We can ignore the return value since suspension is not possible
-   * with the stdio data source.
-   */
+   /* We can ignore the return value since suspension is not possible
+    * with the stdio data source.
+    */
 
-  /* Step 8: Release JPEG decompression object */
-  
-if (DEBUG) printf("Entree Step 8\n");
+   /* Step 8: Release JPEG decompression object */
+   if (DEBUG) printf("Entree Step 8\n");
 
-  /* This is an important step since it will release a good deal of memory. */
-  
-  jpeg_destroy_decompress(&cinfo);
+   /* This is an important step since it will release a good deal of memory. */
+   jpeg_destroy_decompress(&cinfo);
 
-  /* After finish_decompress, we can close the input file.
-   * Here we postpone it until after no more JPEG errors are possible,
-   * so as to simplify the setjmp error logic above.  (Actually, I don't
-   * think that jpeg_destroy can do an error exit, but why assume anything...)
-   */
+   /* After finish_decompress, we can close the input file.
+    * Here we postpone it until after no more JPEG errors are possible,
+    * so as to simplify the setjmp error logic above.  (Actually, I don't
+    * think that jpeg_destroy can do an error exit, but why assume anything...)
+    */
 
-  /* At this point you may want to check to see whether any corrupt-data
-   * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
-   */
+   /* At this point you may want to check to see whether any corrupt-data
+    * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
+    */
 
-  /* And we're done! */
-  
-  return(true);
+   /* And we're done! */
+
+   return(true);
 }
 
 /*
@@ -393,10 +376,5 @@ if (DEBUG) printf("Entree Step 8\n");
  * On some systems you may need to set up a signal handler to ensure that
  * temporary files are deleted if the program is interrupted.  See libjpeg.doc.
  */
-
-
-
-
 
+//-----------------------------------------------------------------------------
index 895c865b553b971dbd5376c6e4da8de192b57b88..2d60fe09b816bb6973715c8e4f65dcaf78ecc098 100644 (file)
@@ -1,16 +1,13 @@
- /* -------------------------------------------------------------------- */
- //
- // JPEG 2000 Files
- //
- /* -------------------------------------------------------------------- */
-
+// gdcmJpeg2000.cxx
+//-----------------------------------------------------------------------------
 #include <stdio.h>
 #include "gdcmFile.h"
 
+//-----------------------------------------------------------------------------
 bool gdcmFile::gdcm_read_JPEG2000_file (FILE *fp,void * image_buffer) {
    printf("Sorry JPEG 2000 File not yet taken into account\n");
    return false;
 }
 
+//-----------------------------------------------------------------------------
 
index d618c3156c63752c30667ecfeef5588d8ae72e50..57a09dacbd2fa9e2d7f14e2159be84918cfdf6d8 100644 (file)
@@ -1,5 +1,5 @@
 // gdcmParse.cxx
-
+//-----------------------------------------------------------------------------
 //This is needed when compiling in debug mode
 #ifdef _MSC_VER
 // 'type' : forcing value to bool 'true' or 'false' (performance warning)
@@ -17,7 +17,7 @@
 
 #define str2num(str, typeNum) *((typeNum *)(str))
 
-/////////////////////////////////////////////////////////////////
+//-----------------------------------------------------------------------------
 /**
  * \ingroup gdcmFile
  * \brief   Parse pixel data from disk and *prints* the result
  *
  */
 bool gdcmFile::ParsePixelData(void) {
-
 // DO NOT remove the printf s.
 // The ONLY purpose of this methos is to PRINT the content
-
    FILE *fp;
 
    if ( !(fp=Header->OpenFile()))
@@ -246,3 +244,5 @@ bool gdcmFile::ParsePixelData(void) {
    }
    return true;            
 }
+
+//-----------------------------------------------------------------------------
index ab7f62f7e269d9fb1a55a7ebc7bcac96832321cf..4387ebcfd78bb1460a1b434c9c886a81399184ab 100644 (file)
@@ -1,17 +1,12 @@
-
+// gdcmRLE.cxx
+//-----------------------------------------------------------------------------
 #include <stdio.h>
 #include "gdcmFile.h"
 #include <ctype.h>             /* to declare isprint() */
 
 #define str2num(str, typeNum) *((typeNum *)(str))
 
-static int _gdcm_read_RLE_fragment (char ** image_buffer, 
-                                    long lengthToDecode,
-                                    long uncompressedSegmentSize, 
-                                    FILE* fp);
-// static because nothing but gdcm_read_RLE_file may call it
-
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 /**
  * \ingroup   gdcmFile
  * \brief     Reads a 'Run Length Encoded' Dicom encapsulated file
@@ -21,14 +16,6 @@ static int _gdcm_read_RLE_fragment (char ** image_buffer,
  *   
  * @return    Boolean 
  */
-
-// This is a debug version.
-// Forget the printf as they will be removed
-// as soon as the last Heuristics are checked
-
-// pb with RLE 16 Bits : 
-
-
 bool gdcmFile::gdcm_read_RLE_file (FILE *fp,void * image_buffer) {
    long fragmentBegining; // for ftell, fseek
    char * im = (char *)image_buffer;
@@ -97,7 +84,7 @@ bool gdcmFile::gdcm_read_RLE_file (FILE *fp,void * image_buffer) {
             RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k];
             ftellRes=ftell(fp);
             fragmentBegining=ftell(fp);   
-            _gdcm_read_RLE_fragment (&im, RleSegmentLength[k],uncompressedSegmentSize,fp);
+            gdcm_read_RLE_fragment (&im, RleSegmentLength[k],uncompressedSegmentSize,fp);
             fseek(fp,fragmentBegining,SEEK_SET);  
             fseek(fp,RleSegmentLength[k],SEEK_CUR);        
          }
@@ -105,7 +92,7 @@ bool gdcmFile::gdcm_read_RLE_file (FILE *fp,void * image_buffer) {
       RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments];
       ftellRes=ftell(fp);
       fragmentBegining=ftell(fp);
-      _gdcm_read_RLE_fragment (&im, RleSegmentLength[nbRleSegments],uncompressedSegmentSize, fp);
+      gdcm_read_RLE_fragment (&im, RleSegmentLength[nbRleSegments],uncompressedSegmentSize, fp);
       fseek(fp,fragmentBegining,SEEK_SET);  
       fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR);    
       
@@ -147,20 +134,10 @@ bool gdcmFile::gdcm_read_RLE_file (FILE *fp,void * image_buffer) {
 }
 
 
- /* -------------------------------------------------------------------- */
- //
- // RLE LossLess Fragment
- //
- /* -------------------------------------------------------------------- */
-
-   // static because nothing but gdcm_read_RLE_file can call it
-   // DO NOT doxygen !
-
-static int
-_gdcm_read_RLE_fragment (char ** areaToRead, 
-                         long lengthToDecode, 
-                         long uncompressedSegmentSize, 
-                         FILE* fp) {
+// ----------------------------------------------------------------------------
+// RLE LossLess Fragment
+int gdcmFile::gdcm_read_RLE_fragment(char **areaToRead, long lengthToDecode, 
+                                     long uncompressedSegmentSize, FILE *fp) {
    long ftellRes;
    int count;
    long numberOfOutputBytes=0;
@@ -168,7 +145,6 @@ _gdcm_read_RLE_fragment (char ** areaToRead,
    ftellRes =ftell(fp);
 
    while(numberOfOutputBytes<uncompressedSegmentSize) {
-
       ftellRes =ftell(fp);
       fread(&n,sizeof(char),1,fp);
       count=n;
@@ -190,3 +166,5 @@ _gdcm_read_RLE_fragment (char ** areaToRead,
    } 
    return 1;
 }
+
+// ----------------------------------------------------------------------------
index 25b97e32debc3a3c37e62167cdf086459cd7b70e..f3e89ab9b5e166218f10c16332a084eacb0f8212 100644 (file)
@@ -1,5 +1,5 @@
 // gdcmTS.cxx
-
+//-----------------------------------------------------------------------------
 #include <fstream>
 
 #include "gdcmTS.h"
@@ -10,6 +10,8 @@
 #endif
 #define DICT_TS "dicomTS.dic"
 
+//-----------------------------------------------------------------------------
+// Constructor / Destructor
 gdcmTS::gdcmTS(void) {
    std::string filename=gdcmDictSet::BuildDictPath() + std::string(DICT_TS);
    std::ifstream from(filename.c_str());
@@ -38,6 +40,11 @@ gdcmTS::~gdcmTS() {
    ts.clear();
 }
 
+//-----------------------------------------------------------------------------
+// Print
+
+//-----------------------------------------------------------------------------
+// Public
 int gdcmTS::Count(TSKey key) {
    return ts.count(key);
 }
@@ -47,3 +54,11 @@ std::string gdcmTS::GetValue(TSKey key) {
       return (GDCM_UNFOUND);
    return ts[key];
 }
+
+//-----------------------------------------------------------------------------
+// Protected
+
+//-----------------------------------------------------------------------------
+// Private
+
+//-----------------------------------------------------------------------------
index fde45c6b33b4c5ff7c7c4a7e7b4c2fb733e8085b..7cd142bc14362332feca2f7f7048d2c01f7922a7 100644 (file)
@@ -1,5 +1,5 @@
 // gdcmTS.h
-
+//-----------------------------------------------------------------------------
 #ifndef GDCMTS_H
 #define GDCMTS_H
 
@@ -7,23 +7,26 @@
 #include <map>
 #include <string>
 
+//-----------------------------------------------------------------------------
 typedef std::string TSKey;
 typedef std::string TSAtr;
 typedef std::map<TSKey, TSAtr> TSHT;    // Transfert Syntax Hash Table
 
+//-----------------------------------------------------------------------------
 /*
  * Container for dicom Transfert Syntax Hash Table
  * \note   This is a singleton
  */
 class GDCM_EXPORT gdcmTS {
-private:
-   TSHT ts;    
-
 public:
    gdcmTS(void);
    ~gdcmTS();
    int Count(TSKey key);
    std::string GetValue(TSKey key);
+
+private:
+   TSHT ts;    
 };
 
+//-----------------------------------------------------------------------------
 #endif
index 729d400eaf5ef8b9a99fb8b664ebffae47e2351c..40143310270811fa753301afa7bf6ac6663befc2 100644 (file)
@@ -1,14 +1,16 @@
-// $Header: /cvs/public/gdcm/src/gdcmUtil.cxx,v 1.25 2003/10/02 11:26:16 malaterre Exp $
-
+// gdcmUtil.cxx
+//-----------------------------------------------------------------------------
 #include "gdcmUtil.h"
 
 #include <stdio.h>
 #include <ctype.h>   // For isspace
 #include <string.h>
 
+//-----------------------------------------------------------------------------
 // Library globals.
 gdcmDebug dbg;
 
+//-----------------------------------------------------------------------------
 gdcmDebug::gdcmDebug(int level) {
    DebugLevel = level;
 }
@@ -19,14 +21,6 @@ void gdcmDebug::Verbose(int Level, const char * Msg1, const char * Msg2) {
    std::cerr << Msg1 << ' ' << Msg2 << std::endl;
 }
 
-void gdcmDebug::Assert(int Level, bool Test,
-                 const char * Msg1, const char * Msg2) {
-   if (Level > DebugLevel)
-      return ;
-   if (!Test)
-      std::cerr << Msg1 << ' ' << Msg2 << std::endl;
-}
-
 void gdcmDebug::Error( bool Test, const char * Msg1, const char * Msg2) {
    if (!Test)
       return;
@@ -40,6 +34,14 @@ void gdcmDebug::Error(const char* Msg1, const char* Msg2,
    Exit(1);
 }
 
+void gdcmDebug::Assert(int Level, bool Test,
+                 const char * Msg1, const char * Msg2) {
+   if (Level > DebugLevel)
+      return ;
+   if (!Test)
+      std::cerr << Msg1 << ' ' << Msg2 << std::endl;
+}
+
 void gdcmDebug::Exit(int a) {
 #ifdef __GNUC__
    std::exit(a);
@@ -49,7 +51,7 @@ void gdcmDebug::Exit(int a) {
 #endif
 }
 
-///////////////////////////////////////////////////////////////////////////
+//-----------------------------------------------------------------------------
 gdcmVR      * gdcmGlobal::VR    = (gdcmVR*)0;
 gdcmTS      * gdcmGlobal::TS    = (gdcmTS*)0;
 gdcmDictSet * gdcmGlobal::Dicts = (gdcmDictSet*)0;
@@ -76,11 +78,12 @@ gdcmVR * gdcmGlobal::GetVR(void) {
 gdcmTS * gdcmGlobal::GetTS(void) {
    return TS;
 }
+
 gdcmDictSet * gdcmGlobal::GetDicts(void) {
    return Dicts;
 }
 
-///////////////////////////////////////////////////////////////////////////
+//-----------------------------------------------------------------------------
 // Because is not yet available in g++2.96
 std::istream& eatwhite(std::istream& is) {
    char c;
@@ -95,7 +98,6 @@ std::istream& eatwhite(std::istream& is) {
 
 ///////////////////////////////////////////////////////////////////////////
 // Because is not  available in C++ (?)
-
 void Tokenize (const std::string& str,
                std::vector<std::string>& tokens,
                const std::string& delimiters) {
@@ -111,7 +113,6 @@ void Tokenize (const std::string& str,
 
 ///////////////////////////////////////////////////////////////////////////
 // to prevent a flashing screen when non-printable character
-
 char * _cleanString(char *v) {
    char *d;
    int i, l;
@@ -128,20 +129,7 @@ char * _cleanString(char *v) {
 
 ///////////////////////////////////////////////////////////////////////////
 // to prevent a flashing screen when non-printable character
-
 std::string _CreateCleanString(std::string s) {
-/*   char *d, *di, *v;
-   int i, l;
-   v=(char*)s.c_str();
-   l = strlen(v);
-   d = di = strdup(v);
-   for (i=0; 
-        i<l ; 
-        i++,di++,v++) {
-      if (!isprint(*v))
-         *di = '.';
-      }        
-   return d;*/
   std::string str=s;
   for(int i=0;i<str.size();i++)
   {
@@ -152,20 +140,3 @@ std::string _CreateCleanString(std::string s) {
   return(str);
 }
 
-///////////////////////////////////////////////////////////////////////////
-//
-// because it may not be associated to a dictionary ...
-
-std::string TranslateToKey(guint16 group, guint16 element) {
-       char trash[10];
-       std::string key;
-       // CLEAN ME: better call the iostream<< with the hex manipulator on.
-       // This requires some reading of the stdlibC++ sources to make the
-       // proper call (or copy).
-       sprintf(trash, "%04x|%04x", group , element);
-       key = trash;  // Convertion through assignement
-       return key;
-}
-
-
-
index 2e4696258e524baddc8fd267ea68a42a12279ad5..7b35b952b6eb373fcfcc2944059f3cc54bb7ea97 100644 (file)
@@ -1,5 +1,5 @@
-// $Header: /cvs/public/gdcm/src/gdcmUtil.h,v 1.17 2004/01/12 13:12:28 regrain Exp $
-
+// gdcmUtil.h
+//-----------------------------------------------------------------------------
 #ifndef GDCMUTIL_H
 #define GDCMUTIL_H
 
@@ -10,6 +10,7 @@
 #include <vector>
 #include <string>
 
+//-----------------------------------------------------------------------------
 /*
  * gdcmDebug is an object for debugging in program.
  * It has 2 debugging modes :
  * message level.
  */
 class gdcmDebug {
-private:
-       int DebugLevel;
 public:
        gdcmDebug(int  = 0);
-       void Verbose(int, const char*, const char* ="");
+       void SetDebug (int i) {DebugLevel = i;}
+
+   void Verbose(int, const char*, const char* ="");
        void Error(bool, const char*,  const char* ="");
        void Error(const char*, const char* ="", const char* ="");
+
        void Assert(int, bool, const char*, const char*);
        void Exit(int);
-       void SetDebug (int i) {DebugLevel = i;}
+
+private:
+       int DebugLevel;
 };
 
+//-----------------------------------------------------------------------------
 /*
  * This class contains all globals elements that might be
  * instanciated only one time
  */
 class gdcmGlobal {
-private:
-   static gdcmVR *VR;
-   static gdcmTS *TS; 
-   static gdcmDictSet *Dicts; 
 public:
    gdcmGlobal(void);
    ~gdcmGlobal();
+
    static gdcmVR * GetVR(void);
    static gdcmTS * GetTS(void);
    static gdcmDictSet * GetDicts(void);
+
+private:
+   static gdcmVR *VR;
+   static gdcmTS *TS; 
+   static gdcmDictSet *Dicts; 
 };
 
+//-----------------------------------------------------------------------------
 std::istream & eatwhite(std::istream & is);
 
 void Tokenize (const std::string& str,
@@ -61,7 +69,6 @@ extern gdcmDebug dbg;
 char * _cleanString(char *v);
 std::string _CreateCleanString(std::string s);
 
-std::string TranslateToKey(guint16 group, guint16 element);
-
+//-----------------------------------------------------------------------------
 #endif
 
index 3d2ea9c2deb7fd3a4002446e611f27c286f42805..de4f1e1c2d2d46ba33cf484bf1e6c3dd419c195c 100644 (file)
@@ -1,6 +1,6 @@
 // gdcmVR.cxx
 #include <fstream>
-
+//-----------------------------------------------------------------------------
 #include "gdcmVR.h"
 #include "gdcmUtil.h"
 
@@ -9,6 +9,8 @@
 #endif
 #define DICT_VR "dicomVR.dic"
 
+//-----------------------------------------------------------------------------
+// Constructor / Destructor
 gdcmVR::gdcmVR(void) {
    std::string filename=gdcmDictSet::BuildDictPath() + std::string(DICT_VR);
    std::ifstream from(filename.c_str());
@@ -41,6 +43,19 @@ gdcmVR::~gdcmVR() {
    vr.clear();
 }
 
+//-----------------------------------------------------------------------------
+// Print
+
+//-----------------------------------------------------------------------------
+// Public
 int gdcmVR::Count(VRKey key) {
    return vr.count(key);
 }
+
+//-----------------------------------------------------------------------------
+// Protected
+
+//-----------------------------------------------------------------------------
+// Private
+
+//-----------------------------------------------------------------------------
index f29321936257a943ab0c84f13547162eab326dbd..82663675463063eb3cf0af556e130a25505ec369 100644 (file)
@@ -1,5 +1,5 @@
 // gdcmVR.h
-
+//-----------------------------------------------------------------------------
 #ifndef GDCMVR_H
 #define GDCMVR_H
 
@@ -7,21 +7,25 @@
 #include <map>
 #include <string>
 
+//-----------------------------------------------------------------------------
 typedef std::string VRKey;
 typedef std::string VRAtr;
 typedef std::map<VRKey, VRAtr> VRHT;    // Value Representation Hash Table
 
+//-----------------------------------------------------------------------------
 /*
  * Container for dicom Value Representation Hash Table
  * \note   This is a singleton
  */
 class GDCM_EXPORT gdcmVR {
-private:
-   VRHT vr;
 public:
        gdcmVR(void);
    ~gdcmVR();
    int Count(VRKey key);
+
+private:
+   VRHT vr;
 };
 
+//-----------------------------------------------------------------------------
 #endif