]> Creatis software - gdcm.git/blob - src/gdcmParser.h
239ff64417a71a74c1bae9b931f660730ae99d42
[gdcm.git] / src / gdcmParser.h
1 // gdcmParser.h
2 //-----------------------------------------------------------------------------
3 #ifndef GDCMPARSER_H
4 #define GDCMPARSER_H
5
6 #include "gdcmCommon.h"
7 #include "gdcmVR.h"
8 #include "gdcmTS.h"
9 #include "gdcmException.h"
10 #include "gdcmDictSet.h"
11 #include "gdcmHeaderEntry.h"
12
13 #include <map>
14 #include <list>
15
16 //-----------------------------------------------------------------------------
17 typedef std::string VRKey;
18 typedef std::string VRAtr;
19 typedef std::map<VRKey, VRAtr> VRHT;    // Value Representation Hash Table
20
21 typedef std::multimap<TagKey, gdcmHeaderEntry *> TagHeaderEntryHT;
22 typedef std::pair<TagKey, gdcmHeaderEntry *> PairHT;
23 typedef std::pair<TagHeaderEntryHT::iterator,TagHeaderEntryHT::iterator> IterHT; 
24 /// for linking together the Elements
25 typedef std::list<gdcmHeaderEntry *> ListTag;
26
27 typedef std::string GroupKey;
28 typedef std::map<GroupKey, int> GroupHT;
29
30 //-----------------------------------------------------------------------------
31 /**
32  * \brief used by both gdcmHeader and gdcmDicomDir
33  */
34 class GDCM_EXPORT gdcmParser
35 {
36 private:
37    /// Public dictionary used to parse this header
38    gdcmDict *RefPubDict;
39    
40    /// Optional "shadow dictionary" (private elements) used to parse
41    /// this header
42    gdcmDict *RefShaDict;
43
44    /// Equals 1 if a gdcmHeaderEntry was added post parsing 
45    int wasUpdated;
46    
47    /// Equals =1 if user wants to skip shadow groups while parsing
48    /// (to save space)
49    int ignoreShadow;
50
51    /// Size threshold above which an element value will NOT be loaded in 
52    /// memory (to avoid loading the image/volume itself). By default,
53    /// this upper bound is fixed to 1024 bytes (which might look reasonable
54    /// when one considers the definition of the various VR contents).
55    guint32 MaxSizeLoadEntry;
56    
57    /// Size threshold above which an element value will NOT be *printed* in
58    /// order no to polute the screen output. By default, this upper bound
59    /// is fixed to 64 bytes.
60    guint32 MaxSizePrintEntry;
61
62 protected:
63    /// Refering underlying filename.
64    std::string filename; 
65
66    /// SWap code (e.g. Big Endian, Little Endian, Bad Big Endian,
67    /// Bad Little Endian) according to the processor Endianity and
68    /// what is written on disc.
69    int sw;
70
71    /// File Pointer, opened during Header parsing.
72    FILE *fp;
73
74    /// ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown
75    FileType filetype;  
76
77    /// After opening the file, we read HEADER_LENGTH_TO_READ bytes.
78    static const unsigned int HEADER_LENGTH_TO_READ; 
79
80    /// Elements whose value is longer than MAX_SIZE_LOAD_ELEMENT_VALUE
81    /// are NOT loaded.
82    static const unsigned int MAX_SIZE_LOAD_ELEMENT_VALUE;
83
84    /// Elements whose value is longer than  MAX_SIZE_PRINT_ELEMENT_VALUE
85    /// are NOT printed.
86    static const unsigned int MAX_SIZE_PRINT_ELEMENT_VALUE;
87
88    /// Hash Table (multimap), to provide fast access
89    TagHeaderEntryHT tagHT; 
90
91    /// Chained list, to keep the 'spacial' ordering
92    ListTag listEntries; 
93
94    /// will be set 1 if user asks to 'go inside' the 'sequences' (VR = "SQ")
95    int enableSequences;
96
97    /// Amount of printed details for each Header Entry (Dicom Element):
98    /// 0 : stands for the least detail level.
99    int printLevel;
100    
101 public:
102    
103
104 // Print
105    /// Canonical Printing method (see also gdcmParser::SetPrintLevel)
106    virtual void Print        (std::ostream &os = std::cout) 
107       {PrintEntry(os);};
108    virtual void PrintEntry      (std::ostream &os = std::cout);
109    virtual void PrintEntryNoSQ  (std::ostream &os = std::cout);
110    // the 2 following will be merged
111    virtual void PrintEntryNiceSQ(std::ostream &os = std::cout);
112    virtual void PrintPubDict (std::ostream &os = std::cout);
113    virtual void PrintShaDict (std::ostream &os = std::cout);
114
115 // Dictionnaries
116    gdcmDict *GetPubDict(void);
117    gdcmDict *GetShaDict(void);
118    bool SetShaDict(gdcmDict *dict);
119    bool SetShaDict(DictKey dictName);
120
121 // Informations contained in the parser
122    virtual bool IsReadable(void);
123    bool IsImplicitVRLittleEndianTransferSyntax(void);
124    bool IsExplicitVRLittleEndianTransferSyntax(void);
125    bool IsDeflatedExplicitVRLittleEndianTransferSyntax(void);
126    bool IsExplicitVRBigEndianTransferSyntax(void);
127    FileType GetFileType(void);
128
129 // Read (used in gdcmFile, gdcmDicomDir)
130    FILE *OpenFile(bool exception_on_error = false) throw(gdcmFileError);
131    bool CloseFile(void);
132
133 // Write (used in gdcmFile, gdcmDicomDir)
134    virtual bool Write(FILE *, FileType);
135    virtual void WriteEntryTagVRLength(gdcmHeaderEntry *tag,
136                                        FILE *_fp, FileType type);
137    virtual void WriteEntryValue(gdcmHeaderEntry *tag,FILE *_fp,FileType type);
138    virtual bool WriteEntry(gdcmHeaderEntry *tag,FILE *_fp,FileType type);
139    virtual bool WriteEntries(FILE *_fp,FileType type);
140    void WriteEntriesDeprecated(FILE *_fp,FileType type); // JPR
141
142    gdcmHeaderEntry * ReplaceOrCreateByNumber(std::string Value,
143                                              guint16 Group, guint16 Elem);
144    bool ReplaceIfExistByNumber (char *Value, guint16 Group, guint16 Elem);
145
146 // System access
147    guint16 SwapShort(guint16);   // needed by gdcmFile
148    guint32 SwapLong(guint32);    // needed by gdcmFile
149    guint16 UnswapShort(guint16); // needed by gdcmFile
150    guint32 UnswapLong(guint32);  // needed by gdcmFile
151
152 protected:
153    // Constructor and destructor are protected to forbid end user 
154    // to instanciate from this class gdcmParser (only gdcmHeader and
155    // gdcmDicomDir are meaningfull).
156    gdcmParser(bool exception_on_error  = false);
157    gdcmParser(const char *inFilename, 
158               bool  exception_on_error = false, 
159               bool  enable_sequences   = false,
160               bool  ignore_shadow      = false);
161    virtual ~gdcmParser(void);
162 // Entry
163    int CheckIfEntryExistByNumber(guint16 Group, guint16 Elem ); // int !
164    virtual std::string GetEntryByName    (std::string tagName);
165    virtual std::string GetEntryVRByName  (std::string tagName);
166    virtual std::string GetEntryByNumber  (guint16 group, guint16 element);
167    virtual std::string GetEntryVRByNumber(guint16 group, guint16 element);
168    virtual int     GetEntryLengthByNumber(guint16 group, guint16 element);
169
170    virtual bool SetEntryByName  (std::string content, std::string tagName);
171    virtual bool SetEntryByNumber(std::string content,
172                                  guint16 group, guint16 element);
173    virtual bool SetEntryLengthByNumber(guint32 length,
174                                  guint16 group, guint16 element);
175
176    virtual size_t GetEntryOffsetByNumber  (guint16 Group, guint16 Elem);
177    virtual void  *GetEntryVoidAreaByNumber(guint16 Group, guint16 Elem);   
178    virtual void  *LoadEntryVoidArea       (guint16 Group, guint16 Element);
179    virtual bool   SetEntryVoidAreaByNumber(void *a, guint16 Group, guint16 Elem);
180
181    virtual void UpdateShaEntries(void);
182
183 // Header entry
184    gdcmHeaderEntry *GetHeaderEntryByNumber  (guint16 group, guint16 element); 
185    gdcmHeaderEntry *GetHeaderEntryByName    (std::string Name);
186    IterHT           GetHeaderEntrySameNumber(guint16 group, guint16 element); 
187 // IterHT           GetHeaderEntrySameName  (std::string Name); 
188
189    void LoadHeaderEntrySafe(gdcmHeaderEntry *);
190
191    void UpdateGroupLength(bool SkipSequence = false,
192                           FileType type = ImplicitVR);
193
194    void AddHeaderEntry       (gdcmHeaderEntry *);
195    
196       
197 private:
198    // Read
199    bool ParseHeader(bool exception_on_error = false) throw(gdcmFormatError);
200
201    void LoadHeaderEntries    (void);
202    void LoadHeaderEntry      (gdcmHeaderEntry *);
203    void FindHeaderEntryLength(gdcmHeaderEntry *);
204    void FindHeaderEntryVR    (gdcmHeaderEntry *);
205    bool CheckHeaderEntryVR   (gdcmHeaderEntry *, VRKey);
206
207    std::string GetHeaderEntryValue  (gdcmHeaderEntry *);
208    std::string GetHeaderEntryUnvalue(gdcmHeaderEntry *);
209
210    void SkipHeaderEntry          (gdcmHeaderEntry *);
211    void FixHeaderEntryFoundLength(gdcmHeaderEntry *, guint32);
212    bool IsHeaderEntryAnInteger   (gdcmHeaderEntry *);
213
214    guint32 FindHeaderEntryLengthOB(void);
215
216    guint16 ReadInt16(void);
217    guint32 ReadInt32(void);
218    void    SkipBytes(guint32);
219
220    void Initialise(void);
221    bool CheckSwap(void);
222    void SwitchSwapToBigEndian(void);
223    void SetMaxSizeLoadEntry(long);
224    void SetMaxSizePrintEntry(long);
225
226    // DictEntry  related utilities
227    gdcmDictEntry *GetDictEntryByName  (std::string Name);
228    gdcmDictEntry *GetDictEntryByNumber(guint16, guint16);
229    gdcmDictEntry *NewVirtualDictEntry(guint16 group, 
230                                       guint16 element,
231                                       std::string vr     = "unkn",
232                                       std::string fourth = "unkn",
233                                       std::string name   = "unkn");
234    //gdcmDictEntry *NewVirtualDictEntry(gdcmHeaderEntry *); // never defined
235    
236    // HeaderEntry related utilities
237    
238    gdcmHeaderEntry *ReadNextHeaderEntry   (void);
239    gdcmHeaderEntry *NewHeaderEntryByNumber(guint16 group, 
240                                            guint16 element);
241    gdcmHeaderEntry *NewHeaderEntryByName  (std::string Name);
242    
243    // Deprecated (Not used) --> commented out
244    //gdcmHeaderEntry *NewManualHeaderEntryToPubDict(std::string NewTagName,
245    //                                               std::string VR);
246    
247    guint32 GenerateFreeTagKeyInGroup(guint16 group);
248
249 public:
250 // Accessors:
251    /// Accessor to \ref printLevel
252    void SetPrintLevel(int level) { printLevel = level; };
253
254    /// Accessor to \ref filename
255    inline std::string GetFileName(void) {return filename;}
256
257    /// Accessor to \ref filename
258    inline void SetFileName(char* fileName) {filename = fileName;}
259
260    /// Accessor to \ref gdcmParser::tagHT
261    inline TagHeaderEntryHT &GetEntry(void) { return tagHT; };
262
263    /// Accessor to \ref gdcmParser::listEntries
264    inline ListTag &GetListEntry(void) { return listEntries; };
265
266    /// 'Swap code' accessor (see \ref sw )
267    inline int GetSwapCode(void) { return sw; }
268 };
269
270 //-----------------------------------------------------------------------------
271 #endif