public void OnBeginSequence(IByteSource source, DicomTag tag, uint length) { _currentSequenceTag.Push(tag); if (tag == DicomTag.DirectoryRecordSequence) { _directoryRecordSequence = _dataset.Get<DicomSequence>(tag); } }
public void OnBeginSequence(IByteSource source, DicomTag tag, uint length) { DicomSequence sq = new DicomSequence(tag); _sequences.Push(sq); DicomDataset ds = _datasets.Peek(); ds.Add(sq); }
public void OnBeginSequenceItem(IByteSource source, uint length) { if (_currentSequenceTag.Peek() == DicomTag.DirectoryRecordSequence && _directoryRecordSequence != null) { _lookup.Add((uint)source.Position - 8, _directoryRecordSequence.LastOrDefault()); } }
public void OnBeginSequenceItem(IByteSource source, uint length) { DicomSequence sq = _sequences.Peek(); DicomDataset item = new DicomDataset(); sq.Items.Add(item); _datasets.Push(item); }
public IAsyncResult BeginRead(IByteSource source, IDicomReaderObserver fileMetaInfo, IDicomReaderObserver dataset, AsyncCallback callback, object state) { _result = DicomReaderResult.Processing; _source = source; _fmiObserver = fileMetaInfo; _dataObserver = dataset; _async = new EventAsyncResult(callback, state); ParsePreamble(source, null); // ThreadPool? return _async; }
public IAsyncResult BeginRead(IByteSource source, IDicomReaderObserver observer, DicomTag stop, AsyncCallback callback, object state) { _stop = stop; _observer = observer; _result = DicomReaderResult.Processing; _exception = null; _async = new EventAsyncResult(callback, state); ThreadPool.QueueUserWorkItem(ParseProc, source); return _async; }
public IAsyncResult BeginRead(IByteSource source, IDicomReaderObserver fileMetaInfo, IDicomReaderObserver dataset, AsyncCallback callback, object state) { _result = DicomReaderResult.Processing; _source = source; _fmiObserver = fileMetaInfo; _dataObserver = dataset; _async = new EventAsyncResult(callback, state); ParsePreamble(source, null); // ThreadPool? return(_async); }
public IAsyncResult BeginRead(IByteSource source, IDicomReaderObserver observer, DicomTag stop, AsyncCallback callback, object state) { _stop = stop; _observer = observer; _result = DicomReaderResult.Processing; _exception = null; _async = new EventAsyncResult(callback, state); ThreadPool.QueueUserWorkItem(ParseProc, source); return(_async); }
public void OnBeginSequence(IByteSource source, DicomTag tag, uint length) { DicomSequence sq = new DicomSequence(tag); _sequences.Push(sq); DicomDataset ds = _datasets.Peek(); ds.AddOrUpdate(sq); }
public static IAsyncResult BeginRead( this DicomFileReader @this, IByteSource source, IDicomReaderObserver fileMetaInfo, IDicomReaderObserver dataset, AsyncCallback callback, object state) { return AsyncFactory.ToBegin(@this.ReadAsync(source, fileMetaInfo, dataset), callback, state); }
public static IAsyncResult BeginRead( this DicomReader @this, IByteSource source, IDicomReaderObserver observer, Func<ParseState, bool> stop, AsyncCallback callback, object state) { return AsyncFactory.ToBegin(@this.ReadAsync(source, observer, stop), callback, state); }
public void OnElement(IByteSource source, DicomTag tag, DicomVR vr, IByteBuffer data) { DicomElement element = vr.Code switch { "AE" => new DicomApplicationEntity(tag, data), "AS" => new DicomAgeString(tag, data), "AT" => new DicomAttributeTag(tag, data), "CS" => new DicomCodeString(tag, data), "DA" => new DicomDate(tag, data), "DS" => new DicomDecimalString(tag, data), "DT" => new DicomDateTime(tag, data), "FD" => new DicomFloatingPointDouble(tag, data), "FL" => new DicomFloatingPointSingle(tag, data), "IS" => new DicomIntegerString(tag, data), "LO" => new DicomLongString(tag, _encodings.Peek(), data), "LT" => new DicomLongText(tag, _encodings.Peek(), data), "OB" => new DicomOtherByte(tag, data), "OD" => new DicomOtherDouble(tag, data), "OF" => new DicomOtherFloat(tag, data), "OL" => new DicomOtherLong(tag, data), "OV" => new DicomOtherVeryLong(tag, data), "OW" => new DicomOtherWord(tag, data), "PN" => new DicomPersonName(tag, _encodings.Peek(), data), "SH" => new DicomShortString(tag, _encodings.Peek(), data), "SL" => new DicomSignedLong(tag, data), "SS" => new DicomSignedShort(tag, data), "ST" => new DicomShortText(tag, _encodings.Peek(), data), "SV" => new DicomSignedVeryLong(tag, data), "TM" => new DicomTime(tag, data), "UC" => new DicomUnlimitedCharacters(tag, _encodings.Peek(), data), "UI" => new DicomUniqueIdentifier(tag, data), "UL" => new DicomUnsignedLong(tag, data), "UN" => new DicomUnknown(tag, data), "UR" => new DicomUniversalResource(tag, _encodings.Peek(), data), "US" => new DicomUnsignedShort(tag, data), "UT" => new DicomUnlimitedText(tag, _encodings.Peek(), data), "UV" => new DicomUnsignedVeryLong(tag, data), _ => throw new DicomDataException($"Unhandled VR in DICOM parser observer: {vr.Code}"), }; if (element.Tag == DicomTag.SpecificCharacterSet) { Encoding[] encodings = _encodings.Peek(); if (element.Count > 0) { encodings = DicomEncoding.GetEncodings(element.Get <string[]>(0)); } _encodings.Pop(); _encodings.Push(encodings); } DicomDataset ds = _datasets.Peek(); ds.AddOrUpdate(element); }
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 OnBeginFragmentSequence(IByteSource source, DicomTag tag, DicomVR vr) { if (vr == DicomVR.OB) _fragment = new DicomOtherByteFragment(tag); else if (vr == DicomVR.OW) _fragment = new DicomOtherWordFragment(tag); else throw new DicomDataException("Unexpected VR found for DICOM fragment sequence: {0}", vr.Code); DicomDataset ds = _datasets.Peek(); ds.Add(_fragment); }
public void OnBeginFragmentSequence(IByteSource source, DicomTag tag, DicomVR vr) { _log.Log( _level, "{marker:x8}: {padding}{tag} {vrCode} {tagDictionaryEntryName}", source.Marker, _pad, tag, vr.Code, tag.DictionaryEntry.Name); IncreaseDepth(); }
public void OnBeginSequence(IByteSource source, DicomTag tag, uint length) { _log.Log( _level, "{marker:x8}: {padding}{tag} SQ {length}", source.Marker, _pad, tag, tag.DictionaryEntry.Name, length); IncreaseDepth(); }
public void OnElement(IByteSource source, DicomTag tag, DicomVR vr, IByteBuffer data) { _log.Log( _level, "{marker:x8}: {padding}{tag} {vrCode} {tagDictionaryEntryName} [{size}]", source.Marker, _pad, tag, vr.Code, tag.DictionaryEntry.Name, data.Size); }
public void OnFragmentSequenceItem(IByteSource source, IByteBuffer data) { if (data == null) { // if a null-buffer is added, then the FragmentSequence is not complete and shall not be added to the DicomDataset _fragment = null; } else { _fragment?.Add(data); } }
public bool Equals(Object o) { if (o == this) { return(true); } if (o instanceof IByteSource) { IByteSource bs = (IByteSource)o; return(Arrays.equals(getBytes(), bs.getBytes())); } return(false); }
/// <summary> /// Asynchronously read the byte source. /// </summary> /// <param name="source">Byte source to read.</param> /// <returns>Awaitable read result.</returns> internal async Task <DicomReaderResult> DoWorkAsync(IByteSource source) { ResetState(); source = ConvertSource(source); await ParseDatasetAsync(source).ConfigureAwait(false); if (_tag == DicomTag.SequenceDelimitationItem && _result == DicomReaderResult.Processing && source.IsEOF) { _result = DicomReaderResult.Success; } return(_result); }
/// <summary> /// Read the byte source. /// </summary> /// <param name="source">Byte source to read.</param> /// <returns>Read result.</returns> internal DicomReaderResult DoWork(IByteSource source) { ResetState(); source = ConvertSource(source); ParseDataset(source); if (_tag == DicomTag.SequenceDelimitationItem && _result == DicomReaderResult.Processing && source.IsEOF) { _result = DicomReaderResult.Success; } return(_result); }
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 static bool IsPrivateSequenceBad(IByteSource source, uint count, bool isExplicitVR) { source.Mark(); try { // Skip "item" tags; continue skipping until length is non-zero (#223) // Using & instead of && enforces RHS to be evaluated regardless of LHS uint length; while (source.GetUInt16() == DicomTag.Item.Group & source.GetUInt16() == DicomTag.Item.Element & (length = source.GetUInt32()) < uint.MaxValue) // Dummy condition to ensure that length is included in parsing { // Length non-zero, end skipping (#223) if (length > 0) { break; } // Handle scenario where last tag is private sequence with empty items (#487) count -= 8; if (count <= 0) { return(false); } } source.GetUInt16(); // group source.GetUInt16(); // element var bytes = source.GetBytes(2); var vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); DicomVR dummy; if (DicomVR.TryParse(vr, out dummy)) { return(!isExplicitVR); } // unable to parse VR if (isExplicitVR) { return(true); } } finally { source.Rewind(); } return(false); }
private IByteSource Decompress(IByteSource source) { var compressed = source.GetStream(); var decompressed = new MemoryStream(); using (var decompressor = new DeflateStream(compressed, CompressionMode.Decompress, true)) { decompressor.CopyTo(decompressed); } decompressed.Seek(0, SeekOrigin.Begin); return(new StreamByteSource(decompressed)); }
/// <summary> /// Read DICOM file object. /// </summary> /// <param name="source">Byte source to read.</param> /// <param name="fileMetaInfo">Reader observer for file meta information.</param> /// <param name="dataset">Reader observer for dataset.</param> /// <param name="stop">Stop criterion in dataset.</param> /// <returns>Reader result.</returns> public DicomReaderResult Read( IByteSource source, IDicomReaderObserver fileMetaInfo, IDicomReaderObserver dataset, Func<ParseState, bool> stop = null) { var parse = Parse(source, fileMetaInfo, dataset, stop); lock (this.locker) { this.fileFormat = parse.Item2; this.syntax = parse.Item3; } return parse.Item1; }
public override void Close() { try { if (sourceOrDestination != null) { if (consumer != null && !inconsistentState) { Flush(); } } if (producer != null && producer is IDisposable) { ((IDisposable)producer).Dispose(); } if (consumer != null && consumer is IDisposable) { ((IDisposable)consumer).Dispose(); } } finally { if (sourceOrDestination != null) { if (sourceOrDestination is Stream) { ((Stream)sourceOrDestination).Close(); } else if (sourceOrDestination is TextReader) { ((TextReader)sourceOrDestination).Close(); } else { ((TextWriter)sourceOrDestination).Close(); } } sourceOrDestination = null; consumer = null; producer = null; chunkToReadBuffer = null; writeBuffer = null; byteSource = null; } }
public void OnBeginFragmentSequence(IByteSource source, DicomTag tag, DicomVR vr) { if (vr == DicomVR.OB) { _fragment = new DicomOtherByteFragment(tag); } else if (vr == DicomVR.OW) { _fragment = new DicomOtherWordFragment(tag); } else { throw new DicomDataException($"Unexpected VR found for DICOM fragment sequence: {vr.Code}"); } }
private void ParseItemSequencePostProcess(IByteSource source) { // end of explicit length sequence if (source.HasReachedMilestone()) { source.PopMilestone(); } this.observer.OnEndSequence(); if (this.badPrivateSequence) { this.isExplicitVR = !this.isExplicitVR; this.badPrivateSequence = false; } }
/// <summary> /// Asynchronously read DICOM file object. /// </summary> /// <param name="source">Byte source to read.</param> /// <param name="fileMetaInfo">Reader observer for file meta information.</param> /// <param name="dataset">Reader observer for dataset.</param> /// <param name="stop">Stop criterion in dataset.</param> /// <returns>Awaitable reader result.</returns> public async Task <DicomReaderResult> ReadAsync( IByteSource source, IDicomReaderObserver fileMetaInfo, IDicomReaderObserver dataset, Func <ParseState, bool> stop = null) { var parse = await ParseAsync(source, fileMetaInfo, dataset, stop).ConfigureAwait(false); lock (_locker) { FileFormat = parse.Item2; Syntax = parse.Item3; } return(parse.Item1); }
/// <summary> /// Read DICOM file object. /// </summary> /// <param name="source">Byte source to read.</param> /// <param name="fileMetaInfo">Reader observer for file meta information.</param> /// <param name="dataset">Reader observer for dataset.</param> /// <param name="stop">Stop criterion in dataset.</param> /// <returns>Reader result.</returns> public DicomReaderResult Read( IByteSource source, IDicomReaderObserver fileMetaInfo, IDicomReaderObserver dataset, Func <ParseState, bool> stop = null) { var parse = Parse(source, fileMetaInfo, dataset, stop); lock (this.locker) { this.fileFormat = parse.Item2; this.syntax = parse.Item3; } return(parse.Item1); }
public void OnBeginSequenceItem(IByteSource source, uint length) { DicomSequence sq = _sequences.Peek(); DicomDataset item = new DicomDataset().NotValidated(); sq.Items.Add(item); _datasets.Push(item); var encoding = _encodings.Peek(); item.SetFallbackEncodings(encoding); _encodings.Push(encoding); }
private void ParseDataset(IByteSource source) { if (this.isDeflated) { #if NET35 throw new NotSupportedException("Deflated datasets not supported in Unity."); #else source = this.Decompress(source); #endif } this.result = DicomReaderResult.Processing; while (!source.IsEOF && !source.HasReachedMilestone() && this.result == DicomReaderResult.Processing) { if (!this.ParseTag(source)) { return; } if (!this.ParseVR(source)) { return; } if (!this.ParseLength(source)) { return; } if (!this.ParseValue(source)) { return; } } if (source.HasReachedMilestone()) { // end of explicit length sequence item source.PopMilestone(); return; } if (this.result != DicomReaderResult.Processing) { return; } // end of processing this.result = DicomReaderResult.Success; }
/// <summary> /// Closes the current stream and releases any resources (such as sockets and file handles) associated with the current stream. /// </summary> public override void Close() { try { if (this.sourceOrDestination != null) { if (this.consumer != null && !this.inconsistentState) { this.Flush(); } } if (this.producer != null && this.producer is IDisposable) { ((IDisposable)this.producer).Dispose(); } if (this.consumer != null && this.consumer is IDisposable) { ((IDisposable)this.consumer).Dispose(); } } finally { if (this.sourceOrDestination != null) { if (this.sourceOrDestination is Stream stream) { stream.Close(); } else if (this.sourceOrDestination is TextReader textReader) { textReader.Close(); } else if (this.sourceOrDestination is TextWriter textWriter) { textWriter.Close(); } } this.sourceOrDestination = null; this.consumer = null; this.producer = null; this.chunkToReadBuffer = null; this.writeBuffer = null; this.byteSource = null; } }
/// <summary> /// Read DICOM file object. /// </summary> /// <param name="source">Byte source to read.</param> /// <param name="fileMetaInfo">Reader observer for file meta information.</param> /// <param name="dataset">Reader observer for dataset.</param> /// <param name="stop">Stop criterion in dataset.</param> /// <returns>Reader result.</returns> public DicomReaderResult Read( IByteSource source, IDicomReaderObserver fileMetaInfo, IDicomReaderObserver dataset, Func <ParseState, bool> stop = null) { var parse = Parse(source, fileMetaInfo, dataset, stop); lock (_locker) { FileFormat = parse.Format; Syntax = parse.Syntax; } return(parse.Result); }
private async Task ParseFragmentSequenceAsync(IByteSource source) { _result = DicomReaderResult.Processing; while (!source.IsEOF) { if (!ParseFragmentSequenceTag(source)) { return; } if (!await ParseFragmentSequenceValueAsync(source).ConfigureAwait(false)) { return; } } }
private void ParseFragmentSequence(IByteSource source) { _result = DicomReaderResult.Processing; while (!source.IsEOF) { if (!ParseFragmentSequenceTag(source)) { return; } if (!ParseFragmentSequenceValue(source)) { return; } } }
public void OnElement(IByteSource source, DicomTag tag, DicomVR vr, IByteBuffer data) { DicomElement element; switch (vr.Code) { case "AE": element = new DicomApplicationEntity(tag, data); break; case "AS": element = new DicomAgeString(tag, data); break; case "AT": element = new DicomAttributeTag(tag, data); break; case "CS": element = new DicomCodeString(tag, data); break; case "DA": element = new DicomDate(tag, data); break; case "DS": element = new DicomDecimalString(tag, data); break; case "DT": element = new DicomDateTime(tag, data); break; case "FD": element = new DicomFloatingPointDouble(tag, data); break; case "FL": element = new DicomFloatingPointSingle(tag, data); break; case "IS": element = new DicomIntegerString(tag, data); break; case "LO": element = new DicomLongString(tag, _encodings.Peek(), data); break; case "LT": element = new DicomLongText(tag, _encodings.Peek(), data); break; case "OB": element = new DicomOtherByte(tag, data); break; case "OD": element = new DicomOtherDouble(tag, data); break; case "OF": element = new DicomOtherFloat(tag, data); break; case "OW": element = new DicomOtherWord(tag, data); break; case "PN": element = new DicomPersonName(tag, _encodings.Peek(), data); break; case "SH": element = new DicomShortString(tag, _encodings.Peek(), data); break; case "SL": element = new DicomSignedLong(tag, data); break; case "SS": element = new DicomSignedShort(tag, data); break; case "ST": element = new DicomShortText(tag, _encodings.Peek(), data); break; case "TM": element = new DicomTime(tag, data); break; case "UC": element = new DicomUnlimitedCharacters(tag, _encodings.Peek(), data); break; case "UI": element = new DicomUniqueIdentifier(tag, data); break; case "UL": element = new DicomUnsignedLong(tag, data); break; case "UN": element = new DicomUnknown(tag, data); break; case "UR": element = new DicomUniversalResource(tag, _encodings.Peek(), data); break; case "US": element = new DicomUnsignedShort(tag, data); break; case "UT": element = new DicomUnlimitedText(tag, _encodings.Peek(), data); break; default: throw new DicomDataException("Unhandled VR in DICOM parser observer: {0}", vr.Code); } if (element.Tag == DicomTag.SpecificCharacterSet) { Encoding encoding = _encodings.Peek(); if (element.Count > 0) encoding = DicomEncoding.GetEncoding(element.Get<string>(0)); _encodings.Pop(); _encodings.Push(encoding); } DicomDataset ds = _datasets.Peek(); ds.Add(element); }
private void ParseItemSequencePostProcess(IByteSource source) { // end of explicit length sequence if (source.HasReachedMilestone()) { source.PopMilestone(); } _observer.OnEndSequence(); // #565 Only reset the badPrivate sequence if we're in the correct depth // This prevents prematurely resetting in case of sub-sequences contained in the bad private sequence if (_badPrivateSequence && _sequenceDepth == _badPrivateSequenceDepth) { _isExplicitVR = !_isExplicitVR; _badPrivateSequence = false; } }
private async Task <bool> ParseItemSequenceValueAsync(IByteSource source) { if (_parseStage == ParseStage.Value) { if (_length != _undefinedLength) { if (!source.Require(_length)) { _result = DicomReaderResult.Suspended; return(false); } source.PushMilestone(_length); } _observer.OnBeginSequenceItem(source, _length); ResetState(); ++_sequenceDepth; await ParseDatasetAsync(source).ConfigureAwait(false); --_sequenceDepth; // bugfix k-pacs. there a sequence was not ended by ItemDelimitationItem>SequenceDelimitationItem, but directly with SequenceDelimitationItem bool isEndSequence = (_tag == DicomTag.SequenceDelimitationItem); ResetState(); _observer.OnEndSequenceItem(); if (isEndSequence) { // end of sequence _observer.OnEndSequence(); // #565 Only reset the badPrivate sequence if we're in the correct depth // This prevents prematurely resetting in case of sub-sequences contained in the bad private sequence if (_badPrivateSequence && _sequenceDepth == _badPrivateSequenceDepth) { _isExplicitVR = !_isExplicitVR; _badPrivateSequence = false; } ResetState(); return(false); } } return(true); }
private async Task ParseItemSequenceAsync(IByteSource source) { _result = DicomReaderResult.Processing; while (!source.IsEOF && !source.HasReachedMilestone()) { if (!ParseItemSequenceTag(source)) { return; } if (!await ParseItemSequenceValueAsync(source).ConfigureAwait(false)) { return; } } ParseItemSequencePostProcess(source); }
public DicomReaderResult Read(IByteSource source, IDicomReaderObserver observer, DicomTag stop = null) { return EndRead(BeginRead(source, observer, stop, null, null)); }
private bool IsPrivateSequenceBad(IByteSource source) { source.Mark(); try { var group = source.GetUInt16(); var element = source.GetUInt16(); var tag = new DicomTag(group, element); var length = source.GetUInt32(); group = source.GetUInt16(); element = source.GetUInt16(); tag = new DicomTag(group, element); byte[] bytes = source.GetBytes(2); string vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); try { DicomVR.Parse(vr); return !_explicit; } catch { // unable to parse VR if (_explicit) return true; } } finally { source.Rewind(); } return false; }
private void ParseFragmentSequence(IByteSource source, object state) { try { _result = DicomReaderResult.Processing; while (!source.IsEOF) { if (_state == ParseState.Tag) { source.Mark(); if (!source.Require(8, ParseFragmentSequence, state)) { _result = DicomReaderResult.Suspended; return; } ushort group = source.GetUInt16(); ushort element = source.GetUInt16(); DicomTag tag = new DicomTag(group, element); if (tag != DicomTag.Item && tag != DicomTag.SequenceDelimitationItem) throw new DicomReaderException("Unexpected tag in DICOM fragment sequence: {0}", tag); _length = source.GetUInt32(); if (tag == DicomTag.SequenceDelimitationItem) { // end of fragment _observer.OnEndFragmentSequence(); _fragmentItem = 0; ResetState(); ParseDataset(source, PopState()); return; } _fragmentItem++; _state = ParseState.Value; } if (_state == ParseState.Value) { if (!source.Require(_length, ParseFragmentSequence, state)) { _result = DicomReaderResult.Suspended; return; } IByteBuffer buffer = source.GetBuffer(_length); if (_fragmentItem == 1) buffer = EndianByteBuffer.Create(buffer, source.Endian, 4); else buffer = EndianByteBuffer.Create(buffer, source.Endian, _vr.UnitSize); _observer.OnFragmentSequenceItem(source, buffer); _state = ParseState.Tag; } } } catch (Exception e) { _exception = e; _result = DicomReaderResult.Error; } finally { if (_result != DicomReaderResult.Processing && _result != DicomReaderResult.Suspended) { _async.Set(); } } }
private void ParseItemSequence(IByteSource source, object state) { try { _result = DicomReaderResult.Processing; while (!source.IsEOF && !source.HasReachedMilestone()) { if (_state == ParseState.Tag) { source.Mark(); if (!source.Require(8, ParseItemSequence, state)) { _result = DicomReaderResult.Suspended; return; } ushort group = source.GetUInt16(); ushort element = source.GetUInt16(); _tag = new DicomTag(group, element); if (_tag != DicomTag.Item && _tag != DicomTag.SequenceDelimitationItem) { // assume invalid sequence source.Rewind(); if (!_implicit) source.PopMilestone(); _observer.OnEndSequence(); if (_badPrivateSequence) { _explicit = !_explicit; _badPrivateSequence = false; } return; } _length = source.GetUInt32(); if (_tag == DicomTag.SequenceDelimitationItem) { // end of sequence _observer.OnEndSequence(); if (_badPrivateSequence) { _explicit = !_explicit; _badPrivateSequence = false; } ResetState(); return; } _state = ParseState.Value; } if (_state == ParseState.Value) { if (_length != UndefinedLength) { if (!source.Require(_length, ParseItemSequence, state)) { _result = DicomReaderResult.Suspended; return; } source.PushMilestone(_length); } _observer.OnBeginSequenceItem(source, _length); ResetState(); ParseDataset(source, state); ResetState(); _observer.OnEndSequenceItem(); continue; } } // end of explicit length sequence if (source.HasReachedMilestone()) source.PopMilestone(); _observer.OnEndSequence(); if (_badPrivateSequence) { _explicit = !_explicit; _badPrivateSequence = false; } } catch (Exception e) { _exception = e; _result = DicomReaderResult.Error; } finally { if (_result != DicomReaderResult.Processing && _result != DicomReaderResult.Suspended) { _async.Set(); } } }
private bool IsPrivateSequence(IByteSource source) { source.Mark(); try { var group = source.GetUInt16(); var element = source.GetUInt16(); var tag = new DicomTag(group, element); if (tag == DicomTag.Item || tag == DicomTag.SequenceDelimitationItem) return true; } finally { source.Rewind(); } return false; }
public void OnBeginSequenceItem(IByteSource source, uint length) { foreach (IDicomReaderObserver observer in _observers) observer.OnBeginSequenceItem(source, length); }
public void OnBeginSequence(IByteSource source, DicomTag tag, uint length) { foreach (IDicomReaderObserver observer in _observers) observer.OnBeginSequence(source, tag, length); }
public void OnElement(IByteSource source, DicomTag tag, DicomVR vr, IByteBuffer data) { foreach (IDicomReaderObserver observer in _observers) observer.OnElement(source, tag, vr, data); }
public void OnBeginFragmentSequence(IByteSource source, DicomTag tag, DicomVR vr) { foreach (IDicomReaderObserver observer in _observers) observer.OnBeginFragmentSequence(source, tag, vr); }
public void OnBeginSequenceItem(IByteSource source, uint length) { }
public void OnElement(IByteSource source, DicomTag tag, DicomVR vr, IByteBuffer data) { this.Tag = tag; this.VR = vr; this.Data = Encoding.UTF8.GetString(data.Data); }
public void OnBeginSequence(IByteSource source, DicomTag tag, uint length) { }
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); 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); try { _vr = DicomVR.Parse(vr); } catch { // unable to parse VR _vr = DicomVR.UN; } } else { DicomDictionaryEntry entry = Dictionary[_tag]; 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 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); 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); // 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 void OnFragmentSequenceItem(IByteSource source, IByteBuffer data) { _fragment.Add(data); }
public void OnFragmentSequenceItem(IByteSource source, IByteBuffer data) { foreach (IDicomReaderObserver observer in _observers) observer.OnFragmentSequenceItem(source, data); }
public void OnBeginFragmentSequence(IByteSource source, DicomTag tag, DicomVR vr) { }