If I write a 16-bit integer as a literal like &h7FE0 in the IDE, why (in the debugger) do I get the decimal value 32736?
Is the nomenclature in big or little endian? If the IDE is running on a little endian machine (which they all are), which run of bytes is represented by &h7FE0?
Byte position
-------------
0 1
7F E0
or
Byte position
-------------
0 1
E0 7F
I had assumed that literals were taken in big endian format?
I’m trying to read a very complex binary file (a DICOM file - a medical image file). These can be encoded as either little or big endian (this is known in advance).
One part of the file format species a two byte group number followed immediately by a two byte element number. I’ve opened up a file in a hex editor and I can see that the (group, element) (0002, 0012) is represented in the file as:
02 00 12 00
I know this is little endian encoded.
Where I am a little confused is that I need to grab these 4 bytes (easy) and then compare them to a giant table of known (group, element) combinations. Should I compare this with &h00020012 or &h02001200?
you need to look at transfer syntax uid. I believe the encoding is always the same. From TS, you should be able to see if the TS is big-indian or little-indian for the dicom file.
“By default the DICOM object(s) returned shall be encoded in Explicit VR Little Endian. Neither Implicit VR, nor Big Endian shall be used. The response shall be the Transfer Syntax requested if possible. If it is not possible for the response to be sent using the requested transfer syntax then the Explicit VR Little Endian Uncompressed Transfer Syntax shall be used, unless the pixel data in its compressed form is of such length that it cannot be encoded in the Explicit VR Little Endian Uncompressed Transfer Syntax.”
So always read the literal &h in my head in big endian notation but just be sure to set the .LittleEndian flag on BinaryStreams and MemoryBlocks before pulling out the value. Right?
here is a snippet from my dicom class to check header
dim bs as BinaryStream
if dicomFile.Locked = true or dicomFile.IsReadable = false then return false ' check to see if file is readable
bs = BinaryStream.Open(dicomFile,false) ' Read file to memory
dicomMB = bs.read(bs.Length)
bs.Close
dicomMB = dicomMB.MidB(128, dicomMB.Size - 128)
dicomMB.LittleEndian = true
read("TransferSyntaxUID")
ts = vf
vf = ""
if dicomMB.StringValue(0,4) = "DICM" then ' Check for DICM in Header
return true
else
return false
end if
exception ' Error Handling
return false
in other snippets of my code I have
if ts <> "1.2.840.10008.1.2.2" or (ts = "1.2.840.10008.1.2.2" and group = "0002") then ' Little Endian Detected
dicomMB.LittleEndian = true
return val("&h" + element + group)
end if
if ts = "1.2.840.10008.1.2.2" and group <> "0002" then ' Big Endian Detected
dicomMB.LittleEndian = false
return val("&h" + group + element)
end if
Yeah basically when you set little endian and then read a memoryblock Uint16 etc the little endian property says “do these byte swapping things BEFORE you give the value back to the user in big endian format”
If you set the endianness of the memoryblock correctly initially you just use Uint16 and compare to &h < hex in big endian > and you’re fine
the BIGGEST problem with dicom is that there is a standard… and with that standard is, everyone has their own interpretation to the standard. Also, dont get me started on a rant about accession numbers
actually… worse than that are companies who store images not as dicom… it still goes on to this day. Recently, I have the privilege of dealing with a legacy vendor who likes to stack images into one file and then say only they can open it… I didnt have the heart to tell them that I built a tool that could.