public void SerializeAndDeserializePrivateTags() { var privCreatorDictEntry = new DicomDictionaryEntry(new DicomTag(0x0011, 0x0010), "Private Creator", "PrivateCreator", DicomVM.VM_1, false, DicomVR.LO); DicomDictionary.Default.Add(privCreatorDictEntry); DicomPrivateCreator privateCreator1 = DicomDictionary.Default.GetPrivateCreator("TESTCREATOR1"); DicomDictionary privDict1 = DicomDictionary.Default[privateCreator1]; var dictEntry = new DicomDictionaryEntry(DicomMaskedTag.Parse("0011", "xx01"), "TestPrivTagName", "TestPrivTagKeyword", DicomVM.VM_1, false, DicomVR.CS); privDict1.Add(dictEntry); var ds = new DicomDataset(); ds.Add(dictEntry.Tag, "VAL1"); ds.Add(DicomTag.SOPClassUID, DicomUID.CTImageStorage); ds.Add(DicomTag.SOPInstanceUID, "2.25.123"); Assert.Equal(DicomVR.CS, ds.Get <DicomVR>(dictEntry.Tag)); var bytes = SerializeDicom_(ds); File.OpenWrite("C:\\Temp\\x.dcm").Write(bytes, 0, bytes.Length); var ds2 = ParseDicom_(bytes); Assert.Equal(DicomVR.CS, ds2.Get <DicomVR>(dictEntry.Tag)); }
public void GetPrivateTagsChangesNothingWhenPresent() { DicomPrivateCreator privateCreator = DicomDictionary.Default.GetPrivateCreator("TESTCREATOR"); DicomDictionary privDict = DicomDictionary.Default[privateCreator]; var privTag = new DicomDictionaryEntry(DicomMaskedTag.Parse("0011", "xx10"), "TestPrivTagName", "TestPrivTagKeyword", DicomVM.VM_1, false, DicomVR.DT); privDict.Add(privTag); var dataSet = new DicomDataset { { DicomTag.SOPInstanceUID, "2.999.1241" }, { DicomTag.SOPClassUID, "2.999.1242" }, { privTag.Tag, "19700101123456" } }; var dataBefore = SerializeDicom_(dataSet); var val = dataSet.Get <string>(privTag.Tag); var dataAfter = SerializeDicom_(dataSet); Assert.Equal(dataBefore, dataAfter); Assert.Equal(val, "19700101123456"); }
private static DicomTag ParseDicomTagNumber(string s) { // When composed with number, length could only be 8 if (s.Length != 8) { return(null); } if (!ushort.TryParse(s.AsSpan(0, 4), NumberStyles.HexNumber, null, out ushort group)) { return(null); } if (!ushort.TryParse(s.AsSpan(4, 4), NumberStyles.HexNumber, null, out ushort element)) { return(null); } var dicomTag = new DicomTag(group, element); DicomDictionaryEntry knownTag = DicomDictionary.Default[dicomTag]; // Check if the tag is null or unknown. // Tag with odd group is considered as private. if (knownTag == null || (!dicomTag.IsPrivate && knownTag == DicomDictionary.UnknownTag)) { return(null); } return(dicomTag); }
private void ResetState() { _state = ParseState.Tag; _tag = null; _entry = null; _vr = null; _length = 0; }
private void ResetState() { this.parseStage = ParseStage.Tag; this._tag = null; this._entry = null; this._vr = null; this.length = 0; }
private bool ParseTag(IByteSource source) { if (_parseStage == ParseStage.Tag) { source.Mark(); if (!source.Require(4)) { _result = DicomReaderResult.Suspended; return(false); } var group = source.GetUInt16(); var element = source.GetUInt16(); DicomPrivateCreator creator = null; // according to // http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_7.8.html // The requirements of this section do not allow any use of elements in the ranges // (gggg,0001-000F) and (gggg,0100-0FFF) where gggg is odd. // So element at [0x0100-0x0FFF] should not has a creator if (@group.IsOdd() && element >= 0x1000) { var card = (uint)(@group << 16) + (uint)(element >> 8); lock (_locker) { if (_private.TryGetValue(card, out string pvt)) { creator = _dictionary.GetPrivateCreator(pvt); } } } _tag = new DicomTag(@group, element, creator); _entry = _dictionary[_tag]; if (!_tag.IsPrivate && _entry != null && _entry.MaskTag == null) { _tag = _entry.Tag; // Use dictionary tag } if (_stop != null && _stop(new ParseState { Tag = _tag, SequenceDepth = _sequenceDepth })) { _result = DicomReaderResult.Stopped; return(false); } _parseStage = ParseStage.VR; } return(true); }
public void AddTagAndReadOut() { var dict = new DicomDictionary(); var tag = new DicomTag(0x0010, 0x0020); var dictEntry = new DicomDictionaryEntry(tag, "TestTagName", "TestTagKeyword", DicomVM.VM_1, false, DicomVR.DT); dict.Add(dictEntry); Assert.Equal(dictEntry, dict[tag]); }
private bool ParseTag(IByteSource source) { if (this.parseStage == ParseStage.Tag) { source.Mark(); if (!source.Require(4)) { this.result = DicomReaderResult.Suspended; return(false); } var group = source.GetUInt16(); var element = source.GetUInt16(); DicomPrivateCreator creator = null; if (@group.IsOdd() && element > 0x00ff) { var card = (uint)(@group << 16) + (uint)(element >> 8); lock (this.locker) { string pvt; if (this._private.TryGetValue(card, out pvt)) { creator = this.dictionary.GetPrivateCreator(pvt); } } } this._tag = new DicomTag(@group, element, creator); this._entry = this.dictionary[this._tag]; if (!this._tag.IsPrivate && this._entry != null && this._entry.MaskTag == null) { this._tag = this._entry.Tag; // Use dictionary tag } if (this.stop != null && this.stop(new ParseState { Tag = this._tag, SequenceDepth = this.sequenceDepth })) { this.result = DicomReaderResult.Stopped; return(false); } this.parseStage = ParseStage.VR; } return(true); }
public void AddPrivateTagAndReadOut() { var dict = new DicomDictionary { new DicomDictionaryEntry(new DicomTag(0x0011, 0x0010), "Private Creator", "PrivateCreator", DicomVM.VM_1, false, DicomVR.LO) }; DicomPrivateCreator privateCreator = dict.GetPrivateCreator("TESTCREATOR"); DicomDictionary privDict = dict[privateCreator]; var dictEntry = new DicomDictionaryEntry(new DicomTag(0x0011, 0x1010), "TestPrivTagName", "TestPrivTagKeyword", DicomVM.VM_1, false, DicomVR.DT); privDict.Add(dictEntry); Assert.True(dictEntry.Equals(dict[dictEntry.Tag.PrivateCreator][dictEntry.Tag])); }
public void CheckAddedPrivateTagValueRepresentation() { var privCreatorDictEntry = new DicomDictionaryEntry(new DicomTag(0x0011, 0x0010), "Private Creator", "PrivateCreator", DicomVM.VM_1, false, DicomVR.LO); DicomDictionary.Default.Add(privCreatorDictEntry); DicomPrivateCreator privateCreator1 = DicomDictionary.Default.GetPrivateCreator("TESTCREATOR1"); DicomDictionary privDict1 = DicomDictionary.Default[privateCreator1]; var dictEntry = new DicomDictionaryEntry(DicomMaskedTag.Parse("0011", "xx10"), "TestPrivTagName", "TestPrivTagKeyword", DicomVM.VM_1, false, DicomVR.CS); privDict1.Add(dictEntry); var ds = new DicomDataset(); ds.Add(dictEntry.Tag, "VAL1"); Assert.Equal(DicomVR.CS, ds.Get <DicomVR>(dictEntry.Tag)); }
public void Add_PrivateTag_ShouldBeAddedWithCorrectVR() { var privCreatorDictEntry = new DicomDictionaryEntry(new DicomTag(0x0011, 0x0010), "Private Creator", "PrivateCreator", DicomVM.VM_1, false, DicomVR.LO); DicomDictionary.Default.Add(privCreatorDictEntry); DicomPrivateCreator privateCreator1 = DicomDictionary.Default.GetPrivateCreator("TESTCREATOR1"); DicomDictionary privDict1 = DicomDictionary.Default[privateCreator1]; var dictEntry = new DicomDictionaryEntry(DicomMaskedTag.Parse("0011", "xx10"), "TestPrivTagName", "TestPrivTagKeyword", DicomVM.VM_1, false, DicomVR.CS); privDict1.Add(dictEntry); var ds = new DicomDataset { { dictEntry.Tag, "VAL1" } }; Assert.Equal(DicomVR.CS, ds.GetDicomItem <DicomItem>(dictEntry.Tag).ValueRepresentation); }
public void EnumerateBothPublicAndPrivateEntries() { var dict = new DicomDictionary(); var tag1 = new DicomTag(0x0010, 0x0020); var dictEntry1 = new DicomDictionaryEntry(tag1, "TestPublicTagName", "TestPublicTagKeyword", DicomVM.VM_1, false, DicomVR.DT); var privCreatorDictEntry = new DicomDictionaryEntry(new DicomTag(0x0011, 0x0010), "Private Creator", "PrivateCreator", DicomVM.VM_1, false, DicomVR.LO); dict.Add(privCreatorDictEntry); DicomPrivateCreator privateCreator = dict.GetPrivateCreator("TESTCREATOR"); DicomDictionary privDict = dict[privateCreator]; var dictEntry2 = new DicomDictionaryEntry(DicomMaskedTag.Parse("0011", "xx10"), "TestPrivTagName", "TestPrivTagKeyword", DicomVM.VM_1, false, DicomVR.DT); privDict.Add(dictEntry2); dict.Add(dictEntry1); Assert.True(dict.Contains(dictEntry1)); Assert.True(dict.Contains(privCreatorDictEntry)); Assert.True(dict[dictEntry2.Tag.PrivateCreator].Contains(dictEntry2)); Assert.True(dict.PrivateCreators.Any(pc => dict[pc].Contains(dictEntry2))); }
private void ParseDataset(IByteSource source, object state) { try { _result = DicomReaderResult.Processing; while (!source.IsEOF && !source.HasReachedMilestone() && _result == DicomReaderResult.Processing) { if (_state == ParseState.Tag) { source.Mark(); if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } ushort group = source.GetUInt16(); ushort element = source.GetUInt16(); DicomPrivateCreator creator = null; if (group.IsOdd() && element > 0x00ff) { string pvt = null; uint card = (uint)(group << 16) + (uint)(element >> 8); if (_private.TryGetValue(card, out pvt)) creator = Dictionary.GetPrivateCreator(pvt); } _tag = new DicomTag(group, element, creator); _entry = Dictionary[_tag]; if (!_tag.IsPrivate && _entry != null && _entry.MaskTag == null) _tag = _entry.Tag; // Use dictionary tag if (_stop != null && _tag.CompareTo(_stop) >= 0) { _result = DicomReaderResult.Stopped; return; } _state = ParseState.VR; } while (_state == ParseState.VR) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { _vr = DicomVR.NONE; _state = ParseState.Length; break; } if (IsExplicitVR) { if (!source.Require(2, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } source.Mark(); byte[] bytes = source.GetBytes(2); string vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); if (!DicomVR.TryParse(vr, out _vr)) { // unable to parse VR; rewind VR bytes for continued attempt to interpret the data. _vr = DicomVR.Implicit; source.Rewind(); } } else { if (_entry != null) { if (_entry == DicomDictionary.UnknownTag) _vr = DicomVR.UN; else if (_entry.ValueRepresentations.Contains(DicomVR.OB) && _entry.ValueRepresentations.Contains(DicomVR.OW)) _vr = DicomVR.OW; // ??? else _vr = _entry.ValueRepresentations.FirstOrDefault(); } } if (_vr == null) _vr = DicomVR.UN; _state = ParseState.Length; if (_vr == DicomVR.UN) { if (_tag.Element == 0x0000) { // Group Length to UL _vr = DicomVR.UL; break; } else if (IsExplicitVR) { break; } } if (_tag.IsPrivate) { if (_tag.Element != 0x0000 && _tag.Element <= 0x00ff && _vr == DicomVR.UN) _vr = DicomVR.LO; // force private creator to LO } } while (_state == ParseState.Length) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); _state = ParseState.Value; break; } if (IsExplicitVR) { if (_vr == DicomVR.Implicit) { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); // assume that undefined length in implicit VR element is SQ if (_length == UndefinedLength) _vr = DicomVR.SQ; } else if (_vr.Is16bitLength) { if (!source.Require(2, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt16(); } else { if (!source.Require(6, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } source.Skip(2); _length = source.GetUInt32(); } } else { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); // assume that undefined length in implicit dataset is SQ if (_length == UndefinedLength && _vr == DicomVR.UN) _vr = DicomVR.SQ; } _state = ParseState.Value; } if (_state == ParseState.Value) { // check dictionary for VR after reading length to handle 16-bit lengths // check before reading value to handle SQ elements var parsedVR = _vr; // check dictionary for VR after reading length to handle 16-bit lengths // check before reading value to handle SQ elements if (_vr == DicomVR.Implicit || (_vr == DicomVR.UN && IsExplicitVR)) { var entry = Dictionary[_tag]; if (entry != null) _vr = entry.ValueRepresentations.FirstOrDefault(); if (_vr == null) _vr = DicomVR.UN; } if (_tag == DicomTag.ItemDelimitationItem) { // end of sequence item return; } while (_vr == DicomVR.SQ && _tag.IsPrivate) { if (!IsPrivateSequence(source)) { _vr = DicomVR.UN; break; } if (IsPrivateSequenceBad(source)) { _badPrivateSequence = true; _explicit = !_explicit; } break; } if (_vr == DicomVR.SQ) { // start of sequence _observer.OnBeginSequence(source, _tag, _length); _state = ParseState.Tag; if (_length != UndefinedLength) { _implicit = false; source.PushMilestone(_length); } else _implicit = true; PushState(state); var last = source.Position; ParseItemSequence(source, null); // Aeric Sylvan - https://github.com/rcd/fo-dicom/issues/62#issuecomment-46248073 // Fix reading of SQ with parsed VR of UN if (source.Position > last || _length == 0) continue; else { _state = ParseState.Value; _vr = parsedVR; } } if (_length == UndefinedLength) { _observer.OnBeginFragmentSequence(source, _tag, _vr); _state = ParseState.Tag; PushState(state); ParseFragmentSequence(source, null); continue; } if (!source.Require(_length, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } IByteBuffer buffer = source.GetBuffer(_length); if (!_vr.IsString) buffer = EndianByteBuffer.Create(buffer, source.Endian, _vr.UnitSize); _observer.OnElement(source, _tag, _vr, buffer); // parse private creator value and add to lookup table if (_tag.IsPrivate && _tag.Element != 0x0000 && _tag.Element <= 0x00ff) { var creator = DicomEncoding.Default.GetString(buffer.Data, 0, buffer.Data.Length) .TrimEnd((char)DicomVR.LO.PaddingValue); var card = (uint)(_tag.Group << 16) + (uint)(_tag.Element); _private[card] = creator; } ResetState(); } } if (source.HasReachedMilestone()) { // end of explicit length sequence item source.PopMilestone(); return; } if (_result != DicomReaderResult.Processing) return; // end of processing _result = DicomReaderResult.Success; } catch (Exception e) { _exception = e; _result = DicomReaderResult.Error; } finally { if (_result != DicomReaderResult.Processing) { _async.Set(); } } }
private void ReadTags(string columnName, object value, uint[] dicomTags) { foreach (var dicomTag in dicomTags) { DicomDictionaryEntry dicEntry = DicomDictionary.Default[dicomTag]; var vr = dicEntry.ValueRepresentations.First(); Type valueType = value.GetType( ); if (vr == DicomVR.PN) { PersonNameParts currentPart = SchemaProvider.GetPNColumnPart(columnName); if (CurrentData.CurrentPersonNameData == null) { CurrentData.CurrentPersonNameData = new PersonNameData( ); CurrentData.CurrentPersonNameTagValue = (uint)dicEntry.Tag; CurrentData.CurrentPersonNames.Add(CurrentData.CurrentPersonNameTagValue, CurrentData.CurrentPersonNameData); } else { if (dicEntry.Tag != CurrentData.CurrentPersonNameTagValue) { if (CurrentData.CurrentPersonNames.TryGetValue((uint)dicEntry.Tag, out CurrentData.CurrentPersonNameData)) { CurrentData.CurrentPersonNameTagValue = (uint)dicEntry.Tag; } else { CurrentData.CurrentPersonNameData = new PersonNameData( ); CurrentData.CurrentPersonNameTagValue = (uint)dicEntry.Tag; CurrentData.CurrentPersonNames.Add(CurrentData.CurrentPersonNameTagValue, CurrentData.CurrentPersonNameData); } } } CurrentData.CurrentPersonNameData.SetPart(currentPart, (string)value); } if (valueType == typeof(String)) //shortcut { CurrentData.CurrentDs.AddOrUpdate <string>(dicomTag, (string)value); } else if (valueType == typeof(DateTime)) { CurrentData.CurrentDs.AddOrUpdate <DateTime>(dicomTag, (DateTime)value); } else if (valueType == typeof(Int32)) { DicomTag tag = (DicomTag)dicomTag; var VR = tag.DictionaryEntry.ValueRepresentations.First(); // Unsigned String must be stored as Int in SQL DB // https://social.msdn.microsoft.com/Forums/en-US/ff08c190-a981-4896-9542-3f64b95a84a2/sql-server-data-type-for-signedunsigned-integral-c-types?forum=adodotnetdataproviders if (VR == DicomVR.US) { CurrentData.CurrentDs.AddOrUpdate <UInt16>(dicomTag, Convert.ToUInt16(value)); } else { CurrentData.CurrentDs.AddOrUpdate <Int32>(dicomTag, (Int32)value); } } else if (valueType == typeof(Int64)) { CurrentData.CurrentDs.AddOrUpdate <Int64>(dicomTag, (Int64)value); } else { CurrentData.CurrentDs.AddOrUpdate <string>(dicomTag, value as string); System.Diagnostics.Debug.Assert(false, "Unknown element db value"); } } }
private bool ParseTag(IByteSource source) { if (this.parseStage == ParseStage.Tag) { source.Mark(); if (!source.Require(4)) { this.result = DicomReaderResult.Suspended; return false; } var group = source.GetUInt16(); var element = source.GetUInt16(); DicomPrivateCreator creator = null; if (@group.IsOdd() && element > 0x00ff) { var card = (uint)(@group << 16) + (uint)(element >> 8); lock (this.locker) { string pvt; if (this._private.TryGetValue(card, out pvt)) { creator = this.dictionary.GetPrivateCreator(pvt); } } } this._tag = new DicomTag(@group, element, creator); this._entry = this.dictionary[this._tag]; if (!this._tag.IsPrivate && this._entry != null && this._entry.MaskTag == null) { this._tag = this._entry.Tag; // Use dictionary tag } if (this.stop != null && this.stop(new ParseState { Tag = this._tag, SequenceDepth = this.sequenceDepth })) { this.result = DicomReaderResult.Stopped; return false; } this.parseStage = ParseStage.VR; } return true; }
private void ParseDataset(IByteSource source, object state) { try { _result = DicomReaderResult.Processing; while (!source.IsEOF && !source.HasReachedMilestone()) { if (_state == ParseState.Tag) { source.Mark(); if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } ushort group = source.GetUInt16(); ushort element = source.GetUInt16(); DicomPrivateCreator creator = null; if (group.IsOdd() && element > 0x00ff) { string pvt = null; uint card = (uint)(group << 16) + (uint)(element >> 8); if (_private.TryGetValue(card, out pvt)) { creator = Dictionary.GetPrivateCreator(pvt); } } _tag = new DicomTag(group, element, creator); if (_stop != null && _tag.CompareTo(_stop) >= 0) { _result = DicomReaderResult.Stopped; return; } _state = ParseState.VR; } while (_state == ParseState.VR) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { _vr = DicomVR.NONE; _state = ParseState.Length; break; } if (IsExplicitVR) { if (!source.Require(2, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } byte[] bytes = source.GetBytes(2); string vr = Encoding.ASCII.GetString(bytes); _vr = DicomVR.Parse(vr); } else { DicomDictionaryEntry entry = Dictionary[_tag]; if (entry != null) { if (entry.ValueRepresentations.Contains(DicomVR.OB) && entry.ValueRepresentations.Contains(DicomVR.OW)) { _vr = DicomVR.OW; // ??? } else { _vr = entry.ValueRepresentations.FirstOrDefault(); } } } if (_vr == null) { _vr = DicomVR.UN; } _state = ParseState.Length; if (_vr == DicomVR.UN) { if (_tag.Element == 0x0000) { // Group Length to UL _vr = DicomVR.UL; break; } if (_tag.Group.IsOdd()) { if (_tag.Element <= 0x00ff) { // Private Creator to LO _vr = DicomVR.LO; break; } else if (IsExplicitVR) { DicomDictionaryEntry entry = Dictionary[_tag]; if (entry != null) { _vr = entry.ValueRepresentations.FirstOrDefault(); } if (_vr == null) { _vr = DicomVR.UN; } break; } } } } while (_state == ParseState.Length) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); _state = ParseState.Value; break; } if (IsExplicitVR) { if (_vr.Is16bitLength) { if (!source.Require(2, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt16(); } else { if (!source.Require(6, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } source.Skip(2); _length = source.GetUInt32(); } } else { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); } _state = ParseState.Value; } if (_state == ParseState.Value) { if (_tag == DicomTag.ItemDelimitationItem) { // end of sequence item ParseItemSequence(source, state); return; } if (_vr == DicomVR.SQ) { // start of sequence _observer.OnBeginSequence(source, _tag, _length); _state = ParseState.Tag; if (_length != UndefinedLength) { source.PushMilestone(_length); } PushState(state); ParseItemSequence(source, null); continue; } if (_length == UndefinedLength) { _observer.OnBeginFragmentSequence(source, _tag, _vr); _state = ParseState.Tag; PushState(state); ParseFragmentSequence(source, null); continue; } if (!source.Require(_length, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } IByteBuffer buffer = source.GetBuffer(_length); if (!_vr.IsString) { buffer = EndianByteBuffer.Create(buffer, source.Endian, _vr.UnitSize); } _observer.OnElement(source, _tag, _vr, buffer); ResetState(); } } if (source.HasReachedMilestone()) { // end of explicit length sequence item _observer.OnEndSequenceItem(); source.PopMilestone(); ParseItemSequence(source, state); return; } // end of processing _result = DicomReaderResult.Success; } catch (Exception e) { _exception = e; _result = DicomReaderResult.Error; } finally { if (_result != DicomReaderResult.Processing && _result != DicomReaderResult.Suspended) { _async.Set(); } } }
private void ParseDataset(IByteSource source, object state) { try { _result = DicomReaderResult.Processing; while (!source.IsEOF && !source.HasReachedMilestone() && _result == DicomReaderResult.Processing) { if (_state == ParseState.Tag) { source.Mark(); if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } ushort group = source.GetUInt16(); ushort element = source.GetUInt16(); DicomPrivateCreator creator = null; if (group.IsOdd() && element > 0x00ff) { string pvt = null; uint card = (uint)(group << 16) + (uint)(element >> 8); if (_private.TryGetValue(card, out pvt)) { creator = Dictionary.GetPrivateCreator(pvt); } } _tag = new DicomTag(group, element, creator); _entry = Dictionary[_tag]; if (!_tag.IsPrivate && _entry != null && _entry.MaskTag == null) { _tag = _entry.Tag; // Use dictionary tag } if (_stop != null && _tag.CompareTo(_stop) >= 0) { _result = DicomReaderResult.Stopped; return; } _state = ParseState.VR; } while (_state == ParseState.VR) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { _vr = DicomVR.NONE; _state = ParseState.Length; break; } if (IsExplicitVR) { if (!source.Require(2, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } byte[] bytes = source.GetBytes(2); string vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); if (!DicomVR.TryParse(vr, out _vr)) { // unable to parse VR _vr = DicomVR.UN; } } else { if (_entry != null) { if (_entry == DicomDictionary.UnknownTag) { _vr = DicomVR.UN; } else if (_entry.ValueRepresentations.Contains(DicomVR.OB) && _entry.ValueRepresentations.Contains(DicomVR.OW)) { _vr = DicomVR.OW; // ??? } else { _vr = _entry.ValueRepresentations.FirstOrDefault(); } } } if (_vr == null) { _vr = DicomVR.UN; } _state = ParseState.Length; if (_vr == DicomVR.UN) { if (_tag.Element == 0x0000) { // Group Length to UL _vr = DicomVR.UL; break; } else if (IsExplicitVR) { break; } } if (_tag.IsPrivate) { if (_tag.Element != 0x0000 && _tag.Element <= 0x00ff && _vr == DicomVR.UN) { _vr = DicomVR.LO; // force private creator to LO } } } while (_state == ParseState.Length) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); _state = ParseState.Value; break; } if (IsExplicitVR) { if (_vr.Is16bitLength) { if (!source.Require(2, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt16(); } else { if (!source.Require(6, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } source.Skip(2); _length = source.GetUInt32(); } } else { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); // assume that undefined length in implicit dataset is SQ if (_length == UndefinedLength && _vr == DicomVR.UN) { _vr = DicomVR.SQ; } } _state = ParseState.Value; } if (_state == ParseState.Value) { // check dictionary for VR after reading length to handle 16-bit lengths // check before reading value to handle SQ elements var parsedVR = _vr; // check dictionary for VR after reading length to handle 16-bit lengths // check before reading value to handle SQ elements if (_vr == DicomVR.UN && IsExplicitVR) { var entry = Dictionary[_tag]; if (entry != null) { _vr = entry.ValueRepresentations.FirstOrDefault(); } if (_vr == null) { _vr = DicomVR.UN; } } if (_tag == DicomTag.ItemDelimitationItem) { // end of sequence item return; } while (_vr == DicomVR.SQ && _tag.IsPrivate) { if (!IsPrivateSequence(source)) { _vr = DicomVR.UN; break; } if (IsPrivateSequenceBad(source)) { _badPrivateSequence = true; _explicit = !_explicit; } break; } if (_vr == DicomVR.SQ) { // start of sequence _observer.OnBeginSequence(source, _tag, _length); _state = ParseState.Tag; if (_length != UndefinedLength) { _implicit = false; source.PushMilestone(_length); } else { _implicit = true; } PushState(state); var last = source.Position; ParseItemSequence(source, null); // Aeric Sylvan - https://github.com/rcd/fo-dicom/issues/62#issuecomment-46248073 // Fix reading of SQ with parsed VR of UN if (source.Position > last || _length == 0) { continue; } else { _state = ParseState.Value; _vr = parsedVR; } } if (_length == UndefinedLength) { _observer.OnBeginFragmentSequence(source, _tag, _vr); _state = ParseState.Tag; PushState(state); ParseFragmentSequence(source, null); continue; } if (!source.Require(_length, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } IByteBuffer buffer = source.GetBuffer(_length); if (!_vr.IsString) { buffer = EndianByteBuffer.Create(buffer, source.Endian, _vr.UnitSize); } _observer.OnElement(source, _tag, _vr, buffer); // parse private creator value and add to lookup table if (_tag.IsPrivate && _tag.Element != 0x0000 && _tag.Element <= 0x00ff) { var creator = DicomEncoding.Default.GetString(buffer.Data, 0, buffer.Data.Length).TrimEnd((char)DicomVR.LO.PaddingValue); var card = (uint)(_tag.Group << 16) + (uint)(_tag.Element); _private[card] = creator; } ResetState(); } } if (source.HasReachedMilestone()) { // end of explicit length sequence item source.PopMilestone(); return; } if (_result != DicomReaderResult.Processing) { return; } // end of processing _result = DicomReaderResult.Success; } catch (Exception e) { _exception = e; _result = DicomReaderResult.Error; } finally { if (_result != DicomReaderResult.Processing && _result != DicomReaderResult.Suspended) { _async.Set(); } } }
public static void SetDicomTag(DicomDataset dataset, DicomDictionaryEntry tag, object value) { SetDicomTag(dataset, tag.Tag, value); }