]> Creatis software - gdcm.git/blob - src/gdcmDocument.h
* CLEANUP_ROUND (5) for gdcmPixelConvert (Upshit creek without a paddle)
[gdcm.git] / src / gdcmDocument.h
1 /*=========================================================================
2  
3   Program:   gdcm
4   Module:    $RCSfile: gdcmDocument.h,v $
5   Language:  C++
6   Date:      $Date: 2004/10/06 21:30:02 $
7   Version:   $Revision: 1.47 $
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 "gdcmCommon.h"
23 #include "gdcmVR.h"
24 #include "gdcmTS.h"
25 #include "gdcmException.h"
26 #include "gdcmDictSet.h"
27 #include "gdcmDocEntry.h"
28 #include "gdcmRLEFramesInfo.h"
29
30 class gdcmValEntry;
31 class gdcmBinEntry;
32 class gdcmSeqEntry;
33
34 #include "gdcmDocEntrySet.h"
35 #include "gdcmElementSet.h"
36
37 #include <map>
38 #include <list>
39
40 //-----------------------------------------------------------------------------
41 /**
42  * \brief Derived by both gdcmHeader and gdcmDicomDir
43  */
44 class GDCM_EXPORT gdcmDocument : public gdcmElementSet
45 {
46 friend class gdcmFile;
47 private:
48    /// Public dictionary used to parse this header
49    gdcmDict *RefPubDict;
50    
51    /// \brief Optional "shadow dictionary" (private elements) used to parse
52    /// this header
53    gdcmDict *RefShaDict;
54
55    /// \brief Size threshold above which an element value will NOT be loaded
56    /// in memory (to avoid loading the image/volume itself). By default,
57    /// this upper bound is fixed to 1024 bytes (which might look reasonable
58    /// when one considers the definition of the various VR contents).
59    uint32_t MaxSizeLoadEntry;
60    
61    /// \brief Size threshold above which an element value will NOT be *printed*
62    /// in order no to polute the screen output. By default, this upper bound
63    /// is fixed to 64 bytes.
64    uint32_t MaxSizePrintEntry;   
65
66 protected:
67    /// Refering underlying filename.
68    std::string Filename;
69
70    /// \brief SWap code (e.g. Big Endian, Little Endian, Bad Big Endian,
71    /// Bad Little Endian) according to the processor Endianity and
72    /// what is written on disc.
73    int SwapCode;
74
75    /// File Pointer, opened during Header parsing.
76    FILE *Fp;
77
78    /// ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown
79    FileType Filetype;  
80
81    /// After opening the file, we read HEADER_LENGTH_TO_READ bytes.
82    static const unsigned int HEADER_LENGTH_TO_READ; 
83
84    /// \brief Elements whose value is longer than MAX_SIZE_LOAD_ELEMENT_VALUE
85    /// are NOT loaded.
86    static const unsigned int MAX_SIZE_LOAD_ELEMENT_VALUE;
87
88    /// \brief Elements whose value is longer than  MAX_SIZE_PRINT_ELEMENT_VALUE
89    /// are NOT printed.
90    /// \todo Currently not used since collides with #define in
91    ///       \ref gdcmDocEntry.cxx. See also
92    ///       \ref gdcmDocument::SetMaxSizePrintEntry()
93    static const unsigned int MAX_SIZE_PRINT_ELEMENT_VALUE;
94
95    /// Store the RLE frames info obtained during parsing of pixels.
96    gdcmRLEFramesInfo RLEInfo;
97
98    /// \brief Amount of printed details for each Header Entry (Dicom Element):
99    /// 0 : stands for the least detail level.
100    int PrintLevel;
101    
102 public:
103 // the 2 following will be merged
104    virtual void PrintPubDict (std::ostream &os = std::cout);
105    virtual void PrintShaDict (std::ostream &os = std::cout);
106
107 // Dictionnaries
108    gdcmDict *GetPubDict();
109    gdcmDict *GetShaDict();
110    bool SetShaDict(gdcmDict *dict);
111    bool SetShaDict(DictKey const & dictName);
112
113 // Informations contained in the parser
114    virtual bool IsReadable();
115    bool IsGivenTransferSyntax(std::string const & syntaxToCheck);
116    bool IsImplicitVRLittleEndianTransferSyntax();
117    bool IsExplicitVRLittleEndianTransferSyntax();
118    bool IsDeflatedExplicitVRLittleEndianTransferSyntax();
119    bool IsExplicitVRBigEndianTransferSyntax();
120    bool IsJPEGBaseLineProcess1TransferSyntax();
121    bool IsJPEGExtendedProcess2_4TransferSyntax();
122    bool IsJPEGExtendedProcess3_5TransferSyntax();
123    bool IsJPEGSpectralSelectionProcess6_8TransferSyntax();
124    bool IsRLELossLessTransferSyntax();
125    bool IsJPEGLossless();
126    bool IsJPEG2000();
127    bool IsEncapsulateTransferSyntax();
128    bool IsDicomV3();
129
130    FileType GetFileType();
131
132    FILE* OpenFile();
133    bool CloseFile();
134
135    void Write(FILE* fp, FileType type);
136
137    gdcmValEntry* ReplaceOrCreateByNumber(std::string const & value,
138                                          uint16_t group, uint16_t elem,
139                                          std::string const & VR ="unkn");
140    
141    gdcmBinEntry* ReplaceOrCreateByNumber(uint8_t* binArea, int lgth,
142                                          uint16_t group, uint16_t elem,
143                                          std::string const & VR="unkn");
144
145    gdcmSeqEntry* ReplaceOrCreateByNumber(uint16_t group, uint16_t elem);
146
147    bool ReplaceIfExistByNumber ( std::string const & value,
148                                  uint16_t group,
149                                  uint16_t elem );
150    
151    virtual void* LoadEntryBinArea(uint16_t group, uint16_t elem);
152    virtual void* LoadEntryBinArea(gdcmBinEntry* entry);
153       
154    // System access (meaning endian related !?)
155    uint16_t SwapShort(uint16_t);   // needed by gdcmFile
156    uint32_t SwapLong(uint32_t);    // needed by gdcmFile
157    uint16_t UnswapShort(uint16_t); // needed by gdcmFile
158    uint32_t UnswapLong(uint32_t);  // needed by gdcmFile
159
160 protected:
161    // Constructor and destructor are protected to forbid end user 
162    // to instanciate from this class gdcmDocument (only gdcmHeader and
163    // gdcmDicomDir are meaningfull).
164    gdcmDocument();
165    gdcmDocument( std::string const & filename );
166    virtual ~gdcmDocument();
167    
168    void ComputeRLEInfo();
169    // Entry
170    bool CheckIfEntryExistByNumber(uint16_t group, uint16_t elem );
171 public:
172    virtual std::string GetEntryByName    (TagName const & tagName);
173    virtual std::string GetEntryVRByName  (TagName const & tagName);
174    virtual std::string GetEntryByNumber  (uint16_t group, uint16_t elem);
175    virtual std::string GetEntryVRByNumber(uint16_t group, uint16_t elem);
176    virtual int     GetEntryLengthByNumber(uint16_t group, uint16_t elem);
177 //protected:
178    virtual bool SetEntryByName  (std::string const & content, 
179                                  std::string const & tagName);
180    virtual bool SetEntryByNumber(std::string const & content,
181                                  uint16_t group, uint16_t element);
182    virtual bool SetEntryByNumber(uint8_t* content, int lgth,
183                                  uint16_t group, uint16_t element);
184    virtual bool SetEntryLengthByNumber(uint32_t length,
185                                        uint16_t group, uint16_t element);
186
187    virtual size_t GetEntryOffsetByNumber (uint16_t group, uint16_t elem);
188    virtual void* GetEntryBinAreaByNumber(uint16_t group, uint16_t elem);   
189    virtual bool  SetEntryBinAreaByNumber(uint8_t* a, uint16_t group,
190                                                    uint16_t elem);
191
192    virtual void UpdateShaEntries();
193
194    // Header entry
195    gdcmDocEntry* GetDocEntryByNumber(uint16_t group, uint16_t element); 
196    gdcmDocEntry* GetDocEntryByName  (std::string const & tagName);
197
198    gdcmValEntry* GetValEntryByNumber(uint16_t group, uint16_t element); 
199    //gdcmBinEntry* GetBinEntryByNumber(uint16_t group, uint16_t element); 
200
201    void LoadDocEntrySafe(gdcmDocEntry* entry);
202    TagDocEntryHT* BuildFlatHashTable();
203
204 private:
205    // Read
206    void ParseDES(gdcmDocEntrySet *set,long offset, long l_max, bool delim_mode);
207    void ParseSQ (gdcmSeqEntry *seq,   long offset, long l_max, bool delim_mode);
208
209    void LoadDocEntry      (gdcmDocEntry *);
210    void FindDocEntryLength(gdcmDocEntry *) throw ( gdcmFormatError );
211    void FindDocEntryVR    (gdcmDocEntry *);
212    bool CheckDocEntryVR   (gdcmDocEntry *, gdcmVRKey);
213
214    std::string GetDocEntryValue  (gdcmDocEntry *);
215    std::string GetDocEntryUnvalue(gdcmDocEntry *);
216
217    void SkipDocEntry          (gdcmDocEntry *);
218    void SkipToNextDocEntry    (gdcmDocEntry *);
219
220    void FixDocEntryFoundLength(gdcmDocEntry *, uint32_t);
221    bool IsDocEntryAnInteger   (gdcmDocEntry *);
222
223    uint32_t FindDocEntryLengthOB() throw( gdcmFormatUnexpected );
224
225    uint16_t ReadInt16() throw ( gdcmFormatError );
226    uint32_t ReadInt32() throw ( gdcmFormatError );
227    void     SkipBytes(uint32_t);
228    bool     ReadTag(uint16_t, uint16_t);
229    uint32_t ReadTagLength(uint16_t, uint16_t);
230
231    void Initialise();
232    bool CheckSwap();
233    void SwitchSwapToBigEndian();
234    void SetMaxSizeLoadEntry(long);
235    void SetMaxSizePrintEntry(long);
236
237    // DocEntry related utilities
238    gdcmDocEntry* ReadNextDocEntry();
239
240    uint32_t GenerateFreeTagKeyInGroup(uint16_t group);
241    void BuildFlatHashTableRecurse( TagDocEntryHT& builtHT,
242                                    gdcmDocEntrySet* set );
243
244
245 public:
246 // Accessors:
247    /// Accessor to \ref PrintLevel
248    void SetPrintLevel(int level) { PrintLevel = level; }
249
250    /// Accessor to \ref Filename
251    const std::string &GetFileName() { return Filename; }
252
253    /// Accessor to \ref Filename
254    void SetFileName(std::string const & fileName) { Filename = fileName; }
255
256    /// 'Swap code' accessor (see \ref SwapCode )
257    int GetSwapCode() { return SwapCode; }
258    
259    /// File pointer
260    FILE * GetFP() { return Fp; }
261
262    bool operator<(gdcmDocument &document);
263
264 };
265
266 //-----------------------------------------------------------------------------
267 #endif