public override DcmItem Clone() { DcmFragmentSequence sq = new DcmFragmentSequence(Tag, VR, StreamPosition, Endian); sq.SetOffsetTable(OffsetTable); foreach (ByteBuffer fragment in Fragments) { sq.AddFragment(fragment.Clone()); } return(sq); }
private static void SaveFragmentOffsetTable(XElement item, DcmFragmentSequence seq) { if (item.Value == String.Empty) { return; } string[] strs = item.FirstText().Split('\\'); foreach (string s in strs) { seq.OffsetTable.Add(uint.Parse(s, NumberStyles.HexNumber, CultureInfo.InvariantCulture)); } }
private static void LoadSequence(XElement parent, IList <DcmItem> items, XDicomOptions options) { foreach (DcmItem item in items) { if (!Flags.IsSet(options, XDicomOptions.IncludePixelData) && item.Tag == DicomTags.PixelData) { continue; } XElement attr = new XElement("attr"); attr.SetAttributeValue("tag", item.Tag.Card.ToString("x8")); attr.SetAttributeValue("vr", item.VR.VR); if (item is DcmItemSequence) { DcmItemSequence seq = (DcmItemSequence)item; attr.SetAttributeValue("len", -1); foreach (DcmItemSequenceItem si in seq.SequenceItems) { XElement itm = new XElement("item"); LoadSequence(itm, si.Dataset.Elements, options); attr.Add(itm); } } else if (item is DcmFragmentSequence) { DcmFragmentSequence seq = (DcmFragmentSequence)item; attr.SetAttributeValue("len", -1); LoadFragmentOffsetTable(attr, seq); foreach (ByteBuffer fi in seq.Fragments) { LoadFragmentItem(attr, seq.VR, fi); } } else { DcmElement element = (DcmElement)item; attr.SetAttributeValue("len", element.Length); attr.Add(element.GetValueString()); } if (Flags.IsSet(options, XDicomOptions.Comments)) { parent.Add(new XComment(item.Tag.Entry.Name)); } parent.Add(attr); } }
public void AddFrame(byte[] data) { _frames++; if (IsFragmented) { DcmFragmentSequence sequence = PixelDataSequence; uint offset = 0; foreach (ByteBuffer fragment in sequence.Fragments) { offset += (uint)(8 + fragment.Length); } sequence.OffsetTable.Add(offset); int pos = 0; while (pos < data.Length) { int count = (int)Math.Min(FragmentSize, (uint)(data.Length - pos)); ByteBuffer buffer = new ByteBuffer(); buffer.Append(data, pos, count); if ((buffer.Length % 2) != 0) { buffer.Append(new byte[1], 0, 1); } sequence.Fragments.Add(buffer); pos += count; } } else { if (BytesAllocated > 1 && TransferSyntax.Endian != Endian.LocalMachine) { Endian.SwapBytes(BytesAllocated, data); } else if (BytesAllocated == 1 && PixelDataItem.VR == DicomVR.OW && TransferSyntax.Endian == Endian.Big) { Endian.SwapBytes(2, data); } long pos = UncompressedFrameSize * (NumberOfFrames - 1); PixelDataElement.ByteBuffer.Stream.Seek(pos, System.IO.SeekOrigin.Begin); PixelDataElement.ByteBuffer.Stream.Write(data, 0, data.Length); if ((PixelDataElement.ByteBuffer.Length % 2) != 0) { PixelDataElement.ByteBuffer.Stream.Write(new byte[1], 0, 1); } } }
private static void LoadFragmentOffsetTable(XElement parent, DcmFragmentSequence seq) { if (seq.HasOffsetTable) { XElement item = new XElement("item"); item.SetAttributeValue("len", seq.OffsetTable.Count * 4); StringBuilder sb = new StringBuilder(); foreach (uint offset in seq.OffsetTable) { sb.AppendFormat("{0:X8}\\", offset); } item.Add(sb.ToString().TrimEnd('\\')); parent.Add(item); } else { XElement item = new XElement("item"); item.SetAttributeValue("len", 0); parent.Add(item); } }
private static void Save(XElement parent, DcmDataset dataset) { foreach (XElement attr in parent.Elements("attr")) { DicomTag tag = DicomTag.Parse(attr.Attribute("tag").Value); DicomVR vr = DicomVR.Lookup(attr.Attribute("vr").Value); int len = int.Parse(attr.Attribute("len").Value, CultureInfo.InvariantCulture); if (vr == DicomVR.SQ) { DcmItemSequence seq = new DcmItemSequence(tag); foreach (XElement itm in attr.Elements("item")) { DcmItemSequenceItem item = new DcmItemSequenceItem(); Save(itm, item.Dataset); seq.AddSequenceItem(item); } dataset.AddItem(seq); } else if (len == -1) { DcmFragmentSequence seq = new DcmFragmentSequence(tag, vr); bool first = true; foreach (XElement itm in attr.Elements("item")) { if (first) { SaveFragmentOffsetTable(itm, seq); first = false; } else { SaveFragmentItem(itm, seq); } } dataset.AddItem(seq); } else { DcmElement element = DcmElement.Create(tag, vr); element.SetValueString(attr.FirstText()); dataset.AddItem(element); } } }
private static void SaveFragmentItem(XElement item, DcmFragmentSequence seq) { ByteBuffer bb = new ByteBuffer(); string[] strs = item.FirstText().Split('\\'); if (seq.VR == DicomVR.OW) { foreach (string s in strs) { bb.Writer.Write(ushort.Parse(s, NumberStyles.HexNumber, CultureInfo.InvariantCulture)); } } else { foreach (string s in strs) { bb.Writer.Write(byte.Parse(s, NumberStyles.HexNumber, CultureInfo.InvariantCulture)); } } seq.AddFragment(bb); }
public List <ByteBuffer> GetFrameFragments(int frame) { if (frame < 0 || frame >= NumberOfFrames) { throw new IndexOutOfRangeException("Requested frame out of range!"); } if (!IsFragmented) { throw new InvalidOperationException("No fragmented pixel data!"); } List <ByteBuffer> fragments = new List <ByteBuffer>(); DcmFragmentSequence sequence = PixelDataSequence; int fragmentCount = sequence.Fragments.Count; if (NumberOfFrames == 1) { fragments.AddRange(sequence.Fragments); return(fragments); } if (fragmentCount == NumberOfFrames) { fragments.Add(sequence.Fragments[frame]); return(fragments); } if (sequence.HasOffsetTable && sequence.OffsetTable.Count == NumberOfFrames) { uint offset = sequence.OffsetTable[frame]; uint stop = 0xffffffff; uint pos = 0; if ((frame + 1) < NumberOfFrames) { stop = sequence.OffsetTable[frame + 1]; } int i = 0; while (pos < offset && i < fragmentCount) { pos += (uint)(8 + sequence.Fragments[i].Length); i++; } // check for invalid offset table if (pos != offset) { goto GUESS_FRAME_OFFSET; } while (offset < stop && i < fragmentCount) { fragments.Add(sequence.Fragments[i]); offset += (uint)(8 + sequence.Fragments[i].Length); i++; } return(fragments); } GUESS_FRAME_OFFSET: if (sequence.Fragments.Count > 0) { int fragmentSize = sequence.Fragments[0].Length; bool allSameLength = true; for (int i = 0; i < fragmentCount; i++) { if (sequence.Fragments[i].Length != fragmentSize) { allSameLength = false; break; } } if (allSameLength) { if ((fragmentCount % NumberOfFrames) != 0) { throw new DicomDataException("Unable to determine frame length from pixel data sequence!"); } int count = fragmentCount / NumberOfFrames; int start = frame * count; for (int i = 0; i < fragmentCount; i++) { fragments.Add(sequence.Fragments[i]); } return(fragments); } else { // what if a single frame ends on a fragment boundary? int count = 0; int start = 0; for (int i = 0; i < fragmentCount && count < frame; i++, start++) { if (sequence.Fragments[i].Length != fragmentSize) { count++; } } for (int i = start; i < fragmentCount; i++) { fragments.Add(sequence.Fragments[i]); if (sequence.Fragments[i].Length != fragmentSize) { break; } } return(fragments); } } return(fragments); }
private DicomReadStatus InsertFragmentItem(DicomReadOptions options) { if (_tag == DicomTags.Item) { if (_len > _remain) return NeedMoreData(_len); ByteBuffer data = CurrentBuffer(options); _remain -= _len; _read += _len; if (!_fragment.HasOffsetTable) _fragment.SetOffsetTable(data); else _fragment.AddFragment(data); } else if (_tag == DicomTags.SequenceDelimitationItem) { _fragment = null; } else { // unexpected tag return DicomReadStatus.UnknownError; } return DicomReadStatus.Success; }
/// <summary> /// Read dataset from stream /// </summary> /// <param name="stopAtTag">End parsing at this tag</param> /// <param name="options">DICOM read options</param> /// <returns>Status code</returns> public DicomReadStatus Read(DicomTag stopAtTag, DicomReadOptions options) { // Counters: // _remain - bytes remaining in stream // _bytes - estimates bytes to end of dataset // _read - number of bytes read from stream try { _need = 0; _remain = _stream.Length - _stream.Position; while (_remain > 0) { DicomReadStatus status = ParseTag(stopAtTag, options); if (status == DicomReadStatus.SuccessEndRead) return DicomReadStatus.Success; if (status != DicomReadStatus.Success) return status; status = ParseVR(options); if (status != DicomReadStatus.Success) return status; status = ParseLength(options); if (status != DicomReadStatus.Success) return status; if (_tag.IsPrivate) { if (_tag.Element != 0x0000 && _tag.Element <= 0x00ff) { // handle UN private creator id if (_vr != DicomVR.LO && Flags.IsSet(options, DicomReadOptions.ForcePrivateCreatorToLO)) { Dicom.Debug.Log.Warn("Converting Private Creator VR from '{0}' to 'LO'", _vr.VR); _vr = DicomVR.LO; } } } if (_vr == DicomVR.UN && _syntax.IsExplicitVR && Flags.IsSet(options, DicomReadOptions.UseDictionaryForExplicitUN)) { _vr = _tag.Entry.DefaultVR; } if (_fragment != null) { status = InsertFragmentItem(options); if (status != DicomReadStatus.Success) return status; } else if (_sqs.Count > 0 && (_tag == DicomTags.Item || _tag == DicomTags.ItemDelimitationItem || _tag == DicomTags.SequenceDelimitationItem)) { status = InsertSequenceItem(options); if (status != DicomReadStatus.Success) return status; } else { if (_sqs.Count > 0) { DcmItemSequence sq = _sqs.Peek(); if (sq.StreamLength != UndefinedLength) { long end = sq.StreamPosition + 8 + sq.StreamLength; if (_syntax.IsExplicitVR) end += 2 + 2; if ((_stream.Position - _offset) >= end) { if (_sds.Count == _sqs.Count) _sds.Pop(); _sqs.Pop(); } } } if (_len == UndefinedLength) { if (_vr == DicomVR.SQ) { DcmItemSequence sq = new DcmItemSequence(_tag, _pos, _len, _endian); InsertDatasetItem(sq, options); _sqs.Push(sq); } else { _fragment = new DcmFragmentSequence(_tag, _vr, _pos, _endian); InsertDatasetItem(_fragment, options); } } else { if (_vr == DicomVR.SQ) { DcmItemSequence sq = new DcmItemSequence(_tag, _pos, _len, _endian); InsertDatasetItem(sq, options); _sqs.Push(sq); } else { if (_len > _remain) return NeedMoreData(_len); DcmElement elem = DcmElement.Create(_tag, _vr, _pos, _endian, CurrentBuffer(options)); _remain -= _len; _read += _len; InsertDatasetItem(elem, options); } } } _tag = null; _vr = null; _len = UndefinedLength; } return DicomReadStatus.Success; } catch (EndOfStreamException) { // should never happen return DicomReadStatus.UnknownError; } }
public override DcmItem Clone() { DcmFragmentSequence sq = new DcmFragmentSequence(Tag, VR, StreamPosition, Endian); sq.SetOffsetTable(OffsetTable); foreach (ByteBuffer fragment in Fragments) { sq.AddFragment(fragment.Clone()); } return sq; }
private static void SaveFragmentOffsetTable(XElement item, DcmFragmentSequence seq) { if (item.Value == String.Empty) return; string[] strs = item.FirstText().Split('\\'); foreach (string s in strs) { seq.OffsetTable.Add(uint.Parse(s, NumberStyles.HexNumber, CultureInfo.InvariantCulture)); } }