internal uint ParseStream(SwappableBinaryReader br, ILogger logger, TransferSyntax transferSyntax, uint length, bool encapImage) { IsEncapsulatedImage = encapImage; if (encapImage && length != 0xFFFFFFFF) { //Encapsulated Image with explicit length! EncapsulatedImageData = br.ReadBytes((int)length); //Any way to figure out if we need to MSB-swap this? (i.e. is it an OW or an OB? Does that come from the parent element?) return(length); } bool done = false; uint count = 0; while (!done) { //Check if we're past the end yet if (length != 0xFFFFFFFF && count >= length) { done = true; continue; } long readPosition = br.BaseStream.Position; //Read in group/element info ushort group = br.ReadUInt16(); ushort elem = br.ReadUInt16(); count += 4; //Make element uint outLen; DICOMElement nelem = DICOMElement.Parse(group, elem, logger, transferSyntax, br, this, false, out outLen); //Store reading position in case it's useful later nelem.ReadPosition = readPosition; count += outLen; //Was that the end-of-sequence item? if (group == 0xFFFE && elem == 0xE00D) { done = true; } else { ElementsLookup[nelem.Tag] = nelem; Elements.Add(nelem); } } return(count); }
/// <summary> /// Returns a new DICOMElement object of the correct VR, using the specified Group and Element /// </summary> /// <param name="group">A DICOM Group Tag</param> /// <param name="elem">A DICOM Element Tag</param> /// <param name="vr">A DICOM Value Representation (VR), a two character string</param> /// <returns>A new DICOMElement encapsulating theh specified group, element, and VR.</returns> public static DICOMElement CreateByVR(ushort group, ushort elem, ushort vr) { DICOMElement ret = null; if (vr == DICOMElementAE.vrshort) { ret = new DICOMElementAE(group, elem); } else if (vr == DICOMElementAS.vrshort) { ret = new DICOMElementAE(group, elem); } else if (vr == DICOMElementAT.vrshort) { ret = new DICOMElementAT(group, elem); } else if (vr == DICOMElementCS.vrshort) { ret = new DICOMElementCS(group, elem); } else if (vr == DICOMElementDA.vrshort) { ret = new DICOMElementDA(group, elem); } else if (vr == DICOMElementDS.vrshort) { ret = new DICOMElementDS(group, elem); } else if (vr == DICOMElementDT.vrshort) { ret = new DICOMElementDT(group, elem); } else if (vr == DICOMElementFD.vrshort) { ret = new DICOMElementFD(group, elem); } else if (vr == DICOMElementFL.vrshort) { ret = new DICOMElementFL(group, elem); } else if (vr == DICOMElementIS.vrshort) { ret = new DICOMElementIS(group, elem); } else if (vr == DICOMElementLO.vrshort) { ret = new DICOMElementLO(group, elem); } else if (vr == DICOMElementLT.vrshort) { ret = new DICOMElementLT(group, elem); } else if (vr == DICOMElementOB.vrshort) { ret = new DICOMElementOB(group, elem); } else if (vr == DICOMElementOW.vrshort) { ret = new DICOMElementOW(group, elem); } else if (vr == DICOMElementPN.vrshort) { ret = new DICOMElementPN(group, elem); } else if (vr == DICOMElementSH.vrshort) { ret = new DICOMElementSH(group, elem); } else if (vr == DICOMElementSL.vrshort) { ret = new DICOMElementSL(group, elem); } else if (vr == DICOMElementSQ.vrshort) { ret = new DICOMElementSQ(group, elem); } else if (vr == DICOMElementSS.vrshort) { ret = new DICOMElementSS(group, elem); } else if (vr == DICOMElementST.vrshort) { ret = new DICOMElementST(group, elem); } else if (vr == DICOMElementTM.vrshort) { ret = new DICOMElementTM(group, elem); } else if (vr == DICOMElementUI.vrshort) { ret = new DICOMElementUI(group, elem); } else if (vr == DICOMElementUL.vrshort) { ret = new DICOMElementUL(group, elem); } else if (vr == DICOMElementUN.vrshort) { ret = new DICOMElementUN(group, elem); } else if (vr == DICOMElementUS.vrshort) { ret = new DICOMElementUS(group, elem); } else if (vr == DICOMElementUT.vrshort) { ret = new DICOMElementUT(group, elem); } else { ret = new DICOMElementOB(group, elem); //fall back to OB } return(ret); }
//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); }