]> Creatis software - gdcm.git/blob - src/gdcmParser.h
8c976a63bb16348894a2638377063bfce7c1a975
[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>       // for linking together *all* the Dicom Elements
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
25 typedef std::list<gdcmHeaderEntry *> ListTag; // for linking together the Elements
26
27 typedef std::string GroupKey;
28 typedef std::map<GroupKey, int> GroupHT;
29
30 //-----------------------------------------------------------------------------
31 /*
32  * \defgroup gdcmParser
33  * \brief used by both gdcmHeader and gdcmDicomDir
34  */
35 class GDCM_EXPORT gdcmParser
36 {
37 public:
38    gdcmParser(bool exception_on_error  = false);
39    gdcmParser(const char *inFilename, 
40               bool  exception_on_error = false, 
41               bool  enable_sequences   = false,
42               bool  ignore_shadow      = false);
43    virtual ~gdcmParser(void);
44
45 // Print
46    /**
47     * \ingroup gdcmParser
48     * \brief   Sets the print level for the Dicom Header 
49     * \note    0 for Light Print; 1 for 'medium' Print, 2 for Heavy
50     */
51    void SetPrintLevel(int level) { printLevel = level; };
52    /**
53     * \ingroup gdcmParser
54     * \brief   canonical Printer 
55     * \sa    SetPrintLevel
56     */   
57    virtual void Print        (std::ostream &os = std::cout) {PrintEntry(os);};
58    virtual void PrintEntry   (std::ostream &os = std::cout);
59    virtual void PrintPubDict (std::ostream &os = std::cout);
60    virtual void PrintShaDict (std::ostream &os = std::cout);
61
62 // Standard values
63    /**
64     * \ingroup gdcmParser
65     * \brief   Gets the external File Name 
66     */
67    inline std::string GetFileName(void) {return filename;}
68
69 // Dictionnaries
70    gdcmDict *GetPubDict(void);
71    gdcmDict *GetShaDict(void);
72    bool SetShaDict(gdcmDict *dict);
73    bool SetShaDict(DictKey dictName);
74
75 // Informations contained in the parser
76    virtual bool IsReadable(void);
77    bool IsImplicitVRLittleEndianTransferSyntax(void);
78    bool IsExplicitVRLittleEndianTransferSyntax(void);
79    bool IsDeflatedExplicitVRLittleEndianTransferSyntax(void);
80    bool IsExplicitVRBigEndianTransferSyntax(void);
81    FileType GetFileType(void);
82
83 // Entries
84    /**
85     * \ingroup gdcmHeader
86     * \brief   returns a ref to the Dicom Header H table (multimap)
87     * return the Dicom Header H table
88     */
89    inline TagHeaderEntryHT &GetEntry(void) { return tagHT; };
90
91    /**
92     * \ingroup gdcmHeader
93     * \brief   returns a ref to the Dicom Header chained list
94     * return the Dicom Header chained list
95     */
96    inline ListTag &GetListEntry(void) { return listEntries; };
97
98 // Read (used in gdcmFile, gdcmDicomDir)
99    FILE *OpenFile(bool exception_on_error = false) throw(gdcmFileError);
100    bool CloseFile(void);
101
102 // Write (used in gdcmFile, gdcmDicomDir)
103    virtual bool Write(FILE *, FileType);
104
105    bool ReplaceOrCreateByNumber(std::string Value, guint16 Group, guint16 Elem);
106    bool ReplaceOrCreateByNumber(     char  *Value, guint16 Group, guint16 Elem);
107    bool ReplaceIfExistByNumber (     char  *Value, guint16 Group, guint16 Elem);
108
109 // System access
110    /**
111     * \ingroup gdcmHeader
112     * \brief   returns the 'swap code' 
113     *          (Big Endian, Little Endian, 
114     *          Bad Big Endian, Bad Little Endian)
115     *          according to the processor Endianity and what's written on disc
116     * return 
117     */
118    inline int GetSwapCode(void) { return sw; }
119    
120    guint16 SwapShort(guint16);   // needed by gdcmFile
121    guint32 SwapLong(guint32);    // needed by gdcmFile
122    guint16 UnswapShort(guint16); // needed by gdcmFile
123    guint32 UnswapLong(guint32);  // needed by gdcmFile
124
125 protected:
126 // Entry
127    int CheckIfEntryExistByNumber(guint16 Group, guint16 Elem ); // int !
128    virtual std::string GetEntryByName    (std::string tagName);
129    virtual std::string GetEntryVRByName  (std::string tagName);
130    virtual std::string GetEntryByNumber  (guint16 group, guint16 element);
131    virtual std::string GetEntryVRByNumber(guint16 group, guint16 element);
132    virtual int     GetEntryLengthByNumber(guint16 group, guint16 element);
133
134    virtual bool SetEntryByName  (std::string content, std::string tagName);
135    virtual bool SetEntryByNumber(std::string content, guint16 group, guint16 element);
136    virtual bool SetEntryLengthByNumber(guint32 length, guint16 group, guint16 element);
137
138    virtual size_t GetEntryOffsetByNumber  (guint16 Group, guint16 Elem);
139    virtual void  *GetEntryVoidAreaByNumber(guint16 Group, guint16 Elem);   
140    virtual void  *LoadEntryVoidArea       (guint16 Group, guint16 Element);
141    virtual bool   SetEntryVoidAreaByNumber(void *a, guint16 Group, guint16 Elem);
142
143    virtual void UpdateShaEntries(void);
144
145 // Header entry
146    gdcmHeaderEntry *GetHeaderEntryByNumber  (guint16 group, guint16 element); 
147    gdcmHeaderEntry *GetHeaderEntryByName    (std::string Name);
148    IterHT           GetHeaderEntrySameNumber(guint16 group, guint16 element); 
149 // IterHT           GetHeaderEntrySameName  (std::string Name); 
150
151    void LoadHeaderEntrySafe(gdcmHeaderEntry *);
152
153    void UpdateGroupLength(bool SkipSequence = false, FileType type = ImplicitVR);
154    void WriteEntries(FILE *_fp,FileType type);
155    void WriteEntriesDeprecated(FILE *_fp,FileType type); // JPR
156
157    void AddHeaderEntry       (gdcmHeaderEntry *);
158
159 // Variables
160    /**
161    * \brief File Pointer, open during Header parsing
162    */
163    FILE *fp;
164    /**
165    * \brief ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown
166    */
167    FileType filetype;  
168
169    static const unsigned int HEADER_LENGTH_TO_READ; 
170    static const unsigned int MAX_SIZE_LOAD_ELEMENT_VALUE;
171    static const unsigned int MAX_SIZE_PRINT_ELEMENT_VALUE;
172
173 protected:
174    /**
175    * \brief H Table (multimap), to provide fast access
176    */
177    TagHeaderEntryHT tagHT; 
178    /**
179    * \brief chained list, to keep the 'spacial' ordering
180    */
181    ListTag listEntries; 
182    /**
183    * \brief will be set 1 if user asks to 'go inside' the 'sequences' (VR = "SQ")
184    */    
185    int enableSequences;
186    /**
187    * \brief amount of printed details for each Header Entry (Dicom Element)
188    *  0 : the least 
189    */    
190    int printLevel;
191    
192    /** 
193    * \brief For some ACR-NEMA images, it's *not* 7fe0 ... 
194    */   
195    guint16 GrPixel;
196    
197    /** 
198    * \brief For some ACR-NEMA images, it's *not* 0010 ... 
199    */    
200    guint16 NumPixel;
201    /**
202    * \brief some files may contain icons; GrPixel,NumPixel appears several times
203    * Let's remember how many times!
204    */
205    int countGrPixel;
206       
207 private:
208    // Read
209    bool ParseHeader(bool exception_on_error = false) throw(gdcmFormatError);
210
211    void LoadHeaderEntries    (void);
212    void LoadHeaderEntry      (gdcmHeaderEntry *);
213    void FindHeaderEntryLength(gdcmHeaderEntry *);
214    void FindHeaderEntryVR    (gdcmHeaderEntry *);
215    bool CheckHeaderEntryVR   (gdcmHeaderEntry *, VRKey);
216
217    std::string GetHeaderEntryValue  (gdcmHeaderEntry *);
218    std::string GetHeaderEntryUnvalue(gdcmHeaderEntry *);
219
220    void SkipHeaderEntry          (gdcmHeaderEntry *);
221    void FixHeaderEntryFoundLength(gdcmHeaderEntry *, guint32);
222    bool IsHeaderEntryAnInteger   (gdcmHeaderEntry *);
223
224    guint32 FindHeaderEntryLengthOB(void);
225
226    guint16 ReadInt16(void);
227    guint32 ReadInt32(void);
228    void    SkipBytes(guint32);
229
230    void Initialise(void);
231    bool CheckSwap(void);
232    void SwitchSwapToBigEndian(void);
233    void SetMaxSizeLoadEntry(long);
234    void SetMaxSizePrintEntry(long);
235
236    // DictEntry  related utilities
237    gdcmDictEntry *GetDictEntryByName  (std::string Name);
238    gdcmDictEntry *GetDictEntryByNumber(guint16, guint16);
239    gdcmDictEntry *NewVirtualDictEntry(guint16 group, 
240                                       guint16 element,
241                                       std::string vr     = "unkn",
242                                       std::string fourth = "unkn",
243                                       std::string name   = "unkn");
244    gdcmDictEntry *NewVirtualDictEntry(gdcmHeaderEntry *);
245    
246    // HeaderEntry related utilities
247    gdcmHeaderEntry *ReadNextHeaderEntry   (void);
248    gdcmHeaderEntry *NewHeaderEntryByNumber(guint16 group, 
249                                            guint16 element);
250    gdcmHeaderEntry *NewHeaderEntryByName  (std::string Name);
251
252
253    // Deprecated (Not used) --> commented out
254    //gdcmHeaderEntry *NewManualHeaderEntryToPubDict(std::string NewTagName,
255    //                                               std::string VR);
256    guint32 GenerateFreeTagKeyInGroup(guint16 group);
257
258    // Refering underlying filename.
259    std::string filename; 
260
261    // Public dictionary used to parse this header
262    gdcmDict *RefPubDict;
263    // Optional "shadow dictionary" (private elements) used to parse this header
264    gdcmDict *RefShaDict;
265
266    // = 1 if a gdcmHeaderEntry was added post parsing 
267    int wasUpdated;
268    
269    // =1 if user wants to skip shadow groups while parsing (to save space)
270    int ignoreShadow;
271
272    // Swap code e.g. little, big, bad-big, bad-little endian). Warning:
273    // this code is not fixed during header parsing.
274    int sw;
275
276    // Size treshold above which an element value will NOT be loaded in 
277    // memory (to avoid loading the image/volume itself). By default,
278    // this upper bound is fixed to 1024 bytes (which might look reasonable
279    // when one considers the definition of the various VR contents).
280    guint32 MaxSizeLoadEntry;
281    // Size treshold above which an element value will NOT be *printed* in 
282    // order no to polute the screen output. By default,
283    // this upper bound is fixed to 64 bytes.   
284    guint32 MaxSizePrintEntry;
285    
286 };
287
288 //-----------------------------------------------------------------------------
289 #endif