private static bool IsPrivateSequenceBad(IByteSource source, bool isExplicitVR) { source.Mark(); try { source.GetUInt16(); // group source.GetUInt16(); // element source.GetUInt32(); // length source.GetUInt16(); // group source.GetUInt16(); // element var bytes = source.GetBytes(2); var vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); DicomVR dummy; if (DicomVR.TryParse(vr, out dummy)) { return(!isExplicitVR); } // unable to parse VR if (isExplicitVR) { return(true); } } finally { source.Rewind(); } return(false); }
private 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); DicomVR dummy; if (DicomVR.TryParse(vr, out dummy)) { return(!_explicit); } // unable to parse VR if (_explicit) { return(true); } } finally { source.Rewind(); } return(false); }
private static bool IsPrivateSequenceBad(IByteSource source, bool isExplicitVR) { source.Mark(); try { // Skip "item" tags; continue skipping until length is non-zero (#223) while (new DicomTag(source.GetUInt16(), source.GetUInt16()) == DicomTag.Item // group, element & source.GetUInt32() == 0) // length (using & instead of && enforces RHS to be evaluated regardless of LHS) { } source.GetUInt16(); // group source.GetUInt16(); // element var bytes = source.GetBytes(2); var vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); DicomVR dummy; if (DicomVR.TryParse(vr, out dummy)) { return(!isExplicitVR); } // unable to parse VR if (isExplicitVR) { return(true); } } finally { source.Rewind(); } return(false); }
private 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); }
public void ExportBytes(IByteSource editvar) { var dlg = new SaveFileDialog(); var bytes = editvar.GetBytes(); dlg.Filter = string.Join("|", ImportExportUtility.GetPossibleExtensions(bytes, (CVariable)editvar)); dlg.InitialDirectory = MainController.Get().Configuration.InitialExportDirectory; if (dlg.ShowDialog() == DialogResult.OK) { MainController.Get().Configuration.InitialExportDirectory = Path.GetDirectoryName(dlg.FileName); using (var fs = new FileStream(dlg.FileName, FileMode.Create, FileAccess.Write)) using (var writer = new BinaryWriter(fs)) { bytes = ImportExportUtility.GetExportBytes(bytes, Path.GetExtension(dlg.FileName), (CVariable)editvar); writer.Write(bytes); MainController.LogString( $"{((CVariable) editvar).GetFullDependencyStringName()} succesfully exported to {dlg.FileName}", Logtype.Success); } } }
private void ParseDataset(IByteSource source, object state) { try { _result = DicomReaderResult.Processing; while (!source.IsEOF && !source.HasReachedMilestone() && _result == DicomReaderResult.Processing) { if (_state == ParseState.Tag) { source.Mark(); if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } ushort group = source.GetUInt16(); ushort element = source.GetUInt16(); DicomPrivateCreator creator = null; if (group.IsOdd() && element > 0x00ff) { string pvt = null; uint card = (uint)(group << 16) + (uint)(element >> 8); if (_private.TryGetValue(card, out pvt)) { creator = Dictionary.GetPrivateCreator(pvt); } } _tag = new DicomTag(group, element, creator); _entry = Dictionary[_tag]; if (!_tag.IsPrivate && _entry != null && _entry.MaskTag == null) { _tag = _entry.Tag; // Use dictionary tag } if (_stop != null && _tag.CompareTo(_stop) >= 0) { _result = DicomReaderResult.Stopped; return; } _state = ParseState.VR; } while (_state == ParseState.VR) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { _vr = DicomVR.NONE; _state = ParseState.Length; break; } if (IsExplicitVR) { if (!source.Require(2, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } byte[] bytes = source.GetBytes(2); string vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); if (!DicomVR.TryParse(vr, out _vr)) { // unable to parse VR _vr = DicomVR.UN; } } else { if (_entry != null) { if (_entry == DicomDictionary.UnknownTag) { _vr = DicomVR.UN; } else if (_entry.ValueRepresentations.Contains(DicomVR.OB) && _entry.ValueRepresentations.Contains(DicomVR.OW)) { _vr = DicomVR.OW; // ??? } else { _vr = _entry.ValueRepresentations.FirstOrDefault(); } } } if (_vr == null) { _vr = DicomVR.UN; } _state = ParseState.Length; if (_vr == DicomVR.UN) { if (_tag.Element == 0x0000) { // Group Length to UL _vr = DicomVR.UL; break; } else if (IsExplicitVR) { break; } } if (_tag.IsPrivate) { if (_tag.Element != 0x0000 && _tag.Element <= 0x00ff && _vr == DicomVR.UN) { _vr = DicomVR.LO; // force private creator to LO } } } while (_state == ParseState.Length) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); _state = ParseState.Value; break; } if (IsExplicitVR) { if (_vr.Is16bitLength) { if (!source.Require(2, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt16(); } else { if (!source.Require(6, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } source.Skip(2); _length = source.GetUInt32(); } } else { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); // assume that undefined length in implicit dataset is SQ if (_length == UndefinedLength && _vr == DicomVR.UN) { _vr = DicomVR.SQ; } } _state = ParseState.Value; } if (_state == ParseState.Value) { // check dictionary for VR after reading length to handle 16-bit lengths // check before reading value to handle SQ elements var parsedVR = _vr; // check dictionary for VR after reading length to handle 16-bit lengths // check before reading value to handle SQ elements if (_vr == DicomVR.UN && IsExplicitVR) { var entry = Dictionary[_tag]; if (entry != null) { _vr = entry.ValueRepresentations.FirstOrDefault(); } if (_vr == null) { _vr = DicomVR.UN; } } if (_tag == DicomTag.ItemDelimitationItem) { // end of sequence item return; } while (_vr == DicomVR.SQ && _tag.IsPrivate) { if (!IsPrivateSequence(source)) { _vr = DicomVR.UN; break; } if (IsPrivateSequenceBad(source)) { _badPrivateSequence = true; _explicit = !_explicit; } break; } if (_vr == DicomVR.SQ) { // start of sequence _observer.OnBeginSequence(source, _tag, _length); _state = ParseState.Tag; if (_length != UndefinedLength) { _implicit = false; source.PushMilestone(_length); } else { _implicit = true; } PushState(state); var last = source.Position; ParseItemSequence(source, null); // Aeric Sylvan - https://github.com/rcd/fo-dicom/issues/62#issuecomment-46248073 // Fix reading of SQ with parsed VR of UN if (source.Position > last || _length == 0) { continue; } else { _state = ParseState.Value; _vr = parsedVR; } } if (_length == UndefinedLength) { _observer.OnBeginFragmentSequence(source, _tag, _vr); _state = ParseState.Tag; PushState(state); ParseFragmentSequence(source, null); continue; } if (!source.Require(_length, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } IByteBuffer buffer = source.GetBuffer(_length); if (!_vr.IsString) { buffer = EndianByteBuffer.Create(buffer, source.Endian, _vr.UnitSize); } _observer.OnElement(source, _tag, _vr, buffer); // parse private creator value and add to lookup table if (_tag.IsPrivate && _tag.Element != 0x0000 && _tag.Element <= 0x00ff) { var creator = DicomEncoding.Default.GetString(buffer.Data, 0, buffer.Data.Length).TrimEnd((char)DicomVR.LO.PaddingValue); var card = (uint)(_tag.Group << 16) + (uint)(_tag.Element); _private[card] = creator; } ResetState(); } } if (source.HasReachedMilestone()) { // end of explicit length sequence item source.PopMilestone(); return; } if (_result != DicomReaderResult.Processing) { return; } // end of processing _result = DicomReaderResult.Success; } catch (Exception e) { _exception = e; _result = DicomReaderResult.Error; } finally { if (_result != DicomReaderResult.Processing && _result != DicomReaderResult.Suspended) { _async.Set(); } } }
private void ParseDataset(IByteSource source, object state) { try { _result = DicomReaderResult.Processing; while (!source.IsEOF && !source.HasReachedMilestone() && _result == DicomReaderResult.Processing) { if (_state == ParseState.Tag) { source.Mark(); if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } ushort group = source.GetUInt16(); ushort element = source.GetUInt16(); DicomPrivateCreator creator = null; if (group.IsOdd() && element > 0x00ff) { string pvt = null; uint card = (uint)(group << 16) + (uint)(element >> 8); if (_private.TryGetValue(card, out pvt)) creator = Dictionary.GetPrivateCreator(pvt); } _tag = new DicomTag(group, element, creator); if (_stop != null && _tag.CompareTo(_stop) >= 0) { _result = DicomReaderResult.Stopped; return; } _state = ParseState.VR; } while (_state == ParseState.VR) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { _vr = DicomVR.NONE; _state = ParseState.Length; break; } if (IsExplicitVR) { if (!source.Require(2, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } byte[] bytes = source.GetBytes(2); string vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); try { _vr = DicomVR.Parse(vr); } catch { // unable to parse VR _vr = DicomVR.UN; } } else { DicomDictionaryEntry entry = Dictionary[_tag]; if (entry != null) { if (entry == DicomDictionary.UnknownTag) _vr = DicomVR.UN; else if (entry.ValueRepresentations.Contains(DicomVR.OB) && entry.ValueRepresentations.Contains(DicomVR.OW)) _vr = DicomVR.OW; // ??? else _vr = entry.ValueRepresentations.FirstOrDefault(); } } if (_vr == null) _vr = DicomVR.UN; _state = ParseState.Length; if (_vr == DicomVR.UN) { if (_tag.Element == 0x0000) { // Group Length to UL _vr = DicomVR.UL; break; } else if (IsExplicitVR) { break; } } if (_tag.IsPrivate) { if (_tag.Element != 0x0000 && _tag.Element <= 0x00ff && _vr == DicomVR.UN) _vr = DicomVR.LO; // force private creator to LO } } while (_state == ParseState.Length) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); _state = ParseState.Value; break; } if (IsExplicitVR) { if (_vr.Is16bitLength) { if (!source.Require(2, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt16(); } else { if (!source.Require(6, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } source.Skip(2); _length = source.GetUInt32(); } } else { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); // assume that undefined length in implicit dataset is SQ if (_length == UndefinedLength && _vr == DicomVR.UN) _vr = DicomVR.SQ; } _state = ParseState.Value; } if (_state == ParseState.Value) { // check dictionary for VR after reading length to handle 16-bit lengths // check before reading value to handle SQ elements if (_vr == DicomVR.UN && IsExplicitVR) { var entry = Dictionary[_tag]; if (entry != null) _vr = entry.ValueRepresentations.FirstOrDefault(); if (_vr == null) _vr = DicomVR.UN; } if (_tag == DicomTag.ItemDelimitationItem) { // end of sequence item return; } while (_vr == DicomVR.SQ && _tag.IsPrivate) { if (!IsPrivateSequence(source)) { _vr = DicomVR.UN; break; } if (IsPrivateSequenceBad(source)) { _badPrivateSequence = true; _explicit = !_explicit; } break; } if (_vr == DicomVR.SQ) { // start of sequence _observer.OnBeginSequence(source, _tag, _length); _state = ParseState.Tag; if (_length != UndefinedLength) { _implicit = false; source.PushMilestone(_length); } else _implicit = true; PushState(state); ParseItemSequence(source, null); continue; } if (_length == UndefinedLength) { _observer.OnBeginFragmentSequence(source, _tag, _vr); _state = ParseState.Tag; PushState(state); ParseFragmentSequence(source, null); continue; } if (!source.Require(_length, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } IByteBuffer buffer = source.GetBuffer(_length); if (!_vr.IsString) buffer = EndianByteBuffer.Create(buffer, source.Endian, _vr.UnitSize); _observer.OnElement(source, _tag, _vr, buffer); // parse private creator value and add to lookup table if (_tag.IsPrivate && _tag.Element != 0x0000 && _tag.Element <= 0x00ff) { var creator = DicomEncoding.Default.GetString(buffer.Data, 0, buffer.Data.Length).TrimEnd((char)DicomVR.LO.PaddingValue); var card = (uint)(_tag.Group << 16) + (uint)(_tag.Element); _private[card] = creator; } ResetState(); } } if (source.HasReachedMilestone()) { // end of explicit length sequence item source.PopMilestone(); return; } if (_result != DicomReaderResult.Processing) return; // end of processing _result = DicomReaderResult.Success; } catch (Exception e) { _exception = e; _result = DicomReaderResult.Error; } finally { if (_result != DicomReaderResult.Processing && _result != DicomReaderResult.Suspended) { _async.Set(); } } }
public SimpleByteSource(IByteSource source) { _bytes = source.GetBytes(); }
private static void Preprocess( IByteSource source, ref DicomFileFormat fileFormat, ref DicomTransferSyntax syntax) { // mark file origin source.Mark(); // test for DICM preamble source.Skip(128); if (source.GetUInt8() == 'D' && source.GetUInt8() == 'I' && source.GetUInt8() == 'C' && source.GetUInt8() == 'M') { fileFormat = DicomFileFormat.DICOM3; } // test for incorrect syntax in file meta info do { if (fileFormat == DicomFileFormat.DICOM3) { // move milestone to after preamble source.Mark(); } else { // rewind to origin milestone source.Rewind(); } // test for file meta info var group = source.GetUInt16(); if (@group > 0x00ff) { source.Endian = Endian.Big; syntax = DicomTransferSyntax.ExplicitVRBigEndian; @group = Endian.Swap(@group); } if (@group > 0x00ff) { // invalid starting tag fileFormat = DicomFileFormat.Unknown; source.Rewind(); break; } if (fileFormat == DicomFileFormat.Unknown) { fileFormat = @group == 0x0002 ? DicomFileFormat.DICOM3NoPreamble : DicomFileFormat.DICOM3NoFileMetaInfo; } var element = source.GetUInt16(); var tag = new DicomTag(@group, element); // test for explicit VR var vrt = Encoding.UTF8.GetBytes(tag.DictionaryEntry.ValueRepresentations[0].Code); var vrs = source.GetBytes(2); if (vrt[0] != vrs[0] || vrt[1] != vrs[1]) { // implicit VR syntax = syntax.Endian == Endian.Little ? DicomTransferSyntax.ImplicitVRLittleEndian : DicomTransferSyntax.ImplicitVRBigEndian; } source.Rewind(); }while (fileFormat == DicomFileFormat.Unknown); if (fileFormat == DicomFileFormat.Unknown) { throw new DicomReaderException("Attempted to read invalid DICOM file"); } // Adopt transfer syntax endianess to byte source. source.Endian = syntax.Endian; }
private bool IsPrivateSequenceBad(IByteSource source) { source.Mark(); try { var group = source.GetUInt16(); var element = source.GetUInt16(); var tag = new DicomTag(group, element); var length = source.GetUInt32(); group = source.GetUInt16(); element = source.GetUInt16(); tag = new DicomTag(group, element); byte[] bytes = source.GetBytes(2); string vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); try { DicomVR.Parse(vr); return !_explicit; } catch { // unable to parse VR if (_explicit) return true; } } finally { source.Rewind(); } return false; }
private bool ParseVR(IByteSource source) { while (this.parseStage == ParseStage.VR) { if (this._tag == DicomTag.Item || this._tag == DicomTag.ItemDelimitationItem || this._tag == DicomTag.SequenceDelimitationItem) { this._vr = DicomVR.NONE; this.parseStage = ParseStage.Length; break; } if (this.isExplicitVR) { if (!source.Require(2)) { this.result = DicomReaderResult.Suspended; return false; } source.Mark(); var bytes = source.GetBytes(2); var vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); if (string.IsNullOrWhiteSpace(vr)) { if (this._entry != null) { this._vr = this._entry.ValueRepresentations.FirstOrDefault(); } } else if (!DicomVR.TryParse(vr, out this._vr)) { // unable to parse VR; rewind VR bytes for continued attempt to interpret the data. this._vr = DicomVR.Implicit; source.Rewind(); } } else { if (this._entry != null) { if (this._entry == DicomDictionary.UnknownTag) { this._vr = DicomVR.UN; } else if (this._entry.ValueRepresentations.Contains(DicomVR.OB) && this._entry.ValueRepresentations.Contains(DicomVR.OW)) { this._vr = DicomVR.OW; // ??? } else { this._vr = this._entry.ValueRepresentations.FirstOrDefault(); } } } if (this._vr == null) { this._vr = DicomVR.UN; } this.parseStage = ParseStage.Length; if (this._vr == DicomVR.UN) { if (this._tag.Element == 0x0000) { // Group Length to UL this._vr = DicomVR.UL; break; } if (this.isExplicitVR) { break; } } if (this._tag.IsPrivate) { if (this._tag.Element != 0x0000 && this._tag.Element <= 0x00ff && this._vr == DicomVR.UN) { this._vr = DicomVR.LO; // force private creator to LO } } } return true; }
private bool ParseVR(IByteSource source) { while (_parseStage == ParseStage.VR) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { _vr = DicomVR.NONE; _parseStage = ParseStage.Length; break; } if (_isExplicitVR || _badPrivateSequence) { if (!source.Require(2)) { _result = DicomReaderResult.Suspended; return(false); } source.Mark(); var bytes = source.GetBytes(2); var vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); if (string.IsNullOrEmpty(vr.Trim())) { if (_entry != null) { _vr = _entry.ValueRepresentations.FirstOrDefault(); } } else if (!DicomVR.TryParse(vr, out _vr)) { // unable to parse VR; rewind VR bytes for continued attempt to interpret the data. _vr = DicomVR.Implicit; source.Rewind(); } } else { if (_entry != null) { if (_entry == DicomDictionary.UnknownTag) { _vr = DicomVR.UN; } else if (_entry.ValueRepresentations.Contains(DicomVR.OB) && _entry.ValueRepresentations.Contains(DicomVR.OW)) { _vr = DicomVR.OW; // ??? } else { _vr = _entry.ValueRepresentations.FirstOrDefault(); } } } if (_vr == null) { _vr = DicomVR.UN; } _parseStage = ParseStage.Length; if (_vr == DicomVR.UN) { if (_tag.Element == 0x0000) { // Group Length to UL // change 20161216: if changing from UN to UL then ParseLength causes a error, since length in UL is 2 bytes while length in UN is 6 bytes. // so the source hat UN and coded the length in 6 bytes. if here the VR was changed to UL then ParseLength would only read 2 bytes and the parser is then wrong. // but no worry: in ParseValue in the first lines there is a lookup in the Dictionary of DicomTags and there the VR is changed to UL so that the value is finally interpreted correctly as UL. // _vr = DicomVR.UL; break; } if (_isExplicitVR) { break; } } if (_tag.IsPrivate) { // 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.Element >= 0x0010 && _tag.Element <= 0x00ff && _vr == DicomVR.UN) { _vr = DicomVR.LO; // force private creator to LO } } } return(true); }
private static void Preprocess( IByteSource source, ref DicomFileFormat fileFormat, ref DicomTransferSyntax syntax) { // mark file origin source.Mark(); // test for DICM preamble source.Skip(128); if (source.GetUInt8() == 'D' && source.GetUInt8() == 'I' && source.GetUInt8() == 'C' && source.GetUInt8() == 'M') { fileFormat = DicomFileFormat.DICOM3; } // test for incorrect syntax in file meta info do { if (fileFormat == DicomFileFormat.DICOM3) { // move milestone to after preamble source.Mark(); } else { // rewind to origin milestone source.Rewind(); } // test for file meta info var group = source.GetUInt16(); if (@group > 0x00ff) { source.Endian = Endian.Big; syntax = DicomTransferSyntax.ExplicitVRBigEndian; @group = Endian.Swap(@group); } if (@group > 0x00ff) { // invalid starting tag fileFormat = DicomFileFormat.Unknown; source.Rewind(); break; } if (fileFormat == DicomFileFormat.Unknown) { fileFormat = @group == 0x0002 ? DicomFileFormat.DICOM3NoPreamble : DicomFileFormat.DICOM3NoFileMetaInfo; } var element = source.GetUInt16(); var tag = new DicomTag(@group, element); // test for explicit VR var vrt = Encoding.UTF8.GetBytes(tag.DictionaryEntry.ValueRepresentations[0].Code); var vrs = source.GetBytes(2); if (vrt[0] != vrs[0] || vrt[1] != vrs[1]) { // implicit VR syntax = syntax.Endian == Endian.Little ? DicomTransferSyntax.ImplicitVRLittleEndian : DicomTransferSyntax.ImplicitVRBigEndian; } source.Rewind(); } while (fileFormat == DicomFileFormat.Unknown); if (fileFormat == DicomFileFormat.Unknown) { throw new DicomReaderException("Attempted to read invalid DICOM file"); } // Adopt transfer syntax endianess to byte source. source.Endian = syntax.Endian; }
private static bool IsPrivateSequenceBad(IByteSource source, bool isExplicitVR) { source.Mark(); try { source.GetUInt16(); // group source.GetUInt16(); // element source.GetUInt32(); // length source.GetUInt16(); // group source.GetUInt16(); // element var bytes = source.GetBytes(2); var vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); DicomVR dummy; if (DicomVR.TryParse(vr, out dummy)) return !isExplicitVR; // unable to parse VR if (isExplicitVR) return true; } finally { source.Rewind(); } return false; }
private void ParseDataset(IByteSource source, object state) { try { _result = DicomReaderResult.Processing; while (!source.IsEOF && !source.HasReachedMilestone()) { if (_state == ParseState.Tag) { source.Mark(); if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } ushort group = source.GetUInt16(); ushort element = source.GetUInt16(); DicomPrivateCreator creator = null; if (group.IsOdd() && element > 0x00ff) { string pvt = null; uint card = (uint)(group << 16) + (uint)(element >> 8); if (_private.TryGetValue(card, out pvt)) { creator = Dictionary.GetPrivateCreator(pvt); } } _tag = new DicomTag(group, element, creator); if (_stop != null && _tag.CompareTo(_stop) >= 0) { _result = DicomReaderResult.Stopped; return; } _state = ParseState.VR; } while (_state == ParseState.VR) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { _vr = DicomVR.NONE; _state = ParseState.Length; break; } if (IsExplicitVR) { if (!source.Require(2, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } byte[] bytes = source.GetBytes(2); string vr = Encoding.ASCII.GetString(bytes); _vr = DicomVR.Parse(vr); } else { DicomDictionaryEntry entry = Dictionary[_tag]; if (entry != null) { if (entry.ValueRepresentations.Contains(DicomVR.OB) && entry.ValueRepresentations.Contains(DicomVR.OW)) { _vr = DicomVR.OW; // ??? } else { _vr = entry.ValueRepresentations.FirstOrDefault(); } } } if (_vr == null) { _vr = DicomVR.UN; } _state = ParseState.Length; if (_vr == DicomVR.UN) { if (_tag.Element == 0x0000) { // Group Length to UL _vr = DicomVR.UL; break; } if (_tag.Group.IsOdd()) { if (_tag.Element <= 0x00ff) { // Private Creator to LO _vr = DicomVR.LO; break; } else if (IsExplicitVR) { DicomDictionaryEntry entry = Dictionary[_tag]; if (entry != null) { _vr = entry.ValueRepresentations.FirstOrDefault(); } if (_vr == null) { _vr = DicomVR.UN; } break; } } } } while (_state == ParseState.Length) { if (_tag == DicomTag.Item || _tag == DicomTag.ItemDelimitationItem || _tag == DicomTag.SequenceDelimitationItem) { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); _state = ParseState.Value; break; } if (IsExplicitVR) { if (_vr.Is16bitLength) { if (!source.Require(2, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt16(); } else { if (!source.Require(6, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } source.Skip(2); _length = source.GetUInt32(); } } else { if (!source.Require(4, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } _length = source.GetUInt32(); } _state = ParseState.Value; } if (_state == ParseState.Value) { if (_tag == DicomTag.ItemDelimitationItem) { // end of sequence item ParseItemSequence(source, state); return; } if (_vr == DicomVR.SQ) { // start of sequence _observer.OnBeginSequence(source, _tag, _length); _state = ParseState.Tag; if (_length != UndefinedLength) { source.PushMilestone(_length); } PushState(state); ParseItemSequence(source, null); continue; } if (_length == UndefinedLength) { _observer.OnBeginFragmentSequence(source, _tag, _vr); _state = ParseState.Tag; PushState(state); ParseFragmentSequence(source, null); continue; } if (!source.Require(_length, ParseDataset, state)) { _result = DicomReaderResult.Suspended; return; } IByteBuffer buffer = source.GetBuffer(_length); if (!_vr.IsString) { buffer = EndianByteBuffer.Create(buffer, source.Endian, _vr.UnitSize); } _observer.OnElement(source, _tag, _vr, buffer); ResetState(); } } if (source.HasReachedMilestone()) { // end of explicit length sequence item _observer.OnEndSequenceItem(); source.PopMilestone(); ParseItemSequence(source, state); return; } // end of processing _result = DicomReaderResult.Success; } catch (Exception e) { _exception = e; _result = DicomReaderResult.Error; } finally { if (_result != DicomReaderResult.Processing && _result != DicomReaderResult.Suspended) { _async.Set(); } } }
private bool ParseVR(IByteSource source) { while (this.parseStage == ParseStage.VR) { if (this._tag == DicomTag.Item || this._tag == DicomTag.ItemDelimitationItem || this._tag == DicomTag.SequenceDelimitationItem) { this._vr = DicomVR.NONE; this.parseStage = ParseStage.Length; break; } if (this.isExplicitVR) { if (!source.Require(2)) { this.result = DicomReaderResult.Suspended; return(false); } source.Mark(); var bytes = source.GetBytes(2); var vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); if (string.IsNullOrWhiteSpace(vr)) { if (this._entry != null) { this._vr = this._entry.ValueRepresentations.FirstOrDefault(); } } else if (!DicomVR.TryParse(vr, out this._vr)) { // unable to parse VR; rewind VR bytes for continued attempt to interpret the data. this._vr = DicomVR.Implicit; source.Rewind(); } } else { if (this._entry != null) { if (this._entry == DicomDictionary.UnknownTag) { this._vr = DicomVR.UN; } else if (this._entry.ValueRepresentations.Contains(DicomVR.OB) && this._entry.ValueRepresentations.Contains(DicomVR.OW)) { this._vr = DicomVR.OW; // ??? } else { this._vr = this._entry.ValueRepresentations.FirstOrDefault(); } } } if (this._vr == null) { this._vr = DicomVR.UN; } this.parseStage = ParseStage.Length; if (this._vr == DicomVR.UN) { if (this._tag.Element == 0x0000) { // Group Length to UL this._vr = DicomVR.UL; break; } if (this.isExplicitVR) { break; } } if (this._tag.IsPrivate) { if (this._tag.Element != 0x0000 && this._tag.Element <= 0x00ff && this._vr == DicomVR.UN) { this._vr = DicomVR.LO; // force private creator to LO } } } return(true); }
private bool ParseVR(IByteSource source) { while (this.parseStage == ParseStage.VR) { if (this._tag == DicomTag.Item || this._tag == DicomTag.ItemDelimitationItem || this._tag == DicomTag.SequenceDelimitationItem) { this._vr = DicomVR.NONE; this.parseStage = ParseStage.Length; break; } if (this.isExplicitVR || this.badPrivateSequence) { if (!source.Require(2)) { this.result = DicomReaderResult.Suspended; return(false); } source.Mark(); var bytes = source.GetBytes(2); var vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); if (string.IsNullOrEmpty(vr.Trim())) { if (this._entry != null) { this._vr = this._entry.ValueRepresentations.FirstOrDefault(); } } else if (!DicomVR.TryParse(vr, out this._vr)) { // unable to parse VR; rewind VR bytes for continued attempt to interpret the data. this._vr = DicomVR.Implicit; source.Rewind(); } } else { if (this._entry != null) { if (this._entry == DicomDictionary.UnknownTag) { this._vr = DicomVR.UN; } else if (this._entry.ValueRepresentations.Contains(DicomVR.OB) && this._entry.ValueRepresentations.Contains(DicomVR.OW)) { this._vr = DicomVR.OW; // ??? } else { this._vr = this._entry.ValueRepresentations.FirstOrDefault(); } } } if (this._vr == null) { this._vr = DicomVR.UN; } this.parseStage = ParseStage.Length; if (this._vr == DicomVR.UN) { if (this._tag.Element == 0x0000) { // Group Length to UL // change 20161216: if changing from UN to UL then ParseLength causes a error, since length in UL is 2 bytes while length in UN is 6 bytes. // so the source hat UN and coded the length in 6 bytes. if here the VR was changed to UL then ParseLength would only read 2 bytes and the parser is then wrong. // but no worry: in ParseValue in the first lines there is a lookup in the Dictionary of DicomTags and there the VR is changed to UL so that the value is finally interpreted correctly as UL. // this._vr = DicomVR.UL; break; } if (this.isExplicitVR) { break; } } if (this._tag.IsPrivate) { if (this._tag.Element != 0x0000 && this._tag.Element <= 0x00ff && this._vr == DicomVR.UN) { this._vr = DicomVR.LO; // force private creator to LO } } } return(true); }
private static bool IsPrivateSequenceBad(IByteSource source, bool isExplicitVR) { source.Mark(); try { // Skip "item" tags; continue skipping until length is non-zero (#223) while (new DicomTag(source.GetUInt16(), source.GetUInt16()) == DicomTag.Item // group, element & source.GetUInt32() == 0) // length (using & instead of && enforces RHS to be evaluated regardless of LHS) { } source.GetUInt16(); // group source.GetUInt16(); // element var bytes = source.GetBytes(2); var vr = Encoding.UTF8.GetString(bytes, 0, bytes.Length); DicomVR dummy; if (DicomVR.TryParse(vr, out dummy)) return !isExplicitVR; // unable to parse VR if (isExplicitVR) return true; } finally { source.Rewind(); } return false; }
private void ParsePreamble(IByteSource source, object state) { try { if (!source.Require(132, ParsePreamble, state)) { return; } // mark file origin _source.Mark(); // test for DICM preamble _source.Skip(128); if (_source.GetUInt8() == 'D' && _source.GetUInt8() == 'I' && _source.GetUInt8() == 'C' && _source.GetUInt8() == 'M') { _fileFormat = DicomFileFormat.DICOM3; } // test for incorrect syntax in file meta info do { if (_fileFormat == DicomFileFormat.DICOM3) { // move milestone to after preamble _source.Mark(); } else { // rewind to origin milestone _source.Rewind(); } // test for file meta info var group = _source.GetUInt16(); if (group > 0x00ff) { _source.Endian = Endian.Big; _syntax = DicomTransferSyntax.ExplicitVRBigEndian; group = Endian.Swap(group); } if (group > 0x00ff) { // invalid starting tag _fileFormat = DicomFileFormat.Unknown; _source.Rewind(); break; } if (_fileFormat == DicomFileFormat.Unknown) { if (group == 0x0002) { _fileFormat = DicomFileFormat.DICOM3NoPreamble; } else { _fileFormat = DicomFileFormat.DICOM3NoFileMetaInfo; } } var element = _source.GetUInt16(); var tag = new DicomTag(group, element); // test for explicit VR var vrt = Encoding.ASCII.GetBytes(tag.DictionaryEntry.ValueRepresentations[0].Code); var vrs = _source.GetBytes(2); if (vrt[0] != vrs[0] || vrt[1] != vrs[1]) { // implicit VR if (_syntax.Endian == Endian.Little) { _syntax = DicomTransferSyntax.ImplicitVRLittleEndian; } else { _syntax = DicomTransferSyntax.ImplicitVRBigEndian; } } _source.Rewind(); } while (_fileFormat == DicomFileFormat.Unknown); if (_fileFormat == DicomFileFormat.Unknown) { throw new DicomReaderException("Attempted to read invalid DICOM file"); } var obs = new DicomReaderCallbackObserver(); if (_fileFormat != DicomFileFormat.DICOM3) { obs.Add(DicomTag.RecognitionCodeRETIRED, (object sender, DicomReaderEventArgs ea) => { try { string code = Encoding.ASCII.GetString(ea.Data.Data); if (code == "ACR-NEMA 1.0") { _fileFormat = DicomFileFormat.ACRNEMA1; } else if (code == "ACR-NEMA 2.0") { _fileFormat = DicomFileFormat.ACRNEMA2; } } catch { } }); } obs.Add(DicomTag.TransferSyntaxUID, (object sender, DicomReaderEventArgs ea) => { try { string uid = Encoding.ASCII.GetString(ea.Data.Data); _syntax = DicomTransferSyntax.Parse(uid); } catch { } }); _source.Endian = _syntax.Endian; _reader.IsExplicitVR = _syntax.IsExplicitVR; if (_fileFormat == DicomFileFormat.DICOM3NoFileMetaInfo) { _reader.BeginRead(_source, new DicomReaderMultiObserver(obs, _dataObserver), null, OnDatasetParseComplete, null); } else { _reader.BeginRead(_source, new DicomReaderMultiObserver(obs, _fmiObserver), FileMetaInfoStopTag, OnFileMetaInfoParseComplete, null); } } catch (Exception e) { if (_exception == null) { _exception = e; } _result = DicomReaderResult.Error; } finally { if (_result != DicomReaderResult.Processing && _result != DicomReaderResult.Suspended) { _async.Set(); } } }