Ejemplo n.º 1
0
        /// <summary>
        /// Writes the element value to the stream.
        /// </summary>
        /// <param name="stream">The stream to write that positioned at the proper location to write.</param>
        /// <param name="syntax">The tranfer syntax to use if the value is binary.</param>
        /// <param name="encoding">The specific character set to use if the value is text.</param>
        /// <param name="options">The options used to encode tags.</param>
        protected override void WriteValueOnStream(Stream stream, string syntax, SpecificCharacterSet encoding, DataSetOptions options)
        {
            EndianBinaryWriter writer = new EndianBinaryWriter(stream, Syntax.GetEndian(syntax));

            unchecked
            {
                foreach (Elements elements in items)
                {
                    writer.Write((short)0xFFFE);
                    writer.Write((short)0xE000);

                    // each nested element list can have its own SpecificCharacterSet,
                    // and it is valid for all nested elements, unless overridden again further down
                    SpecificCharacterSet scoped = encoding;
                    if (elements.Contains(t.SpecificCharacterSet))
                    {
                        scoped = new SpecificCharacterSet(elements[t.SpecificCharacterSet].Value);
                    }

                    uint size = 0;
                    // and account for the size of each child element
                    foreach (Element child in elements)
                    {
                        size += child.GetSize(syntax, scoped);
                    }
                    writer.Write(size);

                    foreach (Element child in elements)
                    {
                        child.Write(writer.BaseStream, syntax, scoped, options);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Writes the element value to the stream.
        /// </summary>
        /// <param name="stream">The stream to write that positioned at the proper location to write.</param>
        /// <param name="syntax">The tranfer syntax to use if the value is binary.</param>
        /// <param name="encoding">The specific character set to use if the value is text.</param>
        /// <param name="options">The options used to encode tags.</param>
        protected override void WriteValueOnStream(Stream stream, string syntax, SpecificCharacterSet encoding, DataSetOptions options)
        {
            EndianBinaryWriter writer = new EndianBinaryWriter(stream, Syntax.GetEndian(syntax));

            if (Syntax.CanEncapsulatePixelData(syntax))
            {
                WriteEncapsulatedPixelData(writer);
            }
            else
            {
                if (vr == "OW")
                {
                    short[] words = Value as short[];
                    foreach (short word in words)
                    {
                        writer.Write(word);
                    }
                }
                else if (vr == "OB")
                {
                    byte[] value = Value as byte[];
                    writer.Write((byte[])value);
                    if (value.Length % 2 != 0)
                    {
                        writer.Write('\0');
                    }
                }
                else
                {
                    throw new Exception(String.Format("Unexpected vr={0} in WriteValueOnStream", vr));
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// This method reads the value from the stream and sets the vm for string types
        /// </summary>
        /// <param name="stream">The stream to read the data from.</param>
        /// <param name="syntax">The transfer syntax used to interpret binary data.</param>
        /// <param name="encoding">The encoding to use to decode string data.</param>
        /// <param name="length">The length, in bytes, of the data to read.</param>
        /// <remarks>The stream is assumed to be positioned at the beginning of the encoded tag value.</remarks>
        protected override void ReadValueFromStream(Stream stream, string syntax, SpecificCharacterSet encoding, uint length)
        {
            this.length = length;
            value       = null;
            if (length != 0)
            {
                EndianBinaryReader reader = new EndianBinaryReader(stream, Syntax.GetEndian(syntax));

                //System.Diagnostics.Debug.WriteLine(String.Format("0x{0:X8}:{0}: Reading sequence of length={1}", stream.Position, (length == UInt32.MaxValue) ? "undefined" : length.ToString()));
                ReadSequence(reader, encoding, reader.BaseStream.Position);
                //System.Diagnostics.Debug.WriteLine(String.Format("0x{0:X8}:{0}: Finished reading sequence", stream.Position));
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// This method reads the value from the stream and sets the vm for string types
        /// </summary>
        /// <param name="stream">The stream to read the data from.</param>
        /// <param name="syntax">The transfer syntax used to interpret binary data.</param>
        /// <param name="encoding">The encoding to use to decode string data.</param>
        /// <param name="length">The length, in bytes, of the data to read.</param>
        /// <remarks>The stream is assumed to be positioned at the beginning of the encoded tag value.</remarks>
        protected override void ReadValueFromStream(Stream stream, string syntax, SpecificCharacterSet encoding, uint length)
        {
            this.length = length;

            EndianBinaryReader reader = new EndianBinaryReader(stream, Syntax.GetEndian(syntax));

            if (length == 0xFFFFFFFF)
            {
                if (!Syntax.CanEncapsulatePixelData(syntax))
                {
                    throw new Exception(String.Format("Current syntax {0} does not support Encapsulated Pixel Data.", syntax, this.tag.Name));
                }
                ReadEncapsulatedPixelData(reader);
            }
            else
            {
                ReadNativePixelData(reader);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Parses the stream for tags.
        /// </summary>
        /// <param name="parent">The parent Element that the tags will belong to, if any.</param>
        /// <param name="stream">The stream to Read from.</param>
        /// <param name="elements">The Elements collection to add the Elements to.</param>
        /// <param name="current">The current postion in the stream.</param>
        /// <param name="length">The maximum number of bytes to read.</param>
        /// <param name="stop">The group number ot read up to and including.</param>
        /// <param name="syntax">The Transfer Syntax of the stream.</param>
        /// <param name="encoding">The character encoding of the stream.</param>
        /// <returns>The final position in the stream Read to.</returns>
        public static long Scan(Element parent, Stream stream, Elements elements, long current, long length, ushort stop, string syntax, SpecificCharacterSet encoding)
        {
            //System.Diagnostics.Debug.WriteLine(String.Format("0x{0:X8}:{0}: Scan called parent={1}:{2}. current={3} length={4} stop={5}",
            //    stream.Position, (parent!=null)?parent.Tag.ToString():"root", (parent!=null)?parent.VR:"", current, length, stop));

            // we have to get the stream on top of the current position
            stream.Position = current;

            EndianBinaryReader reader = new EndianBinaryReader(stream, Syntax.GetEndian(syntax));

            // Scan stops when either the stream position exceeds length, or the group exceeds stop,
            // or we reach the end of a file, or we reach an ItemDelimiter or SequenceDelimiter, or
            // we can no longer read
            while (true)
            {
                if (!stream.CanRead)
                {
                    //System.Diagnostics.Debug.WriteLine("stream CanRead==false");
                    break;
                }

                if (length != -1 && (ulong)current >= (ulong)length)
                {
                    //System.Diagnostics.Debug.WriteLine(String.Format("0x{0:X8}:{0}: current={1} exceeds length={2}", stream.Position, current, length));
                    break;
                }

                // keep track of where we are before reading the next element
                long previous  = current;
                Tag  lookahead = PeekTag(reader, syntax);

                //System.Diagnostics.Debug.WriteLine(String.Format("0x{0:X8}:{0}: Peek {1} in Scan", stream.Position, lookahead.Name));

                // we scan up to and including the group specified by stop
                // so we check if we have gone beyond the specified group
                if (lookahead.Group > stop)
                {
                    //System.Diagnostics.Debug.WriteLine(String.Format("0x{0:X8}:{0}: group={1} exceeds stop={2}", stream.Position, lookahead.Group, stop));
                    // we need to rewind to before this element
                    current = previous;
                    break;
                }

                if (length == -1)
                {
                    //if (lookahead.Equals(t.ItemDelimitationItem) || lookahead.Equals(t.SequenceDelimitationItem))
                    if (lookahead.Equals(t.ItemDelimitationItem))
                    {
                        //System.Diagnostics.Debug.WriteLine(String.Format("0x{0:X8}:{0}: undefined length, found {1}:{2}", stream.Position, lookahead.Description, lookahead.Name));
                        // position stream beyond delimitation tag
                        stream.Position += sizeof(ushort) * 2;
                        // no need to check zero
                        int zero = reader.ReadInt32();
                        break;
                    }
                }

                Exception exception = null;
                Element   element   = Element.Factory(parent, lookahead);
                try
                {
                    //System.Diagnostics.Debug.WriteLine(String.Format("reading {0}", lookahead.ToString()));
                    element.Read(stream, syntax, encoding);
                }
                catch (Exception ex)
                {
                    // we are going to delay throwing an exception from reading
                    // until we see if we are going to add it to the collection
                    exception = ex;
                }

                current = stream.Position;

                // if we have the SpecificCharacterSet, create an Encoding for the rest of the DataSet
                if (element.Tag.Equals(t.SpecificCharacterSet))
                {
                    encoding = new SpecificCharacterSet(element.Value);
                }
                else if (element.Tag.Equals(t.PixelData) && !Syntax.IsExplicit(syntax))
                {
                    // if we have the PixelData, insure that it matches the BitsStored
                    // this can happen with implicit vrs and OW is the default

                    if (elements.Contains(t.BitsStored))
                    {
                        ushort stored = (ushort)elements[t.BitsStored].Value;
                        Type   type   = element.Value.GetType().GetElementType();
                        if (stored == 8 && element.Value is ushort[])
                        {
                            ushort[] pixels = element.Value as ushort[];
                            byte[]   bytes  = new byte[pixels.Length * 2];
                            Buffer.BlockCopy(pixels, 0, bytes, 0, bytes.Length);
                            element.Value = bytes;
                        }
                    }
                }
                else if (element.Tag.Equals(t.ItemDelimitationItem) || element.Tag.Equals(t.SequenceDelimitationItem) || element.Tag.Equals(t.Item))
                {
                    // if we have a sequence or item delimiter, stop scanning
                    if (length == -1)
                    {
                        return(current);
                    }
                }

                // now that we are about to add the tag, check and see if it parsed correctly
                if (exception != null)
                {
                    // we have failed to parse, so we create a tag that contains the rest of the data
                    stream.Position = previous;
                    element         = new Element("(BAAD,F00D)", reader.ReadBytes((int)(length - previous)));
                }

                string key = Tag.ToString(element);
                // and insert the tag name/value pair in the hash table, allows duplicates
                elements[key] = element;
                //Logging.Log("Adding {0}:{1}", key, element.ToString());

                // now we can throw the exception if there is one
                if (exception != null)
                {
                    throw exception;
                }

                if ((ulong)current >= (ulong)length)
                {
                    //System.Diagnostics.Debug.WriteLine(String.Format("0x{0:X8}:{0}: current={1} at or exceeds length={2}", stream.Position, current, length));
                    break;
                }
            }
            return(current);
        }