-#include <string>
-using namespace std;
-
-#include <iostream>
-#include <stddef.h> // For size_t
-#include <stdio.h> // FIXME For FILE on GCC only
-#include <list>
-#include <map>
-#include "gdcmException.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)
- //
- // En fait, je disais que dans LE Directory Dicom (dans son etat 2001)
- // il y a +/- 1600 entrees.
- // Une valeur raisonable pour un majorant du nombre d'entrees
- // dans une entete DICOM d'une image semble semble etre 300
- // Si on 'decortique' les elements SQ (ce qui ne semble pas etre fait pour le moment)
- // on risque en fait de depasser ... un nombre non previsible dans le cas d'une entree SQ
- // contenant lui même un tres grand nombre d'entrees ?!?)
- // Quant au nombre d'entrees dans un DICOMDIR, c'est encore pire : il n'est limité
- // que par la taille d'un CD-ROM (les DVD-ROM ne sont pas encore pris en compte)
- // On peut s'attendre a 30 entrees par fichier dicom présent sur le CD-ROM
- // REMARQUE : il faudra se pencher sur le pb de la creation du DICOMDIR lorsqu'on voudra
- // exporter des images lisibles par les consoles cliniques
- // et pas seulement importables dans e-film.
-
-#ifdef __GNUC__
-#include <stdint.h>
-#define guint16 uint16_t
-#define guint32 uint32_t
-#endif
-
-#ifdef _MSC_VER
-typedef unsigned short guint16;
-typedef unsigned int guint32;
-#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
-// concatenating the group value and the element value (both of type
-// unsigned 16 bit integers in Dicom) expressed in hexadecimal.
-// Example: consider the tag given as (group, element) = (0x0010, 0x0010).
-// Then the corresponding TagKey shall be the string 0010|0010 (where
-// the | (pipe symbol) acts as a separator). Refer to
-// gdcmDictEntry::TranslateToKey for this conversion function.
-
-typedef string TagKey;
-typedef string TagName;
-
-class GDCM_EXPORT gdcmDictEntry {
-private:
- guint16 group; // e.g. 0x0010
- guint16 element; // e.g. 0x0103
- string vr; // Value Representation i.e. some clue about the nature
- // of the data represented e.g. "FD" short for
- // "Floating Point Double"
- // CLEANME: find the official dicom name for this field !
- string fourth; // Fourth field containing some semantics.
- string name; // e.g. "Patient_Name"
- TagKey key; // Redundant with (group, element) but we add it
- // on efficiency purposes.
- // DCMTK has many fields for handling a DictEntry (see below). What are the
- // relevant ones for gdcmlib ?
- // struct DBI_SimpleEntry {
- // Uint16 upperGroup;
- // Uint16 upperElement;
- // DcmEVR evr;
- // const char* tagName;
- // int vmMin;
- // int vmMax;
- // const char* standardVersion;
- // DcmDictRangeRestriction groupRestriction;
- // DcmDictRangeRestriction elementRestriction;
- // };
-public:
- gdcmDictEntry(guint16 group,
- guint16 element,
- string vr = "Unknown",
- string fourth = "Unknown",
- string name = "Unknown");
- // fabrique une 'clé' par concaténation du numGroupe et du numElement
- 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);
- void SetKey(string k){ key = k; }
- bool IsVrUnknown(void);
- string GetFourth(void) {return fourth;};
- string GetName(void) {return name; };
- string GetKey(void) {return key; };
-};
-
-////////////////////////////////////////////////////////////////////////////
-// A single DICOM dictionary i.e. a container for a collection of dictionary
-// 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...
-
-typedef map<TagKey, gdcmDictEntry*> TagKeyHT;
-typedef map<TagName, gdcmDictEntry*> TagNameHT;
-
-class GDCM_EXPORT gdcmDict {
- string name;
- string filename;
- TagKeyHT KeyHt; // Both accesses with a TagKey or with a
- TagNameHT NameHt; // TagName are required.
-public:
- gdcmDict(const char* FileName); // Reads Dict from ascii file
- int AddNewEntry (gdcmDictEntry* NewEntry);
- int ReplaceEntry(gdcmDictEntry* NewEntry);
- int RemoveEntry (TagKey key);
- int RemoveEntry (guint16 group, guint16 element);
- gdcmDictEntry * GetTagByKey(guint16 group, guint16 element);
- gdcmDictEntry * GetTagByName(TagName name);
- void Print(ostream&);
- void PrintByKey(ostream&);
- void PrintByName(ostream&);
- TagKeyHT & GetEntries(void) { return KeyHt; }
-};
-
-
-////////////////////////////////////////////////////////////////////////////
-// Container for managing a set of loaded dictionaries. Sharing dictionaries
-// should avoid :
-// * reloading an allready loaded dictionary,
-// * having many in memory representations of the same dictionary.
-
-typedef string DictKey;
-typedef map<DictKey, gdcmDict*> DictSetHT;
-
-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
- // 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 !?!?!
- // TODO Swig int LoadDictFromName(string filename);
- // TODO Swig int LoadAllDictFromDirectory(string DirectoryName);
- // TODO Swig string* GetAllDictNames();
- //
- // Question : ne faudra-t-il pas mettre LE dictionnaire DICOM dans un Directory
- // et les eventuels 'dictionnaires prives' dans un autre?
- // (pour eviter a un utilisateur mal dégourdi de tout saccager ?)
- //
- int LoadDicomV3Dict(void);
- void Print(ostream&);
- gdcmDict* GetDict(DictKey DictName);
- gdcmDict* GetDefaultPublicDict(void);
-};
-
-///////////////////////////////////////////////////////////////////////////
-// 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 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.
-public:
- string value;
- size_t Offset; // Offset from the begining of file for direct user access
-
- ElValue(gdcmDictEntry*);
- void SetDictEntry(gdcmDictEntry *NewEntry) { entry = NewEntry; };
- bool IsVrUnknown(void) { return entry->IsVrUnknown(); };
- void SetImplicitVr(void) { ImplicitVr = true; };
- bool IsImplicitVr(void) { return ImplicitVr; };
-
- guint16 GetGroup(void) { return entry->GetGroup(); };
- guint16 GetElement(void) { return entry->GetElement();};
- string GetKey(void) { return entry->GetKey(); };
- string GetName(void) { return entry->GetName(); };
- string GetVR(void) { return entry->GetVR(); };
- void SetVR(string v) { entry->SetVR(v); };
- void SetLength(guint32 l){ LgrElem = l; };
- guint32 GetLength(void) { return LgrElem; };
-
- // Question : SetLength est public
- // (sinon, on ne pourrait pas l'appeler dans ElValSet)
- // alors que *personne* ne devrait s'en servir !
- // c'est *forcément* la lgr de la string 'value', non?
-
- void SetValue(string val){ value = val; };
- string GetValue(void) { return value;};
-
- void SetOffset(size_t of){ Offset = of; };
- size_t GetOffset(void) { return Offset;};
- // Question : SetOffset est public ...
- // Quel utilisateur serait ammené à modifier l'Offset ?
-};
-