]> Creatis software - gdcm.git/blobdiff - src/gdcm.h
* src/gdcm.h and gdcmHeader.cxx are now "Big Endian transfer syntax"
[gdcm.git] / src / gdcm.h
index 512c86e4f39e78ccd524c81196d307bdf36c5565..c84f9c00ec36534a23b86c8a615977d8601deb17 100644 (file)
@@ -7,21 +7,46 @@
 // * Formats: this lib should be able to read ACR-NEMA v1 and v2, Dicom v3 (as
 //   stated in part10). [cf dcmtk/dcmdata/docs/datadict.txt]
 // * Targeted plateforms: Un*xes and Win32/VC++6.0
+//
+//
+// TODO
+// The declarations commented out and starting with "TODO Swig" needed
+// to be temporarily removed for swig to proceed correctly (in fact
+// problems appears at loading of _gdcm.[so/dll]). So, simply uncomment
+// the declaration once you provided the definition of the method...
 
 #include <string>
-#include <stddef.h>    // For size_t
+#include <iostream>
+#include <stddef.h>   // For size_t
+#include <stdio.h>    // FIXME For FILE on GCC only
+#include <map>        // The requirement for the hash table (or map) that
+                      // we shall use:
+                      // 1/ First, next, last (iterators)
+                      // 2/ should be sortable (i.e. sorted by TagKey). This
+                      //    condition shall be droped since the Win32/VC++
+                      //    implementation doesn't look a sorted one. Pffff....
+                      // 3/ Make sure we can setup some default size value,
+                      //    which should be around 4500 entries which is the
+                      //    average dictionary size (said JPR)
+#ifdef __GNUC__
+#include <stdint.h>
+#define guint16 uint16_t
+#define guint32 uint32_t
+#define g_malloc malloc
+#define g_free   free
+#endif
+#ifdef _MSC_VER
 #include <glib.h>
-#include <stdio.h>
-
-// The requirement for the hash table (or map) that we shall use:
-// 1/ First, next, last (iterators)
-// 2/ should be sortable (i.e. sorted by TagKey). This condition
-//    shall be droped since the Win32/VC++ implementation doesn't look
-//    a sorted one. Pffff....
-// 3/ Make sure we can setup some default size value, which should be
-//    around 4500 entries which is the average dictionary size (said JPR)
-#include <map>
+#endif
 
+#ifdef _MSC_VER
+       using namespace std;  // string type lives in the std namespace on VC++
+#endif
+#ifdef _MSC_VER
+#define GDCM_EXPORT __declspec( dllexport )
+#else
+#define GDCM_EXPORT
+#endif
 
 // Tag based hash tables.
 // We shall use as keys the strings (as the C++ type) obtained by
@@ -33,7 +58,7 @@
 // gdcmDictEntry::TranslateToKey for this conversion function.
 typedef string TagKey;
 
-class gdcmDictEntry {
+class GDCM_EXPORT gdcmDictEntry {
 private:
        guint16 group;    // e.g. 0x0010
        guint16 element;  // e.g. 0x0010
@@ -63,12 +88,15 @@ private:
 public:
        //CLEANME gdcmDictEntry();
        gdcmDictEntry(guint16 group, guint16 element,
-                     string vr, string fourth, string vr);
+                     string vr     = "Unknown",
+                                         string fourth = "Unknown",
+                                         string name   = "Unknown");
        static TagKey TranslateToKey(guint16 group, guint16 element);
        guint16 GetGroup(void)  { return group;};
        guint16 GetElement(void){return element;};
        string  GetVR(void)     {return vr; };
-       void    SetVR(string in){vr = in; };
+       void    SetVR(string);
+       bool    IsVrUnknown(void);
        string  GetFourth(void) {return fourth;};
        string  GetName(void)   {return name;};
        string  GetKey(void)    {return key;};
@@ -80,14 +108,13 @@ typedef map<TagKey, gdcmDictEntry*> TagHT;
 // entries. There should be a single public dictionary (THE dictionary of
 // the actual DICOM v3) but as many shadow dictionaries as imagers 
 // combined with all software versions...
-class gdcmDict {
+class GDCM_EXPORT gdcmDict {
        string name;
        string filename;
        TagHT entries;
 public:
-       gdcmDict();
-       gdcmDict(char *FileName);   // Read Dict from disk
-       int AppendEntry(gdcmDictEntry* NewEntry);
+       gdcmDict(const char* FileName);   // Read Dict from disk
+       // TODO Swig int AppendEntry(gdcmDictEntry* NewEntry);
        gdcmDictEntry * GetTag(guint32 group, guint32 element);
        void Print(ostream&);
 };
@@ -96,25 +123,25 @@ public:
 // should avoid :
 // * reloading an allready loaded dictionary.
 // * having many in memory representations of the same dictionary.
-#define PUBDICTNAME     "DicomV3Dict"
-#define PUBDICTFILENAME "../Dicts/dicomV3.dic"
 typedef string DictKey;
 typedef map<DictKey, gdcmDict*> DictSetHT;
-class gdcmDictSet {
+class GDCM_EXPORT gdcmDictSet {
 private:
+       string DictPath;      // Directory path to dictionaries
        DictSetHT dicts;
        int AppendDict(gdcmDict* NewDict);
+       int LoadDictFromFile(string filename, DictKey);
+       void SetDictPath(void);
 public:
        gdcmDictSet(void);    // loads THE DICOM v3 dictionary
-       int LoadDictFromFile(string filename);
+       // TODO Swig int LoadDictFromFile(string filename);
 ///// QUESTION: the following function might not be thread safe !? Maybe
 /////           we need some mutex here, to avoid concurent creation of
 /////           the same dictionary !?!?!
-       int LoadDictFromName(string filename);
-       int LoadDictFromFile(char*, DictKey);
-       int LoadAllDictFromDirectory(string DirectoryName);
+       // TODO Swig int LoadDictFromName(string filename);
+       // TODO Swig int LoadAllDictFromDirectory(string DirectoryName);
+       // TODO Swig string* GetAllDictNames();
        int LoadDicomV3Dict(void);
-       string* GetAllDictNames();
        void Print(ostream&);
        gdcmDict* GetDict(DictKey DictName);
        gdcmDict* GetDefaultPublicDict(void);
@@ -122,23 +149,32 @@ public:
 
 // The dicom header of a Dicom file contains a set of such ELement VALUES
 // (when successfuly parsed against a given Dicom dictionary)
-class ElValue {
+class GDCM_EXPORT ElValue {
 private:
        gdcmDictEntry *entry;
        guint32 LgrElem;
+       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.
        // Might prove of some interest (see _ID_DCM_ELEM)
        // int Swap;
 public:
        string  value;     // used to be char * valeurElem
        size_t Offset;     // Offset from the begining of file for direct user access
        ElValue(gdcmDictEntry*);
-       void   SetVR(string);
-       string GetVR(void);
+       void SetDictEntry(gdcmDictEntry *NewEntry) { entry = NewEntry; };
+
+       bool   IsVrUnknown(void) { return entry->IsVrUnknown(); };
        void SetLength(guint32 l){LgrElem = l; };
        void SetValue(string val){ value = val; };
        void SetOffset(size_t of){ Offset = of; };
+       void SetImplicitVr(void) { ImplicitVr = true; };
+       bool  IsImplicitVr(void) { return ImplicitVr; };
+       void    SetVR(string);
+       string  GetVR(void);
        string  GetValue(void)   { return value; };
-       guint32 GetLength(void) { return LgrElem; };
+       guint32 GetLength(void)  { return LgrElem; };
        size_t  GetOffset(void)  { return Offset; };
        guint16 GetGroup(void)   { return entry->GetGroup(); };
        guint16 GetElement(void) { return entry->GetElement(); };
@@ -149,7 +185,7 @@ public:
 typedef map<TagKey, ElValue*> TagElValueHT;
 typedef map<string, ElValue*> TagElValueNameHT;
 // Container for a set of succefully parsed ElValues.
-class ElValSet {
+class GDCM_EXPORT ElValSet {
        // We need both accesses with a TagKey and the Dicentry.Name
        TagElValueHT tagHt;
        TagElValueNameHT NameHt;
@@ -177,7 +213,7 @@ typedef map<TagKey, VRAtr> VRHT;    // Value Representation Hash Table
 // Notes:
 // * the gdcmHeader::Set*Tag* family members cannot be defined as protected
 //   (Swig limitations for as Has_a dependency between gdcmFile and gdcmHeader)
-class gdcmHeader {     
+class GDCM_EXPORT gdcmHeader {
 //FIXME sw should be qn EndianType !!!
        //enum EndianType {
                //LittleEndian, 
@@ -185,7 +221,7 @@ class gdcmHeader {
                //BigEndian, 
                //BadBigEndian};
 private:
-       // All instances share the same valur representation dictionary
+       // All instances share the same value representation dictionary
        static VRHT *dicom_vr;
        static gdcmDictSet* Dicts;  // Global dictionary container
        gdcmDict* RefPubDict;       // Public Dictionary
@@ -212,9 +248,13 @@ private:
        void FindLength(ElValue *);
        void FindVR(ElValue *);
        void LoadElementValue(ElValue *);
+       void LoadElementValueSafe(ElValue *);
        void SkipElementValue(ElValue *);
        void InitVRDict(void);
-       bool IsAnInteger(guint16, guint16, string, guint32);
+       void SwitchSwapToBigEndian(void);
+       void FixFoundLength(ElValue*, guint32);
+       bool IsAnInteger(ElValue *);
+       bool IsBigEndianTransferSyntax(void);
        ElValue * ReadNextElement(void);
        gdcmDictEntry * IsInDicts(guint32, guint32);
        size_t GetPixelOffset(void);
@@ -235,50 +275,51 @@ protected:
 public:
        void LoadElements(void);
        virtual void ParseHeader(void);
-       gdcmHeader(char* filename);
+       gdcmHeader(const char* filename);
        virtual ~gdcmHeader();
 
-       int SetPubDict(string filename);
+       // TODO Swig int SetPubDict(string filename);
        // When some proprietary shadow groups are disclosed, whe can set
        // up an additional specific dictionary to access extra information.
-       int SetShaDict(string filename);
+       // TODO Swig int SetShaDict(string filename);
 
        // Retrieve all potentially available tag [tag = (group, element)] names
        // from the standard (or public) dictionary (hence static). Typical usage:
        // enable the user of a GUI based interface to select his favorite fields
        // for sorting or selection.
-       string* GetPubTagNames();
+       // TODO Swig string* GetPubTagNames();
        // Get the element values themselves:
        string GetPubElValByName(string TagName);
        string GetPubElValByNumber(guint16 group, guint16 element);
        // Get the element value representation: (VR) might be needed by caller
        // to convert the string typed content to caller's native type (think
        // of C/C++ vs Python).
-       string GetPubElValRepByName(string TagName);
-       string GetPubElValRepByNumber(guint16 group, guint16 element);
-       void   PrintPubElVal(ostream &);
+       // TODO Swig string GetPubElValRepByName(string TagName);
+       // TODO Swig string GetPubElValRepByNumber(guint16 group, guint16 element);
+       TagElValueHT & GetPubElVal(void) { return PubElVals.GetTagHt(); };
+       void   PrintPubElVal(ostream & os = cout);
        void   PrintPubDict(ostream &);
          
        // Same thing with the shadow :
-       string* GetShaTagNames(); 
-       string GetShaElValByName(string TagName);
-       string GetShaElValByNumber(guint16 group, guint16 element);
-       string GetShaElValRepByName(string TagName);
-       string GetShaElValRepByNumber(guint16 group, guint16 element);
+       // TODO Swig string* GetShaTagNames(); 
+       // TODO Swig string GetShaElValByName(string TagName);
+       // TODO Swig string GetShaElValByNumber(guint16 group, guint16 element);
+       // TODO Swig string GetShaElValRepByName(string TagName);
+       // TODO Swig string GetShaElValRepByNumber(guint16 group, guint16 element);
 
        // Wrappers of the above (both public and shadow) to avoid bugging the
        // caller with knowing if ElVal is from the public or shadow dictionary.
-       string GetElValByName(string TagName);
-       string GetElValByNumber(guint16 group, guint16 element);
-       string GetElValRepByName(string TagName);
-       string GetElValRepByNumber(guint16 group, guint16 element);
+       // TODO Swig string GetElValByName(string TagName);
+       // TODO Swig string GetElValByNumber(guint16 group, guint16 element);
+       // TODO Swig string GetElValRepByName(string TagName);
+       // TODO Swig string GetElValRepByNumber(guint16 group, guint16 element);
 
-       int SetPubElValByName(string content, string TagName);
-       int SetPubElValByNumber(string content, guint16 group, guint16 element);
-       int SetShaElValByName(string content, string ShadowTagName);
-       int SetShaElValByNumber(string content, guint16 group, guint16 element);
+       // TODO Swig int SetPubElValByName(string content, string TagName);
+       // TODO Swig int SetPubElValByNumber(string content, guint16 group, guint16 element);
+       // TODO Swig int SetShaElValByName(string content, string ShadowTagName);
+       // TODO Swig int SetShaElValByNumber(string content, guint16 group, guint16 element);
 
-       int GetSwapCode();
+       // TODO Swig int GetSwapCode();
 };
 
 // In addition to Dicom header exploration, this class is designed
@@ -287,7 +328,7 @@ public:
 ////// QUESTION: this looks still like an open question wether the
 //////           relationship between a gdcmFile and gdcmHeader is of
 //////           type IS_A or HAS_A !
-class gdcmFile: gdcmHeader
+class GDCM_EXPORT gdcmFile: gdcmHeader
 {
 private:
        void* Data;
@@ -296,7 +337,7 @@ private:
 public:
        // Constructor dedicated to writing a new DICOMV3 part10 compliant
        // file (see SetFileName, SetDcmTag and Write)
-       gdcmFile();
+       // TODO Swig gdcmFile();
        // Opens (in read only and when possible) an existing file and checks
        // for DICOM compliance. Returns NULL on failure.
        // Note: the in-memory representation of all available tags found in
@@ -306,28 +347,28 @@ public:
        //    seen a a side effect).
        gdcmFile(string & filename);
        // For promotion (performs a deepcopy of pointed header object)
-       gdcmFile(gdcmHeader* header);
-       ~gdcmFile();
+       // TODO Swig gdcmFile(gdcmHeader* header);
+       // TODO Swig ~gdcmFile();
 
        // On writing purposes. When instance was created through
        // gdcmFile(string filename) then the filename argument MUST be different
        // from the constructor's one (no overwriting aloud).
-       int SetFileName(string filename);
+       // TODO Swig int SetFileName(string filename);
 
        // Allocates necessary memory, copies the data (image[s]/volume[s]) to
        // newly allocated zone and return a pointer to it:
-       void * GetImageData();
+       // TODO Swig void * GetImageData();
        // Returns size (in bytes) of required memory to contain data
        // represented in this file.
-       size_t GetImageDataSize();
+       // TODO Swig size_t GetImageDataSize();
        // Copies (at most MaxSize bytes) of data to caller's memory space.
        // Returns an error code on failure (if MaxSize is not big enough)
-       int PutImageDataHere(void* destination, size_t MaxSize );
+       // TODO Swig int PutImageDataHere(void* destination, size_t MaxSize );
        // Allocates ExpectedSize bytes of memory at this->Data and copies the
        // pointed data to it.
-       int SetImageData(void * Data, size_t ExpectedSize);
+       // TODO Swig int SetImageData(void * Data, size_t ExpectedSize);
        // Push to disk.
-       int Write();
+       // TODO Swig int Write();
 };
 
 //class gdcmSerie : gdcmFile;