]> Creatis software - gdcm.git/blob - src/gdcmHeader.h
a5828675c80594fe330ad5a8962eb4d17fe4d989
[gdcm.git] / src / gdcmHeader.h
1 // gdcmHeader.h
2 //-----------------------------------------------------------------------------
3 #ifndef GDCMHEADER_H
4 #define GDCMHEADER_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 <stdio.h>
14 #include <map>
15 #include <list>       // for linking together *all* the Dicom Elements
16
17 //-----------------------------------------------------------------------------
18 typedef std::string VRKey;
19 typedef std::string VRAtr;
20 typedef std::map<VRKey, VRAtr> VRHT;    // Value Representation Hash Table
21
22 typedef std::multimap<TagKey, gdcmHeaderEntry*> TagHeaderEntryHT;
23 typedef std::pair<TagKey, gdcmHeaderEntry*> PairHT;
24 typedef std::pair<TagHeaderEntryHT::iterator,TagHeaderEntryHT::iterator> IterHT; 
25
26 typedef std::list<gdcmHeaderEntry*> ListTag; // for linking together the Elements
27
28 // TODO : to be removed after re-writting   gdcmHeaderEntrySet::UpdateGroupLength
29 //          using the chained list instead of the H table
30 typedef std::string GroupKey;
31 typedef std::map<GroupKey, int> GroupHT;
32
33 //-----------------------------------------------------------------------------
34 /*
35  * \defgroup gdcmHeader
36  * \brief
37  * The purpose of an instance of gdcmHeader is to act as a container of
38  * all the DICOM elements and their corresponding values (and
39  * additionaly the corresponding DICOM dictionary entry) of the header
40  * of a DICOM file.
41  *
42  * The typical usage of instances of class gdcmHeader is to classify a set of
43  * dicom files according to header information e.g. to create a file hierarchy
44  * reflecting the Patient/Study/Serie informations, or extracting a given
45  * SerieId. Accessing the content (image[s] or volume[s]) is beyond the
46  * functionality of this class and belongs to gdmcFile.
47  * \note  The various entries of the explicit value representation (VR) shall
48  *        be managed within a dictionary which is shared by all gdcmHeader
49  *        instances.
50  * \note  The gdcmHeader::Set*Tag* family members cannot be defined as
51  *        protected due to Swig limitations for as Has_a dependency between
52  *        gdcmFile and gdcmHeader.
53  */
54 class GDCM_EXPORT gdcmHeader {
55 public:
56    gdcmHeader(bool exception_on_error = false);
57    gdcmHeader(const char *filename, 
58               bool  exception_on_error = false, 
59               bool  enable_sequences   = false);
60               
61    virtual ~gdcmHeader();
62
63 // Standard values and informations contained in the header
64    inline std::string GetFileName(void) {return filename;}
65
66    bool IsReadable(void);
67    bool IsImplicitVRLittleEndianTransferSyntax(void);
68    bool IsExplicitVRLittleEndianTransferSyntax(void);
69    bool IsDeflatedExplicitVRLittleEndianTransferSyntax(void);
70    bool IsExplicitVRBigEndianTransferSyntax(void);
71    bool IsJPEGBaseLineProcess1TransferSyntax(void);
72    bool IsJPEGExtendedProcess2_4TransferSyntax(void); 
73    bool IsJPEGExtendedProcess3_5TransferSyntax(void);
74    bool IsJPEGSpectralSelectionProcess6_8TransferSyntax(void); 
75    bool IsRLELossLessTransferSyntax(void); 
76    bool IsJPEGLossless(void); 
77    bool IsJPEG2000(void); 
78    bool IsDicomV3(void); 
79    FileType GetFileType(void);
80
81    // Some heuristic based accessors, end user intended 
82    // (to be move to gdcmHeaderHelper?) 
83    int GetXSize(void);  
84    int GetYSize(void);
85    int GetZSize(void);
86    int GetBitsStored(void);
87    int GetBitsAllocated(void);
88    int GetSamplesPerPixel(void);   
89    int GetPlanarConfiguration(void);
90
91    int GetPixelSize(void);   
92    std::string GetPixelType(void);  
93    size_t GetPixelOffset(void);
94    size_t GetPixelAreaLength(void);
95
96    bool   HasLUT(void);
97    int    GetLUTNbits(void);
98    unsigned char * GetLUTRGBA(void);
99
100    std::string GetTransfertSyntaxName(void);
101
102    // When some proprietary shadow groups are disclosed, we can set up
103    // an additional specific dictionary to access extra information.
104    
105    // OK : we still have *ONE* HeaderEntrySet, 
106    // with both Public and Shadow Elements
107    // parsed against THE Public Dictionary and A (single) Shadow Dictionary
108    
109    // TODO Swig int SetShaDict(std::string filename);
110    // TODO Swig int SetPubDict(std::string filename);
111
112 // Public element value
113    std::string GetPubEntryByName    (std::string tagName);
114    std::string GetPubEntryVRByName  (std::string tagName);
115    std::string GetPubEntryByNumber  (guint16 group, guint16 element);
116    std::string GetPubEntryVRByNumber(guint16 group, guint16 element);
117    
118    bool SetPubEntryByName  (std::string content, std::string tagName); 
119    bool SetPubEntryByNumber(std::string content, guint16 group, guint16 element);  
120    bool SetPubEntryLengthByNumber(guint32 lgr, guint16 group, guint16 element);   
121    
122    /**
123     * \ingroup gdcmHeader
124     * \brief   returns a ref to the Dicom Header H table (multimap)
125     * return the Dicom Header H table
126     */
127    inline TagHeaderEntryHT & GetPubEntry(void) { return tagHT; };
128    
129    /**
130     * \ingroup gdcmHeader
131     * \brief   returns a ref to the Dicom Header chained list
132     * return the Dicom Header chained list
133     */
134    inline ListTag      & GetPubListEntry(void) { return listEntries; };
135    
136    /**
137     * \ingroup gdcmHeader
138     * \brief   Sets the print level for the Dicom Header 
139     * \note 0 for Light Print; 1 for 'medium' Print, 2 for Heavy
140     */
141    void  SetPrintLevel(int level) { printLevel = level; };
142    
143    void PrintPubEntry(std::ostream & os = std::cout);
144    void PrintPubDict (std::ostream & os = std::cout);
145
146 // Element value
147    std::string GetEntryByName    (std::string tagName);
148    std::string GetEntryVRByName  (std::string tagName);
149    std::string GetEntryByNumber  (guint16 group, guint16 element);
150    std::string GetEntryVRByNumber(guint16 group, guint16 element);
151
152    bool SetEntryByName(std::string content,std::string tagName); 
153 //   bool SetEntryByNumber(std::string content,guint16 group, guint16 element);
154
155
156 // Read (used in gdcmFile)
157    FILE *OpenFile(bool exception_on_error = false) throw(gdcmFileError);
158    bool CloseFile(void);
159    virtual void ParseHeader(bool exception_on_error = false) throw(gdcmFormatError);
160
161 // Write (used in gdcmFile)
162    bool Write(FILE *, FileType);
163    void SetImageDataSize(size_t ExpectedSize);
164
165    bool ReplaceOrCreateByNumber(std::string Value, guint16 Group, guint16 Elem); 
166    bool ReplaceOrCreateByNumber(     char * Value, guint16 Group, guint16 Elem);                                
167    bool ReplaceIfExistByNumber (     char * Value, guint16 Group, guint16 Elem);
168
169 // System access
170    inline int GetSwapCode(void) { return sw; }
171    guint16 SwapShort(guint16); // needed by gdcmFile
172    guint32 SwapLong(guint32);  // for JPEG Files
173  
174  
175  
176 // ================= Was in EntrySet =================
177    void Print(std::ostream & os = std::cout);
178    void Add(gdcmHeaderEntry*);                          
179    bool SetEntryByNumber(std::string content, guint16 group, guint16 element);
180    bool SetEntryLengthByNumber(guint32 l, guint16 group, guint16 element);
181    bool SetVoidAreaByNumber(void *a, guint16 Group, guint16 Elem );
182    guint32 GenerateFreeTagKeyInGroup(guint16 group);  
183 // ===================================================
184
185    
186 protected:
187    int CheckIfExistByNumber(guint16 Group, guint16 Elem ); // int !
188
189    gdcmHeaderEntry *GetHeaderEntryByName  (std::string Name);
190    gdcmHeaderEntry *GetHeaderEntryByNumber(guint16 group, guint16 element); 
191
192    int write(std::ostream&);   
193    int anonymize(std::ostream&);  // FIXME : anonymize should be a friend ?
194
195    size_t GetPubEntryOffsetByNumber  (guint16 Group, guint16 Elem);
196    void * GetPubEntryVoidAreaByNumber(guint16 Group, guint16 Elem);   
197    void * LoadEntryVoidArea          (guint16 Group, guint16 Element);
198
199
200 // ================= Was in EntrySet =================
201    void UpdateGroupLength(bool SkipSequence = false, FileType type = ImplicitVR);
202    void WriteEntries(FileType type, FILE *);
203 // ===================================================
204
205 // Variables
206    FILE * fp;
207    FileType filetype; // ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown
208    
209 private:
210    // Read
211    void LoadHeaderEntries    (void);
212    void LoadHeaderEntry      (gdcmHeaderEntry *);
213    void LoadHeaderEntrySafe  (gdcmHeaderEntry *);
214    void FindHeaderEntryLength(gdcmHeaderEntry *);
215    void FindHeaderEntryVR    (gdcmHeaderEntry *);
216
217    void SkipHeaderEntry          (gdcmHeaderEntry *);
218    void FixHeaderEntryFoundLength(gdcmHeaderEntry *, guint32);
219    bool IsHeaderEntryAnInteger   (gdcmHeaderEntry *);
220
221    guint32 FindHeaderEntryLengthOB(void);
222
223    guint16 ReadInt16(void);
224    guint32 ReadInt32(void);
225    void    SkipBytes(guint32);
226
227    void Initialise(void);
228    void CheckSwap(void);
229    void SwitchSwapToBigEndian(void);
230    void SetMaxSizeLoadElementValue(long);
231
232    // Dict
233    gdcmDictEntry *GetDictEntryByName  (std::string Name);
234    gdcmDictEntry *GetDictEntryByNumber(guint16, guint16);
235
236    // HeaderEntry related utilities
237    gdcmHeaderEntry *ReadNextHeaderEntry   (void);
238    gdcmHeaderEntry *NewHeaderEntryByNumber(guint16 group, guint16 element);
239    gdcmHeaderEntry *NewHeaderEntryByName  (std::string Name);
240
241    // Deprecated (Not used)
242    gdcmHeaderEntry *NewManualHeaderEntryToPubDict(std::string NewTagName,
243                                                   std::string VR);
244
245 // Variables
246    // Pointer to the Value Representation Hash Table which contains all
247    // the VR of the DICOM version3 public dictionary. 
248    gdcmVR *dicom_vr;     // Not a class member for thread-safety reasons
249    
250    // Pointer to the Transfert Syntax Hash Table which contains all
251    // the TS of the DICOM version3 public dictionary. 
252    gdcmTS *dicom_ts;     // Not a class member for thread-safety reasons 
253      
254    // Pointer to global dictionary container
255    gdcmDictSet *Dicts;   // Not a class member for thread-safety reasons
256    
257    // Public dictionary used to parse this header
258    gdcmDict *RefPubDict;
259    
260    // Optional "shadow dictionary" (private elements) used to parse this
261    // header
262    gdcmDict *RefShaDict;
263
264    
265    // ================ Was in gdcmHeaderEntrySet =========   
266    TagHeaderEntryHT tagHT; // H Table (multimap), to provide fast access
267    ListTag listEntries;    // chained list, to keep the 'spacial' ordering 
268    int wasUpdated;         // true if a gdcmHeaderEntry was added post parsing 
269    int printLevel;         // for PrintHeader     
270    // ====================================================
271        
272    // Refering underlying filename.
273    std::string filename; 
274   
275    int enableSequences;
276
277    // FIXME sw should be an enum e.g.
278    //enum EndianType {
279       //LittleEndian, 
280       //BadLittleEndian,
281       //BigEndian, 
282       //BadBigEndian};
283    // Swap code e.g. little, big, bad-big, bad-little endian). Warning:
284    // this code is not fixed during header parsing.
285    int sw;
286
287    // Size treshold above which an element value will NOT be loaded in 
288    // memory (to avoid loading the image/volume itself). By default,
289    // this upper bound is fixed to 1024 bytes (which might look reasonable
290    // when one considers the definition of the various VR contents).
291    guint32 MaxSizeLoadElementValue;
292
293    static const unsigned int HEADER_LENGTH_TO_READ; 
294    static const unsigned int MAX_SIZE_LOAD_ELEMENT_VALUE;
295 };
296
297 //-----------------------------------------------------------------------------
298 #endif