2 //-----------------------------------------------------------------------------
6 #include "gdcmCommon.h"
9 #include "gdcmException.h"
10 #include "gdcmDictSet.h"
11 #include "gdcmHeaderEntry.h"
16 //-----------------------------------------------------------------------------
17 typedef std::string VRKey;
18 typedef std::string VRAtr;
19 typedef std::map<VRKey, VRAtr> VRHT; // Value Representation Hash Table
21 typedef std::multimap<TagKey, gdcmHeaderEntry *> TagHeaderEntryHT;
22 typedef std::pair<TagKey, gdcmHeaderEntry *> PairHT;
23 typedef std::pair<TagHeaderEntryHT::iterator,TagHeaderEntryHT::iterator> IterHT;
25 typedef std::list<gdcmHeaderEntry *> ListTag; // for linking together the Elements
27 typedef std::string GroupKey;
28 typedef std::map<GroupKey, int> GroupHT;
30 //-----------------------------------------------------------------------------
32 * \brief used by both gdcmHeader and gdcmDicomDir
34 class GDCM_EXPORT gdcmParser
41 * \brief Sets the print level for the Dicom Header
42 * \note 0 for Light Print; 1 for 'medium' Print, 2 for Heavy
44 void SetPrintLevel(int level)
45 { printLevel = level; };
48 * \brief canonical Printer
51 virtual void Print (std::ostream &os = std::cout)
53 virtual void PrintEntry (std::ostream &os = std::cout);
54 virtual void PrintPubDict (std::ostream &os = std::cout);
55 virtual void PrintShaDict (std::ostream &os = std::cout);
60 * \brief Gets the external File Name
62 inline std::string GetFileName(void)
66 gdcmDict *GetPubDict(void);
67 gdcmDict *GetShaDict(void);
68 bool SetShaDict(gdcmDict *dict);
69 bool SetShaDict(DictKey dictName);
71 // Informations contained in the parser
72 virtual bool IsReadable(void);
73 bool IsImplicitVRLittleEndianTransferSyntax(void);
74 bool IsExplicitVRLittleEndianTransferSyntax(void);
75 bool IsDeflatedExplicitVRLittleEndianTransferSyntax(void);
76 bool IsExplicitVRBigEndianTransferSyntax(void);
77 FileType GetFileType(void);
82 * \brief returns a ref to the Dicom Header H table (multimap)
83 * return the Dicom Header H table
85 inline TagHeaderEntryHT &GetEntry(void) { return tagHT; };
89 * \brief returns a ref to the Dicom Header chained list
90 * return the Dicom Header chained list
92 inline ListTag &GetListEntry(void) { return listEntries; };
94 // Read (used in gdcmFile, gdcmDicomDir)
95 FILE *OpenFile(bool exception_on_error = false) throw(gdcmFileError);
98 // Write (used in gdcmFile, gdcmDicomDir)
99 virtual bool Write(FILE *, FileType);
101 gdcmHeaderEntry * ReplaceOrCreateByNumber(std::string Value, guint16 Group, guint16 Elem);
102 gdcmHeaderEntry * ReplaceOrCreateByNumber( char *Value, guint16 Group, guint16 Elem);
103 bool ReplaceIfExistByNumber ( char *Value, guint16 Group, guint16 Elem);
107 * \ingroup gdcmHeader
108 * \brief returns the 'swap code'
109 * (Big Endian, Little Endian,
110 * Bad Big Endian, Bad Little Endian)
111 * according to the processor Endianity and what's written on disc
114 inline int GetSwapCode(void) { return sw; }
116 guint16 SwapShort(guint16); // needed by gdcmFile
117 guint32 SwapLong(guint32); // needed by gdcmFile
118 guint16 UnswapShort(guint16); // needed by gdcmFile
119 guint32 UnswapLong(guint32); // needed by gdcmFile
122 // constructor and destructor are protected to forbid end user
123 // to instanciate class gdcmParser
124 // (only gdcmHeader and gdcmDicomDir are meaningfull)
125 gdcmParser(bool exception_on_error = false);
126 gdcmParser(const char *inFilename,
127 bool exception_on_error = false,
128 bool enable_sequences = false,
129 bool ignore_shadow = false);
130 virtual ~gdcmParser(void);
132 int CheckIfEntryExistByNumber(guint16 Group, guint16 Elem ); // int !
133 virtual std::string GetEntryByName (std::string tagName);
134 virtual std::string GetEntryVRByName (std::string tagName);
135 virtual std::string GetEntryByNumber (guint16 group, guint16 element);
136 virtual std::string GetEntryVRByNumber(guint16 group, guint16 element);
137 virtual int GetEntryLengthByNumber(guint16 group, guint16 element);
139 virtual bool SetEntryByName (std::string content, std::string tagName);
140 virtual bool SetEntryByNumber(std::string content, guint16 group, guint16 element);
141 virtual bool SetEntryLengthByNumber(guint32 length, guint16 group, guint16 element);
143 virtual size_t GetEntryOffsetByNumber (guint16 Group, guint16 Elem);
144 virtual void *GetEntryVoidAreaByNumber(guint16 Group, guint16 Elem);
145 virtual void *LoadEntryVoidArea (guint16 Group, guint16 Element);
146 virtual bool SetEntryVoidAreaByNumber(void *a, guint16 Group, guint16 Elem);
148 virtual void UpdateShaEntries(void);
151 gdcmHeaderEntry *GetHeaderEntryByNumber (guint16 group, guint16 element);
152 gdcmHeaderEntry *GetHeaderEntryByName (std::string Name);
153 IterHT GetHeaderEntrySameNumber(guint16 group, guint16 element);
154 // IterHT GetHeaderEntrySameName (std::string Name);
156 void LoadHeaderEntrySafe(gdcmHeaderEntry *);
158 void UpdateGroupLength(bool SkipSequence = false, FileType type = ImplicitVR);
159 void WriteEntryTagVRLength(gdcmHeaderEntry *tag, FILE *_fp, FileType type);
160 void WriteEntryValue(gdcmHeaderEntry *tag,FILE *_fp,FileType type);
161 void WriteEntry(gdcmHeaderEntry *tag,FILE *_fp,FileType type);
162 void WriteEntries(FILE *_fp,FileType type);
163 void WriteEntriesDeprecated(FILE *_fp,FileType type); // JPR
165 void AddHeaderEntry (gdcmHeaderEntry *);
168 * \ingroup gdcmParser
169 * \brief Set the external File Name
171 inline void SetFileName(char* fileName)
172 {filename = fileName;}
176 * \brief File Pointer, open during Header parsing
180 * \brief ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown
184 /// after opening the file, we read HEADER_LENGTH_TO_READ bytes.
185 static const unsigned int HEADER_LENGTH_TO_READ;
186 /// Elements whose value is longer than MAX_SIZE_LOAD_ELEMENT_VALUE are NOT loaded
187 static const unsigned int MAX_SIZE_LOAD_ELEMENT_VALUE;
188 /// Elements whose value is longer than MAX_SIZE_PRINT_ELEMENT_VALUE are NOT printed
189 static const unsigned int MAX_SIZE_PRINT_ELEMENT_VALUE;
193 * \brief H Table (multimap), to provide fast access
195 TagHeaderEntryHT tagHT;
197 * \brief chained list, to keep the 'spacial' ordering
201 * \brief will be set 1 if user asks to 'go inside' the 'sequences' (VR = "SQ")
205 * \brief amount of printed details for each Header Entry (Dicom Element)
211 * \brief For some ACR-NEMA images, it's *not* 7fe0 ...
215 /// In some cases (e.g. for some ACR-NEMA images) the Header Entry Element
216 /// Number of the 'Pixel Element' is *not* found at 0x0010. In order to
217 /// make things easier the parser shall store the proper value in
218 /// NumPixel to provide a unique access facility. See also
219 /// \ref gdcmHeader::gdcmHeader
222 * \brief some files may contain icons; GrPixel,NumPixel appears several times
223 * Let's remember how many times!
227 * \brief = true when the 'pixel Element' is reached during writting process
229 bool itsTimeToWritePixels;
233 bool ParseHeader(bool exception_on_error = false) throw(gdcmFormatError);
235 void LoadHeaderEntries (void);
236 void LoadHeaderEntry (gdcmHeaderEntry *);
237 void FindHeaderEntryLength(gdcmHeaderEntry *);
238 void FindHeaderEntryVR (gdcmHeaderEntry *);
239 bool CheckHeaderEntryVR (gdcmHeaderEntry *, VRKey);
241 std::string GetHeaderEntryValue (gdcmHeaderEntry *);
242 std::string GetHeaderEntryUnvalue(gdcmHeaderEntry *);
244 void SkipHeaderEntry (gdcmHeaderEntry *);
245 void FixHeaderEntryFoundLength(gdcmHeaderEntry *, guint32);
246 bool IsHeaderEntryAnInteger (gdcmHeaderEntry *);
248 guint32 FindHeaderEntryLengthOB(void);
250 guint16 ReadInt16(void);
251 guint32 ReadInt32(void);
252 void SkipBytes(guint32);
254 void Initialise(void);
255 bool CheckSwap(void);
256 void SwitchSwapToBigEndian(void);
257 void SetMaxSizeLoadEntry(long);
258 void SetMaxSizePrintEntry(long);
260 // DictEntry related utilities
261 gdcmDictEntry *GetDictEntryByName (std::string Name);
262 gdcmDictEntry *GetDictEntryByNumber(guint16, guint16);
263 gdcmDictEntry *NewVirtualDictEntry(guint16 group,
265 std::string vr = "unkn",
266 std::string fourth = "unkn",
267 std::string name = "unkn");
268 //gdcmDictEntry *NewVirtualDictEntry(gdcmHeaderEntry *); // never defined
270 // HeaderEntry related utilities
272 gdcmHeaderEntry *ReadNextHeaderEntry (void);
273 gdcmHeaderEntry *NewHeaderEntryByNumber(guint16 group,
275 gdcmHeaderEntry *NewHeaderEntryByName (std::string Name);
277 // Deprecated (Not used) --> commented out
278 //gdcmHeaderEntry *NewManualHeaderEntryToPubDict(std::string NewTagName,
281 guint32 GenerateFreeTagKeyInGroup(guint16 group);
284 * \brief Refering underlying filename.
286 std::string filename;
289 * \brief Public dictionary used to parse this header
291 gdcmDict *RefPubDict;
294 * \brief Optional "shadow dictionary" (private elements) used to parse this header
296 gdcmDict *RefShaDict;
299 * \brief = 1 if a gdcmHeaderEntry was added post parsing
304 * \brief =1 if user wants to skip shadow groups while parsing (to save space)
309 * \brief Swap code e.g. little, big, bad-big, bad-little endian).
310 * \warning : this code is not fixed during header parsing.
314 * \brief Size threshold above which an element value will NOT be loaded in
315 * memory (to avoid loading the image/volume itself). By default,
316 * this upper bound is fixed to 1024 bytes (which might look reasonable
317 * when one considers the definition of the various VR contents).
319 guint32 MaxSizeLoadEntry;
322 * \brief Size threshold above which an element value will NOT be *printed* in
323 * order no to polute the screen output.
324 * By default, this upper bound is fixed to 64 bytes.
326 guint32 MaxSizePrintEntry;
330 //-----------------------------------------------------------------------------