/// <summary> /// Loads a dicom file, stopping at a certain tag /// </summary> /// <param name="file">Filename</param> /// <param name="stopTag">Tag to stop parsing at</param> /// <param name="options">DICOM read options</param> public DicomReadStatus Load(String file, DicomTag stopTag, DicomReadOptions options) { using (FileStream fs = File.OpenRead(file)) { fs.Seek(128, SeekOrigin.Begin); CheckFileHeader(fs); DicomStreamReader dsr = new DicomStreamReader(fs); _metainfo = new DcmFileMetaInfo(); dsr.Dataset = _metainfo; dsr.Read(DcmFileMetaInfo.StopTag, options | DicomReadOptions.FileMetaInfoOnly); if (_metainfo.TransferSyntax.IsDeflate) { MemoryStream ms = StreamUtility.Deflate(fs, false); dsr = new DicomStreamReader(ms); } _dataset = new DcmDataset(_metainfo.TransferSyntax); dsr.Dataset = _dataset; DicomReadStatus status = dsr.Read(stopTag, options); fs.Close(); return(status); } }
private DicomReadStatus ParseSequenceItemDataset(DicomTransferSyntax syntax, long len, out DcmDataset dataset, DicomReadOptions options) { long pos = _stream.Position; dataset = new DcmDataset(pos, (uint)len, syntax); Stream stream = (len != UndefinedLength) ? new SegmentStream(_stream, _stream.Position, _len) : _stream; DicomStreamReader idsr = new DicomStreamReader(stream); idsr.Dataset = dataset; idsr.Encoding = _encoding; if (len != UndefinedLength) { idsr.PositionOffset = dataset.StreamPosition; } DicomReadStatus status = idsr.Read(null, options); if (status != DicomReadStatus.Success) { _stream.Seek(pos, SeekOrigin.Begin); dataset = null; } else { if (len == UndefinedLength) { // rewind delimitation item tag _stream.Seek(-4, SeekOrigin.Current); len = _stream.Position - pos; } _remain -= len; _bytes += len; _read += len; } return(status); }
public DicomReadStatus Read(DicomTag stopAtTag, DicomReadOptions options) { if (stopAtTag == null) { stopAtTag = new DicomTag(0xFFFFFFFF, "Bogus Tag", "BogusTag", DicomVr.UNvr, false, 1, 1, false); } // Counters: // _remain - bytes remaining in stream // _bytes - estimates bytes to end of dataset // _read - number of bytes read from stream try { BytesNeeded = 0; _remain = _stream.Length - _stream.Position; while (_remain > 0) { if (_inGroup2 && BytesRead >= _endGroup2) { _inGroup2 = false; // Only change if we're still reading the meta info if (Dataset.StartTagValue < DicomTags.TransferSyntaxUid) { TransferSyntax group2Syntax = TransferSyntax.GetTransferSyntax( Dataset[DicomTags.TransferSyntaxUid].GetString(0, String.Empty)); if (group2Syntax == null) { throw new DicomException("Unsupported transfer syntax in group 2 elements"); } TransferSyntax = group2Syntax; } } uint tagValue; if (LastTagRead == null) { if (_remain < 4) { return(NeedMoreData(4)); } _pos = _stream.Position; ushort g = _reader.ReadUInt16(); ushort e = _reader.ReadUInt16(); tagValue = DicomTag.GetTagValue(g, e); if (DicomTag.IsPrivateGroup(g) && e > 0x00ff) { SaveTagRead = LastTagRead = DicomTagDictionary.GetDicomTag(g, e) ?? new DicomTag((uint)g << 16 | e, "Private Tag", "PrivateTag", DicomVr.UNvr, false, 1, uint.MaxValue, false); } else { if (e == 0x0000) { SaveTagRead = LastTagRead = new DicomTag((uint)g << 16 | e, "Group Length", "GroupLength", DicomVr.ULvr, false, 1, 1, false); } else { SaveTagRead = LastTagRead = DicomTagDictionary.GetDicomTag(g, e) ?? new DicomTag((uint)g << 16 | e, "Private Tag", "PrivateTag", DicomVr.UNvr, false, 1, uint.MaxValue, false); } } _remain -= 4; BytesEstimated += 4; BytesRead += 4; } else { tagValue = LastTagRead.TagValue; } if ((tagValue >= stopAtTag.TagValue) && (_sqrs.Count == 0)) // only exit in root message when after stop tag { if (_inGroup2 && tagValue > 0x0002FFFF) { if (_endGroup2 != BytesRead - 4) { Platform.Log(LogLevel.Debug, "File Meta Info Length, {0}, not equal to actual bytes read in file, {1}, overwriting length.", EndGroupTwo, BytesRead - 4); _endGroup2 = BytesRead - 4; } _inGroup2 = false; } EncounteredStopTag = true; return(DicomReadStatus.Success); } bool twoByteLength; if (_vr == null) { if (_syntax.ExplicitVr) { if (LastTagRead == DicomTag.Item || LastTagRead == DicomTag.ItemDelimitationItem || LastTagRead == DicomTag.SequenceDelimitationItem) { _vr = DicomVr.NONE; twoByteLength = _vr.Is16BitLengthField; } else { if (_remain < 2) { return(NeedMoreData(2)); } string vr = new string(_reader.ReadChars(2)); _vr = DicomVr.GetVR(vr); twoByteLength = _vr.Is16BitLengthField; _remain -= 2; BytesEstimated += 2; BytesRead += 2; if (LastTagRead.VR.Equals(DicomVr.UNvr)) { LastTagRead = new DicomTag(LastTagRead.TagValue, "Private Tag", "PrivateTag", _vr, false, 1, uint.MaxValue, false); if (vr.Equals("??")) { twoByteLength = true; } } else if (!LastTagRead.VR.Equals(_vr)) { if (!vr.Equals(" ")) { DicomTag tag = new DicomTag(LastTagRead.TagValue, LastTagRead.Name, LastTagRead.VariableName, _vr, LastTagRead.MultiVR, LastTagRead.VMLow, LastTagRead.VMHigh, LastTagRead.Retired); LastTagRead = tag; ; // TODO, log something } } } } else { _vr = LastTagRead.VR; twoByteLength = _vr.Is16BitLengthField; } if (_vr == DicomVr.UNvr) { if (LastTagRead.IsPrivate) { if (LastTagRead.Element <= 0x00ff && LastTagRead.Element >= 0x0010) { // Reset the tag with the right VR and a more descriptive name. LastTagRead = new DicomTag(LastTagRead.TagValue, "Private Creator Code", "PrivateCreatorCode", DicomVr.LOvr, false, 1, uint.MaxValue, false); // private creator id // Only set the VR to LO for Implicit VR, if we do it for // Explicit VR syntaxes, we would incorrectly read the tag // length below. if (!_syntax.ExplicitVr) { _vr = DicomVr.LOvr; } } else if (_stream.CanSeek && Flags.IsSet(options, DicomReadOptions.AllowSeekingForContext)) { // attempt to identify private sequence by checking if the tag has // an undefined length long pos = _stream.Position; int bytesToCheck = _syntax.ExplicitVr ? 6 : 4; if (_remain >= bytesToCheck) { if (_syntax.ExplicitVr) { _reader.ReadUInt16(); } uint l = _reader.ReadUInt32(); if (l == _undefinedLength) { _vr = DicomVr.SQvr; } } _stream.Position = pos; } } } } else { twoByteLength = _vr.Is16BitLengthField; } // Read the value length if (_len == _undefinedLength) { if (_syntax.ExplicitVr) { if (LastTagRead == DicomTag.Item || LastTagRead == DicomTag.ItemDelimitationItem || LastTagRead == DicomTag.SequenceDelimitationItem) { if (_remain < 4) { return(NeedMoreData(4)); } _len = _reader.ReadUInt32(); _remain -= 4; BytesEstimated += 4; BytesRead += 4; } else { if (twoByteLength) { if (_remain < 2) { return(NeedMoreData(2)); } _len = _reader.ReadUInt16(); _remain -= 2; BytesEstimated += 2; BytesRead += 2; } else { if (_remain < 6) { return(NeedMoreData(6)); } _reader.ReadByte(); _reader.ReadByte(); _len = _reader.ReadUInt32(); _remain -= 6; BytesEstimated += 6; BytesRead += 6; } } } else { if (_remain < 4) { return(NeedMoreData(4)); } _len = _reader.ReadUInt32(); _remain -= 4; BytesEstimated += 4; BytesRead += 4; } if ((_len != _undefinedLength) && !_vr.Equals(DicomVr.SQvr) && !(LastTagRead.Equals(DicomTag.Item) && _fragment == null)) { BytesEstimated += _len; } } // If we have a private creator code, set the VR to LO, because // that is what it is. We must do this after we read the length // so that the 32 bit length is read properly. if ((LastTagRead.IsPrivate) && (_vr.Equals(DicomVr.UNvr)) && (LastTagRead.Element <= 0x00ff)) { _vr = DicomVr.LOvr; } if (_fragment != null) { // In the middle of parsing pixels if (LastTagRead == DicomTag.Item) { if (_remain < _len) { return(NeedMoreData(_remain - _len)); } if (Flags.IsSet(options, DicomReadOptions.StorePixelDataReferences) && _fragment.HasOffsetTable) { FileReference reference = new FileReference(StreamOpener, _stream.Position, _len, _endian, DicomVr.OBvr); DicomFragment fragment = new DicomFragment(reference); _fragment.AddFragment(fragment); if (_stream.CanSeek) { _stream.Seek(_len, SeekOrigin.Current); } else { ConsumeStreamBytes(_stream, _len); } } else { ByteBuffer data = new ByteBuffer(_endian, _len); data.CopyFrom(_stream, (int)_len); if (!_fragment.HasOffsetTable) { _fragment.SetOffsetTable(data); } else { DicomFragment fragment = new DicomFragment(data); _fragment.AddFragment(fragment); } } _remain -= _len; BytesRead += _len; } else if (LastTagRead == DicomTag.SequenceDelimitationItem) { if (_sqrs.Count > 0) { SequenceRecord rec = _sqrs.Peek(); DicomAttributeCollection ds = rec.Current; ds[_fragment.Tag] = _fragment; if (rec.Curlen != _undefinedLength) { long end = rec.Curpos + rec.Curlen; if (_stream.Position >= end) { rec.Current = null; } } } else { Dataset[_fragment.Tag] = _fragment; } _fragment = null; } else { Platform.Log(LogLevel.Error, "Encountered unexpected tag in stream: {0}", LastTagRead.ToString()); // unexpected tag return(DicomReadStatus.UnknownError); } } else if (_sqrs.Count > 0 && (LastTagRead == DicomTag.Item || LastTagRead == DicomTag.ItemDelimitationItem || LastTagRead == DicomTag.SequenceDelimitationItem)) { SequenceRecord rec = _sqrs.Peek(); if (LastTagRead.Equals(DicomTag.Item)) { if (_len != _undefinedLength) { if (_len > _remain) { return(NeedMoreData(_remain - _len)); } } DicomSequenceItem ds; if (rec.Tag.TagValue.Equals(DicomTags.DirectoryRecordSequence)) { DirectoryRecordSequenceItem dr = new DirectoryRecordSequenceItem { Offset = (uint)_pos }; ds = dr; } else { ds = new DicomSequenceItem(); } rec.Current = ds; if (rec.Tag.VR.Equals(DicomVr.UNvr)) { DicomTag tag = new DicomTag(rec.Tag.TagValue, rec.Tag.Name, rec.Tag.VariableName, DicomVr.SQvr, rec.Tag.MultiVR, rec.Tag.VMLow, rec.Tag.VMHigh, rec.Tag.Retired); rec.Parent[tag].AddSequenceItem(ds); } else { rec.Parent[rec.Tag].AddSequenceItem(ds); } // Specific character set is inherited, save it. It will be overwritten // if a new value of the tag is encountered in the sequence. rec.Current.SpecificCharacterSet = rec.Parent.SpecificCharacterSet; // save the sequence length rec.Curpos = _pos + 8; rec.Curlen = _len; _sqrs.Pop(); _sqrs.Push(rec); if (_len != _undefinedLength) { ByteBuffer data = new ByteBuffer(_endian, _len); data.CopyFrom(_stream, (int)_len); data.Stream.Position = 0; _remain -= _len; BytesRead += _len; DicomStreamReader idsr = new DicomStreamReader(data.Stream) { Dataset = ds, TransferSyntax = rec.Tag.VR.Equals(DicomVr.UNvr) ? TransferSyntax.ImplicitVrLittleEndian : _syntax, StreamOpener = StreamOpener }; DicomReadStatus stat = idsr.Read(null, options & ~DicomReadOptions.StorePixelDataReferences); if (stat != DicomReadStatus.Success) { Platform.Log(LogLevel.Error, "Unexpected parsing error ({0}) when reading sequence attribute: {1}.", stat, rec.Tag.ToString()); return(stat); } } } else if (LastTagRead == DicomTag.ItemDelimitationItem) { } else if (LastTagRead == DicomTag.SequenceDelimitationItem) { SequenceRecord rec2 = _sqrs.Pop(); if (rec2.Current == null) { rec2.Parent[rec.Tag].SetNullValue(); } } if (rec.Len != _undefinedLength) { long end = rec.Pos + 8 + rec.Len; if (_syntax.ExplicitVr) { end += 2 + 2; } if (_stream.Position >= end) { _sqrs.Pop(); } } } else { if (_len == _undefinedLength) { if (_vr.Equals(DicomVr.UNvr)) { if (!_syntax.ExplicitVr) { _vr = DicomVr.SQvr; LastTagRead = LastTagRead.IsPrivate ? new DicomTag(LastTagRead.TagValue, "Private Tag", "PrivateTag", DicomVr.SQvr, false, 1, uint.MaxValue, false) : new DicomTag(LastTagRead.TagValue, "Unknown Tag", "UnknownTag", DicomVr.SQvr, false, 1, uint.MaxValue, false); } else { // To handle this case, we'd have to add a new mechanism to transition the parser to implicit VR parsing, // and then return back to implicit once the parsing of the SQ is complete. Platform.Log(LogLevel.Error, "Encountered unknown tag {0}, encoded as undefined length in an Explicit VR transfer syntax at offset {1}. Unable to parse.", LastTagRead, _stream.Position); return(DicomReadStatus.UnknownError); } } if (_vr.Equals(DicomVr.SQvr)) { SequenceRecord rec = new SequenceRecord { Parent = _sqrs.Count > 0 ? _sqrs.Peek().Current : Dataset, Current = null, Tag = LastTagRead, Len = _undefinedLength }; _sqrs.Push(rec); } else { _fragment = new DicomFragmentSequence(LastTagRead); } } else { if (_vr.Equals(DicomVr.SQvr)) { if (_len == 0) { DicomAttributeCollection ds; if (_sqrs.Count > 0) { SequenceRecord rec = _sqrs.Peek(); ds = rec.Current; } else { ds = Dataset; } ds[LastTagRead].SetNullValue(); } else { SequenceRecord rec = new SequenceRecord { Len = _len, Pos = _pos, Tag = LastTagRead, Parent = _sqrs.Count > 0 ? _sqrs.Peek().Current : Dataset }; _sqrs.Push(rec); } } else { if (_remain < _len) { return(NeedMoreData(_len - _remain)); } if ((LastTagRead.TagValue == DicomTags.PixelData) && Flags.IsSet(options, DicomReadOptions.DoNotStorePixelDataInDataSet)) { // Skip PixelData !! if (_stream.CanSeek) { _stream.Seek((int)_len, SeekOrigin.Current); } else { ConsumeStreamBytes(_stream, _len); } _remain -= _len; BytesRead += _len; } else if ((LastTagRead.TagValue == DicomTags.PixelData) && Flags.IsSet(options, DicomReadOptions.StorePixelDataReferences)) { var reference = new FileReference(StreamOpener, _stream.Position, _len, _endian, LastTagRead.VR); if (_stream.CanSeek) { _stream.Seek((int)_len, SeekOrigin.Current); } else { ConsumeStreamBytes(_stream, _len); } DicomAttribute elem; if (LastTagRead.VR.Equals(DicomVr.OWvr)) { elem = new DicomAttributeOW(LastTagRead, reference); } else if (LastTagRead.VR.Equals(DicomVr.OBvr)) { elem = new DicomAttributeOB(LastTagRead, reference); } else if (LastTagRead.VR.Equals(DicomVr.ODvr)) { elem = new DicomAttributeOD(LastTagRead, reference); } else { elem = new DicomAttributeOF(LastTagRead, reference); } if (_sqrs.Count > 0) { SequenceRecord rec = _sqrs.Peek(); DicomAttributeCollection ds = rec.Current; ds[LastTagRead] = elem; if (rec.Curlen != _undefinedLength) { long end = rec.Curpos + rec.Curlen; if (_stream.Position >= end) { rec.Current = null; } } } else { Dataset[LastTagRead] = elem; } _remain -= _len; BytesRead += _len; } else { ByteBuffer bb = new ByteBuffer(_len); // If the tag is impacted by specific character set, // set the encoding properly. if (LastTagRead.VR.SpecificCharacterSet) { if (_sqrs.Count > 0) { SequenceRecord rec = _sqrs.Peek(); bb.SpecificCharacterSet = rec.Current.SpecificCharacterSet; } else { bb.SpecificCharacterSet = Dataset.SpecificCharacterSet; } } if (LastTagRead.VR.Equals(DicomVr.UNvr) && !SaveTagRead.VR.Equals(DicomVr.UNvr) && !SaveTagRead.VR.Equals(DicomVr.SQvr) && Flags.IsSet(options, DicomReadOptions.UseDictionaryForExplicitUN)) { LastTagRead = SaveTagRead; bb.Endian = Endian.Little; } else { bb.Endian = _endian; } bb.CopyFrom(_stream, (int)_len); DicomAttribute elem = LastTagRead.CreateDicomAttribute(bb); _remain -= _len; BytesRead += _len; if (_sqrs.Count > 0) { SequenceRecord rec = _sqrs.Peek(); DicomAttributeCollection ds = rec.Current; if (elem.Tag.TagValue == DicomTags.SpecificCharacterSet) { ds.SpecificCharacterSet = elem.ToString(); } if (LastTagRead.Element == 0x0000) { if (Flags.IsSet(options, DicomReadOptions.KeepGroupLengths)) { ds[LastTagRead] = elem; } } else { ds[LastTagRead] = elem; } if (rec.Curlen != _undefinedLength) { long end = rec.Curpos + rec.Curlen; if (_stream.Position >= end) { rec.Current = null; } } } else { if (LastTagRead.TagValue == DicomTags.FileMetaInformationGroupLength) { // Save the end of the group 2 elements, so that we can automatically // check and change our transfer syntax when needed. _inGroup2 = true; uint group2Len; elem.TryGetUInt32(0, out group2Len); _endGroup2 = BytesRead + group2Len; } else if (LastTagRead.TagValue == DicomTags.SpecificCharacterSet) { Dataset.SpecificCharacterSet = elem.ToString(); } if (LastTagRead.Element == 0x0000) { if (Flags.IsSet(options, DicomReadOptions.KeepGroupLengths)) { Dataset[LastTagRead] = elem; } } else { Dataset[LastTagRead] = elem; } } } } } } LastTagRead = null; _vr = null; _len = _undefinedLength; } return(DicomReadStatus.Success); } catch (EndOfStreamException e) { // should never happen Platform.Log(LogLevel.Error, "Unexpected exception when reading file: {0}", e.ToString()); return(DicomReadStatus.UnknownError); } }
private DicomReadStatus InsertSequenceItem(DicomReadOptions options) { if (_tag.Equals(DicomTags.Item)) { if (_len != UndefinedLength && _len > _remain) { return(NeedMoreData(_len)); } if (_sds.Count > _sqs.Count) { _sds.Pop(); } DcmItemSequenceItem si = new DcmItemSequenceItem(_pos, _len); if (_len != UndefinedLength || (_stream.CanSeek && Flags.IsSet(options, DicomReadOptions.AllowSeekingForContext))) { if (_len == UndefinedLength) { options |= DicomReadOptions.SequenceItemOnly; } DcmDataset ds = null; DicomReadStatus status = ParseSequenceItemDataset(TransferSyntax, _len, out ds, options); if (status != DicomReadStatus.Success) { Dicom.Debug.Log.Warn("Unknown error while attempting to read sequence item. Trying again with alternate encodings."); DicomTransferSyntax[] syntaxes = null; if (TransferSyntax == DicomTransferSyntax.ExplicitVRBigEndian) { syntaxes = new DicomTransferSyntax[] { DicomTransferSyntax.ImplicitVRLittleEndian, DicomTransferSyntax.ExplicitVRLittleEndian } } ; else if (TransferSyntax.IsExplicitVR) { syntaxes = new DicomTransferSyntax[] { DicomTransferSyntax.ImplicitVRLittleEndian, DicomTransferSyntax.ExplicitVRBigEndian } } ; else { syntaxes = new DicomTransferSyntax[] { DicomTransferSyntax.ExplicitVRLittleEndian, DicomTransferSyntax.ExplicitVRBigEndian } }; foreach (DicomTransferSyntax tx in syntaxes) { status = ParseSequenceItemDataset(tx, _len, out ds, options); if (status == DicomReadStatus.Success) { break; } } } if (status != DicomReadStatus.Success) { return(DicomReadStatus.UnknownError); } si.Dataset = ds; if (_len == UndefinedLength) { if (8 > _remain) { // need more data? _sds.Push(ds); } else { // skip delimitation item _stream.Seek(8, SeekOrigin.Current); _remain -= 8; _bytes += 8; _read += 8; } } } else { DcmDataset ds = new DcmDataset(_pos + 8, _len, TransferSyntax); _sds.Push(ds); } _sqs.Peek().AddSequenceItem(si); } else if (_tag == DicomTags.ItemDelimitationItem) { if (_sds.Count == _sqs.Count) { _sds.Pop(); } } else if (_tag == DicomTags.SequenceDelimitationItem) { if (_sds.Count == _sqs.Count) { _sds.Pop(); } _sqs.Pop(); } return(DicomReadStatus.Success); }
/// <summary> /// Read dataset from stream /// </summary> /// <param name="stopAtTag">End parsing at this tag</param> /// <param name="options">DICOM read options</param> /// <returns>Status code</returns> public DicomReadStatus Read(DicomTag stopAtTag, DicomReadOptions options) { // Counters: // _remain - bytes remaining in stream // _bytes - estimates bytes to end of dataset // _read - number of bytes read from stream try { _need = 0; _remain = _stream.Length - _stream.Position; while (_remain > 0) { DicomReadStatus status = ParseTag(stopAtTag, options); if (status == DicomReadStatus.SuccessEndRead) { return(DicomReadStatus.Success); } if (status != DicomReadStatus.Success) { return(status); } status = ParseVR(options); if (status != DicomReadStatus.Success) { return(status); } status = ParseLength(options); if (status != DicomReadStatus.Success) { return(status); } if (_tag.IsPrivate) { if (_tag.Element != 0x0000 && _tag.Element <= 0x00ff) { // handle UN private creator id if (_vr != DicomVR.LO && Flags.IsSet(options, DicomReadOptions.ForcePrivateCreatorToLO)) { Dicom.Debug.Log.Warn("Converting Private Creator VR from '{0}' to 'LO'", _vr.VR); _vr = DicomVR.LO; } } } if (_vr == DicomVR.UN && _syntax.IsExplicitVR && Flags.IsSet(options, DicomReadOptions.UseDictionaryForExplicitUN)) { _vr = _tag.Entry.DefaultVR; } if (_fragment != null) { status = InsertFragmentItem(options); if (status != DicomReadStatus.Success) { return(status); } } else if (_sqs.Count > 0 && (_tag == DicomTags.Item || _tag == DicomTags.ItemDelimitationItem || _tag == DicomTags.SequenceDelimitationItem)) { status = InsertSequenceItem(options); if (status != DicomReadStatus.Success) { return(status); } } else { if (_sqs.Count > 0) { DcmItemSequence sq = _sqs.Peek(); if (sq.StreamLength != UndefinedLength) { long end = sq.StreamPosition + 8 + sq.StreamLength; if (_syntax.IsExplicitVR) { end += 2 + 2; } if ((_stream.Position - _offset) >= end) { if (_sds.Count == _sqs.Count) { _sds.Pop(); } _sqs.Pop(); } } } if (_len == UndefinedLength) { if (_vr == DicomVR.SQ) { DcmItemSequence sq = new DcmItemSequence(_tag, _pos, _len, _endian); InsertDatasetItem(sq, options); _sqs.Push(sq); } else { _fragment = new DcmFragmentSequence(_tag, _vr, _pos, _endian); InsertDatasetItem(_fragment, options); } } else { if (_vr == DicomVR.SQ) { DcmItemSequence sq = new DcmItemSequence(_tag, _pos, _len, _endian); InsertDatasetItem(sq, options); _sqs.Push(sq); } else { if (_len > _remain) { return(NeedMoreData(_len)); } DcmElement elem = DcmElement.Create(_tag, _vr, _pos, _endian, CurrentBuffer(options)); _remain -= _len; _read += _len; InsertDatasetItem(elem, options); } } } _tag = null; _vr = null; _len = UndefinedLength; } return(DicomReadStatus.Success); } catch (EndOfStreamException) { // should never happen return(DicomReadStatus.UnknownError); } }
public DcmDimseInfo() { IsNewDimse = true; ParseDatasetStatus = DicomReadStatus.NeedMoreData; DatasetStopTag = null; StreamMessage = false; }
private void LoadCore(Stream stream, DicomStreamOpener streamOpener, DicomTag stopTag, DicomReadOptions options) { // TODO CR (24 Jan 2014): DICOM stream read only uses tag value, so the real implementation should be the uint overload! if (stopTag == null) { stopTag = new DicomTag(0xFFFFFFFF, "Bogus Tag", "BogusTag", DicomVr.NONE, false, 1, 1, false); } DicomStreamReader dsr; var iStream = stream ?? streamOpener.Open(); if (iStream.CanSeek) { iStream.Seek(128, SeekOrigin.Begin); if (!FileHasPart10Header(iStream)) { if (!Flags.IsSet(options, DicomReadOptions.ReadNonPart10Files)) { throw new DicomException(String.Format("File is not part 10 format file: {0}", Filename)); } iStream.Seek(0, SeekOrigin.Begin); dsr = new DicomStreamReader(iStream) { StreamOpener = streamOpener, TransferSyntax = TransferSyntax.ImplicitVrLittleEndian, Dataset = DataSet }; DicomReadStatus stat = dsr.Read(stopTag, options); if (stat != DicomReadStatus.Success) { Platform.Log(LogLevel.Error, "Unexpected error when reading file: {0}", Filename); throw new DicomException("Unexpected read error with file: " + Filename); } TransferSyntax = TransferSyntax.ImplicitVrLittleEndian; if (DataSet.Contains(DicomTags.SopClassUid)) { MediaStorageSopClassUid = DataSet[DicomTags.SopClassUid].ToString(); } if (DataSet.Contains(DicomTags.SopInstanceUid)) { MediaStorageSopInstanceUid = DataSet[DicomTags.SopInstanceUid].ToString(); } Loaded = true; return; } } else { // TODO CR (04 Apr 2014): this code here is almost identical to the seekable stream above, except that we use the 4CC wrapper // we can combine these two when we trust that the wrapper works in all cases iStream = FourCcReadStream.Create(iStream); // Read the 128 byte header first, then check for DICM iStream.SeekEx(128, SeekOrigin.Begin); if (!FileHasPart10Header(iStream)) { if (!Flags.IsSet(options, DicomReadOptions.ReadNonPart10Files)) { throw new DicomException(String.Format("File is not part 10 format file: {0}", Filename)); } iStream.Seek(0, SeekOrigin.Begin); dsr = new DicomStreamReader(iStream) { StreamOpener = streamOpener, TransferSyntax = TransferSyntax.ImplicitVrLittleEndian, Dataset = DataSet }; DicomReadStatus stat = dsr.Read(stopTag, options); if (stat != DicomReadStatus.Success) { Platform.Log(LogLevel.Error, "Unexpected error when reading file: {0}", Filename); throw new DicomException("Unexpected read error with file: " + Filename); } TransferSyntax = TransferSyntax.ImplicitVrLittleEndian; if (DataSet.Contains(DicomTags.SopClassUid)) { MediaStorageSopClassUid = DataSet[DicomTags.SopClassUid].ToString(); } if (DataSet.Contains(DicomTags.SopInstanceUid)) { MediaStorageSopInstanceUid = DataSet[DicomTags.SopInstanceUid].ToString(); } Loaded = true; return; } } dsr = new DicomStreamReader(iStream) { TransferSyntax = TransferSyntax.ExplicitVrLittleEndian, StreamOpener = streamOpener, Dataset = MetaInfo }; DicomReadStatus readStat = dsr.Read(new DicomTag(0x0002FFFF, "Bogus Tag", "BogusTag", DicomVr.UNvr, false, 1, 1, false), options); if (readStat != DicomReadStatus.Success) { Platform.Log(LogLevel.Error, "Unexpected error when reading file Meta info for file: {0}", Filename); throw new DicomException("Unexpected failure reading file Meta info for file: " + Filename); } MetaInfoFileLength = dsr.EndGroupTwo + 128 + 4; dsr.Dataset = DataSet; dsr.TransferSyntax = TransferSyntax; readStat = dsr.Read(stopTag, options); if (readStat != DicomReadStatus.Success) { Platform.Log(LogLevel.Error, "Unexpected error ({0}) when reading file at offset {2}: {1}", readStat, Filename, dsr.BytesRead); throw new DicomException("Unexpected failure (" + readStat + ") reading file at offset " + dsr.BytesRead + ": " + Filename); } Loaded = true; }
/// <summary> /// Load a DICOM file from an input stream. /// </summary> /// <remarks> /// Note: If the file does not contain DICM encoded in it, and /// <see cref="Stream.CanSeek"/> is true for <paramref name="iStream"/>, /// the routine will assume the file is not a Part 10 format file, and is /// instead encoded as just a DataSet with the transfer syntax set to /// Implicit VR Little Endian. /// </remarks> /// <param name="iStream">The input stream to read from.</param> /// <param name="stopTag">The dicom tag to stop the reading at.</param> /// <param name="options">The dicom read options to consider.</param> public void Load(Stream iStream, DicomTag stopTag, DicomReadOptions options) { if (iStream == null) { throw new ArgumentNullException("iStream"); } if (stopTag == null) { stopTag = new DicomTag(0xFFFFFFFF, "Bogus Tag", "BogusTag", DicomVr.NONE, false, 1, 1, false); } DicomStreamReader dsr; if (iStream.CanSeek) { iStream.Seek(128, SeekOrigin.Begin); if (!FileHasPart10Header(iStream)) { if (!Flags.IsSet(options, DicomReadOptions.ReadNonPart10Files)) { throw new DicomException(String.Format("File is not part 10 format file: {0}", Filename)); } iStream.Seek(0, SeekOrigin.Begin); dsr = new DicomStreamReader(iStream) { Filename = Filename, TransferSyntax = TransferSyntax.ImplicitVrLittleEndian, Dataset = DataSet }; DicomReadStatus stat = dsr.Read(stopTag, options); if (stat != DicomReadStatus.Success) { Platform.Log(LogLevel.Error, "Unexpected error when reading file: {0}", Filename); throw new DicomException("Unexpected read error with file: " + Filename); } TransferSyntax = TransferSyntax.ImplicitVrLittleEndian; if (DataSet.Contains(DicomTags.SopClassUid)) { MediaStorageSopClassUid = DataSet[DicomTags.SopClassUid].ToString(); } if (DataSet.Contains(DicomTags.SopInstanceUid)) { MediaStorageSopInstanceUid = DataSet[DicomTags.SopInstanceUid].ToString(); } return; } } else { // Read the 128 byte header first, then check for DICM iStream.Read(new byte[128], 0, 128); if (!FileHasPart10Header(iStream)) { Platform.Log(LogLevel.Error, "Reading DICOM file from stream, file does not have part 10 format header."); throw new DicomException("File being read from stream is not a part 10 format file"); } } dsr = new DicomStreamReader(iStream) { TransferSyntax = TransferSyntax.ExplicitVrLittleEndian, Filename = Filename, Dataset = MetaInfo }; DicomReadStatus readStat = dsr.Read(new DicomTag(0x0002FFFF, "Bogus Tag", "BogusTag", DicomVr.UNvr, false, 1, 1, false), options); if (readStat != DicomReadStatus.Success) { Platform.Log(LogLevel.Error, "Unexpected error when reading file Meta info for file: {0}", Filename); throw new DicomException("Unexpected failure reading file Meta info for file: " + Filename); } dsr.Dataset = DataSet; dsr.TransferSyntax = TransferSyntax; readStat = dsr.Read(stopTag, options); if (readStat != DicomReadStatus.Success) { Platform.Log(LogLevel.Error, "Unexpected error ({0}) when reading file at offset {2}: {1}", readStat, Filename, dsr.BytesRead); throw new DicomException("Unexpected failure (" + readStat + ") reading file at offset " + dsr.BytesRead + ": " + Filename); } }