- // The only guaranted way of finding the swap code is to find a
- // group tag since we know it's length has to be of four bytes i.e.
- // 0x00000004. Finding the swap code in then straigthforward. Trouble
- // occurs when we can't find such group...
- guint32 s;
- guint32 x=4; // x : pour ntohs
- bool net2host; // true when HostByteOrder is the same as NetworkByteOrder
-
- int lgrLue;
- char * entCur;
- char deb[HEADER_LENGTH_TO_READ];
-
- // First, compare HostByteOrder and NetworkByteOrder in order to
- // determine if we shall need to swap bytes (i.e. the Endian type).
- if (x==ntohs(x))
- net2host = true;
- else
- net2host = false;
-
- // The easiest case is the one of a DICOM header, since it possesses a
- // file preamble where it suffice to look for the string "DICM".
- lgrLue = fread(deb, 1, HEADER_LENGTH_TO_READ, fp);
-
- entCur = deb + 128;
- if(memcmp(entCur, "DICM", (size_t)4) == 0) {
- dbg.Verbose(1, "gdcmHeader::CheckSwap:", "looks like DICOM Version3");
- // Next, determine the value representation (VR). Let's skip to the
- // first element (0002, 0000) and check there if we find "UL"
- // - or "OB" if the 1st one is (0002,0001) -,
- // in which case we (almost) know it is explicit VR.
- // WARNING: if it happens to be implicit VR then what we will read
- // is the length of the group. If this ascii representation of this
- // length happens to be "UL" then we shall believe it is explicit VR.
- // FIXME: in order to fix the above warning, we could read the next
- // element value (or a couple of elements values) in order to make
- // sure we are not commiting a big mistake.
- // We need to skip :
- // * the 128 bytes of File Preamble (often padded with zeroes),
- // * the 4 bytes of "DICM" string,
- // * the 4 bytes of the first tag (0002, 0000),or (0002, 0001)
- // i.e. a total of 136 bytes.
- entCur = deb + 136;
- // FIXME
- // Use gdcmHeader::dicom_vr to test all the possibilities
- // instead of just checking for UL, OB and UI !?
- if( (memcmp(entCur, "UL", (size_t)2) == 0) ||
- (memcmp(entCur, "OB", (size_t)2) == 0) ||
- (memcmp(entCur, "UI", (size_t)2) == 0) )
- {
- filetype = ExplicitVR;
- dbg.Verbose(1, "gdcmHeader::CheckSwap:",
- "explicit Value Representation");
- } else {
- filetype = ImplicitVR;
- dbg.Verbose(1, "gdcmHeader::CheckSwap:",
- "not an explicit Value Representation");
- }
-
- if (net2host) {
- sw = 4321;
- dbg.Verbose(1, "gdcmHeader::CheckSwap:",
- "HostByteOrder != NetworkByteOrder");
- } else {
- sw = 0;
- dbg.Verbose(1, "gdcmHeader::CheckSwap:",
- "HostByteOrder = NetworkByteOrder");
- }
-
- // Position the file position indicator at first tag (i.e.
- // after the file preamble and the "DICM" string).
- rewind(fp);
- fseek (fp, 132L, SEEK_SET);
- return;
- } // End of DicomV3
-
- // Alas, this is not a DicomV3 file and whatever happens there is no file
- // preamble. We can reset the file position indicator to where the data
- // is (i.e. the beginning of the file).
- dbg.Verbose(1, "gdcmHeader::CheckSwap:", "not a DICOM Version3 file");
- rewind(fp);
-
- // Our next best chance would be to be considering a 'clean' ACR/NEMA file.
- // By clean we mean that the length of the first tag is written down.
- // If this is the case and since the length of the first group HAS to be
- // four (bytes), then determining the proper swap code is straightforward.
-
- entCur = deb + 4;
- // We assume the array of char we are considering contains the binary
- // representation of a 32 bits integer. Hence the following dirty
- // trick :
- s = *((guint32 *)(entCur));
-
- switch (s) {
- case 0x00040000 :
- sw = 3412;
- filetype = ACR;
- return;
- case 0x04000000 :
- sw = 4321;
- filetype = ACR;
- return;
- case 0x00000400 :
- sw = 2143;
- filetype = ACR;
- return;
- case 0x00000004 :
- sw = 0;
- filetype = ACR;
- return;
- default :
- dbg.Verbose(0, "gdcmHeader::CheckSwap:",
- "ACR/NEMA unfound swap info (time to raise bets)");
- }
-
- // We are out of luck. It is not a DicomV3 nor a 'clean' ACR/NEMA file.
- // It is time for despaired wild guesses. So, let's assume this file
- // happens to be 'dirty' ACR/NEMA, i.e. the length of the group is
- // not present. Then the only info we have is the net2host one.
- filetype = Unknown;
- if (! net2host )
- sw = 0;
- else
- sw = 4321;
- return;
-}
-
-void gdcmHeader::SwitchSwapToBigEndian(void) {
- dbg.Verbose(1, "gdcmHeader::SwitchSwapToBigEndian",
- "Switching to BigEndian mode.");
- if ( sw == 0 ) {
- sw = 4321;
- return;
- }
- if ( sw == 4321 ) {
- sw = 0;
- return;
- }
- if ( sw == 3412 ) {
- sw = 2143;
- return;