]> Creatis software - gdcm.git/blob - src/gdcmParser.h
c9306c394530d83dcc8871d7ed5517d623a47984
[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 PrintPubDict (std::ostream &os = std::cout);
110    virtual void PrintShaDict (std::ostream &os = std::cout);
111
112 // Dictionnaries
113    gdcmDict *GetPubDict(void);
114    gdcmDict *GetShaDict(void);
115    bool SetShaDict(gdcmDict *dict);
116    bool SetShaDict(DictKey dictName);
117
118 // Informations contained in the parser
119    virtual bool IsReadable(void);
120    bool IsImplicitVRLittleEndianTransferSyntax(void);
121    bool IsExplicitVRLittleEndianTransferSyntax(void);
122    bool IsDeflatedExplicitVRLittleEndianTransferSyntax(void);
123    bool IsExplicitVRBigEndianTransferSyntax(void);
124    FileType GetFileType(void);
125
126 // Read (used in gdcmFile, gdcmDicomDir)
127    FILE *OpenFile(bool exception_on_error = false) throw(gdcmFileError);
128    bool CloseFile(void);
129
130 // Write (used in gdcmFile, gdcmDicomDir)
131    virtual bool Write(FILE *, FileType);
132    virtual void WriteEntryTagVRLength(gdcmHeaderEntry *tag,
133                                        FILE *_fp, FileType type);
134    virtual void WriteEntryValue(gdcmHeaderEntry *tag,FILE *_fp,FileType type);
135    virtual bool WriteEntry(gdcmHeaderEntry *tag,FILE *_fp,FileType type);
136    virtual bool WriteEntries(FILE *_fp,FileType type);
137    void WriteEntriesDeprecated(FILE *_fp,FileType type); // JPR
138
139    gdcmHeaderEntry * ReplaceOrCreateByNumber(std::string Value,
140                                              guint16 Group, guint16 Elem);
141    bool ReplaceIfExistByNumber (char *Value, guint16 Group, guint16 Elem);
142
143 // System access
144    guint16 SwapShort(guint16);   // needed by gdcmFile
145    guint32 SwapLong(guint32);    // needed by gdcmFile
146    guint16 UnswapShort(guint16); // needed by gdcmFile
147    guint32 UnswapLong(guint32);  // needed by gdcmFile
148
149 protected:
150    // Constructor and destructor are protected to forbid end user 
151    // to instanciate from this class gdcmParser (only gdcmHeader and
152    // gdcmDicomDir are meaningfull).
153    gdcmParser(bool exception_on_error  = false);
154    gdcmParser(const char *inFilename, 
155               bool  exception_on_error = false, 
156               bool  enable_sequences   = false,
157               bool  ignore_shadow      = false);
158    virtual ~gdcmParser(void);
159 // Entry
160    int CheckIfEntryExistByNumber(guint16 Group, guint16 Elem ); // int !
161    virtual std::string GetEntryByName    (std::string tagName);
162    virtual std::string GetEntryVRByName  (std::string tagName);
163    virtual std::string GetEntryByNumber  (guint16 group, guint16 element);
164    virtual std::string GetEntryVRByNumber(guint16 group, guint16 element);
165    virtual int     GetEntryLengthByNumber(guint16 group, guint16 element);
166
167    virtual bool SetEntryByName  (std::string content, std::string tagName);
168    virtual bool SetEntryByNumber(std::string content,
169                                  guint16 group, guint16 element);
170    virtual bool SetEntryLengthByNumber(guint32 length,
171                                  guint16 group, guint16 element);
172
173    virtual size_t GetEntryOffsetByNumber  (guint16 Group, guint16 Elem);
174    virtual void  *GetEntryVoidAreaByNumber(guint16 Group, guint16 Elem);   
175    virtual void  *LoadEntryVoidArea       (guint16 Group, guint16 Element);
176    virtual bool   SetEntryVoidAreaByNumber(void *a, guint16 Group, guint16 Elem);
177
178    virtual void UpdateShaEntries(void);
179
180 // Header entry
181    gdcmHeaderEntry *GetHeaderEntryByNumber  (guint16 group, guint16 element); 
182    gdcmHeaderEntry *GetHeaderEntryByName    (std::string Name);
183    IterHT           GetHeaderEntrySameNumber(guint16 group, guint16 element); 
184 // IterHT           GetHeaderEntrySameName  (std::string Name); 
185
186    void LoadHeaderEntrySafe(gdcmHeaderEntry *);
187
188    void UpdateGroupLength(bool SkipSequence = false,
189                           FileType type = ImplicitVR);
190
191    void AddHeaderEntry       (gdcmHeaderEntry *);
192    
193       
194 private:
195    // Read
196    bool ParseHeader(bool exception_on_error = false) throw(gdcmFormatError);
197
198    void LoadHeaderEntries    (void);
199    void LoadHeaderEntry      (gdcmHeaderEntry *);
200    void FindHeaderEntryLength(gdcmHeaderEntry *);
201    void FindHeaderEntryVR    (gdcmHeaderEntry *);
202    bool CheckHeaderEntryVR   (gdcmHeaderEntry *, VRKey);
203
204    std::string GetHeaderEntryValue  (gdcmHeaderEntry *);
205    std::string GetHeaderEntryUnvalue(gdcmHeaderEntry *);
206
207    void SkipHeaderEntry          (gdcmHeaderEntry *);
208    void FixHeaderEntryFoundLength(gdcmHeaderEntry *, guint32);
209    bool IsHeaderEntryAnInteger   (gdcmHeaderEntry *);
210
211    guint32 FindHeaderEntryLengthOB(void);
212
213    guint16 ReadInt16(void);
214    guint32 ReadInt32(void);
215    void    SkipBytes(guint32);
216
217    void Initialise(void);
218    bool CheckSwap(void);
219    void SwitchSwapToBigEndian(void);
220    void SetMaxSizeLoadEntry(long);
221    void SetMaxSizePrintEntry(long);
222
223    // DictEntry  related utilities
224    gdcmDictEntry *GetDictEntryByName  (std::string Name);
225    gdcmDictEntry *GetDictEntryByNumber(guint16, guint16);
226    gdcmDictEntry *NewVirtualDictEntry(guint16 group, 
227                                       guint16 element,
228                                       std::string vr     = "unkn",
229                                       std::string fourth = "unkn",
230                                       std::string name   = "unkn");
231    //gdcmDictEntry *NewVirtualDictEntry(gdcmHeaderEntry *); // never defined
232    
233    // HeaderEntry related utilities
234    
235    gdcmHeaderEntry *ReadNextHeaderEntry   (void);
236    gdcmHeaderEntry *NewHeaderEntryByNumber(guint16 group, 
237                                            guint16 element);
238    gdcmHeaderEntry *NewHeaderEntryByName  (std::string Name);
239    
240    // Deprecated (Not used) --> commented out
241    //gdcmHeaderEntry *NewManualHeaderEntryToPubDict(std::string NewTagName,
242    //                                               std::string VR);
243    
244    guint32 GenerateFreeTagKeyInGroup(guint16 group);
245
246 public:
247 // Accessors:
248    /// Accessor to \ref printLevel
249    void SetPrintLevel(int level) { printLevel = level; };
250
251    /// Accessor to \ref filename
252    inline std::string GetFileName(void) {return filename;}
253
254    /// Accessor to \ref filename
255    inline void SetFileName(char* fileName) {filename = fileName;}
256
257    /// Accessor to \ref gdcmParser::tagHT
258    inline TagHeaderEntryHT &GetEntry(void) { return tagHT; };
259
260    /// Accessor to \ref gdcmParser::listEntries
261    inline ListTag &GetListEntry(void) { return listEntries; };
262
263    /// 'Swap code' accessor (see \ref sw )
264    inline int GetSwapCode(void) { return sw; }
265 };
266
267 //-----------------------------------------------------------------------------
268 #endif