public bool OnBeginFragment(DicomFragmentSequence fragment) { _log.Log(_level, "{padding}{tag} {vrCode} {tagDictionaryEntryName} [{offsets} offsets, {fragments} fragments]", (_depth > 0) ? _pad + "> " : "", fragment.Tag, fragment.ValueRepresentation.Code, fragment.Tag.DictionaryEntry.Name, fragment.OffsetTable.Count, fragment.Fragments.Count); return(true); }
public bool OnBeginFragment(DicomFragmentSequence fragment) { WriteTagHeader(fragment.Tag, fragment.ValueRepresentation, UndefinedLength); WriteTagHeader(DicomTag.Item, DicomVR.NONE, (uint)(fragment.OffsetTable.Count * 4)); foreach (uint offset in fragment.OffsetTable) _target.Write(offset); return true; }
public bool OnBeginFragment(DicomFragmentSequence fragment) { var tag = String.Format("{0} {1}", fragment.Tag.ToString().ToUpper(), fragment.Tag.DictionaryEntry.Name); TextItems.Add(new DicomTextItem(_level++, tag, fragment.ValueRepresentation.Code)); return(true); }
public bool OnBeginFragment(DicomFragmentSequence fragment) { _log.Log(_level, "{0}{1} {2} {3} [{4} offsets, {5} fragments]", (_depth > 0) ? _pad + "> " : "", fragment.Tag, fragment.ValueRepresentation.Code, fragment.Tag.DictionaryEntry.Name, fragment.OffsetTable.Count, fragment.Fragments.Count); return true; }
public void TestFragmentsWithOffsetTableExplicitVr() { var syntax = TransferSyntax.ExplicitVrLittleEndian; var sq = new DicomFragmentSequence(DicomTags.PixelData); sq.SetOffsetTable(new List <uint>()); // note: an empty fragment sequence still has one item in it representing the empty offset table // furthermore, fragment sequences are *always* undefined sequence length and explicit item (fragment) length // sq_length = tag(4) + vr(2) + reserved(2) + len(4) + item_tag(4) + item_len(4) + offset_table(0) // + sq_delimiter_tag(4) + sq_delimiter_len(4) var options = DicomWriteOptions.WriteFragmentOffsetTable; Assert.AreEqual(28, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); options = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequence; Assert.AreEqual(28, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); options = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequenceItem; Assert.AreEqual(28, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); options = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequence | DicomWriteOptions.ExplicitLengthSequenceItem; Assert.AreEqual(28, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); }
public bool OnBeginFragment(DicomFragmentSequence fragment) { _log.AppendFormat("{0}{1} {2} {3} [{4} offsets, {5} fragments]", (_depth > 0) ? _pad + "> " : "", fragment.Tag, fragment.ValueRepresentation.Code, fragment.Tag.DictionaryEntry.Name, fragment.OffsetTable.Count, fragment.Fragments.Count).AppendLine(); return(true); }
public bool OnBeginFragment(DicomFragmentSequence fragment) { var tag = String.Format("{0} {1}", fragment.Tag.ToString().ToUpper(), fragment.Tag.DictionaryEntry.Name); TextItems.Add(new DicomTextItem(_level++, tag, fragment.ValueRepresentation.Code)); return true; }
public DicomCompressedPixelData(DicomMessageBase msg, byte[] frameData) : base(msg) { _sq = new DicomFragmentSequence(DicomTags.PixelData); AddFrameFragment(frameData); //ByteBuffer buffer = new ByteBuffer(frameData); //DicomFragment fragment = new DicomFragment(buffer); //_sq.AddFragment(fragment); NumberOfFrames = 1; }
public bool OnBeginFragment(DicomFragmentSequence fragment) { var tag = String.Format("{0}{1} {2}", Indent, fragment.Tag.ToString().ToUpper(), fragment.Tag.DictionaryEntry.Name); Form.AddItem(tag, fragment.ValueRepresentation.Code, String.Empty, String.Empty); Level++; return(true); }
public uint Calculate(DicomItem item) { uint length = 0; length += 4; // tag if (_syntax.IsExplicitVR) { length += 2; // vr if (item.ValueRepresentation.Is16bitLength) { length += 2; // length } else { length += 2; // reserved length += 4; // length } } else { length += 4; // length } if (item is DicomElement) { length += (uint)(item as DicomElement).Buffer.Size; } else if (item is DicomFragmentSequence) { DicomFragmentSequence sq = item as DicomFragmentSequence; // fragment item (offset table) length += 4; // tag length += 4; // length length += (uint)(sq.OffsetTable.Count / 4); foreach (IByteBuffer fragment in sq) { // fragment item length += 4; // tag length += 4; // length length += fragment.Size; } // sequence delimitation item length += 4; // tag length += 4; // length } else if (item is DicomSequence) { DicomSequence sq = item as DicomSequence; length += Calculate(sq); } return(length); }
/// <summary> /// Handler for traversing beginning of fragment. /// </summary> /// <param name="fragment">Fragment sequence.</param> /// <returns>true if traversing completed without issues, false otherwise.</returns> /// <remarks>On false return value, the method will invoke the callback method passed in <see cref="IDicomDatasetWalker.OnBeginWalk"/> before returning.</remarks> public bool OnBeginFragment(DicomFragmentSequence fragment) { WriteTagHeader(fragment.Tag, fragment.ValueRepresentation, UndefinedLength); WriteTagHeader(DicomTag.Item, DicomVR.NONE, (uint)(fragment.OffsetTable.Count * 4)); foreach (uint offset in fragment.OffsetTable) { _target.Write(offset); } return(true); }
public void OnEndFragmentSequence() { if (_fragment != null) { // only add the dicomtag if no fragment has been skipped due to SkipLargeTags DicomDataset ds = _datasets.Peek(); ds.AddOrUpdate(_fragment); } _fragment = null; }
/// <summary> /// Initialize new instance of EncapsulatedPixelData with new empty pixel data. /// </summary> /// <param name="dataset">The source dataset where to create new pixel data.</param> /// <param name="bitsAllocated">Bits allocated for the pixel data.</param> public EncapsulatedPixelData(DicomDataset dataset, int bitsAllocated) : base(dataset) { NumberOfFrames = 0; _element = bitsAllocated > 8 ? (DicomFragmentSequence) new DicomOtherWordFragment(DicomTag.PixelData) : new DicomOtherByteFragment(DicomTag.PixelData); Dataset.AddOrUpdate(_element); }
public void OnFragmentSequenceItem(IByteSource source, IByteBuffer data) { if (data == null) { // if a null-buffer is added, then the FragmentSequence is not complete and shall not be added to the DicomDataset _fragment = null; } else { _fragment?.Add(data); } }
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 bool OnBeginFragment(DicomFragmentSequence fragment) { _log.Log( _level, "{padding}{tag} {vrCode} {tagDictionaryEntryName} [{offsets} offsets, {fragments} fragments]", (_depth > 0) ? _pad + "> " : "", fragment.Tag, fragment.ValueRepresentation.Code, fragment.Tag.DictionaryEntry.Name, fragment.OffsetTable.Count, fragment.Fragments.Count); return true; }
public void OnBeginFragmentSequence(IByteSource source, DicomTag tag, DicomVR vr) { if (vr == DicomVR.OB) { _fragment = new DicomOtherByteFragment(tag); } else if (vr == DicomVR.OW) { _fragment = new DicomOtherWordFragment(tag); } else { throw new DicomDataException($"Unexpected VR found for DICOM fragment sequence: {vr.Code}"); } }
public void TestFragmentsWithOffsetTableExplicitVr2() { var syntax = TransferSyntax.ExplicitVrLittleEndian; var sq = new DicomFragmentSequence(DicomTags.PixelData); var frag1 = new DicomFragment(new ByteBuffer(new byte[16])); sq.AddFragment(frag1); var frag2 = new DicomFragment(new ByteBuffer(new byte[12])); sq.AddFragment(frag2); // offset_table = 8 sq.SetOffsetTable(new List <uint> { 0, 24 }); // note: both sequence and item delimiter tags are calculated as part of the sequence - the item considers only the total length of its contents // furthermore, fragment sequences are *always* undefined sequence length and explicit item (fragment) length // frag1_length = 16 Assert.AreEqual(16, frag1.Length, "Frag1 Length"); // frag2_length = 12 Assert.AreEqual(12, frag2.Length, "Frag2 Length"); // sq_length = tag(4) + vr(2) + reserved(2) + len(4) + item_tag(4) + item_len(4) + offset_table(8) // + item_tag(4) + item_len(4) + frag1_length(16) // + item_tag(4) + item_len(4) + frag2_length(12) // + sq_delimiter_tag(4) + sq_delimiter_len(4) var options = DicomWriteOptions.WriteFragmentOffsetTable; Assert.AreEqual(80, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); options = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequence; Assert.AreEqual(80, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); options = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequenceItem; Assert.AreEqual(80, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); options = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequence | DicomWriteOptions.ExplicitLengthSequenceItem; Assert.AreEqual(80, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); }
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); }
/// <summary> /// Constructor from a <see cref="DicomMessageBase"/> instance. /// </summary> /// <param name="msg">The message to initialize the object from.</param> public DicomCompressedPixelData(DicomMessageBase msg) : base(msg) { _sq = (DicomFragmentSequence) msg.DataSet[DicomTags.PixelData]; }
/// <summary> /// Constructor from a <see cref="DicomAttributeCollection"/> instance. /// </summary> /// <param name="collection">The collection to initialize the object from.</param> public DicomCompressedPixelData(DicomAttributeCollection collection) : base(collection) { _sq = (DicomFragmentSequence) collection[DicomTags.PixelData]; }
public bool OnBeginFragment(DicomFragmentSequence fragment) { return true; }
private void CompareFragments(DicomItem i1, DicomItem i2) { DicomFragmentSequence s1 = null; DicomFragmentSequence s2 = null; bool pixel = cbIgnorePixelData.Checked && i1.Tag == DicomTag.PixelData; if (i1 == null) { AddItem(i1, lvFile1, Gray); AddItem(i2, lvFile2, Green); s2 = i2 as DicomFragmentSequence; } else if (i2 == null) { AddItem(i1, lvFile1, Green); AddItem(i2, lvFile2, Gray); s1 = i1 as DicomFragmentSequence; } else if (!(i1 is DicomFragmentSequence)) { AddItem(i1, lvFile1, pixel ? Yellow : Red); AddItem(i2, lvFile2, pixel ? Yellow : Red); s2 = i2 as DicomFragmentSequence; } else if (!(i2 is DicomFragmentSequence)) { AddItem(i1, lvFile1, pixel ? Yellow : Red); AddItem(i2, lvFile2, pixel ? Yellow : Red); s1 = i1 as DicomFragmentSequence; } else { AddItem(i1, lvFile1, pixel ? Yellow : None); AddItem(i2, lvFile2, pixel ? Yellow : None); s1 = i1 as DicomFragmentSequence; s2 = i2 as DicomFragmentSequence; } Level++; if (s1 == null) { AddItem(String.Empty, UInt32.MaxValue, String.Empty, lvFile1, Gray); AddItem( _indent + "Offset Table", (uint)s2.OffsetTable.Count * 4, String.Format("@entries={0}", s2.OffsetTable.Count), lvFile2, pixel ? Yellow : Red); } else if (s2 == null) { AddItem( _indent + "Offset Table", (uint)s1.OffsetTable.Count * 4, String.Format("@entries={0}", s1.OffsetTable.Count), lvFile1, pixel ? Yellow : Red); AddItem(String.Empty, UInt32.MaxValue, String.Empty, lvFile2, Gray); } else { Color c = None; if (s1.OffsetTable.Count != s2.OffsetTable.Count) { c = Red; } else { for (int i = 0; i < s1.OffsetTable.Count; i++) { if (s1.OffsetTable[i] != s2.OffsetTable[i]) { c = Red; break; } } } AddItem( _indent + "Offset Table", (uint)s2.OffsetTable.Count * 4, String.Format("@entries={0}", s1.OffsetTable.Count), lvFile1, pixel ? Yellow : c); AddItem( _indent + "Offset Table", (uint)s2.OffsetTable.Count * 4, String.Format("@entries={0}", s2.OffsetTable.Count), lvFile2, pixel ? Yellow : c); } int count = 0; if (s1 != null) { count = s1.Fragments.Count; } if (s2 != null && s2.Fragments.Count > count) { count = s2.Fragments.Count; } string name = _indent + "Fragment"; for (int i = 0; i < count; i++) { IByteBuffer b1 = null; if (s1 != null && i < s1.Fragments.Count) { b1 = s1.Fragments[i]; } IByteBuffer b2 = null; if (s2 != null && i < s2.Fragments.Count) { b2 = s2.Fragments[i]; } if (b1 == null) { AddItem(String.Empty, UInt32.MaxValue, String.Empty, lvFile1, Gray); AddItem(name, b2.Size, String.Empty, lvFile2, pixel ? Yellow : Red); continue; } else if (b2 == null) { AddItem(name, b1.Size, String.Empty, lvFile1, pixel ? Yellow : Red); AddItem(String.Empty, UInt32.MaxValue, String.Empty, lvFile2, Gray); continue; } Color c = None; if (pixel) { c = Yellow; } else if (!Compare(b1.Data, b2.Data)) { c = Red; } AddItem(name, b1.Size, String.Empty, lvFile1, c); AddItem(name, b2.Size, String.Empty, lvFile2, c); } Level--; }
public DicomWriteStatus Write(TransferSyntax syntax, DicomAttributeCollection dataset, DicomWriteOptions options) { TransferSyntax = syntax; foreach (DicomAttribute item in dataset) { if (item.Tag.Element == 0x0000) { continue; } if (item.IsEmpty) { continue; } if (Flags.IsSet(options, DicomWriteOptions.CalculateGroupLengths) && item.Tag.Group != _group && item.Tag.Group <= 0x7fe0) { _group = item.Tag.Group; _writer.Write((ushort)_group); _writer.Write((ushort)0x0000); if (_syntax.ExplicitVr) { _writer.Write((byte)'U'); _writer.Write((byte)'L'); _writer.Write((ushort)4); } else { _writer.Write((uint)4); } _writer.Write((uint)dataset.CalculateGroupWriteLength(_group, _syntax, options)); } _writer.Write((ushort)item.Tag.Group); _writer.Write((ushort)item.Tag.Element); if (_syntax.ExplicitVr) { _writer.Write((byte)item.Tag.VR.Name[0]); _writer.Write((byte)item.Tag.VR.Name[1]); } if (item is DicomAttributeSQ) { DicomAttributeSQ sq = item as DicomAttributeSQ; if (_syntax.ExplicitVr) { _writer.Write((ushort)0x0000); } if (Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequence)) { int hl = _syntax.ExplicitVr ? 12 : 8; _writer.Write((uint)sq.CalculateWriteLength(_syntax, options & ~DicomWriteOptions.CalculateGroupLengths) - (uint)hl); } else { _writer.Write((uint)UndefinedLength); } foreach (DicomSequenceItem ids in item.Values as DicomSequenceItem[]) { _writer.Write((ushort)DicomTag.Item.Group); _writer.Write((ushort)DicomTag.Item.Element); if (Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequenceItem)) { _writer.Write((uint)ids.CalculateWriteLength(_syntax, options & ~DicomWriteOptions.CalculateGroupLengths)); } else { _writer.Write((uint)UndefinedLength); } Write(this.TransferSyntax, ids, options & ~DicomWriteOptions.CalculateGroupLengths); if (!Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequenceItem)) { _writer.Write((ushort)DicomTag.ItemDelimitationItem.Group); _writer.Write((ushort)DicomTag.ItemDelimitationItem.Element); _writer.Write((uint)0x00000000); } } if (!Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequence)) { _writer.Write((ushort)DicomTag.SequenceDelimitationItem.Group); _writer.Write((ushort)DicomTag.SequenceDelimitationItem.Element); _writer.Write((uint)0x00000000); } } else if (item is DicomFragmentSequence) { DicomFragmentSequence fs = item as DicomFragmentSequence; if (_syntax.ExplicitVr) { _writer.Write((ushort)0x0000); } _writer.Write((uint)UndefinedLength); _writer.Write((ushort)DicomTag.Item.Group); _writer.Write((ushort)DicomTag.Item.Element); if (Flags.IsSet(options, DicomWriteOptions.WriteFragmentOffsetTable) && fs.HasOffsetTable) { _writer.Write((uint)fs.OffsetTableBuffer.Length); fs.OffsetTableBuffer.CopyTo(_writer); } else { _writer.Write((uint)0x00000000); } foreach (DicomFragment bb in fs.Fragments) { _writer.Write((ushort)DicomTag.Item.Group); _writer.Write((ushort)DicomTag.Item.Element); _writer.Write((uint)bb.Length); bb.GetByteBuffer(_syntax).CopyTo(_writer); } _writer.Write((ushort)DicomTag.SequenceDelimitationItem.Group); _writer.Write((ushort)DicomTag.SequenceDelimitationItem.Element); _writer.Write((uint)0x00000000); } else { DicomAttribute de = item; ByteBuffer theData = de.GetByteBuffer(_syntax, dataset.SpecificCharacterSet); if (_syntax.ExplicitVr) { if (de.Tag.VR.Is16BitLengthField) { _writer.Write((ushort)theData.Length); } else { _writer.Write((ushort)0x0000); _writer.Write((uint)theData.Length); } } else { _writer.Write((uint)theData.Length); } if (theData.Length > 0) { theData.CopyTo(_writer); } } } return(DicomWriteStatus.Success); }
/// <summary> /// Constructor from a <see cref="DicomUncompressedPixelData"/> instance. /// </summary> /// <param name="pd">The uuncompressed pixel data attribute to initialize the object from.</param> public DicomCompressedPixelData(DicomUncompressedPixelData pd) : base(pd) { _sq = new DicomFragmentSequence(DicomTags.PixelData); }
public DicomWriteStatus Write(TransferSyntax syntax, DicomAttributeCollection dataset, DicomWriteOptions options) { TransferSyntax = syntax; foreach (DicomAttribute item in dataset) { if (item.Tag.Element == 0x0000) { continue; } if (item.IsEmpty) { continue; } if (Flags.IsSet(options, DicomWriteOptions.CalculateGroupLengths) && item.Tag.Group != _group && item.Tag.Group <= 0x7fe0) { _group = item.Tag.Group; _writer.Write((ushort)_group); _writer.Write((ushort)0x0000); if (_syntax.ExplicitVr) { _writer.Write((byte)'U'); _writer.Write((byte)'L'); _writer.Write((ushort)4); } else { _writer.Write((uint)4); } _writer.Write((uint)dataset.CalculateGroupWriteLength(_group, _syntax, options)); } _writer.Write((ushort)item.Tag.Group); _writer.Write((ushort)item.Tag.Element); if (_syntax.ExplicitVr) { _writer.Write((byte)item.Tag.VR.Name[0]); _writer.Write((byte)item.Tag.VR.Name[1]); } if (item is DicomAttributeSQ) { DicomAttributeSQ sq = item as DicomAttributeSQ; if (_syntax.ExplicitVr) { _writer.Write((ushort)0x0000); } if (Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequence)) { int hl = _syntax.ExplicitVr ? 12 : 8; _writer.Write((uint)sq.CalculateWriteLength(_syntax, options & ~DicomWriteOptions.CalculateGroupLengths) - (uint)hl); } else { _writer.Write((uint)UndefinedLength); } foreach (DicomSequenceItem ids in item.Values as DicomSequenceItem[]) { _writer.Write((ushort)DicomTag.Item.Group); _writer.Write((ushort)DicomTag.Item.Element); if (Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequenceItem)) { _writer.Write((uint)ids.CalculateWriteLength(_syntax, options & ~DicomWriteOptions.CalculateGroupLengths)); } else { _writer.Write((uint)UndefinedLength); } Write(this.TransferSyntax, ids, options & ~DicomWriteOptions.CalculateGroupLengths); if (!Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequenceItem)) { _writer.Write((ushort)DicomTag.ItemDelimitationItem.Group); _writer.Write((ushort)DicomTag.ItemDelimitationItem.Element); _writer.Write((uint)0x00000000); } } if (!Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequence)) { _writer.Write((ushort)DicomTag.SequenceDelimitationItem.Group); _writer.Write((ushort)DicomTag.SequenceDelimitationItem.Element); _writer.Write((uint)0x00000000); } } else if (item is DicomFragmentSequence) { DicomFragmentSequence fs = item as DicomFragmentSequence; if (_syntax.ExplicitVr) { _writer.Write((ushort)0x0000); } _writer.Write((uint)UndefinedLength); _writer.Write((ushort)DicomTag.Item.Group); _writer.Write((ushort)DicomTag.Item.Element); if (Flags.IsSet(options, DicomWriteOptions.WriteFragmentOffsetTable) && fs.HasOffsetTable) { _writer.Write((uint)fs.OffsetTableBuffer.Length); fs.OffsetTableBuffer.CopyTo(_writer); } else { _writer.Write((uint)0x00000000); } foreach (DicomFragment bb in fs.Fragments) { _writer.Write((ushort)DicomTag.Item.Group); _writer.Write((ushort)DicomTag.Item.Element); _writer.Write((uint)bb.Length); bb.GetByteBuffer(_syntax).CopyTo(_writer); } _writer.Write((ushort)DicomTag.SequenceDelimitationItem.Group); _writer.Write((ushort)DicomTag.SequenceDelimitationItem.Element); _writer.Write((uint)0x00000000); } else { DicomAttribute de = item; ByteBuffer theData = de.GetByteBuffer(_syntax, dataset.SpecificCharacterSet); if (_syntax.ExplicitVr) { if (de.Tag.VR.Is16BitLengthField) { // #10890: Can't encode the value length if the length of the data exceeds max value for a 16-bit field if (theData.Length > ushort.MaxValue - 1 /* must be even length so max allowed = 65534 */) { throw new DicomDataException(string.Format( "Value for {0} exceeds maximum stream length allowed for a {1} VR attribute encoded using {2}", de.Tag, de.Tag.VR, _syntax)); } _writer.Write((ushort)theData.Length); } else { _writer.Write((ushort)0x0000); _writer.Write((uint)theData.Length); } } else { _writer.Write((uint)theData.Length); } if (theData.Length > 0) { theData.CopyTo(_writer); } } } return(DicomWriteStatus.Success); }
public void TestFragmentsWithOffsetTableExplicitVr2() { var syntax = TransferSyntax.ExplicitVrLittleEndian; var sq = new DicomFragmentSequence(DicomTags.PixelData); var frag1 = new DicomFragment(new ByteBuffer(new byte[16])); sq.AddFragment(frag1); var frag2 = new DicomFragment(new ByteBuffer(new byte[12])); sq.AddFragment(frag2); // offset_table = 8 sq.SetOffsetTable(new List<uint> {0, 24}); // note: both sequence and item delimiter tags are calculated as part of the sequence - the item considers only the total length of its contents // furthermore, fragment sequences are *always* undefined sequence length and explicit item (fragment) length // frag1_length = 16 Assert.AreEqual(16, frag1.Length, "Frag1 Length"); // frag2_length = 12 Assert.AreEqual(12, frag2.Length, "Frag2 Length"); // sq_length = tag(4) + vr(2) + reserved(2) + len(4) + item_tag(4) + item_len(4) + offset_table(8) // + item_tag(4) + item_len(4) + frag1_length(16) // + item_tag(4) + item_len(4) + frag2_length(12) // + sq_delimiter_tag(4) + sq_delimiter_len(4) var options = DicomWriteOptions.WriteFragmentOffsetTable; Assert.AreEqual(80, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); options = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequence; Assert.AreEqual(80, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); options = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequenceItem; Assert.AreEqual(80, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); options = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequence | DicomWriteOptions.ExplicitLengthSequenceItem; Assert.AreEqual(80, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); }
public void TestFragmentsWithOffsetTableExplicitVr() { var syntax = TransferSyntax.ExplicitVrLittleEndian; var sq = new DicomFragmentSequence(DicomTags.PixelData); sq.SetOffsetTable(new List<uint>()); // note: an empty fragment sequence still has one item in it representing the empty offset table // furthermore, fragment sequences are *always* undefined sequence length and explicit item (fragment) length // sq_length = tag(4) + vr(2) + reserved(2) + len(4) + item_tag(4) + item_len(4) + offset_table(0) // + sq_delimiter_tag(4) + sq_delimiter_len(4) var options = DicomWriteOptions.WriteFragmentOffsetTable; Assert.AreEqual(28, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); options = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequence; Assert.AreEqual(28, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); options = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequenceItem; Assert.AreEqual(28, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); options = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequence | DicomWriteOptions.ExplicitLengthSequenceItem; Assert.AreEqual(28, sq.CalculateWriteLength(syntax, options), "Fragment Sequence Length (Options={0})", options); }
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 uint Calculate(DicomItem item) { // skip group lengths if not writing to file if (!_options.KeepGroupLengths && item.Tag.Element == 0x0000) { return(0); } uint length = 0; length += 4; // tag if (_syntax.IsExplicitVR) { length += 2; // vr if (item.ValueRepresentation.Is16bitLength) { length += 2; // length } else { length += 2; // reserved length += 4; // length } } else { length += 4; // length } if (item is DicomElement) { length += (uint)(item as DicomElement).Buffer.Size; } else if (item is DicomFragmentSequence) { DicomFragmentSequence sq = item as DicomFragmentSequence; // fragment item (offset table) length += 4; // tag length += 4; // length length += (uint)(sq.OffsetTable.Count / 4); foreach (IByteBuffer fragment in sq) { // fragment item length += 4; // tag length += 4; // length length += (uint)fragment.Size; } // sequence delimitation item length += 4; // tag length += 4; // length } else if (item is DicomSequence) { DicomSequence sq = item as DicomSequence; length += Calculate(sq); } return(length); }
public void OnEndFragmentSequence() { _fragment = null; }
public bool OnBeginFragment(DicomFragmentSequence fragment) { var tag = String.Format("{0}{1} {2}", Indent, fragment.Tag.ToString().ToUpper(), fragment.Tag.DictionaryEntry.Name); Form.AddItem(tag, fragment.ValueRepresentation.Code, String.Empty, String.Empty); Level++; return true; }
public bool OnBeginFragment(DicomFragmentSequence fragment) { 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 { 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); } }
/// <summary> /// Initialize new instance of EncapsulatedPixelData based on existing pixel data. /// </summary> /// <param name="dataset">The source dataset to extract pixel data from.</param> public EncapsulatedPixelData(DicomDataset dataset) : base(dataset) { _element = dataset.GetDicomItem <DicomFragmentSequence>(DicomTag.PixelData); }