internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { //Covered by PS 3.5, Chapter 7.5 (pg. 42-45) bool encapImage = (Tag == DICOMTags.PixelData); bool done = false; uint count = 0; while (!done) { //If explicit length, see if we're done if (length != 0xFFFFFFFF && count >= length) { done = true; continue; } ushort grp = br.ReadUInt16(); ushort elem = br.ReadUInt16(); uint len = br.ReadUInt32(); count += 8; //Sometimes there's retarded files that are msb swapped inside of sequences outside of the transfer syntax bool needMoreSwap = (grp == 0xFEFF); if (needMoreSwap) { //Swap the reader for now, then swap back after the sqitem br.ToggleSwapped(); //still have to swap the stuff we've already read by hand tho grp = MSBSwapper.SwapW(grp); elem = MSBSwapper.SwapW(elem); len = MSBSwapper.SwapDW(len); } if (grp == 0xFFFE && elem == 0xE000) { //Normal element, parse it out. SQItem item = new SQItem(this); count += item.ParseStream(br, logger, transferSyntax, len, encapImage); Items.Add(item); } else if (grp == 0xFFFE && elem == 0xE0DD) { //End element //In case there's garbage in there, read the length bytes br.ReadBytes((int)len); count += len; done = true; } else { throw new NotImplementedException(); } //toggle back in case it's just one SQItem that's hosed if (needMoreSwap) { br.ToggleSwapped(); } } return(count); }
//parseLen returns total bytes read internal static DICOMElement Parse(ushort group, ushort elem, ILogger logger, TransferSyntax transferSyntax, SwappableBinaryReader br, SQItem parentSQ, bool skipOverData, out uint parseLen) { ushort vr; uint len; uint headerBytes = 0; // Group 0 is always little-endian implicit vr, group 2 is always little-endian explicit vr if ((transferSyntax.ExplicitVR && group != 0) || group == 2) { vr = br.ReadUInt16MSB(); headerBytes += 2; if (vr == DICOMElementUT.vrshort || vr == DICOMElementUN.vrshort || vr == DICOMElementOB.vrshort || vr == DICOMElementOW.vrshort || vr == DICOMElementSQ.vrshort) { //next 2 bytes reserved br.ReadUInt16(); headerBytes += 2; //len is next 4 len = br.ReadUInt32(); headerBytes += 4; } else { //len is next 2 len = br.ReadUInt16(); headerBytes += 2; } } else { //Look up VR in the dictionary DataDictionaryElement dde = DataDictionary.LookupElement(group, elem); if (dde != null) { //Found it. vr = dde.vrshort; } else { //No idea... OB! vr = DICOMElementOB.vrshort; } //Length will always be 32-bit here len = br.ReadUInt32(); headerBytes += 4; } DICOMElement ret = null; //Is it a compressed weirdo image data sequence that's actually an SQ? if (len == 0xFFFFFFFF) { ret = new DICOMElementSQ(group, elem); } else { ret = CreateByVR(group, elem, vr); } ret.parentSQItem = parentSQ; //Parse internal Data parseLen = headerBytes; try { // Can't skip over the length if it's not explicit if (skipOverData && len != 0xFFFFFFFF) { parseLen += len; br.BaseStream.Seek(len, SeekOrigin.Current); } else { parseLen += ret.ParseData(br, logger, len, transferSyntax); } } catch (Exception e) { logger.Log(LogLevel.Error, "Exception in ParseData(grp=" + group + ", elem=" + elem + ", len=" + len + "): " + e.ToString()); } return(ret); }