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);
		}
예제 #3
0
 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);
		}
예제 #5
0
		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;
		}
예제 #6
0
		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;
		}
예제 #7
0
 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);
 }
예제 #8
0
 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);
 }
예제 #9
0
        public void OnBeginSequence(IByteSource source, DicomTag tag, uint length)
        {
            DicomSequence sq = new DicomSequence(tag);

            _sequences.Push(sq);

            DicomDataset ds = _datasets.Peek();

            ds.AddOrUpdate(sq);
        }
예제 #10
0
 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);
 }
예제 #11
0
 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);
 }
예제 #12
0
        public void OnBeginSequenceItem(IByteSource source, uint length)
        {
            DicomSequence sq = _sequences.Peek();

            DicomDataset item = new DicomDataset();

            sq.Items.Add(item);

            _datasets.Push(item);
        }
예제 #13
0
        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);
        }
예제 #14
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);
            }
예제 #15
0
        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);
        }
예제 #16
0
 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();
 }
예제 #17
0
 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();
 }
예제 #18
0
 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);
 }
예제 #19
0
 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();
 }
예제 #20
0
 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);
 }
예제 #21
0
 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();
 }
예제 #22
0
 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);
     }
 }
예제 #23
0
 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);
 }
예제 #24
0
            /// <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);
            }
예제 #25
0
            /// <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);
            }
예제 #26
0
            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);
            }
예제 #27
0
            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);
            }
예제 #28
0
            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));
            }
예제 #29
0
 /// <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;
 }
예제 #30
0
        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;
            }
        }
예제 #31
0
 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}");
     }
 }
예제 #32
0
            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;
                }
            }
예제 #33
0
        /// <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);
        }
예제 #34
0
        /// <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);
        }
예제 #35
0
        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);
        }
예제 #36
0
            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;
            }
예제 #37
0
        /// <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;
            }
        }
예제 #38
0
        /// <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);
        }
예제 #39
0
            private async Task ParseFragmentSequenceAsync(IByteSource source)
            {
                _result = DicomReaderResult.Processing;

                while (!source.IsEOF)
                {
                    if (!ParseFragmentSequenceTag(source))
                    {
                        return;
                    }
                    if (!await ParseFragmentSequenceValueAsync(source).ConfigureAwait(false))
                    {
                        return;
                    }
                }
            }
예제 #40
0
            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);
		}
예제 #42
0
            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;
                }
            }
예제 #43
0
            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);
            }
예제 #44
0
            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);
            }
예제 #45
0
		public DicomReaderResult Read(IByteSource source, IDicomReaderObserver observer, DicomTag stop = null) {
			return EndRead(BeginRead(source, observer, stop, null, null));
		}
예제 #46
0
		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;
		}
예제 #47
0
		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();
				}
			}
		}
예제 #48
0
		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();
				}
			}
		}
예제 #49
0
		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;
		}
예제 #50
0
 public void OnBeginSequenceItem(IByteSource source, uint length)
 {
     foreach (IDicomReaderObserver observer in _observers) observer.OnBeginSequenceItem(source, length);
 }
예제 #51
0
 public void OnBeginSequence(IByteSource source, DicomTag tag, uint length)
 {
     foreach (IDicomReaderObserver observer in _observers) observer.OnBeginSequence(source, tag, length);
 }
예제 #52
0
 public void OnElement(IByteSource source, DicomTag tag, DicomVR vr, IByteBuffer data)
 {
     foreach (IDicomReaderObserver observer in _observers) observer.OnElement(source, tag, vr, data);
 }
예제 #53
0
 public void OnBeginFragmentSequence(IByteSource source, DicomTag tag, DicomVR vr)
 {
     foreach (IDicomReaderObserver observer in _observers) observer.OnBeginFragmentSequence(source, tag, vr);
 }
예제 #54
0
 public void OnBeginSequenceItem(IByteSource source, uint length)
 {
 }
예제 #55
0
 public void OnElement(IByteSource source, DicomTag tag, DicomVR vr, IByteBuffer data)
 {
     this.Tag = tag;
     this.VR = vr;
     this.Data = Encoding.UTF8.GetString(data.Data);
 }
예제 #56
0
 public void OnBeginSequence(IByteSource source, DicomTag tag, uint length)
 {
 }
예제 #57
0
		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();
				}
			}
		}
예제 #58
0
 public void OnFragmentSequenceItem(IByteSource source, IByteBuffer data)
 {
     _fragment.Add(data);
 }
예제 #59
0
 public void OnFragmentSequenceItem(IByteSource source, IByteBuffer data)
 {
     foreach (IDicomReaderObserver observer in _observers) observer.OnFragmentSequenceItem(source, data);
 }
예제 #60
0
 public void OnBeginFragmentSequence(IByteSource source, DicomTag tag, DicomVR vr)
 {
 }