public void OnBeginSequence(IByteSource source, DicomTag tag, uint length) { _currentSequenceTag.Push(tag); if (tag == DicomTag.DirectoryRecordSequence) { _directoryRecordSequence = _dataset.Get<DicomSequence>(tag); } }
private bool IsStoredTag(DicomTag tag) { if (_metaInfo.Contains(tag)) return true; //if it's meta info, just defer to the file. if (tag.TagValue <= 0x0002FFFF) return false; if (_xml.IsTagExcluded(tag.TagValue)) return false; if (tag.VR == DicomVr.SQvr) { var items = _xml[tag].Values as DicomSequenceItem[]; if (items != null) { if (items.OfType<InstanceXmlDicomSequenceItem>().Any(item => item.HasExcludedTags(true))) return false; } } bool isBinary = tag.VR == DicomVr.OBvr || tag.VR == DicomVr.OWvr || tag.VR == DicomVr.OFvr; //these tags are not stored in the xml. if (isBinary || tag.IsPrivate || tag.VR == DicomVr.UNvr) return false; return true; }
public void OnBeginSequence(IByteSource source, DicomTag tag, uint length) { DicomSequence sq = new DicomSequence(tag); _sequences.Push(sq); DicomDataset ds = _datasets.Peek(); ds.Add(sq); }
public void TestFile() { string filename = "OutOfRange.dcm"; DicomFile file = new DicomFile(filename, new DicomAttributeCollection(), new DicomAttributeCollection()); SetupMR(file.DataSet); SetupMetaInfo(file); DicomTag tag = new DicomTag(0x00030010, "Test", "TestBad", DicomVr.LOvr, false, 1, 1, false); file.DataSet[tag].SetStringValue("Test"); file.Save(filename); file = new DicomFile(filename); file.DataSet.IgnoreOutOfRangeTags = true; file.Load(); Assert.IsNotNull(file.DataSet.GetAttribute(tag)); file = new DicomFile(filename); file.DataSet.IgnoreOutOfRangeTags = false; try { file.Load(); Assert.Fail("file.Load failed"); } catch (DicomException) { } }
public DicomReaderEventArgs(long position, DicomTag tag, DicomVR vr, IByteBuffer data) { Position = position; Tag = tag; VR = vr; Data = data; }
public void OnElement_ValidData_AddsCorrectTypeToDataset(DicomTag tag, DicomVR vr, string data, Type expected) { var dataset = new DicomDataset(); var observer = new DicomDatasetReaderObserver(dataset); var buffer = new MemoryByteBuffer(Encoding.ASCII.GetBytes(data)); observer.OnElement(null, tag, vr, buffer); Assert.IsType(expected, dataset.First()); }
public DicomNGetRequest( DicomUID requestedClassUid, DicomUID requestedInstanceUid, DicomTag[] attributes, DicomPriority priority = DicomPriority.Medium) : base(DicomCommandField.NGetRequest, requestedClassUid, priority) { SOPInstanceUID = requestedInstanceUid; }
public IAsyncResult BeginRead(IByteSource source, IDicomReaderObserver observer, DicomTag stop, AsyncCallback callback, object state) { _stop = stop; _observer = observer; _result = DicomReaderResult.Processing; _exception = null; _async = new EventAsyncResult(callback, state); ThreadPool.QueueUserWorkItem(ParseProc, source); return _async; }
public void OnBeginFragmentSequence(IByteSource source, DicomTag tag, DicomVR vr) { if (vr == DicomVR.OB) _fragment = new DicomOtherByteFragment(tag); else if (vr == DicomVR.OW) _fragment = new DicomOtherWordFragment(tag); else throw new DicomDataException("Unexpected VR found for DICOM fragment sequence: {0}", vr.Code); DicomDataset ds = _datasets.Peek(); ds.Add(_fragment); }
public void OnElement(IByteSource source, DicomTag tag, DicomVR vr, IByteBuffer data) { _log.Log( _level, "{marker:x8}: {padding}{tag} {vrCode} {tagDictionaryEntryName} [{size}]", source.Marker, _pad, tag, vr.Code, tag.DictionaryEntry.Name, data.Size); }
public void OnBeginSequence(IByteSource source, DicomTag tag, uint length) { _log.Log( _level, "{marker:x8}: {padding}{tag} SQ {length}", source.Marker, _pad, tag, tag.DictionaryEntry.Name, length); IncreaseDepth(); }
public void OnBeginFragmentSequence(IByteSource source, DicomTag tag, DicomVR vr) { _log.Log( _level, "{marker:x8}: {padding}{tag} {vrCode} {tagDictionaryEntryName}", source.Marker, _pad, tag, vr.Code, tag.DictionaryEntry.Name); IncreaseDepth(); }
public DicomDictionaryEntry(DicomTag tag, string name, string keyword, DicomVM vm, bool retired, params DicomVr[] vrs) { Tag = tag; Name = string.IsNullOrWhiteSpace(name) ? tag.ToString() : name; Keyword = string.IsNullOrWhiteSpace(keyword) ? Name : keyword; ValueMultiplicity = vm; ValueRepresentations = vrs; IsRetired = retired; }
public void ConvertAttributeToUN(DicomAttributeCollection theSet, uint tag) { ByteBuffer theData = theSet[tag].GetByteBuffer(TransferSyntax.ImplicitVrLittleEndian, theSet.SpecificCharacterSet); DicomTag baseTag = DicomTagDictionary.GetDicomTag(tag); DicomTag theTag = new DicomTag(tag, baseTag.Name, baseTag.VariableName, DicomVr.UNvr, baseTag.MultiVR, baseTag.VMLow, baseTag.VMHigh, baseTag.Retired); DicomAttribute unAttrib = DicomVr.UNvr.CreateDicomAttribute(theTag, theData); theSet[tag] = unAttrib; }
public void TestIgnoreOutOfRangeTags() { DicomFile file = new DicomFile(); DicomAttributeCollection collection = file.DataSet; SetupMR(collection); collection.IgnoreOutOfRangeTags = true; DicomTag tag = new DicomTag(0x00030010, "Test", "TestBad", DicomVr.STvr, false, 1, 1, false); Assert.IsNotNull(collection.GetAttribute(tag)); Assert.IsNotNull(collection[tag]); try { DicomAttribute attrib = collection[tag.TagValue]; Assert.Fail("DicomAttributeCollection.GetAttribute failed"); } catch (DicomException) { } collection.IgnoreOutOfRangeTags = false; try { collection.GetAttribute(tag); Assert.Fail("DicomAttributeCollection.GetAttribute failed"); } catch (DicomException) { } try { DicomAttribute attrib = collection[tag]; Assert.Fail("DicomAttributeCollection.GetAttribute failed"); } catch (DicomException) { } try { DicomAttribute attrib = collection[tag.TagValue]; Assert.Fail("DicomAttributeCollection.GetAttribute failed"); } catch (DicomException) { } }
public void BeginRead_ValidExplicitVRData_YieldsSuccess(DicomTag tag, DicomVR vr, string data, byte[] bytes) { var stream = new MemoryStream(bytes); var source = new StreamByteSource(stream); var reader = new DicomReader { IsExplicitVR = true }; var observer = new LastElementObserver(); var result = reader.EndRead(reader.BeginRead(source, observer, null, null, null)); Assert.Equal(DicomReaderResult.Success, result); Assert.Equal(tag, observer.Tag); Assert.Equal(vr, observer.VR); Assert.Equal(data, observer.Data); }
public static void ValidateString(DicomTag tag, string stringValue) { if (string.IsNullOrEmpty(stringValue)) return; string[] temp = stringValue.Split(new[] { '\\' }); foreach (string s in temp) { double decVal; if (!string.IsNullOrEmpty(s) && !double.TryParse(s, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out decVal)) { throw new DicomDataException(string.Format("Invalid DS value '{0}' for {1}", stringValue, tag)); } } }
public static void ValidateString(DicomTag tag, string stringValue) { if (string.IsNullOrEmpty(stringValue)) return; string[] temp = stringValue.Split(new[] {'\\'}); foreach (string value in temp) { string s = value.Trim(); DateTime dt; if (!string.IsNullOrEmpty(s) && !DateParser.Parse(s, out dt)) { throw new DicomDataException(string.Format("Invalid DA value '{0}' for {1}", value, tag)); } } }
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); }
/// <summary> /// Creates an in-memory DICOM image /// </summary> /// <returns></returns> internal static DicomFile CreateDicomImage(int rows = 20, int columns = 30, bool bitsAllocated16 = true, bool signed = false, int numberOfFrames = 1, Endian endian = Endian.Little, bool useOB = false) { var sopClassUid = bitsAllocated16 ? SopClass.MultiFrameGrayscaleWordSecondaryCaptureImageStorageUid : SopClass.MultiFrameGrayscaleByteSecondaryCaptureImageStorageUid; var sopInstanceUid = DicomUid.GenerateUid().UID; var dcf = new DicomFile(); dcf.MediaStorageSopClassUid = sopClassUid; dcf.MediaStorageSopInstanceUid = sopInstanceUid; dcf.TransferSyntax = endian == Endian.Little ? TransferSyntax.ExplicitVrLittleEndian : TransferSyntax.ExplicitVrBigEndian; dcf.DataSet[DicomTags.PatientId].SetStringValue("TEST"); dcf.DataSet[DicomTags.PatientsName].SetStringValue("TEST"); dcf.DataSet[DicomTags.StudyInstanceUid].SetStringValue(DicomUid.GenerateUid().UID); dcf.DataSet[DicomTags.StudyId].SetStringValue("TEST"); dcf.DataSet[DicomTags.StudyDescription].SetStringValue("TEST"); dcf.DataSet[DicomTags.SeriesInstanceUid].SetStringValue(DicomUid.GenerateUid().UID); dcf.DataSet[DicomTags.SeriesNumber].SetInt32(0, 1); dcf.DataSet[DicomTags.SeriesDescription].SetStringValue("TEST"); dcf.DataSet[DicomTags.SopClassUid].SetStringValue(sopClassUid); dcf.DataSet[DicomTags.SopInstanceUid].SetStringValue(sopInstanceUid); dcf.DataSet[DicomTags.InstanceNumber].SetInt32(0, 1); var frameSize = rows*columns*(bitsAllocated16 ? 2 : 1); var data = new byte[numberOfFrames*frameSize]; for (var n = 0; n < numberOfFrames; ++n) { var value = (byte) (0xFF & (n + 0x80)); for (var k = 0; k < frameSize; ++k) data[n*frameSize + k] = (byte) ((value + k)%255); } var pixelDataTag = DicomTagDictionary.GetDicomTag(DicomTags.PixelData); pixelDataTag = new DicomTag(pixelDataTag.TagValue, pixelDataTag.Name, pixelDataTag.VariableName, useOB ? DicomVr.OBvr : DicomVr.OWvr, pixelDataTag.MultiVR, pixelDataTag.VMLow, pixelDataTag.VMHigh, pixelDataTag.Retired); dcf.DataSet[DicomTags.PhotometricInterpretation].SetStringValue(PhotometricInterpretation.Monochrome2.Code); dcf.DataSet[DicomTags.SamplesPerPixel].SetInt32(0, 1); dcf.DataSet[DicomTags.PixelRepresentation].SetInt32(0, signed ? 1 : 0); dcf.DataSet[DicomTags.BitsAllocated].SetInt32(0, bitsAllocated16 ? 16 : 8); dcf.DataSet[DicomTags.BitsStored].SetInt32(0, bitsAllocated16 ? 16 : 8); dcf.DataSet[DicomTags.HighBit].SetInt32(0, bitsAllocated16 ? 15 : 7); dcf.DataSet[DicomTags.Rows].SetInt32(0, rows); dcf.DataSet[DicomTags.Columns].SetInt32(0, columns); dcf.DataSet[DicomTags.NumberOfFrames].SetInt32(0, numberOfFrames); dcf.DataSet[pixelDataTag].Values = data; return dcf; }
private static void addValue(Dictionary<DicomTag, List<String>> tagTovalues, DicomTag tag, String value) { if (value == null || value.Length == 0) { return; } List<String> values; if (!tagTovalues.TryGetValue(tag, out values)) { values = new List<String>(); tagTovalues.Add(tag, values); } if (!values.Contains(value)) { values.Add(value); } }
public UnsignedDicomTagColumn(DicomTag dicomTag) : base(dicomTag) { }
public DicomAttribute this[DicomTag tag] { get { return(_collection[tag]); } set { _collection[tag] = value; } }
public void OnBeginFragmentSequence(IByteSource source, DicomTag tag, DicomVR vr) { _stack.Push(new DicomReaderEventArgs(source.Marker, tag, vr, null)); }
public static ExtendedQueryTagStoreEntry BuildExtendedQueryTagStoreEntry(this DicomTag tag, int key = 1, string vr = null, string privateCreator = null, QueryTagLevel level = QueryTagLevel.Series, ExtendedQueryTagStatus status = ExtendedQueryTagStatus.Ready) { return(new ExtendedQueryTagStoreEntry(key: key, path: tag.GetPath(), vr: vr ?? tag.GetDefaultVR().Code, privateCreator: privateCreator, level: level, status: status, queryStatus: QueryStatus.Enabled, errorCount: 0)); }
public override DicomAttribute this[DicomTag tag] { get { return(_dataset[tag]); } }
private DicomTag NewDicomTag(ushort group, ushort element) { return(new DicomTag(DicomTag.GetTagValue(group, element), "Throwaway Tag", "ThrowawayTag", DicomVr.UNvr, false, 1, uint.MaxValue, false)); }
/// <summary> /// Sets the specified <paramref name="dicomTag"/>'s attribute value to be null. /// </summary> /// <param name="dicomTag">The dicom tag.</param> public void SetAttributeNull(DicomTag dicomTag) { this.DicomAttributeProvider[dicomTag].SetNullValue(); }
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; }
private void InitializeSettings() { _logger.Log(LogLevel.Information, "Initializing AE Title {0} with processor {1}", _configuration.AeTitle, _configuration.Processor); string setting = string.Empty; if (_configuration.ProcessorSettings.TryGetValue("timeout", out setting)) { if (int.TryParse(setting, out int timeout)) { _timeout = timeout < 5 ? 5 : timeout; } else { throw new ConfigurationException($"Invalid processor setting 'timeout' specified for AE Title {_configuration.AeTitle}"); } } else { _timeout = DEFAULT_TIMEOUT_SECONDS; } _logger.Log(LogLevel.Information, "AE Title {0} Processor Setting: timeout={1}s", _configuration.AeTitle, _timeout); if (_configuration.ProcessorSettings.TryGetValue("jobRetryDelay", out setting)) { if (int.TryParse(setting, out int delay)) { _jobRetryDelay = delay; } else { throw new ConfigurationException($"Invalid processor setting 'jobRetryDelay' specified for AE Title {_configuration.AeTitle}"); } } else { _jobRetryDelay = DEFAULT_JOB_RETRY_DELAY_MS; } _logger.Log(LogLevel.Information, "AE Title {0} Processor Setting: jobRetryDelay={1}ms", _configuration.AeTitle, _jobRetryDelay); if (_configuration.ProcessorSettings.TryGetValue("priority", out setting)) { if (Enum.TryParse(setting, true, out JobPriority priority)) { _priority = priority; } else { throw new ConfigurationException($"Invalid processor setting 'priority' specified for AE Title {_configuration.AeTitle}"); } } else { _priority = JobPriority.Normal; } _logger.Log(LogLevel.Information, "AE Title {0} Processor Setting: priority={1}", _configuration.AeTitle, _priority); if (_configuration.ProcessorSettings.TryGetValue("groupBy", out setting)) { try { _grouping = DicomTag.Parse(setting); } catch (System.Exception ex) { throw new ConfigurationException($"Invalid processor setting 'groupBy' specified for AE Title {_configuration.AeTitle}", ex); } } else { _grouping = DicomTag.StudyInstanceUID; } _logger.Log(LogLevel.Information, "AE Title {0} Processor Setting: groupBy={1}", _configuration.AeTitle, _grouping); foreach (var key in _configuration.ProcessorSettings.Keys) { if (key.StartsWith("pipeline-", StringComparison.OrdinalIgnoreCase)) { var name = key.Substring(9); var value = _configuration.ProcessorSettings[key]; _pipelines.Add(name, value); _logger.Log(LogLevel.Information, "Pipeline {0}={1} added for AE Title {2}", name, value, _configuration.AeTitle); } } if (_pipelines.Count == 0) { throw new ConfigurationException($"No pipeline defined for AE Title {_configuration.AeTitle}"); } }
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; }
/// <summary> /// Gets the functional group sequence item for a particular tag in the data set (i.e. the parent sequence item containing the requested tag). /// </summary> /// <remarks> /// <para> /// If the requested tag is the root sequence tag of a functional group (e.g. <see cref="DicomTags.PatientOrientationInFrameSequence"/>), /// the returned sequence item will be the functional group sequence item for the frame in which the requested attribute can be found. /// </para> /// <para> /// If the requested tag is a nested tag of a functional group and the root sequence tag allows only one sequence item /// (e.g. <see cref="DicomTags.PatientOrientation"/> as a nested tag of <see cref="DicomTags.PatientOrientationInFrameSequence"/>), /// the returned sequence item will be the single sequence item in the root sequence attribute. /// </para> /// <para> /// It is not possible to directly access a nested tag of a functional group if the root sequence tag allows multiple sequence items /// (e.g. <see cref="DicomTags.RadiopharmaceuticalAgentNumber"/> as a nested tag of <see cref="DicomTags.RadiopharmaceuticalUsageSequence"/>). /// To do so, access the <see cref="DicomTags.RadiopharmaceuticalUsageSequence"/> and handle the sequence items individually. /// </para> /// </remarks> /// <param name="frameNumber">DICOM frame number (first frame is 1).</param> /// <param name="tag">DICOM tag of the attribute.</param> /// <param name="isFrameSpecific">Indicates whether or not the returned functional group is specific to the requested frame.</param> /// <returns>The requested functional group sequence item.</returns> public DicomSequenceItem GetFrameFunctionalGroupItem(int frameNumber, DicomTag tag, out bool isFrameSpecific) { return(GetFrameFunctionalGroupItem(frameNumber, tag.TagValue, out isFrameSpecific)); }
/// <summary> /// Get path of given Dicom Tag. /// e.g:Path of Dicom tag (0008,0070) is 00080070 /// </summary> /// <param name="dicomTag">The dicom tag</param> /// <returns>The path.</returns> public static string GetPath(this DicomTag dicomTag) { EnsureArg.IsNotNull(dicomTag, nameof(dicomTag)); return(dicomTag.Group.ToString("X4") + dicomTag.Element.ToString("X4")); }
public override bool TryGetAttribute(DicomTag tag, out DicomAttribute attribute) { return(_dataset.TryGetAttribute(tag, out attribute)); }
private bool ParseItemSequenceTag(IByteSource source) { if (_parseStage == ParseStage.Tag) { source.Mark(); if (!source.Require(8)) { _result = DicomReaderResult.Suspended; return(false); } var group = source.GetUInt16(); var 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(); // #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; } return(false); } _length = source.GetUInt32(); if (_tag == DicomTag.SequenceDelimitationItem) { // #64, in case explicit length has been specified despite occurrence of Sequence Delimitation Item if (source.HasReachedMilestone() && source.MilestonesCount > _sequenceDepth) { ResetState(); return(true); } // 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); } _parseStage = ParseStage.Value; } return(true); }
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 { 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(Filename, _stream.Position, _len, _endian, DicomVr.OBvr); DicomFragment fragment = new DicomFragment(reference); _fragment.AddFragment(fragment); _stream.Seek(_len, SeekOrigin.Current); } 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) { 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, Filename = Filename }; DicomReadStatus stat = idsr.Read(null, options); 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); Dataset.LoadDicomFields(_fragment); } } 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 !! _stream.Seek((int)_len, SeekOrigin.Current); _remain -= _len; BytesRead += _len; } else if ((LastTagRead.TagValue == DicomTags.PixelData) && Flags.IsSet(options, DicomReadOptions.StorePixelDataReferences)) { FileReference reference = new FileReference(Filename, _stream.Position, _len, _endian, LastTagRead.VR); _stream.Seek((int)_len, SeekOrigin.Current); if (LastTagRead.VR.Equals(DicomVr.OWvr)) { DicomAttributeOW elem = new DicomAttributeOW(LastTagRead, reference); Dataset[LastTagRead] = elem; } else if (LastTagRead.VR.Equals(DicomVr.OBvr)) { DicomAttributeOB elem = new DicomAttributeOB(LastTagRead, reference); Dataset[LastTagRead] = elem; } else { DicomAttributeOF elem = new DicomAttributeOF(LastTagRead, reference); 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); } }
public TextDicomTagColumn(DicomTag dicomTag) : base(dicomTag) { }
DicomAttribute IDicomAttributeProvider.this[DicomTag dicomTag] { get { return(this[dicomTag]); } set { throw new InvalidOperationException("The DICOM attributes of the Frame class should be considered read-only."); } }
/// <summary> /// Evaluate /// </summary> /// <param name="arg"></param> /// <returns></returns> public override object Evaluate(object arg) { if (string.IsNullOrEmpty(Text)) { return(null); } if (Text.StartsWith("$")) { var msg = arg as DicomMessageBase; var collection = arg as IDicomAttributeProvider; if (collection == null && msg == null) { return(null); } var tagArray = Text.Split(new[] { '/' }); DicomTag t = DicomTagDictionary.GetDicomTag(tagArray[0].Substring(1)); if (t == null) { throw new NoSuchDicomTagException(tagArray[0].Substring(1)); } if (msg != null) { if (msg.DataSet.Contains(t)) { collection = msg.DataSet; } else if (msg.MetaInfo.Contains(t)) { collection = msg.MetaInfo; } } if (collection == null) { return(null); } var attributeList = new List <DicomAttribute>(); ScanCollection(collection, tagArray, 0, attributeList); if (attributeList.Count == 0) { return(null); } if (attributeList.Count == 1) { return(CheckAttributeCollection(attributeList[0])); } string returnString = string.Empty; bool first = true; foreach (var attrib in attributeList) { var o = CheckAttributeCollection(attrib); if (o != null) { if (!first) { returnString += "\\"; } returnString += o.ToString(); first = false; } } if (string.IsNullOrEmpty(returnString)) { return(null); } return(returnString); } return(Text); }
public static AddExtendedQueryTagEntry BuildAddExtendedQueryTagEntry(this DicomTag tag, string vr = null, string privateCreator = null, QueryTagLevel level = QueryTagLevel.Series) { return(new AddExtendedQueryTagEntry { Path = tag.GetPath(), VR = vr ?? tag.GetDefaultVR()?.Code, PrivateCreator = privateCreator, Level = level }); }
bool IDicomAttributeProvider.TryGetAttribute(DicomTag dicomTag, out DicomAttribute dicomAttribute) { return(_parentImageSop.TryGetFrameAttribute(_frameNumber, dicomTag, out dicomAttribute)); }
/// <summary> /// Gets a specific DICOM attribute for this frame. /// </summary> /// <remarks> /// <see cref="DicomAttribute"/>s returned by this method should be considered /// read-only and should not be modified in any way. /// </remarks> /// <param name="dicomTag">The DICOM tag to retrieve.</param> /// <returns>Returns the requested <see cref="DicomAttribute"/>.</returns> public DicomAttribute this[DicomTag dicomTag] { get { return(_parentImageSop.GetFrameAttribute(_frameNumber, dicomTag)); } }
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(); } } }
public static GetExtendedQueryTagEntry BuildGetExtendedQueryTagEntry(this DicomTag tag, string vr = null, string privateCreator = null, QueryTagLevel level = QueryTagLevel.Series, ExtendedQueryTagStatus status = ExtendedQueryTagStatus.Ready) { return(new GetExtendedQueryTagEntry { Path = tag.GetPath(), VR = vr ?? tag.GetDefaultVR()?.Code, PrivateCreator = privateCreator, Level = level, Status = status }); }
public DicomReaderResult Read(IByteSource source, IDicomReaderObserver observer, DicomTag stop = null) { return EndRead(BeginRead(source, observer, stop, null, null)); }
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(); } } }
private string TagName(DicomTag t) { return(t.DictionaryEntry.Name + " " + t.ToString().ToUpper()); }
private static XmlElement CreateDicomAttributeElement(XmlDocument document, DicomTag dicomTag, string name) { XmlElement dicomAttributeElement = document.CreateElement(name); XmlAttribute tag = document.CreateAttribute("Tag"); tag.Value = "$" + dicomTag.VariableName; XmlAttribute vr = document.CreateAttribute("VR"); vr.Value = dicomTag.VR.ToString(); dicomAttributeElement.Attributes.Append(tag); dicomAttributeElement.Attributes.Append(vr); return dicomAttributeElement; }
/// <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 bool TryGetAttribute(DicomTag tag, out DicomAttribute attribute) { return(_collection.TryGetAttribute(tag, out attribute)); }
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 DicomReadStatus ParseTag(DicomTag stopAtTag, DicomReadOptions options) { if (_tag == null) { if (_remain >= 4) { _pos = _stream.Position + _offset; ushort g = _reader.ReadUInt16(); if (Flags.IsSet(options, DicomReadOptions.FileMetaInfoOnly) && g != 0x0002) { _stream.Seek(-2, SeekOrigin.Current); return(DicomReadStatus.SuccessEndRead); } ushort e = _reader.ReadUInt16(); if (DicomTag.IsPrivateGroup(g) && e > 0x00ff) { uint card = DicomTag.GetCard(g, e); if ((card & 0xffffff00) != _privateCreatorCard) { _privateCreatorCard = card & 0xffffff00; DicomTag pct = DicomTag.GetPrivateCreatorTag(g, e); DcmDataset ds = _dataset; if (_sds.Count > 0 && _sds.Count == _sqs.Count) { ds = _sds.Peek(); if (!ds.Contains(pct)) { ds = _dataset; } } _privateCreatorId = ds.GetString(pct, String.Empty); } _tag = new DicomTag(g, e, _privateCreatorId); } else { _tag = new DicomTag(g, e); if (g == 0xfffe) { if (_tag == DicomTags.Item || _tag == DicomTags.ItemDelimitationItem || _tag == DicomTags.SequenceDelimitationItem) { _vr = DicomVR.NONE; } } } _remain -= 4; _bytes += 4; _read += 4; } else { return(NeedMoreData(4)); } } if (_tag == DicomTags.ItemDelimitationItem && Flags.IsSet(options, DicomReadOptions.SequenceItemOnly)) { return(DicomReadStatus.SuccessEndRead); } if (_tag >= stopAtTag) { return(DicomReadStatus.SuccessEndRead); } return(DicomReadStatus.Success); }
private void ResetState() { _state = ParseState.Tag; _tag = null; _vr = null; _length = 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); }
public void OnBeginSequence(IByteSource source, DicomTag tag, uint length) { _log.Log(_level, "{marker:x8}: {padding}{tag} SQ {length}", source.Marker, _pad, tag, tag.DictionaryEntry.Name, length); IncreaseDepth(); }
public void OnBeginFragmentSequence(IByteSource source, DicomTag tag, DicomVR vr) { _log.Log(_level, "{marker:x8}: {padding}{tag} {vrCode} {tagDictionaryEntryName}", source.Marker, _pad, tag, vr.Code, tag.DictionaryEntry.Name); IncreaseDepth(); }
public void TestExcludePrivateTags() { List<DicomFile> images = SetupImages(2); StudyXml xml = new StudyXml(); DicomTag privateTag = new DicomTag(0x00210010, "Private Tag", "Private Tag", DicomVr.LTvr, false, 1, uint.MaxValue, false); foreach (DicomFile file in images) { file.DataSet[privateTag].SetStringValue("My Private Tag"); xml.AddFile(file); } StudyXmlOutputSettings settings = new StudyXmlOutputSettings(); XmlDocument doc = xml.GetMemento(settings); List<InstanceXmlDicomAttributeCollection> dataSets = GetInstanceXmlDataSets(xml); foreach (InstanceXmlDicomAttributeCollection dataSet in dataSets) Assert.IsFalse(dataSet.Contains(privateTag)); xml = new StudyXml(); xml.SetMemento(doc); dataSets = GetInstanceXmlDataSets(xml); foreach (InstanceXmlDicomAttributeCollection dataSet in dataSets) Assert.IsFalse(dataSet.Contains(privateTag)); }
public ExistsDicomMatchRule(DicomTag tag) { _tag = tag; }
private string GetTagName(DicomTag t) { return String.Format("{0}{1} {2}", _indent, t.ToString().ToUpper(), t.DictionaryEntry.Name); }
public void OnBeginSequence(IByteSource source, DicomTag tag, uint length) { _stack.Push(new DicomReaderEventArgs(source.Marker, tag, DicomVR.SQ, null)); }