2 //-----------------------------------------------------------------------------
4 #include "gdcmElementSet.h"
8 //-----------------------------------------------------------------------------
9 // Constructor / Destructor
11 * \ingroup gdcmElementSet
12 * \brief Constructor from a given gdcmElementSet
14 gdcmDocEntrySet::gdcmDocEntrySet() {
19 * \ingroup gdcmElementSet
20 * \brief Canonical destructor.
22 gdcmElementSet::~gdcmElementSet()
24 /* for(tous les DocEntry)
32 //-----------------------------------------------------------------------------
36 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
43 * \brief Find the value Length of the passed Header Entry
44 * @param Entry Header Entry whose length of the value shall be loaded.
46 void gdcmElementSet::FindDocEntryLength (gdcmDocEntry *Entry) {
47 guint16 element = Entry->GetElement();
48 //guint16 group = Entry->GetGroup(); //FIXME
49 std::string vr = Entry->GetVR();
53 if ( (filetype == ExplicitVR) && (! Entry->IsImplicitVR()) )
55 if ( (vr=="OB") || (vr=="OW") || (vr=="SQ") || (vr=="UN") )
57 // The following reserved two bytes (see PS 3.5-2001, section
58 // 7.1.2 Data element structure with explicit vr p27) must be
59 // skipped before proceeding on reading the length on 4 bytes.
60 fseek(fp, 2L, SEEK_CUR);
61 guint32 length32 = ReadInt32();
63 if ( (vr == "OB") && (length32 == 0xffffffff) )
65 Entry->SetLength(FindHeaderEntryLengthOB());
68 FixHeaderEntryFoundLength(Entry, length32);
72 // Length is encoded on 2 bytes.
73 length16 = ReadInt16();
75 // We can tell the current file is encoded in big endian (like
76 // Data/US-RGB-8-epicard) when we find the "Transfer Syntax" tag
77 // and it's value is the one of the encoding of a big endian file.
78 // In order to deal with such big endian encoded files, we have
79 // (at least) two strategies:
80 // * when we load the "Transfer Syntax" tag with value of big endian
81 // encoding, we raise the proper flags. Then we wait for the end
82 // of the META group (0x0002) among which is "Transfer Syntax",
83 // before switching the swap code to big endian. We have to postpone
84 // the switching of the swap code since the META group is fully encoded
85 // in little endian, and big endian coding only starts at the next
86 // group. The corresponding code can be hard to analyse and adds
87 // many additional unnecessary tests for regular tags.
88 // * the second strategy consists in waiting for trouble, that shall
89 // appear when we find the first group with big endian encoding. This
90 // is easy to detect since the length of a "Group Length" tag (the
91 // ones with zero as element number) has to be of 4 (0x0004). When we
92 // encounter 1024 (0x0400) chances are the encoding changed and we
93 // found a group with big endian encoding.
94 // We shall use this second strategy. In order to make sure that we
95 // can interpret the presence of an apparently big endian encoded
96 // length of a "Group Length" without committing a big mistake, we
97 // add an additional check: we look in the already parsed elements
98 // for the presence of a "Transfer Syntax" whose value has to be "big
99 // endian encoding". When this is the case, chances are we have got our
100 // hands on a big endian encoded file: we switch the swap code to
101 // big endian and proceed...
102 if ( (element == 0x0000) && (length16 == 0x0400) )
104 if ( ! IsExplicitVRBigEndianTransferSyntax() )
106 dbg.Verbose(0, "gdcmDocument::FindLength", "not explicit VR");
111 SwitchSwapToBigEndian();
112 // Restore the unproperly loaded values i.e. the group, the element
113 // and the dictionary entry depending on them.
114 guint16 CorrectGroup = SwapShort(Entry->GetGroup());
115 guint16 CorrectElem = SwapShort(Entry->GetElement());
116 gdcmDictEntry * NewTag = GetDictEntryByNumber(CorrectGroup,
120 // This correct tag is not in the dictionary. Create a new one.
121 NewTag = NewVirtualDictEntry(CorrectGroup, CorrectElem);
123 // FIXME this can create a memory leaks on the old entry that be
124 // left unreferenced.
125 Entry->SetDictEntry(NewTag);
128 // Heuristic: well some files are really ill-formed.
129 if ( length16 == 0xffff)
132 //dbg.Verbose(0, "gdcmDocument::FindLength",
133 // "Erroneous element length fixed.");
134 // Actually, length= 0xffff means that we deal with
135 // Unknown Sequence Length
137 FixHeaderEntryFoundLength(Entry, (guint32)length16);
142 // Either implicit VR or a non DICOM conformal (see note below) explicit
143 // VR that ommited the VR of (at least) this element. Farts happen.
144 // [Note: according to the part 5, PS 3.5-2001, section 7.1 p25
145 // on Data elements "Implicit and Explicit VR Data Elements shall
146 // not coexist in a Data Set and Data Sets nested within it".]
147 // Length is on 4 bytes.
149 FixHeaderEntryFoundLength(Entry, ReadInt32());