/// <summary> /// Returns a new DICOMElement based on the listed group and element. It looks up the element in the data dictionary /// to figure out the correct VR for the tag, and creates the proper DICOM Element type. /// </summary> /// <param name="group">DICOM Group Tag</param> /// <param name="elem">DICOM Element Tag</param> /// <returns>A DICOMElement encapsulating the specified Group and Element</returns> public static DICOMElement CreateFromGroupElem(ushort group, ushort elem) { DataDictionaryElement dde = DataDictionary.LookupElement(group, elem); if (dde != null) { return(CreateByVR(dde.Group, dde.Elem, dde.vrshort)); } else { return(CreateByVR(group, elem, DICOMElementOB.vrshort)); } }
/// <summary> /// Returns a new DICOMElement based on the listed tag from <see cref="DICOMTags"/> /// </summary> /// <param name="tag">A DICOM Tag from <see cref="DICOMTags"/></param> /// <returns>A new DICOMElement encapsulating the specified Tag</returns> public static DICOMElement CreateFromTag(uint tag) { DataDictionaryElement dde = DataDictionary.LookupElement(tag); if (dde != null) { return(CreateByVR(dde.Group, dde.Elem, dde.vrshort)); } else { return(CreateByVR((ushort)(tag << 16), (ushort)tag, DICOMElementOB.vrshort)); } }
internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { if (length < 2) { //busted... data = (ushort)0; br.ReadBytes((int)length); } else if (length == 2) { data = br.ReadUInt16(); } else if (length > 2) { uint readBytes = 0; DataDictionaryElement elemCheck = DataDictionary.LookupElement(this.Tag); if (elemCheck == null || elemCheck.VMMax > 1) { //Unknown VM or VM goes to > 1 data = new ushort[length / 2]; for (int i = 0; i < length / 2; i++) { ((ushort[])data)[i] = br.ReadUInt16(); } readBytes = (length / 2) * 2; } else { //VM of 1 -- force to single data point data = br.ReadUInt16(); readBytes = 2; } if (length - readBytes > 0) { br.ReadBytes((int)(length - readBytes)); } } return(length); }
//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); }