Beispiel #1
0
        private static DicomTag GetTagFromAttributeNode(XmlNode attributeNode)
        {
            String tag = attributeNode.Attributes["Tag"].Value;

            DicomTag theTag;

            if (tag.StartsWith("$"))
            {
                theTag = DicomTagDictionary.GetDicomTag(tag.Substring(1));
            }
            else
            {
                uint tagValue = uint.Parse(tag, NumberStyles.HexNumber);
                theTag = DicomTagDictionary.GetDicomTag(tagValue);
                DicomVr xmlVr = DicomVr.GetVR(attributeNode.Attributes["VR"].Value);
                if (theTag == null)
                {
                    theTag = new DicomTag(tagValue, "Unknown tag", "UnknownTag", xmlVr, false, 1, uint.MaxValue, false);
                }

                if (!theTag.VR.Equals(xmlVr))
                {
                    theTag = new DicomTag(tagValue, theTag.Name, theTag.VariableName, xmlVr, theTag.MultiVR, theTag.VMLow,
                                          theTag.VMHigh, theTag.Retired);
                }
            }
            return(theTag);
        }
        private static DicomTag CreateTag(int id, DicomVr vr)
        {
            uint tagValue = (uint)id;

            tagValue = ((((tagValue >> 16) << 1) + 0x11) << 16) + (tagValue & 0x0000ffff);             // this generates a serial private tag
            return(new DicomTag(tagValue, string.Format("({0:x4},{1:x4})", (tagValue >> 16), (tagValue & 0x0000ffff)), string.Format("tag{0:x8}", tagValue), vr, true, 0, 10, false));
        }
        public void TestAttributeFD()
        {
            DicomVr vr = DicomVr.FDvr;

            SetCurrentCulture();
            try
            {
                //there seems to invariably be some precision loss with floats
                //SetAndAssertFloat32(vr, "0", 0.00000000f);
                //SetAndAssertFloat32(vr, "2.048", 2.048f);
                //SetAndAssertFloat32(vr, "-2.048", -2.048f);
                //SetAndAssertFloat32(vr, "12345.6", 12345.6f);
                //SetAndAssertFloat32(vr, "-12345.6", -12345.6f);
                //SetAndAssertFloat32(vr, "1.797693E+38", 1.797693e38f);
                //SetAndAssertFloat32(vr, "-1.797693E+38", -1.797693e38f);
                //SetAndAssertFloat32(vr, "1.797693E-38", 1.797693e-38f);
                //SetAndAssertFloat32(vr, "-1.797693E-38", -1.797693e-38f);

                SetAndAssertFloat64(vr, "0", 0.00000000);
                SetAndAssertFloat64(vr, "12.3456789", 12.3456789);
                SetAndAssertFloat64(vr, "-12.3456789", -12.3456789);
                SetAndAssertFloat64(vr, "12345.6789", 12345.6789);
                SetAndAssertFloat64(vr, "-12345.6789", -12345.6789);
                SetAndAssertFloat64(vr, "1.7976931349E+38", 1.7976931349e38);
                SetAndAssertFloat64(vr, "-1.797693135E+38", -1.797693135e38);
                SetAndAssertFloat64(vr, "1.7976931349E-38", 1.7976931349e-38);
                SetAndAssertFloat64(vr, "-1.797693135E-38", -1.797693135e-38);
            }
            finally
            {
                ResetCurrentCulture();
            }
        }
Beispiel #4
0
		internal FileReference(string file, long offset, long length, Endian endian, DicomVr vr)
		{
			_filename = file;
			_offset = offset;
			_length = length;
			_endian = endian;
			_vr = vr;
		}
 internal FileReference(string file, long offset, long length, Endian endian, DicomVr vr)
 {
     _filename = file;
     _offset   = offset;
     _length   = length;
     _endian   = endian;
     _vr       = vr;
 }
        private static void SetAndAssertDateTime(DicomVr vr, DateTime value, string expected)
        {
            DicomAttributeCollection dataset = new DicomAttributeCollection();
            DicomTag tag = CreateTag(1, vr);

            dataset[tag].SetDateTime(0, value);
            Trace.WriteLine(string.Format("Testing {0} attribute with {1} (set as DateTime)", vr.Name, value));
            Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
            Assert.AreEqual(value, dataset[tag].GetDateTime(0));
            Assert.AreEqual(expected, dataset[tag].ToString());
        }
Beispiel #7
0
        protected virtual IDicomXmlVrWriter CreateDefualtVrWriter(DicomVr dicomVr)
        {
            IDicomXmlVrWriter writer = null;

            if (!_defaultVrWriters.TryGetValue(dicomVr.Name, out writer))
            {
                throw new ApplicationException("Default VR writer not registered!");
            }

            return(writer);
        }
Beispiel #8
0
        private static IEnumerable <DicomTag> GetTags(IList <uint> tags, DicomVr vr)
        {
            var dicomTags = new List <DicomTag>();

            for (int i = 0; i < tags.Count; ++i)
            {
                var tag   = tags[i];
                var theVr = i < tags.Count - 1 ? DicomVr.SQvr : vr;
                dicomTags.Add(NewTag(tag, theVr));
            }

            return(dicomTags);
        }
        /// <summary>
        /// Fixes the VR of the specified DICOM tag, which is especially important for multi-VR tags.
        /// </summary>
        private static DicomTag FixVR(uint tag, DicomVr newVR)
        {
            var dicomTag = DicomTagDictionary.GetDicomTag(tag);

            if (dicomTag.VR == newVR)
            {
                return(dicomTag);
            }
            if (!dicomTag.MultiVR)
            {
                throw new ArgumentException("The specified DICOM tag does not support multiple VRs.", "tag");
            }
            return(new DicomTag(dicomTag.TagValue, dicomTag.Name, dicomTag.VariableName, newVR, true, dicomTag.VMLow, dicomTag.VMHigh, dicomTag.Retired));
        }
Beispiel #10
0
        internal static bool IsWildcardCriterion(DicomVr vr, string criterion)
        {
            if (String.IsNullOrEmpty(criterion))
            {
                return(false);
            }

            if (!IsWildcardCriterionAllowed(vr))
            {
                return(false);
            }

            return(criterion.Contains("*") || criterion.Contains("?"));
        }
Beispiel #11
0
        internal static DicomTag NewTag(uint tag, DicomVr vr)
        {
            var theTag = DicomTagDictionary.GetDicomTag(tag);

            if (theTag == null)
            {
                theTag = new DicomTag(tag, "Unknown tag", "UnknownTag", vr ?? DicomVr.UNvr, false, 1, uint.MaxValue, false);
            }
            else if (vr != null && !theTag.VR.Equals(vr))
            {
                theTag = new DicomTag(tag, theTag.Name, theTag.VariableName, vr, theTag.MultiVR, theTag.VMLow,
                                      theTag.VMHigh, theTag.Retired);
            }

            return(theTag);
        }
Beispiel #12
0
        private bool MatchVr(DicomAttribute element)
        {
            DicomVr elementVr = element.Tag.VR;

            if (!elementVr.Equals(DicomVr.DAvr) && !elementVr.Equals(DicomVr.TMvr) && !elementVr.Equals(DicomVr.DTvr))
            {
                return(false);
            }

            if (HasWildcardMatching(element.ToString( )))
            {
                return(false);
            }

            return(true);
        }
 /// <summary>
 /// 获取VR类型
 /// </summary>
 /// <returns></returns>
 private string GetVR()
 {
     try
     {
         _buffer.SetOrder(ByteOrder.BigEndian);
         _vr    = _buffer.ReadUInt16();
         _strVr = DicomVr.ToString(_vr);
         _buffer.SetOrder(ByteOrder.LittleEndian);
         return(_strVr);
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex.Message);
         _buffer.Close();
         return(_strVr + " GetVR ERROR");
     }
 }
Beispiel #14
0
        private static IEnumerable <DicomTag> GetTags(string path, DicomVr vr)
        {
            Platform.CheckForEmptyString(path, "path");

            var dicomTags = new List <DicomTag>();

            string[] groupElementValues = path.Split(_pathSeparators);

            for (int i = 0; i < groupElementValues.Length; ++i)
            {
                var      groupElement = groupElementValues[i];
                string[] values       = groupElement.Split(_tagSeparator);
                if (values.Length != 2)
                {
                    throw new ArgumentException(String.Format(_exceptionFormatInvalidTagPath, path));
                }

                string group = values[0];
                if (!group.StartsWith("(") || group.Length != 5)
                {
                    throw new ArgumentException(String.Format(_exceptionFormatInvalidTagPath, path));
                }

                string element = values[1];
                if (!element.EndsWith(")") || element.Length != 5)
                {
                    throw new ArgumentException(String.Format(_exceptionFormatInvalidTagPath, path));
                }

                try
                {
                    ushort groupValue   = Convert.ToUInt16(group.TrimStart('('), 16);
                    ushort elementValue = Convert.ToUInt16(element.TrimEnd(')'), 16);

                    var theVr = i < groupElementValues.Length - 1 ? DicomVr.SQvr : vr;
                    dicomTags.Add(NewTag(DicomTag.GetTagValue(groupValue, elementValue), theVr));
                }
                catch
                {
                    throw new ArgumentException(String.Format(_exceptionFormatInvalidTagPath, path));
                }
            }

            return(dicomTags);
        }
        /// <summary>
        /// 获取Group为0002的Tag占用的Length
        /// </summary>
        /// <returns></returns>
        private int GetLength0002()
        {
            try
            {
                if (DicomVr.IsLengthField16Bit(_vr))
                {
                    return(_buffer.ReadUInt16());
                }

                _buffer.ReadUInt16();
                return(_buffer.ReadInt32());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                _buffer.Close();
                return(-1);
            }
        }
        public void TestAttributeSL()
        {
            DicomVr vr = DicomVr.SLvr;

            SetCurrentCulture();
            try
            {
                SetAndAssertInt16(vr, "0", 0);
                SetAndAssertInt16(vr, "1", 1);
                SetAndAssertInt16(vr, "-1", -1);
                SetAndAssertInt16(vr, "32767", 32767);
                SetAndAssertInt16(vr, "-32768", -32768);

                SetAndAssertInt32(vr, "0", 0);
                SetAndAssertInt32(vr, "1", 1);
                SetAndAssertInt32(vr, "-1", -1);
                SetAndAssertInt32(vr, "2147483647", 2147483647);
                SetAndAssertInt32(vr, "-2147483648", -2147483648);

                SetAndAssertInt64(vr, "0", 0);
                SetAndAssertInt64(vr, "1", 1);
                SetAndAssertInt64(vr, "-1", -1);
                SetAndAssertInt64(vr, "2147483647", 2147483647);
                SetAndAssertInt64(vr, "-2147483648", -2147483648);

                SetAndAssertUInt16(vr, "0", 0);
                SetAndAssertUInt16(vr, "1", 1);
                SetAndAssertUInt16(vr, "65535", 65535);

                SetAndAssertUInt32(vr, "0", 0);
                SetAndAssertUInt32(vr, "1", 1);
                SetAndAssertUInt32(vr, "2147483647", 2147483647);

                SetAndAssertUInt64(vr, "0", 0);
                SetAndAssertUInt64(vr, "1", 1);
                SetAndAssertUInt64(vr, "2147483647", 2147483647);
            }
            finally
            {
                ResetCurrentCulture();
            }
        }
Beispiel #17
0
        public static string GetValue(ByteBuffer buffer, int vr, int length)
        {
            if (DicomVr.IsStringValue(vr))
            {
                return(buffer.ReadBytesToString(length));
            }

            switch (vr)
            {
            case DicomVr.AT:
                return(GetValueAT(buffer, length));

            case DicomVr.FD:
                return(GetValueFD(buffer, length));

            case DicomVr.FL:
                return(GetValueFL(buffer, length));

            case DicomVr.OB:
            case DicomVr.OW:
            case DicomVr.UN:
                return(GetValueOB(buffer, length));

            case DicomVr.SL:
                return(GetValueSL(buffer, length));

            case DicomVr.SQ:
                return(GetValueSQ(buffer, length));

            case DicomVr.SS:
                return(GetValueSS(buffer, length));

            case DicomVr.UL:
                return(GetValueUL(buffer, length));

            case DicomVr.US:
                return(GetValueUS(buffer, length));

            default:
                return("GetValue ERROR");
            }
        }
        public void TestAttributeUS()
        {
            DicomVr vr = DicomVr.USvr;

            SetCurrentCulture();
            try
            {
                SetAndAssertInt16(vr, "0", 0);
                SetAndAssertInt16(vr, "1", 1);
                SetAndAssertInt16(vr, "32767", 32767);

                SetAndAssertUInt16(vr, "0", 0);
                SetAndAssertUInt16(vr, "1", 1);
                SetAndAssertUInt16(vr, "65535", 65535);
            }
            finally
            {
                ResetCurrentCulture();
            }
        }
        public void TestAttributeDT()
        {
            DicomVr vr = DicomVr.DTvr;

            SetCurrentCulture();
            try
            {
                SetAndAssertDateTime(vr, @"20090101000000+0000", new DateTime(2009, 1, 1, 0, 0, 0, DateTimeKind.Utc));
                SetAndAssertDateTime(vr, @"20080101000000-0500", new DateTime(2007, 12, 31, 19, 0, 0, DateTimeKind.Utc));
                SetAndAssertDateTime(vr, @"20070101000000+0500", new DateTime(2007, 1, 1, 5, 0, 0, DateTimeKind.Utc));
                SetAndAssertDateTime(vr, @"20060101000000-0000", new DateTime(2006, 1, 1, 0, 0, 0, DateTimeKind.Utc));

                SetAndAssertDateTime(vr, new DateTime(2009, 1, 2, 3, 4, 5, 6, DateTimeKind.Utc), "20090102030405.006000");
                SetAndAssertDateTime(vr, new DateTime(2009, 1, 2, 3, 4, 5, 6, DateTimeKind.Local), "20090102030405.006000");
            }
            finally
            {
                ResetCurrentCulture();
            }
        }
        public void TestAttributeFL()
        {
            DicomVr vr = DicomVr.FLvr;

            SetCurrentCulture();
            try
            {
                SetAndAssertFloat32(vr, "0", 0.00000000f);
                SetAndAssertFloat32(vr, "2.048", 2.048f);
                SetAndAssertFloat32(vr, "-2.048", -2.048f);
                SetAndAssertFloat32(vr, "12345.6", 12345.6f);
                SetAndAssertFloat32(vr, "-12345.6", -12345.6f);
                SetAndAssertFloat32(vr, "1.797693E+38", 1.797693e38f);
                SetAndAssertFloat32(vr, "-1.797693E+38", -1.797693e38f);
                SetAndAssertFloat32(vr, "1.797693E-38", 1.797693e-38f);
                SetAndAssertFloat32(vr, "-1.797693E-38", -1.797693e-38f);
            }
            finally
            {
                ResetCurrentCulture();
            }
        }
        private static void ConvertValue(DicomAttribute element, XmlWriter writer)
        {
            DicomVr dicomVr = element.Tag.VR;


            for (int index = 0; index < element.Count; index++)
            {
                writer.WriteStartElement("Value");
                WriteNumberAttrib(writer, index);

                if (dicomVr.Equals(DicomVr.ATvr))
                {
                    writer.WriteString(element.GetString(index, string.Empty)); //TODO: check standard
                }
                else
                {
                    writer.WriteString(element.GetString(index, string.Empty));
                }

                writer.WriteEndElement( );
            }
        }
        public void TestAttributeSS()
        {
            DicomVr vr = DicomVr.SSvr;

            SetCurrentCulture();
            try
            {
                SetAndAssertInt16(vr, "0", 0);
                SetAndAssertInt16(vr, "1", 1);
                SetAndAssertInt16(vr, "-1", -1);
                SetAndAssertInt16(vr, "32767", 32767);
                SetAndAssertInt16(vr, "-32768", -32768);

                SetAndAssertUInt16(vr, "0", 0);
                SetAndAssertUInt16(vr, "1", 1);
                SetAndAssertUInt16(vr, "32767", 32767);
            }
            finally
            {
                ResetCurrentCulture();
            }
        }
        private static void SetAndAssertFloat64(DicomVr vr, string szValue, double dValue)
        {
            DicomAttributeCollection dataset = new DicomAttributeCollection();
            DicomTag tag = CreateTag(1, vr);

            dataset[tag].SetStringValue(szValue);
            Trace.WriteLine(string.Format("Testing {0} attribute with {1} (set as string)", vr.Name, szValue));
            Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
            Assert.AreEqual(szValue, dataset[tag].ToString(), "SetStringValue (double) vs dataset[tag].ToString()");
            Assert.AreEqual(dValue, dataset[tag].GetFloat64(0, -123), "SetStringValue (double) vs dataset[tag].GetFloat64(...)");

            dataset[tag].SetFloat64(0, dValue);
            Trace.WriteLine(string.Format("Testing {0} attribute with {1} (set as double)", vr.Name, dValue));
            Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
            Assert.AreEqual(szValue, dataset[tag].ToString(), "SetFloat64 vs dataset[tag].ToString()");
            Assert.AreEqual(dValue, dataset[tag].GetFloat64(0, -123), "SetFloat64 vs dataset[tag].GetFloat64(...)");

            dataset[tag].AppendFloat64(dValue);
            Trace.WriteLine(string.Format("Testing {0} attribute with {1} (append as double)", vr.Name, dValue));
            Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
            Assert.AreEqual(szValue + @"\" + szValue, dataset[tag].ToString(), "AppendFloat64 vs dataset[tag].ToString()");
            Assert.AreEqual(dValue, dataset[tag].GetFloat64(1, -123), "AppendFloat64 vs dataset[tag].GetFloat64(...)");
        }
        private static void SetAndAssertUInt32(DicomVr vr, string szValue, uint uiValue)
        {
            DicomAttributeCollection dataset = new DicomAttributeCollection();
            DicomTag tag = CreateTag(1, vr);

            dataset[tag].SetStringValue(szValue);
            Trace.WriteLine(string.Format("Testing {0} attribute with {1} (set as string)", vr.Name, szValue));
            Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
            Assert.AreEqual(szValue, dataset[tag].ToString(), "SetStringValue (uint) vs dataset[tag].ToString()");
            Assert.AreEqual(uiValue, dataset[tag].GetUInt32(0, 123), "SetStringValue (uint) vs dataset[tag].GetUInt32(...)");

            dataset[tag].SetUInt32(0, uiValue);
            Trace.WriteLine(string.Format("Testing {0} attribute with {1} (set as uint)", vr.Name, uiValue));
            Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
            Assert.AreEqual(szValue, dataset[tag].ToString(), "SetUInt32 vs dataset[tag].ToString()");
            Assert.AreEqual(uiValue, dataset[tag].GetUInt32(0, 123), "SetUInt32 vs dataset[tag].GetUInt32(...)");

            dataset[tag].AppendUInt32(uiValue);
            Trace.WriteLine(string.Format("Testing {0} attribute with {1} (append as uint)", vr.Name, uiValue));
            Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
            Assert.AreEqual(szValue + @"\" + szValue, dataset[tag].ToString(), "AppendUInt32 vs dataset[tag].ToString()");
            Assert.AreEqual(uiValue, dataset[tag].GetUInt32(1, 123), "AppendUInt32 vs dataset[tag].GetUInt32(...)");
        }
        public void TestAttributeAT()
        {
            DicomVr vr = DicomVr.ATvr;

            SetCurrentCulture();
            try
            {
                SetAndAssertInt16(vr, "0", 0);
                SetAndAssertInt16(vr, "1", 1);
                SetAndAssertInt16(vr, "7FFF", 0x7FFF);

                SetAndAssertInt32(vr, "0", 0);
                SetAndAssertInt32(vr, "1", 1);
                SetAndAssertInt32(vr, "7FFFFFFF", 0x7FFFFFFF);

                SetAndAssertInt64(vr, "0", 0);
                SetAndAssertInt64(vr, "1", 1);
                SetAndAssertInt64(vr, "FFFFFFFF", 0xFFFFFFFF);

                SetAndAssertUInt16(vr, "0", 0);
                SetAndAssertUInt16(vr, "1", 1);
                SetAndAssertUInt16(vr, "FFFF", 0xFFFF);

                SetAndAssertUInt32(vr, "0", 0);
                SetAndAssertUInt32(vr, "1", 1);
                SetAndAssertUInt32(vr, "FFFFFFFF", 0xFFFFFFFF);

                SetAndAssertUInt64(vr, "0", 0);
                SetAndAssertUInt64(vr, "1", 1);
                SetAndAssertUInt64(vr, "FFFFFFFF", 0xFFFFFFFF);
            }
            finally
            {
                ResetCurrentCulture();
            }
        }
        public void TestAttributeUL()
        {
            DicomVr vr = DicomVr.ULvr;

            SetCurrentCulture();
            try
            {
                SetAndAssertInt16(vr, "0", 0);
                SetAndAssertInt16(vr, "1", 1);
                SetAndAssertInt16(vr, "32767", 32767);

                SetAndAssertInt32(vr, "0", 0);
                SetAndAssertInt32(vr, "1", 1);
                SetAndAssertInt32(vr, "2147483647", 2147483647);

                SetAndAssertInt64(vr, "0", 0);
                SetAndAssertInt64(vr, "1", 1);
                SetAndAssertInt64(vr, "4294967295", 4294967295);

                SetAndAssertUInt16(vr, "0", 0);
                SetAndAssertUInt16(vr, "1", 1);
                SetAndAssertUInt16(vr, "65535", 65535);

                SetAndAssertUInt32(vr, "0", 0);
                SetAndAssertUInt32(vr, "1", 1);
                SetAndAssertUInt32(vr, "4294967295", 4294967295);

                SetAndAssertUInt64(vr, "0", 0);
                SetAndAssertUInt64(vr, "1", 1);
                SetAndAssertUInt64(vr, "4294967295", 4294967295);
            }
            finally
            {
                ResetCurrentCulture();
            }
        }
        private void WriteDicomAttribute
        (
            DicomAttributeCollection ds,
            DicomAttribute element,
            XmlWriter writer
        )
        {
            if (null == element)
            {
                return;
            }

            DicomVr dicomVr = element.Tag.VR;

            writer.WriteStartElement("DiocomAttribute");

            writer.WriteAttributeString("keyword", element.Tag.VariableName);
            writer.WriteAttributeString("tag", element.Tag.Group.ToString("D4") + element.Tag.Element.ToString("D4"));
            writer.WriteAttributeString("vr", element.Tag.VR.Name);

            //VR should at least support a switch!
            if (dicomVr.Name == DicomVr.SQvr.Name)
            {
                ConvertSequence(element, writer);
            }
            else if (dicomVr.Equals(DicomVr.PNvr))
            {
                for (int index = 0; index < element.Count; index++)
                {
                    writer.WriteStartElement("PersonName");
                    WriteNumberAttrib(writer, index);

                    writer.WriteElementString("Alphabetic", element.ToString());  //TODO: check the standard
                    writer.WriteEndElement( );
                }
            }
            else if (dicomVr.Equals(DicomVr.OBvr) || dicomVr.Equals(DicomVr.ODvr) ||
                     dicomVr.Equals(DicomVr.OFvr) || dicomVr.Equals(DicomVr.OWvr) ||
                     dicomVr.Equals(DicomVr.UNvr))    //TODO inline bulk
            {
                if (element.Tag.TagValue == DicomTags.PixelData)
                {
                }
                else
                {
                    byte[] data = (byte[])element.Values;
                    writer.WriteBase64(data, 0, data.Length);
                }
            }
            //else if ( dicomVr.Equals (DicomVr.PNvr) ) //TODO bulk reference
            //{

            //}
            else
            {
                ConvertValue(element, writer);
            }

            if (element.Tag.IsPrivate)
            {
                //TODO:
                //writer.WriteAttributeString ("privateCreator", ds[DicomTags.privatecreatro. ) ;
            }

            writer.WriteEndElement( );
        }
Beispiel #28
0
 internal static bool IsWildcardCriterionAllowed(DicomVr vr)
 {
     return(!WildcardExcludedVRs.Any(excludedVr => excludedVr == vr.Name));
 }
		private static DicomTag CreateTag(int id, DicomVr vr)
		{
			uint tagValue = (uint) id;
			tagValue = ((((tagValue >> 16) << 1) + 0x11) << 16) + (tagValue & 0x0000ffff); // this generates a serial private tag
			return new DicomTag(tagValue, string.Format("({0:x4},{1:x4})", (tagValue >> 16), (tagValue & 0x0000ffff)), string.Format("tag{0:x8}", tagValue), vr, true, 0, 10, false);
		}
		private static void SetAndAssertDateTime(DicomVr vr, DateTime value, string expected)
		{
			DicomAttributeCollection dataset = new DicomAttributeCollection();
			DicomTag tag = CreateTag(1, vr);
			dataset[tag].SetDateTime(0, value);
			Trace.WriteLine(string.Format("Testing {0} attribute with {1} (set as DateTime)", vr.Name, value));
			Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
			Assert.AreEqual(value, dataset[tag].GetDateTime(0));
			Assert.AreEqual(expected, dataset[tag].ToString());
		}
		private static void SetAndAssertFloat64(DicomVr vr, string szValue, double dValue)
		{
			DicomAttributeCollection dataset = new DicomAttributeCollection();
			DicomTag tag = CreateTag(1, vr);
			dataset[tag].SetStringValue(szValue);
			Trace.WriteLine(string.Format("Testing {0} attribute with {1} (set as string)", vr.Name, szValue));
			Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
			Assert.AreEqual(szValue, dataset[tag].ToString(), "SetStringValue (double) vs dataset[tag].ToString()");
			Assert.AreEqual(dValue, dataset[tag].GetFloat64(0, -123), "SetStringValue (double) vs dataset[tag].GetFloat64(...)");

			dataset[tag].SetFloat64(0, dValue);
			Trace.WriteLine(string.Format("Testing {0} attribute with {1} (set as double)", vr.Name, dValue));
			Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
			Assert.AreEqual(szValue, dataset[tag].ToString(), "SetFloat64 vs dataset[tag].ToString()");
			Assert.AreEqual(dValue, dataset[tag].GetFloat64(0, -123), "SetFloat64 vs dataset[tag].GetFloat64(...)");

			dataset[tag].AppendFloat64(dValue);
			Trace.WriteLine(string.Format("Testing {0} attribute with {1} (append as double)", vr.Name, dValue));
			Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
			Assert.AreEqual(szValue + @"\" + szValue, dataset[tag].ToString(), "AppendFloat64 vs dataset[tag].ToString()");
			Assert.AreEqual(dValue, dataset[tag].GetFloat64(1, -123), "AppendFloat64 vs dataset[tag].GetFloat64(...)");
		}
		private static void SetAndAssertUInt32(DicomVr vr, string szValue, uint uiValue)
		{
			DicomAttributeCollection dataset = new DicomAttributeCollection();
			DicomTag tag = CreateTag(1, vr);
			dataset[tag].SetStringValue(szValue);
			Trace.WriteLine(string.Format("Testing {0} attribute with {1} (set as string)", vr.Name, szValue));
			Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
			Assert.AreEqual(szValue, dataset[tag].ToString(), "SetStringValue (uint) vs dataset[tag].ToString()");
			Assert.AreEqual(uiValue, dataset[tag].GetUInt32(0, 123), "SetStringValue (uint) vs dataset[tag].GetUInt32(...)");

			dataset[tag].SetUInt32(0, uiValue);
			Trace.WriteLine(string.Format("Testing {0} attribute with {1} (set as uint)", vr.Name, uiValue));
			Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
			Assert.AreEqual(szValue, dataset[tag].ToString(), "SetUInt32 vs dataset[tag].ToString()");
			Assert.AreEqual(uiValue, dataset[tag].GetUInt32(0, 123), "SetUInt32 vs dataset[tag].GetUInt32(...)");

			dataset[tag].AppendUInt32(uiValue);
			Trace.WriteLine(string.Format("Testing {0} attribute with {1} (append as uint)", vr.Name, uiValue));
			Trace.WriteLine(string.Format("Attribute Value is: \"{0}\"", dataset[tag].ToString()));
			Assert.AreEqual(szValue + @"\" + szValue, dataset[tag].ToString(), "AppendUInt32 vs dataset[tag].ToString()");
			Assert.AreEqual(uiValue, dataset[tag].GetUInt32(1, 123), "AppendUInt32 vs dataset[tag].GetUInt32(...)");
		}
Beispiel #33
0
        private void WriteDicomAttribute
        (
            DicomAttributeCollection ds,
            DicomAttribute element,
            JsonWriter writer
        )
        {
            DicomVr dicomVr = element.Tag.VR;

            writer.WritePropertyName(element.Tag.HexString, false);
            //writer.WritePropertyName(element.Tag.Group.ToString("D4") + element.Tag.Element.ToString("D4"), false);
            writer.WriteStartObject();


            writer.WritePropertyName("temp");
            writer.WriteValue(element.Tag.VariableName);

            writer.WritePropertyName("vr");
            writer.WriteValue(element.Tag.VR.Name);


            //VR should at least support a switch!
            if (dicomVr.Name == DicomVr.SQvr.Name)
            {
                ConvertSequence(element, writer);
            }
            else if (dicomVr.Equals(DicomVr.PNvr))
            {
                writer.WritePropertyName(JsonConstants.ValueField);
                writer.WriteStartArray();
                writer.WriteStartObject();
                writer.WritePropertyName(JsonConstants.Alphabetic);
                writer.WriteValue(element.ToString().TrimEnd());           //TODO: not sure if PN need to be trimmed
                writer.WriteEndObject();
                writer.WriteEndArray();
            }
            else if (dicomVr.Equals(DicomVr.OBvr) || dicomVr.Equals(DicomVr.ODvr) ||
                     dicomVr.Equals(DicomVr.OFvr) || dicomVr.Equals(DicomVr.OWvr) ||
                     dicomVr.Equals(DicomVr.UNvr))    //TODO inline bulk
            {
                if (element.Tag.TagValue == DicomTags.PixelData)
                {
                }
                else
                {
                    byte[] data = (byte[])element.Values;
                    WriteStringValue(writer, System.Convert.ToBase64String(data));
                }
            }
            //else if ( dicomVr.Equals (DicomVr.PNvr) ) //TODO bulk reference
            //{

            //}
            else
            {
                ConvertValue(element, writer);
            }

            if (element.Tag.IsPrivate)
            {
                //TODO:
                //writer.WriteAttributeString ("privateCreator", ds[DicomTags.privatecreatro. ) ;
            }

            writer.WriteEndObject( );
        }
        public void TestAttributeDS()
        {
            DicomVr vr = DicomVr.DSvr;

            SetCurrentCulture();
            try
            {
                SetAndAssertInt16(vr, "0", 0);
                SetAndAssertInt16(vr, "1", 1);
                SetAndAssertInt16(vr, "-1", -1);
                SetAndAssertInt16(vr, "32767", 32767);
                SetAndAssertInt16(vr, "-32768", -32768);

                SetAndAssertInt32(vr, "0", 0);
                SetAndAssertInt32(vr, "1", 1);
                SetAndAssertInt32(vr, "-1", -1);
                SetAndAssertInt32(vr, "2147483647", 2147483647);
                SetAndAssertInt32(vr, "-2147483648", -2147483648);

                SetAndAssertInt64(vr, "0", 0);
                SetAndAssertInt64(vr, "1", 1);
                SetAndAssertInt64(vr, "-1", -1);
                SetAndAssertInt64(vr, "2147483647", 2147483647);
                SetAndAssertInt64(vr, "-2147483648", -2147483648);

                SetAndAssertUInt16(vr, "0", 0);
                SetAndAssertUInt16(vr, "1", 1);
                SetAndAssertUInt16(vr, "65535", 65535);

                SetAndAssertUInt32(vr, "0", 0);
                SetAndAssertUInt32(vr, "1", 1);
                SetAndAssertUInt32(vr, "2147483647", 2147483647);

                SetAndAssertUInt64(vr, "0", 0);
                SetAndAssertUInt64(vr, "1", 1);
                SetAndAssertUInt64(vr, "2147483647", 2147483647);

                //there seems to invariably be some precision loss with floats
                //SetAndAssertFloat32(vr, "0", 0.00000000f);
                //SetAndAssertFloat32(vr, "2.048", 2.048f);
                //SetAndAssertFloat32(vr, "-2.048", -2.048f);
                //SetAndAssertFloat32(vr, "12345.6", 12345.6f);
                //SetAndAssertFloat32(vr, "-12345.6", -12345.6f);
                //SetAndAssertFloat32(vr, "1.797693E+38", 1.797693e38f);
                //SetAndAssertFloat32(vr, "-1.797693E+38", -1.797693e38f);
                //SetAndAssertFloat32(vr, "1.797693E-38", 1.797693e-38f);
                //SetAndAssertFloat32(vr, "-1.797693E-38", -1.797693e-38f);

                SetAndAssertFloat64(vr, "0", 0.00000000);
                SetAndAssertFloat64(vr, "12.3456789", 12.3456789);
                SetAndAssertFloat64(vr, "-12.3456789", -12.3456789);
                SetAndAssertFloat64(vr, "12345.6789", 12345.6789);
                SetAndAssertFloat64(vr, "-12345.6789", -12345.6789);
                SetAndAssertFloat64(vr, "1.7976931349E+38", 1.7976931349e38);
                SetAndAssertFloat64(vr, "-1.797693135E+38", -1.797693135e38);
                SetAndAssertFloat64(vr, "1.7976931349E-38", 1.7976931349e-38);
                SetAndAssertFloat64(vr, "-1.797693135E-38", -1.797693135e-38);
            }
            finally
            {
                ResetCurrentCulture();
            }
        }
		/// <summary>
		/// Fixes the VR of the specified DICOM tag, which is especially important for multi-VR tags.
		/// </summary>
		private static DicomTag FixVR(uint tag, DicomVr newVR)
		{
			var dicomTag = DicomTagDictionary.GetDicomTag(tag);
			if (dicomTag.VR == newVR)
				return dicomTag;
			if (!dicomTag.MultiVR)
				throw new ArgumentException("The specified DICOM tag does not support multiple VRs.", "tag");
			return new DicomTag(dicomTag.TagValue, dicomTag.Name, dicomTag.VariableName, newVR, true, dicomTag.VMLow, dicomTag.VMHigh, dicomTag.Retired);
		}
Beispiel #36
0
        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);
            }
        }
Beispiel #37
0
        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;
            }
        }