Ejemplo n.º 1
0
        public async Task CopyToStreamAsync_ShouldWorkCorrectly(int length)
        {
            // Arrange
            var bytes    = new byte[length];
            var expected = new byte[length];

            for (int i = 0; i < length; i++)
            {
                bytes[i]    = (byte)i;
                expected[i] = i % 2 == 0
                    ? (byte)(i + 1)
                    : (byte)(i - 1);
            }
            var buffer = new SwapByteBuffer(new MemoryByteBuffer(bytes), 2);

            using var ms = new MemoryStream(length);

            // Act
            await buffer.CopyToStreamAsync(ms, CancellationToken.None).ConfigureAwait(false);

            var actual = ms.ToArray();

            // Assert
            Assert.Equal(expected, actual);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Handler for traversing a DICOM element.
        /// </summary>
        /// <param name="element">Element to traverse.</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 OnElement(DicomElement element)
        {
            WriteTagHeader(element.Tag, element.ValueRepresentation, element.Length);

            var buffer = element.Buffer;

            if (buffer is EndianByteBuffer)
            {
                var ebb = (EndianByteBuffer)buffer;
                if (ebb.Endian != Endian.LocalMachine && ebb.Endian == _target.Endian)
                {
                    buffer = ebb.Internal;
                }
            }
            else if (_target.Endian != Endian.LocalMachine)
            {
                if (element.ValueRepresentation.UnitSize > 1)
                {
                    buffer = new SwapByteBuffer(buffer, element.ValueRepresentation.UnitSize);
                }
            }

            WriteBuffer(_target, buffer, _options.LargeObjectSize);

            return(true);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Asynchronous handler for traversing a DICOM element.
        /// </summary>
        /// <param name="element">Element to traverse.</param>
        /// <returns>true if traversing completed without issues, false otherwise.</returns>
        public async Task <bool> OnElementAsync(DicomElement element)
        {
            WriteTagHeader(element.Tag, element.ValueRepresentation, element.Length);

            var buffer = element.Buffer;

            if (buffer is EndianByteBuffer ebb)
            {
                if (ebb.Endian != Endian.LocalMachine && ebb.Endian == _target.Endian)
                {
                    buffer = ebb.Internal;
                }
            }
            else if (_target.Endian != Endian.LocalMachine)
            {
                if (element.ValueRepresentation.UnitSize > 1)
                {
                    buffer = new SwapByteBuffer(buffer, element.ValueRepresentation.UnitSize);
                }
            }

            await WriteBufferAsync(_target, buffer, _options.LargeObjectSize).ConfigureAwait(false);

            return(true);
        }
Ejemplo n.º 4
0
        public void CopyToStream_ShouldWorkCorrectly(int length)
        {
            // Arrange
            var bytes    = new byte[length];
            var expected = new byte[length];

            for (int i = 0; i < length; i++)
            {
                bytes[i]    = (byte)i;
                expected[i] = i % 2 == 0
                    ? (byte)(i + 1)
                    : (byte)(i - 1);
            }

            var buffer = new SwapByteBuffer(new MemoryByteBuffer(bytes), 2);

            using var ms = new MemoryStream(length);

            // Act
            buffer.CopyToStream(ms);
            var actual = ms.ToArray();

            // Assert
            Assert.Equal(expected, actual);
        }
Ejemplo n.º 5
0
        public bool OnElement(DicomElement element)
        {
            WriteTagHeader(element.Tag, element.ValueRepresentation, element.Length);

            IByteBuffer buffer = element.Buffer;

            if (buffer is EndianByteBuffer)
            {
                EndianByteBuffer ebb = buffer as EndianByteBuffer;
                if (ebb.Endian != Endian.LocalMachine && ebb.Endian == _target.Endian)
                {
                    buffer = ebb.Internal;
                }
            }
            else if (_target.Endian != Endian.LocalMachine)
            {
                if (element.ValueRepresentation.UnitSize > 1)
                {
                    buffer = new SwapByteBuffer(buffer, element.ValueRepresentation.UnitSize);
                }
            }

            if (element.Length >= _options.LargeObjectSize)
            {
                _target.Write(buffer.Data, 0, buffer.Size, OnEndWriteBuffer, null);
                return(false);
            }
            else
            {
                _target.Write(buffer.Data);
                return(true);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Asynchronous handler for traversing a DICOM element.
        /// </summary>
        /// <param name="element">Element to traverse.</param>
        /// <returns>true if traversing completed without issues, false otherwise.</returns>
        public async Task <bool> OnElementAsync(DicomElement element)
        {
            WriteTagHeader(element.Tag, element.ValueRepresentation, element.Length);

            IByteBuffer buffer = element.Buffer;

            if (buffer is EndianByteBuffer)
            {
                EndianByteBuffer ebb = buffer as EndianByteBuffer;
                if (ebb.Endian != Endian.LocalMachine && ebb.Endian == _target.Endian)
                {
                    buffer = ebb.Internal;
                }
            }
            else if (_target.Endian != Endian.LocalMachine)
            {
                if (element.ValueRepresentation.UnitSize > 1)
                {
                    buffer = new SwapByteBuffer(buffer, element.ValueRepresentation.UnitSize);
                }
            }

            if (element.Length < this._options.LargeObjectSize)
            {
                _target.Write(buffer.Data, 0, buffer.Size);
            }
            else
            {
                await _target.WriteAsync(buffer.Data, 0, buffer.Size).ConfigureAwait(false);
            }

            return(true);
        }
Ejemplo n.º 7
0
            /// <inheritdoc />
            public override void AddFrame(IByteBuffer data)
            {
                var buffer = (_element.Buffer as CompositeByteBuffer)
                             ?? throw new DicomImagingException("Expected pixel data element to have a CompositeByteBuffer.");

                if (Syntax.SwapPixelData)
                {
                    data = new SwapByteBuffer(data, 2);
                }

                buffer.Buffers.Add(data);
                NumberOfFrames++;
            }
Ejemplo n.º 8
0
        public void Data_CompareWithInitializer_ExactMatch()
        {
            // Arrange
            var bytes    = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            var expected = new byte[] { 2, 1, 4, 3, 6, 5, 8, 7 };
            var buffer   = new SwapByteBuffer(new MemoryByteBuffer(bytes), 2);

            // Act
            var actual = buffer.Data;

            // Assert
            Assert.Equal(expected.Length, actual.Length);
            Assert.Equal(expected, actual);
        }
Ejemplo n.º 9
0
        public void GetByteRange_WithOffset_ToEnd_ShouldReturnValidArray(int offset, int count)
        {
            // Arrange
            var bytes    = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            var expected = new byte[] { 2, 1, 4, 3, 6, 5, 8, 7 };
            var buffer   = new SwapByteBuffer(new MemoryByteBuffer(bytes), 2);

            // Act
            var actual = new byte[count];

            buffer.GetByteRange(offset, count, actual);

            // Assert
            Assert.Equal(count, actual.Length);
            Assert.Equal(expected.Skip(offset).Take(count).ToArray(), actual);
        }
Ejemplo n.º 10
0
            public override IByteBuffer GetFrame(int frame)
            {
                int         offset = UncompressedFrameSize * frame;
                IByteBuffer buffer = new RangeByteBuffer(Element.Buffer, (uint)offset, (uint)UncompressedFrameSize);

                if (BytesAllocated == 1 && Syntax.Endian == Endian.Little)
                {
                    buffer = new SwapByteBuffer(buffer, 2);
                }
                else if (Syntax.Endian == Endian.Big)
                {
                    buffer = new SwapByteBuffer(buffer, 2);
                }

                return(buffer);
            }
Ejemplo n.º 11
0
            public override void AddFrame(IByteBuffer data)
            {
                if (!(Element.Buffer is CompositeByteBuffer))
                {
                    throw new DicomImagingException("Expected pixel data element to have a CompositeByteBuffer.");
                }

                CompositeByteBuffer buffer = Element.Buffer as CompositeByteBuffer;

                if (BytesAllocated == 1)
                {
                    data = new SwapByteBuffer(data, 2);
                }
                buffer.Buffers.Add(data);

                NumberOfFrames++;
            }
Ejemplo n.º 12
0
            public override IByteBuffer GetFrame(int frame)
            {
                if (frame < 0 || frame >= NumberOfFrames)
                {
                    throw new IndexOutOfRangeException("Requested frame out of range!");
                }

                int         offset = UncompressedFrameSize * frame;
                IByteBuffer buffer = new RangeByteBuffer(Element.Buffer, (uint)offset, (uint)UncompressedFrameSize);

                // mainly for GE Private Implicit VR Big Endian
                if (Syntax.SwapPixelData)
                {
                    buffer = new SwapByteBuffer(buffer, 2);
                }

                return(buffer);
            }
Ejemplo n.º 13
0
            public override IByteBuffer GetFrame(int frame)
            {
                if (frame < 0 || frame >= NumberOfFrames)
                {
                    throw new IndexOutOfRangeException("Requested frame out of range!");
                }

                int         offset = UncompressedFrameSize * frame;
                IByteBuffer buffer = new RangeByteBuffer(Element.Buffer, (uint)offset, (uint)UncompressedFrameSize);

                //TODO: trace down the need for this additional byte swap
                if (Syntax.Endian == Endian.Big && !Syntax.SwapPixelData)
                {
                    buffer = new SwapByteBuffer(buffer, 2);
                }

                // mainly for GE Private Implicit VR Little Endian
                if (Syntax.SwapPixelData)
                {
                    buffer = new SwapByteBuffer(buffer, 2);
                }

                return(buffer);
            }
Ejemplo n.º 14
0
            public override IByteBuffer GetFrame(int frame)
            {
                if (frame < 0 || frame >= NumberOfFrames)
                {
                    throw new IndexOutOfRangeException("Requested frame out of range!");
                }

                IByteBuffer buffer = null;

                if (NumberOfFrames == 1)
                {
                    if (Element.Fragments.Count == 1)
                    {
                        buffer = Element.Fragments[0];
                    }
                    else
                    {
                        buffer = new CompositeByteBuffer(Element.Fragments.ToArray());
                    }
                }
                else if (Element.Fragments.Count == NumberOfFrames)
                {
                    buffer = Element.Fragments[frame];
                }
                else if (Element.OffsetTable.Count == NumberOfFrames)
                {
                    uint start = Element.OffsetTable[frame];
                    uint stop  = (Element.OffsetTable.Count == (frame + 1))
                                    ? uint.MaxValue
                                    : Element.OffsetTable[frame + 1];

                    var composite = new CompositeByteBuffer();

                    uint pos  = 0;
                    int  frag = 0;

                    while (pos < start && frag < Element.Fragments.Count)
                    {
                        pos += 8;
                        pos += Element.Fragments[frag].Size;
                        frag++;
                    }

                    if (pos != start)
                    {
                        throw new DicomImagingException("Fragment start position does not match offset table.");
                    }

                    while (pos < stop && frag < Element.Fragments.Count)
                    {
                        composite.Buffers.Add(Element.Fragments[frag]);

                        pos += 8;
                        pos += Element.Fragments[frag].Size;
                        frag++;
                    }

                    if (pos < stop && stop != uint.MaxValue)
                    {
                        throw new DicomImagingException(
                                  "Image frame truncated while reading fragments from offset table.");
                    }

                    buffer = composite;
                }
                else
                {
                    throw new DicomImagingException(
                              "Support for multi-frame images with varying fragment sizes and no offset table has not been implemented.");
                }

                // mainly for GE Private Implicit VR Little Endian
                if (!Syntax.IsEncapsulated && BitsAllocated == 16 && Syntax.SwapPixelData)
                {
                    buffer = new SwapByteBuffer(buffer, 2);
                }

                return(EndianByteBuffer.Create(buffer, Syntax.Endian, BytesAllocated));
            }
Ejemplo n.º 15
0
        /// <summary>
        /// Handler for traversing a DICOM element.
        /// </summary>
        /// <param name="element">Element to traverse.</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 OnElement(DicomElement element)
        {
            WriteTagHeader(element.Tag, element.ValueRepresentation, element.Length);

            IByteBuffer buffer = element.Buffer;

            if (buffer is EndianByteBuffer)
            {
                EndianByteBuffer ebb = buffer as EndianByteBuffer;
                if (ebb.Endian != Endian.LocalMachine && ebb.Endian == _target.Endian)
                {
                    buffer = ebb.Internal;
                }
            }
            else if (_target.Endian != Endian.LocalMachine)
            {
                if (element.ValueRepresentation.UnitSize > 1)
                {
                    buffer = new SwapByteBuffer(buffer, element.ValueRepresentation.UnitSize);
                }
            }

            if (buffer is CompositeByteBuffer || buffer is StreamByteBuffer || buffer is FileByteBuffer || buffer is PInvokeByteBuffer)
            {
                buffer.writeToTarget(_target, buffer);
            }
            else
            {
                _target.Write(buffer.Data, 0, buffer.Size);
            }
            //if (buffer is CompositeByteBuffer)// 对CompositeByteBuffer避免调用buffer.Data 以降低内存占用
            //{
            //    var tmpbuffer = buffer as CompositeByteBuffer;

            //    tmpbuffer.writeToTarget(_target);
            //}
            //else if (buffer is StreamByteBuffer)
            //{
            //    var tmpbuffer = buffer as StreamByteBuffer;
            //    tmpbuffer.writeToTarget(_target);
            //}
            //else if (buffer is FileByteBuffer)
            //{
            //    var fb = buffer as FileByteBuffer;
            //    const int seg = 4096000;
            //    int gcd = (int)(fb.Size / seg);
            //    int gcf = (int)(fb.Size % seg);

            //    if (gcd == 0)
            //    {
            //        _target.Write(fb.Data, 0, fb.Size);
            //    }
            //    else
            //    {
            //        for (int i = 0; i < gcd; i++)
            //        {

            //            var rgBuffer = fb.GetByteRange(i * seg, seg);
            //            _target.Write(rgBuffer, 0, seg);
            //            rgBuffer = null;
            //        }

            //        if (gcf > 0)
            //        {

            //            var rgBuffer = fb.GetByteRange(gcd * seg, gcf);

            //            _target.Write(rgBuffer, 0, (uint)gcf);

            //            rgBuffer = null;
            //        }


            //    }

            //}
            //else if (buffer is PInvokeByteBuffer)
            //{

            //    var pb = buffer as PInvokeByteBuffer;

            //    var rowBuffer = new byte[pb.RowBufferSize];
            //    for (int i = 0; i < pb.Height; i++)
            //    {
            //        pb.GetByteRange(i, rowBuffer);
            //        _target.Write(rowBuffer, 0, (uint)rowBuffer.Length);
            //    }
            //    rowBuffer = null;
            //}
            //else
            //{
            //    _target.Write(buffer.Data, 0, buffer.Size);
            //}
            return(true);
        }