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