Esempio n. 1
0
            private async Task <bool> ParseFragmentSequenceValueAsync(IByteSource source)
            {
                if (_parseStage == ParseStage.Value)
                {
                    if (!source.Require(_length))
                    {
                        _result = DicomReaderResult.Suspended;
                        return(false);
                    }

                    var buffer = await source.GetBufferAsync(_length).ConfigureAwait(false);

                    buffer = EndianByteBuffer.Create(buffer, source.Endian, _fragmentItem == 1 ? 4 : _vr.UnitSize);
                    _observer.OnFragmentSequenceItem(source, buffer);

                    _parseStage = ParseStage.Tag;
                }
                return(true);
            }
Esempio n. 2
0
            private async Task <bool> ParseValueAsync(IByteSource source)
            {
                if (_parseStage == ParseStage.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 || _tag == DicomTag.SequenceDelimitationItem)
                    {
                        // end of sequence item
                        return(false);
                    }

                    while (_vr == DicomVR.SQ && _tag.IsPrivate && _length > 0)
                    {
                        if (!IsPrivateSequence(source))
                        {
                            _vr = DicomVR.UN;
                            break;
                        }

                        if (IsPrivateSequenceBad(source, _length, _isExplicitVR))
                        {
                            _badPrivateSequence = true;
                            // store the depth of the bad sequence, we only want to switch back once we've processed
                            // the entire sequence, regardless of any sub-sequences.
                            _badPrivateSequenceDepth = _sequenceDepth;
                            _isExplicitVR            = !_isExplicitVR;
                        }
                        break;
                    }

                    var curIndex = source.Position;
                    // Fix to handle sequence items not associated with any sequence (#364)
                    if (_tag.Equals(DicomTag.Item))
                    {
                        source.Rewind();
                        _vr = DicomVR.SQ;
                    }

                    if (_vr == DicomVR.SQ)
                    {
                        // start of sequence
                        _observer.OnBeginSequence(source, _tag, _length);
                        _parseStage = ParseStage.Tag;
                        if (_length == 0)
                        {
                            _implicit = false;
                            source.PushMilestone((uint)(source.Position - curIndex));
                        }
                        else if (_length != _undefinedLength)
                        {
                            _implicit = false;
                            source.PushMilestone(_length);
                        }
                        else
                        {
                            _implicit = true;
                        }
                        var last = source.Position;

                        // Conformance with CP-246 (#177)
                        var needtoChangeEndian = false;
                        if (parsedVR == DicomVR.UN && !_tag.IsPrivate)
                        {
                            _implicit          = true;
                            needtoChangeEndian = source.Endian == Endian.Big;
                        }
                        if (needtoChangeEndian)
                        {
                            source.Endian = Endian.Little;
                        }

                        await ParseItemSequenceAsync(source).ConfigureAwait(false);

                        if (needtoChangeEndian)
                        {
                            source.Endian = Endian.Big;
                        }

                        // 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)
                        {
                            return(true);
                        }

                        _parseStage = ParseStage.Value;
                        _vr         = parsedVR;
                    }

                    if (_length == _undefinedLength)
                    {
                        _observer.OnBeginFragmentSequence(source, _tag, _vr);
                        _parseStage = ParseStage.Tag;
                        await ParseFragmentSequenceAsync(source).ConfigureAwait(false);

                        return(true);
                    }

                    if (!source.Require(_length))
                    {
                        _result = DicomReaderResult.Suspended;
                        return(false);
                    }

                    var buffer = await source.GetBufferAsync(_length).ConfigureAwait(false);

                    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
                    // according to
                    // http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_7.8.html
                    // Private Creator Data Elements numbered (gggg,0010-00FF) (gggg is odd)
                    // The VR of the private identification code shall be LO (Long String) and the VM shall be equal to 1.
                    if (_tag.IsPrivate && _tag.Element >= 0x0010 && _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) + _tag.Element;

                        lock (_locker)
                        {
                            _private[card] = creator;
                        }
                    }

                    ResetState();
                }
                return(true);
            }
Esempio n. 3
0
            private async Task<bool> ParseValueAsync(IByteSource source)
            {
                if (this.parseStage == ParseStage.Value)
                {
                    // check dictionary for VR after reading length to handle 16-bit lengths
                    // check before reading value to handle SQ elements
                    var parsedVR = this._vr;

                    // check dictionary for VR after reading length to handle 16-bit lengths
                    // check before reading value to handle SQ elements
                    if (this._vr == DicomVR.Implicit || (this._vr == DicomVR.UN && this.isExplicitVR))
                    {
                        var entry = this.dictionary[this._tag];
                        if (entry != null)
                        {
                            this._vr = entry.ValueRepresentations.FirstOrDefault();
                        }

                        if (this._vr == null)
                        {
                            this._vr = DicomVR.UN;
                        }
                    }

                    if (this._tag == DicomTag.ItemDelimitationItem)
                    {
                        // end of sequence item
                        return false;
                    }

                    while (this._vr == DicomVR.SQ && this._tag.IsPrivate)
                    {
                        if (!IsPrivateSequence(source))
                        {
                            this._vr = DicomVR.UN;
                            break;
                        }

                        if (IsPrivateSequenceBad(source, this.isExplicitVR))
                        {
                            this.badPrivateSequence = true;
                            this.isExplicitVR = !this.isExplicitVR;
                        }
                        break;
                    }

                    if (this._vr == DicomVR.SQ)
                    {
                        // start of sequence
                        this.observer.OnBeginSequence(source, this._tag, this.length);
                        this.parseStage = ParseStage.Tag;
                        if (this.length != UndefinedLength)
                        {
                            this._implicit = false;
                            source.PushMilestone(this.length);
                        }
                        else
                        {
                            this._implicit = true;
                        }
                        var last = source.Position;

                        // Conformance with CP-246 (#177)
                        var needtoChangeEndian = false;
                        if (parsedVR == DicomVR.UN && !this._tag.IsPrivate)
                        {
                            this._implicit = true;
                            needtoChangeEndian = source.Endian == Endian.Big;
                        }
                        if (needtoChangeEndian)
                        {
                            source.Endian = Endian.Little;
                        }

                        await this.ParseItemSequenceAsync(source).ConfigureAwait(false);

                        if (needtoChangeEndian)
                        {
                            source.Endian = Endian.Big;
                        }

                        // 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 || this.length == 0)
                        {
                            return true;
                        }

                        this.parseStage = ParseStage.Value;
                        this._vr = parsedVR;
                    }

                    if (this.length == UndefinedLength)
                    {
                        this.observer.OnBeginFragmentSequence(source, this._tag, this._vr);
                        this.parseStage = ParseStage.Tag;
                        await this.ParseFragmentSequenceAsync(source).ConfigureAwait(false);
                        return true;
                    }

                    if (!source.Require(this.length))
                    {
                        this.result = DicomReaderResult.Suspended;
                        return false;
                    }

                    var buffer = await source.GetBufferAsync(this.length).ConfigureAwait(false);

                    if (!this._vr.IsString)
                    {
                        buffer = EndianByteBuffer.Create(buffer, source.Endian, this._vr.UnitSize);
                    }
                    this.observer.OnElement(source, this._tag, this._vr, buffer);

                    // parse private creator value and add to lookup table
                    if (this._tag.IsPrivate && this._tag.Element != 0x0000 && this._tag.Element <= 0x00ff)
                    {
                        var creator =
                            DicomEncoding.Default.GetString(buffer.Data, 0, buffer.Data.Length)
                                .TrimEnd((char)DicomVR.LO.PaddingValue);
                        var card = (uint)(this._tag.Group << 16) + this._tag.Element;

                        lock (this.locker)
                        {
                            this._private[card] = creator;
                        }
                    }

                    this.ResetState();
                }
                return true;
            }
Esempio n. 4
0
            private async Task<bool> ParseFragmentSequenceValueAsync(IByteSource source)
            {
                if (this.parseStage == ParseStage.Value)
                {
                    if (!source.Require(this.length))
                    {
                        this.result = DicomReaderResult.Suspended;
                        return false;
                    }

                    var buffer = await source.GetBufferAsync(this.length).ConfigureAwait(false);
                    buffer = EndianByteBuffer.Create(buffer, source.Endian, this.fragmentItem == 1 ? 4 : this._vr.UnitSize);
                    this.observer.OnFragmentSequenceItem(source, buffer);

                    this.parseStage = ParseStage.Tag;
                }
                return true;
            }
Esempio n. 5
0
            private async Task <bool> ParseValueAsync(IByteSource source)
            {
                if (this.parseStage == ParseStage.Value)
                {
                    // check dictionary for VR after reading length to handle 16-bit lengths
                    // check before reading value to handle SQ elements
                    var parsedVR = this._vr;

                    // check dictionary for VR after reading length to handle 16-bit lengths
                    // check before reading value to handle SQ elements
                    if (this._vr == DicomVR.Implicit || (this._vr == DicomVR.UN && this.isExplicitVR))
                    {
                        var entry = this.dictionary[this._tag];
                        if (entry != null)
                        {
                            this._vr = entry.ValueRepresentations.FirstOrDefault();
                        }

                        if (this._vr == null)
                        {
                            this._vr = DicomVR.UN;
                        }
                    }

                    if (this._tag == DicomTag.ItemDelimitationItem)
                    {
                        // end of sequence item
                        return(false);
                    }

                    while (this._vr == DicomVR.SQ && this._tag.IsPrivate)
                    {
                        if (!IsPrivateSequence(source))
                        {
                            this._vr = DicomVR.UN;
                            break;
                        }

                        if (IsPrivateSequenceBad(source, this.isExplicitVR))
                        {
                            this.badPrivateSequence = true;
                            this.isExplicitVR       = !this.isExplicitVR;
                        }
                        break;
                    }

                    if (this._vr == DicomVR.SQ)
                    {
                        // start of sequence
                        this.observer.OnBeginSequence(source, this._tag, this.length);
                        this.parseStage = ParseStage.Tag;
                        if (this.length != UndefinedLength)
                        {
                            this._implicit = false;
                            source.PushMilestone(this.length);
                        }
                        else
                        {
                            this._implicit = true;
                        }
                        var last = source.Position;

                        // Conformance with CP-246 (#177)
                        var needtoChangeEndian = false;
                        if (parsedVR == DicomVR.UN && !this._tag.IsPrivate)
                        {
                            this._implicit     = true;
                            needtoChangeEndian = source.Endian == Endian.Big;
                        }
                        if (needtoChangeEndian)
                        {
                            source.Endian = Endian.Little;
                        }

                        await this.ParseItemSequenceAsync(source).ConfigureAwait(false);

                        if (needtoChangeEndian)
                        {
                            source.Endian = Endian.Big;
                        }

                        // 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 || this.length == 0)
                        {
                            return(true);
                        }

                        this.parseStage = ParseStage.Value;
                        this._vr        = parsedVR;
                    }

                    if (this.length == UndefinedLength)
                    {
                        this.observer.OnBeginFragmentSequence(source, this._tag, this._vr);
                        this.parseStage = ParseStage.Tag;
                        await this.ParseFragmentSequenceAsync(source).ConfigureAwait(false);

                        return(true);
                    }

                    if (!source.Require(this.length))
                    {
                        this.result = DicomReaderResult.Suspended;
                        return(false);
                    }

                    var buffer = await source.GetBufferAsync(this.length).ConfigureAwait(false);

                    if (!this._vr.IsString)
                    {
                        buffer = EndianByteBuffer.Create(buffer, source.Endian, this._vr.UnitSize);
                    }
                    this.observer.OnElement(source, this._tag, this._vr, buffer);

                    // parse private creator value and add to lookup table
                    if (this._tag.IsPrivate && this._tag.Element != 0x0000 && this._tag.Element <= 0x00ff)
                    {
                        var creator =
                            DicomEncoding.Default.GetString(buffer.Data, 0, buffer.Data.Length)
                            .TrimEnd((char)DicomVR.LO.PaddingValue);
                        var card = (uint)(this._tag.Group << 16) + this._tag.Element;

                        lock (this.locker)
                        {
                            this._private[card] = creator;
                        }
                    }

                    this.ResetState();
                }
                return(true);
            }