]> Creatis software - gdcm.git/blob - src/gdcmDocument.h
* Reorder source code
[gdcm.git] / src / gdcmDocument.h
1 /*=========================================================================
2  
3   Program:   gdcm
4   Module:    $RCSfile: gdcmDocument.h,v $
5   Language:  C++
6   Date:      $Date: 2005/02/02 16:18:48 $
7   Version:   $Revision: 1.104 $
8  
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
12  
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16  
17 =========================================================================*/
18
19 #ifndef GDCMDOCUMENT_H
20 #define GDCMDOCUMENT_H
21
22 #include "gdcmVR.h"
23 #include "gdcmDict.h"
24 #include "gdcmElementSet.h"
25 #include "gdcmException.h"
26
27 #include <map>
28 #include <list>
29 #include <fstream>
30
31 namespace gdcm 
32 {
33 class ValEntry;
34 class BinEntry;
35 class SeqEntry;
36 class Dict;
37
38 //-----------------------------------------------------------------------------
39 /**
40  * \brief Derived by both gdcm::File and gdcm::DicomDir
41  */
42 class GDCM_EXPORT Document : public ElementSet
43 {
44 public:
45
46 // Dictionaries
47    Dict* GetPubDict();
48    Dict* GetShaDict();
49    bool SetShaDict(Dict* dict);
50    bool SetShaDict(DictKey const &dictName);
51
52 // Informations contained in the gdcm::Document
53    virtual bool IsReadable();
54    bool IsDicomV3();
55    bool IsPapyrus();
56    FileType GetFileType();
57    std::string GetTransferSyntax();
58    /// Return the Transfer Syntax as a string
59    std::string GetTransferSyntaxName();
60
61 // Swap code
62    /// 'Swap code' accessor (see \ref SwapCode )
63    int GetSwapCode() { return SwapCode; }
64    // System access (meaning endian related !?)
65    uint16_t SwapShort(uint16_t);
66    uint32_t SwapLong(uint32_t);
67    /// \brief  Unswaps back the bytes of 2-bytes long integer 
68    ///         so they agree with the processor order.
69    uint16_t UnswapShort(uint16_t a) { return SwapShort(a);}
70    /// \brief   Unswaps back the bytes of 4-byte long integer 
71    ///         so they agree with the processor order.
72    uint32_t UnswapLong(uint32_t a) { return SwapLong(a);}
73    
74 // File I/O
75    /// Accessor to \ref Filename
76    const std::string &GetFileName() const { return Filename; }
77    /// Accessor to \ref Filename
78    void SetFileName(std::string const &fileName) { Filename = fileName; }
79
80    std::ifstream *OpenFile();
81    bool CloseFile();
82    void WriteContent( std::ofstream *fp, FileType type );
83
84 // Content entries
85    virtual void LoadEntryBinArea(uint16_t group, uint16_t elem);
86    virtual void LoadEntryBinArea(BinEntry *entry);
87
88    void LoadDocEntrySafe(DocEntry *entry);
89
90 // Ordering of Documents
91    bool operator<(Document &document);
92
93 protected:
94 // Methods
95    // Constructor and destructor are protected to forbid end user 
96    // to instanciate from this class Document (only gdcm::File and
97    // gdcm::DicomDir are meaningfull).
98    Document();
99    Document( std::string const &filename );
100    virtual ~Document();
101    
102    uint16_t ReadInt16() throw ( FormatError );
103    uint32_t ReadInt32() throw ( FormatError );
104    void     SkipBytes(uint32_t);
105    int ComputeGroup0002Length( FileType filetype );
106
107 // Variables
108    /// Refering underlying filename.
109    std::string Filename;
110
111    /// \brief Swap code gives an information on the byte order of a 
112    ///  supposed to be an int32, as it's read on disc 
113    /// (depending on the image Transfer Syntax *and* on the processor endianess)
114    /// as opposed as it should in memory to be dealt as an int32.
115    /// For instance :
116    /// - a 'Little Endian' image, read with a little endian processor
117    /// will have a SwapCode= 1234 (the order is OK; nothing to do)
118    /// - a 'Little Endian' image, read with a big endian procesor
119    /// will have a SwapCode= 4321 (the order is wrong; int32 an int16 must be
120    /// swapped)
121    /// note : values 2143, 4321, 3412 remain for the ACR-NEMA time, and
122    /// the well known 'Bad Big Endian' and 'Bad Little Endian' codes
123    int SwapCode;
124
125    ///\brief whether we already parsed group 0002 (Meta Elements)
126    bool Group0002Parsed;
127
128    ///\brief whether file has a DCM Preamble
129    bool HasDCMPreamble;
130
131    /// File Pointer, opened during Document parsing.
132    std::ifstream *Fp;
133
134    /// ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown
135    FileType Filetype;  
136
137    /// After opening the file, we read HEADER_LENGTH_TO_READ bytes.
138    static const unsigned int HEADER_LENGTH_TO_READ; 
139    /// \brief Elements whose value is longer than MAX_SIZE_LOAD_ELEMENT_VALUE
140    /// are NOT loaded.
141    static const unsigned int MAX_SIZE_LOAD_ELEMENT_VALUE;
142    /// \brief Elements whose value is longer than  MAX_SIZE_PRINT_ELEMENT_VALUE
143    /// are NOT printed.
144    static const unsigned int MAX_SIZE_PRINT_ELEMENT_VALUE;
145
146 private:
147 // Methods
148    void Initialize();
149
150    // Read
151    void ParseDES(DocEntrySet *set,long offset, long l_max, bool delim_mode);
152    void ParseSQ (SeqEntry *seq,   long offset, long l_max, bool delim_mode);
153
154    void LoadDocEntry         (DocEntry *e);
155    void FindDocEntryLength   (DocEntry *e) throw ( FormatError );
156    uint32_t FindDocEntryLengthOBOrOW() throw( FormatUnexpected );
157    std::string FindDocEntryVR();
158    bool CheckDocEntryVR      (VRKey k);
159
160    std::string GetDocEntryValue  (DocEntry *entry);
161    std::string GetDocEntryUnvalue(DocEntry *entry);
162
163    void SkipDocEntry          (DocEntry *entry);
164    void SkipToNextDocEntry    (DocEntry *entry);
165
166    void FixDocEntryFoundLength(DocEntry *entry,uint32_t l);
167    bool IsDocEntryAnInteger   (DocEntry *entry);
168
169    bool CheckSwap();
170    void SwitchByteSwapCode();
171    void SetMaxSizeLoadEntry(long);
172    void SetMaxSizePrintEntry(long);
173
174    // DocEntry related utilities
175    DocEntry *ReadNextDocEntry();
176
177    void HandleBrokenEndian  (uint16_t &group, uint16_t &elem);
178    void HandleOutOfGroup0002(uint16_t &group, uint16_t &elem);
179
180 // Variables
181    /// Public dictionary used to parse this header
182    Dict *RefPubDict;
183    /// \brief Optional "shadow dictionary" (private elements) used to parse
184    /// this header
185    Dict *RefShaDict;
186
187    /// \brief Size threshold above which an element value will NOT be loaded
188    /// in memory (to avoid loading the image/volume itself). By default,
189    /// this upper bound is fixed to 1024 bytes (which might look reasonable
190    /// when one considers the definition of the various VR contents).
191    uint32_t MaxSizeLoadEntry;
192    
193    /// \brief Size threshold above which an element value will NOT be *printed*
194    /// in order no to polute the screen output. By default, this upper bound
195    /// is fixed to 64 bytes.
196    uint32_t MaxSizePrintEntry;   
197
198 //  uint32_t GenerateFreeTagKeyInGroup(uint16_t group);
199 //  void BuildFlatHashTableRecurse( TagDocEntryHT &builtHT,
200 //                                   DocEntrySet *set );
201 };
202
203 } // end namespace gdcm
204
205 //-----------------------------------------------------------------------------
206 #endif