Пример #1
0
  public static int Main(string[] args)
    {
    string filename = args[0];
    string outfilename = args[1];

    using( var sfcts = FileChangeTransferSyntax.New() )
      {
      FileChangeTransferSyntax fcts = sfcts.__ref__();
      //SimpleSubjectWatcher watcher = new SimpleSubjectWatcher(fcts, "FileChangeTransferSyntax");
      gdcm.TransferSyntax ts = new TransferSyntax( TransferSyntax.TSType.JPEG2000 );
      fcts.SetTransferSyntax( ts );
      ImageCodec ic = fcts.GetCodec();
      JPEG2000Codec jpeg2000 = JPEG2000Codec.Cast( ic );
      jpeg2000.SetReversible( false );
      jpeg2000.SetQuality(0, 55);

      fcts.SetInputFileName( filename );
      fcts.SetOutputFileName( outfilename );
      if( !fcts.Change() )
        {
        return 1;
        }
      }

    return 0;
    }
Пример #2
0
        /// <summary>
        ///     Read explicit VR little endian up to transfer syntax element and determines transfer syntax for rest of elements
        /// </summary>
        /// <param name="dr">the binary reader which is reading the DICOM object</param>
        /// <param name="syntax">the transfer syntax of the DICOM file</param>
        /// <returns>elements preceeding and including transfer syntax element</returns>
        public static List<IDICOMElement> ReadFileMetadata(DICOMBinaryReader dr, ref TransferSyntax syntax)
        {
            var elements = new List<IDICOMElement>();
            syntax = syntax != TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN
                ? syntax
                : TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN;

            while (dr.StreamPosition < dr.StreamLength)
            {
                long position = dr.StreamPosition;
                if (TagReader.ReadLittleEndian(dr).Group == _metaGroup)
                {
                    dr.StreamPosition = position;
                    IDICOMElement el = DICOMElementReader.ReadElementExplicitLittleEndian(dr);
                    Tag uid = TagHelper.TRANSFER_SYNTAX_UID;
                    if (el.Tag == uid)
                    {
                        syntax = TransferSyntaxHelper.GetSyntax(el);
                    }
                    elements.Add(el);
                }
                else
                {
                    dr.StreamPosition = position;
                    break;
                }
            }

            return elements;
        }
Пример #3
0
  public static int Main(string[] args)
    {
    string filename = args[0];
    string outfilename = args[1];

    using( var sfcts = FileChangeTransferSyntax.New() )
      {
      FileChangeTransferSyntax fcts = sfcts.__ref__();
      //SimpleSubjectWatcher watcher = new SimpleSubjectWatcher(fcts, "FileChangeTransferSyntax");
      gdcm.TransferSyntax ts = new TransferSyntax( TransferSyntax.TSType.JPEGLSNearLossless );
      fcts.SetTransferSyntax( ts );
      ImageCodec ic = fcts.GetCodec();
      JPEGLSCodec jpegls = JPEGLSCodec.Cast( ic );
      jpegls.SetLossless( false );
      jpegls.SetLossyError( 2 );

      fcts.SetInputFileName( filename );
      fcts.SetOutputFileName( outfilename );
      if( !fcts.Change() )
        {
        return 1;
        }
      }

    return 0;
    }
Пример #4
0
        /// <summary>
        /// Read explicit VR little endian up to transfer syntax element and determines transfer syntax for rest of elements
        /// </summary>
        /// <param name="dr">the binary reader which is reading the DICOM object</param>
        /// <param name="syntax">the transfer syntax of the DICOM file</param>
        /// <returns>elements preceeding and including transfer syntax element</returns>
        private static List<IDICOMElement> ReadFileMetadata(DICOMBinaryReader dr, out TransferSyntax syntax)
        {
            List<IDICOMElement> elements = new List<IDICOMElement>();
            syntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN;

            while (dr.StreamPosition < dr.StreamLength)
            {
                long position = dr.StreamPosition;
                if (TagReader.ReadLittleEndian(dr).Group == _MetaGroup)
                {
                    dr.StreamPosition = position;
                    IDICOMElement el = DICOMElementReader.ReadElementExplicitLittleEndian(dr);
                    if (el.Tag.CompleteID == TagHelper.TRANSFER_SYNTAX_UID.CompleteID)
                    {
                        syntax = TransferSyntaxHelper.GetSyntax(el);
                    }
                    elements.Add(el);
                }
                else
                {
                    dr.StreamPosition = position;
                    break;
                }
            }

            return elements;
        }
Пример #5
0
 public static void SkipItemLittleEndian(DICOMBinaryReader dr, TransferSyntax syntax)
 {
     int length = LengthReader.ReadLittleEndian(VR.Null, dr.Skip(4));
     if (length != -1)
     {
         dr.Skip(length);
     }
     else
     {
         if (syntax == TransferSyntax.EXPLICIT_VR_LITTLE_ENDIAN)
         {
             while (!IsEndOfSequenceItemLittleEndian(dr))
             {
                 dr.StreamPosition -= 8;
                 DICOMElementReader.SkipElementExplicitLittleEndian(dr);
             }
         }
         else
         {
             while (!IsEndOfSequenceItemLittleEndian(dr))
             {
                 dr.StreamPosition -= 8;
                 DICOMElementReader.SkipElementImplicitLittleEndian(dr);
             }
         }
     }
 }
Пример #6
0
	    public static void LosslessImageTest(TransferSyntax syntax, DicomFile theFile)
		{
			if (File.Exists(theFile.Filename))
				File.Delete(theFile.Filename);

			DicomFile saveCopy = new DicomFile(theFile.Filename, theFile.MetaInfo.Copy(), theFile.DataSet.Copy());

			theFile.ChangeTransferSyntax(syntax);

			theFile.Save(DicomWriteOptions.ExplicitLengthSequence);

			DicomFile newFile = new DicomFile(theFile.Filename);

			newFile.Load(DicomReadOptions.Default);

			newFile.ChangeTransferSyntax(saveCopy.TransferSyntax);

			List<DicomAttributeComparisonResult> list = new List<DicomAttributeComparisonResult>();
			bool result = newFile.DataSet.Equals(saveCopy.DataSet, ref list);

			StringBuilder sb = new StringBuilder();
			foreach (DicomAttributeComparisonResult compareResult in list)
				sb.AppendFormat("Comparison Failure: {0}, ", compareResult.Details);

			Assert.IsTrue(result,sb.ToString());
		}
Пример #7
0
  public static int Main(string[] args)
    {
    string filename = args[0];
    string outfilename = args[1];

    using( var sfcts = FileChangeTransferSyntax.New() )
      {
      FileChangeTransferSyntax fcts = sfcts.__ref__();
      //SimpleSubjectWatcher watcher = new SimpleSubjectWatcher(fcts, "FileChangeTransferSyntax");
      gdcm.TransferSyntax ts = new TransferSyntax( TransferSyntax.TSType.RLELossless );
      fcts.SetTransferSyntax( ts );
      ImageCodec ic = fcts.GetCodec();
      RLECodec rle = RLECodec.Cast( ic );
      // need to call at least one member func to check not NULL:
      long val = rle.GetBufferLength();
      System.Console.WriteLine( val ); // use val to remove a warning

      fcts.SetInputFileName( filename );
      fcts.SetOutputFileName( outfilename );
      if( !fcts.Change() )
        {
        return 1;
        }
      }

    return 0;
    }
Пример #8
0
		public void ChangeSyntax(TransferSyntax syntax)
		{
			try
			{
				if (!_dicomFile.TransferSyntax.Encapsulated)
				{
					// Check if Overlay is embedded in pixels
					OverlayPlaneModuleIod overlayIod = new OverlayPlaneModuleIod(_dicomFile.DataSet);
					for (int i = 0; i < 16; i++)
					{
						if (overlayIod.HasOverlayPlane(i))
						{
							OverlayPlane overlay = overlayIod[i];
							if (overlay.OverlayData == null)
							{
								DicomUncompressedPixelData pd = new DicomUncompressedPixelData(_dicomFile);
								overlay.ConvertEmbeddedOverlay(pd);	
							}
						}
					}
				}
				else if (syntax.Encapsulated)
				{
					// Must decompress first.
					_dicomFile.ChangeTransferSyntax(TransferSyntax.ExplicitVrLittleEndian);
				}

				_dicomFile.ChangeTransferSyntax(syntax);
			}
			catch (Exception e)
			{
				Platform.Log(LogLevel.Error, e, "Unexpected exception compressing/decompressing DICOM file");
			}
		}
Пример #9
0
		public DicomCompressCommand(DicomMessageBase file, TransferSyntax syntax, IDicomCodec codec, DicomCodecParameters parms)
			: base("DICOM Compress Command", true)
		{

			_file = file;
			_syntax = syntax;
			_codec = codec;
			_parms = parms;
		}
Пример #10
0
 public static DICOMObject ReadObject(byte[] objectBytes, TransferSyntax syntax)
 {
     List<IDICOMElement> elements;
     using (DICOMBinaryReader dr = new DICOMBinaryReader(objectBytes))
     {
         elements = DICOMElementReader.ReadAllElements(dr, syntax);
     }
     return new DICOMObject(elements);
 }
Пример #11
0
		internal DicomPresContext(byte pcid, SopClass abstractSyntax, TransferSyntax transferSyntax, DicomPresContextResult result) {
			_pcid = pcid;
			_result = result;
			_roles = DicomRoleSelection.Disabled;
			_abstract = abstractSyntax;
            if (abstractSyntax.Uid.Length == 0)
                throw new DicomException("Invalid abstract syntax for presentation context, UID is zero length.");
            _transfers = new List<TransferSyntax>();
			_transfers.Add(transferSyntax);
		}
Пример #12
0
 public static int ReadIndefiniteLengthLittleEndian(DICOMBinaryReader dr, TransferSyntax syntax)
 {
     long startingPos = dr.StreamPosition;
     while (!IsEndOfSequenceLittleEndian(dr))
     {
         dr.StreamPosition -= 8;
         SequenceItemReader.SkipItemLittleEndian(dr, syntax);
     }
     return CalculateLength(dr, startingPos)-8;
 }
Пример #13
0
 /// <summary>
 ///     Reads the length from a series of bytes in a stream. The number of bytes is automatically determined from
 ///     VR.
 /// </summary>
 /// <param name="vr">the value representation of the element</param>
 /// <param name="dr">the binary stream with a current position on the length parameter</param>
 /// <param name="syntax">the transfer syntax of this element</param>
 /// <returns></returns>
 public static int Read(VR vr, DICOMBinaryReader dr, TransferSyntax syntax)
 {
     switch (syntax)
     {
         case TransferSyntax.EXPLICIT_VR_BIG_ENDIAN:
             return ReadBigEndian(vr, dr);
         default:
             return ReadLittleEndian(vr, dr);
     }
 }
Пример #14
0
 public static DICOMObject ReadObject(byte[] objectBytes, TransferSyntax syntax, out long bytesRead)
 {
     List<IDICOMElement> elements;
     using (var dr = new DICOMBinaryReader(objectBytes))
     {
         elements = DICOMElementReader.ReadAllElements(dr, syntax);
         bytesRead = dr.StreamPosition;
     }
     return new DICOMObject(elements);
 }
Пример #15
0
 /// <summary>
 ///     Reads the data from an element encoded in little endian byte order
 /// </summary>
 /// <param name="lengthToRead">the length of the data</param>
 /// <param name="dr">the binary reader which is reading the DICOM object</param>
 /// <returns>the data from this element</returns>
 public static byte[] ReadLittleEndian(int lengthToRead, DICOMBinaryReader dr, TransferSyntax syntax)
 {
     if (lengthToRead != -1)
     {
         return dr.ReadBytes(lengthToRead);
     }
     int length = SequenceReader.ReadIndefiniteLengthLittleEndian(dr, syntax);
     byte[] seqBytes = dr.ReadBytes(length);
     dr.Skip(8);
     return seqBytes;
 }
Пример #16
0
 /// <summary>
 ///     Reads a DICOM file from a byte array
 /// </summary>
 /// <param name="fileBytes">the bytes of the DICOM file</param>
 /// <returns>a DICOM object containing all elements</returns>
 public static DICOMObject Read(byte[] fileBytes, TransferSyntax trySyntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN)
 {
     TransferSyntax syntax = trySyntax; //Will keep if metadata doesn't exist
     List<IDICOMElement> elements;
     using (var dr = new DICOMBinaryReader(fileBytes))
     {
         DICOMPreambleReader.Read(dr);
         List<IDICOMElement> metaElements = ReadFileMetadata(dr, ref syntax);
         elements = metaElements.Concat(DICOMElementReader.ReadAllElements(dr, syntax)).ToList();
     }
     return new DICOMObject(elements);
 }
Пример #17
0
 /// <summary>
 ///     Reads a DICOM file from a path
 /// </summary>
 /// <param name="stream">the stream to the DICOM file</param>
 /// <returns>a DICOM object containing all elements</returns>
 public static DICOMObject Read(Stream stream, 
     TransferSyntax trySyntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN)
 {
     TransferSyntax syntax = trySyntax;
     List<IDICOMElement> elements;
     using (var dr = new DICOMBinaryReader(stream))
     {
         DICOMPreambleReader.Read(dr);
         List<IDICOMElement> metaElements = ReadFileMetadata(dr, ref syntax);
         elements = metaElements.Concat(DICOMElementReader.ReadAllElements(dr, syntax)).ToList();
     }
     return new DICOMObject(elements);
 }
Пример #18
0
        public static DICOMObject ReadBigEndian(DICOMBinaryReader dr, TransferSyntax syntax)
        {
            DICOMObject d;
            int length = LengthReader.ReadLittleEndian(VR.Null, dr.Skip(4));
            if (LengthReader.IsIndefinite(length))
            {
                d = ReadIndefiniteBigEndian(dr, syntax);
            }
            else
            {
                d = DICOMObjectReader.ReadObject(dr.ReadBytes(length), syntax);
            }

            return d;
        }
Пример #19
0
 /// <summary>
 ///     Asynchronously reads a DICOM file from a path
 /// </summary>
 /// <param name="filePath">the path to the DICOM file</param>
 /// <returns>a DICOM object containing all elements</returns>
 public static async Task<DICOMObject> ReadAsync(string filePath,
     TransferSyntax trySyntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN)
 {
     return await Task.Run(() =>
     {
         TransferSyntax syntax = trySyntax;
         List<IDICOMElement> elements;
         using (var dr = new DICOMBinaryReader(filePath))
         {
             DICOMPreambleReader.Read(dr);
             List<IDICOMElement> metaElements = ReadFileMetadata(dr, ref syntax);
             elements = metaElements.Concat(DICOMElementReader.ReadAllElements(dr, syntax)).ToList();
         }
         return new DICOMObject(elements);
     });
 }
Пример #20
0
		public void TestRegister()
		{
			const string uid = "1.2.3";
			var registered = new TransferSyntax("a", "1.2.3", true, true, true, false, false, true);

			TransferSyntax.RegisterTransferSyntax(registered);
			Assert.IsTrue(TransferSyntax.TransferSyntaxes.Contains(registered));

			var retrieved = TransferSyntax.GetTransferSyntax(uid);
			Assert.AreEqual(uid, retrieved.UidString);

			TransferSyntax.UnregisterTransferSyntax(registered);
			Assert.IsFalse(TransferSyntax.TransferSyntaxes.Contains(registered));

			TransferSyntax.UnregisterTransferSyntax(registered);
		}
Пример #21
0
 public static List<IDICOMElement> ReadAllElements(DICOMBinaryReader dr, TransferSyntax syntax)
 {
     List<IDICOMElement> elements;
     switch (syntax)
     {
         case TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN:
             elements = ReadAllElementsImplicitLittleEndian(dr);
             break;
         case TransferSyntax.EXPLICIT_VR_BIG_ENDIAN:
             elements = ReadAllElementsExplicitBigEndian(dr);
             break;
         default:
             elements = ReadAllElementsExplicitLittleEndian(dr);
             break;
     }
     return elements;
 }
Пример #22
0
 public static List<DICOMObject> ReadItems(byte[] data, TransferSyntax syntax)
 {
     List<DICOMObject> objects = new List<DICOMObject>();
     using (DICOMBinaryReader dr = new DICOMBinaryReader(data))
     {
         while (dr.StreamPosition < dr.StreamLength)
         {
             switch (syntax)
             {
                 case TransferSyntax.EXPLICIT_VR_BIG_ENDIAN:
                     objects.Add(SequenceItemReader.ReadBigEndian(dr,syntax));
                     break;
                 default:
                     objects.Add(SequenceItemReader.ReadLittleEndian(dr,syntax));
                     break;
             }
         }
     }
     return objects;
 }
Пример #23
0
		public DicomCompressCommand(DicomMessageBase file, XmlDocument parms, bool failOnCodecException)
			: base("DICOM Compress Command", true)
		{
			_file = file;
			_failOnCodecException = failOnCodecException;

			XmlElement element = parms.DocumentElement;

			string syntax = element.Attributes["syntax"].Value;

			_syntax = TransferSyntax.GetTransferSyntax(syntax);
			if (_syntax == null)
			{
				string failureDescription =
					String.Format("Invalid transfer syntax in compression command: {0}", element.Attributes["syntax"].Value);
				Platform.Log(LogLevel.Error, "Error with input syntax: {0}", failureDescription);
				throw new DicomCodecException(failureDescription);
			}

			IDicomCodecFactory[] codecs = DicomCodecRegistry.GetCodecFactories();
			IDicomCodecFactory theCodecFactory = null;
			foreach (IDicomCodecFactory codec in codecs)
				if (codec.CodecTransferSyntax.Equals(_syntax))
				{
					theCodecFactory = codec;
					break;
				}

			if (theCodecFactory == null)
			{
				string failureDescription = String.Format("Unable to find codec for compression: {0}", _syntax.Name);
				Platform.Log(LogLevel.Error, "Error with compression input parameters: {0}", failureDescription);
				throw new DicomCodecException(failureDescription);
			}

			_codec = theCodecFactory.GetDicomCodec();
			_parms = theCodecFactory.GetCodecParameters(parms);
		}
Пример #24
0
		public void TestEquality()
		{
			// ReSharper disable ExpressionIsAlwaysNull

			var ts0 = (TransferSyntax) null;
			var tsA = new TransferSyntax("a", "1.2.3", true, true, true, false, false, true);
			var tsA2 = new TransferSyntax("a2", "1.2.3", true, true, true, false, false, true);
			var tsA3 = tsA;
			var tsB = new TransferSyntax("b", "1.2.3.4", true, true, true, false, false, true);

			Assert.IsTrue(null == ts0);
			Assert.IsTrue(ts0 == null);
			Assert.IsTrue(Equals(null, ts0));
			Assert.IsTrue(Equals(ts0, null));

			Assert.IsTrue(tsA == tsA2);
			Assert.IsTrue(tsA2 == tsA);
			Assert.IsTrue(Equals(tsA, tsA2));
			Assert.IsTrue(Equals(tsA2, tsA));

			Assert.IsTrue(tsA == tsA3);
			Assert.IsTrue(tsA3 == tsA);
			Assert.IsTrue(Equals(tsA, tsA3));
			Assert.IsTrue(Equals(tsA3, tsA));

			Assert.IsFalse(ts0 == tsA);
			Assert.IsFalse(tsA == ts0);
			Assert.IsFalse(Equals(ts0, tsA));
			Assert.IsFalse(Equals(tsA, ts0));

			Assert.IsFalse(tsA == tsB);
			Assert.IsFalse(tsB == tsA);
			Assert.IsFalse(Equals(tsA, tsB));
			Assert.IsFalse(Equals(tsB, tsA));

			// ReSharper restore ExpressionIsAlwaysNull
		}
Пример #25
0
        public void Read(RawPDU raw)
        {
            uint l = raw.Length;

            raw.ReadUInt16("Version");
            raw.SkipBytes("Reserved", 2);
            _assoc.CalledAE = raw.ReadString("Called AE", 16);
            _assoc.CallingAE = raw.ReadString("Calling AE", 16);
            raw.SkipBytes("Reserved", 32);
            l -= 2 + 2 + 16 + 16 + 32;

            while (l > 0)
            {
                byte type = raw.ReadByte("Item-Type");
                raw.SkipBytes("Reserved", 1);
                ushort il = raw.ReadUInt16("Item-Length");

                l -= 4 + (uint)il;

                if (type == 0x10)
                {
                    // Application Context
                    raw.SkipBytes("Application Context", il);
                }
                else

                    if (type == 0x20)
                    {
                        // Presentation Context
                        byte id = raw.ReadByte("Presentation Context ID");
                        raw.SkipBytes("Reserved", 3);
                        il -= 4;

                        while (il > 0)
                        {
                            byte pt = raw.ReadByte("Presentation Context Item-Type");
                            raw.SkipBytes("Reserved", 1);
                            ushort pl = raw.ReadUInt16("Presentation Context Item-Length");
                            string sx = raw.ReadString("Presentation Context Syntax UID", pl);
                            if (pt == 0x30)
                            {
                                SopClass sopClass = SopClass.GetSopClass(sx);
                                if (sopClass == null)
                                    sopClass = new SopClass("Private SOP Class", sx, false);
                                _assoc.AddPresentationContext(id, sopClass);
                            }
                            else if (pt == 0x40)
                            {
                                TransferSyntax transferSyntax = TransferSyntax.GetTransferSyntax(sx);
                                if (transferSyntax == null)
                                    transferSyntax = new TransferSyntax("Private Syntax", sx, true, false, true, false, false, false);
                                _assoc.AddTransferSyntax(id, transferSyntax);
                            }
                            il -= (ushort)(4 + pl);
                        }
                    }
                    else

                        if (type == 0x50)
                        {
                            // User Information
                            while (il > 0)
                            {
                                byte ut = raw.ReadByte("User Information Item-Type");
                                raw.SkipBytes("Reserved", 1);
                                ushort ul = raw.ReadUInt16("User Information Item-Length");
                                il -= (ushort)(4 + ul);
                                if (ut == 0x51)
                                {
                                    _assoc.RemoteMaximumPduLength = raw.ReadUInt32("Max PDU Length");
                                }
                                else if (ut == 0x52)
                                {
                                    _assoc.ImplementationClass = new DicomUid(raw.ReadString("Implementation Class UID", ul), "Implementation Class UID", UidType.Unknown);
                                }
                                else if (ut == 0x53)
                                {
                                    _assoc.RemoteMaxOperationsInvoked = raw.ReadUInt16("Max Operations Invoked");
                                    _assoc.RemoteMaxOperationsPerformed = raw.ReadUInt16("Max Operations Performed");
                                }
                                else if (ut == 0x55)
                                {
                                    _assoc.ImplementationVersion = raw.ReadString("Implementation Version", ul);
                                }
                                else if (ut == 0x54)
                                {
                                    raw.SkipBytes("SCU/SCP Role Selection", ul);
                                    /*
                                    ushort rsul = raw.ReadUInt16();
                                    if ((rsul + 4) != ul) {
                                        throw new DicomNetworkException("SCU/SCP role selection length (" + ul + " bytes) does not match uid length (" + rsul + " + 4 bytes)");
                                    }
                                    raw.ReadChars(rsul);	// Abstract Syntax
                                    raw.ReadByte();		// SCU role
                                    raw.ReadByte();		// SCP role
                                    */
                                }
                                else
                                {
                                    Platform.Log(LogLevel.Error, "Unhandled user item: 0x{0:x2} ({1} + 4 bytes)", ut, ul);
                                    raw.SkipBytes("Unhandled User Item", ul);
                                }
                            }
                        }
            }
        }
Пример #26
0
		/// <summary>
		/// Constructor.
		/// </summary>
		/// <param name="dicomFile"></param>
		public StorageInstance(DicomFile dicomFile)
		{
			_dicomFile = dicomFile;
			
			string sopClassInFile = _dicomFile.DataSet[DicomTags.SopClassUid].ToString();
			if (!sopClassInFile.Equals(_dicomFile.SopClass.Uid))
			{
				Platform.Log(LogLevel.Warn, "SOP Class in Meta Info ({0}) does not match SOP Class in DataSet ({1})",
							 _dicomFile.SopClass.Uid, sopClassInFile);
				_sopClass = SopClass.GetSopClass(sopClassInFile);
				if (_sopClass == null)
				{
					Platform.Log(LogLevel.Warn, "Unknown SOP Class in dataset, reverting to meta info:  {0}", sopClassInFile);
					_sopClass = _dicomFile.SopClass;
				}
			}
			else
				_sopClass = _dicomFile.SopClass;

			_syntax = _dicomFile.TransferSyntax;
			SopInstanceUid = _dicomFile.MediaStorageSopInstanceUid;
			_filename = dicomFile.Filename;

			StudyInstanceUid = _dicomFile.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty);
			SeriesInstanceUid = _dicomFile.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty);
			PatientsName = _dicomFile.DataSet[DicomTags.PatientsName].GetString(0, string.Empty);
			PatientId = _dicomFile.DataSet[DicomTags.PatientId].GetString(0, string.Empty);
			_infoLoaded = true;
		}
Пример #27
0
		/// <summary>
		/// Load enough information from the file to allow negotiation of the association.
		/// </summary>
		public void LoadInfo()
		{
			if (_infoLoaded)
				return;

			DicomFile theFile = new DicomFile(_filename);

			theFile.Load(DicomTags.RelatedGeneralSopClassUid, DicomReadOptions.Default);
			string sopClassInFile = theFile.DataSet[DicomTags.SopClassUid].ToString();
			if (!sopClassInFile.Equals(theFile.SopClass.Uid))
			{
				Platform.Log(LogLevel.Warn, "SOP Class in Meta Info ({0}) does not match SOP Class in DataSet ({1})",
				             theFile.SopClass.Uid, sopClassInFile);
				_sopClass = SopClass.GetSopClass(sopClassInFile);
				if (_sopClass == null)
				{
					Platform.Log(LogLevel.Warn,"Unknown SOP Class in dataset, reverting to meta info:  {0}", sopClassInFile);
					_sopClass = theFile.SopClass;
				}
			}
			else
				_sopClass = theFile.SopClass;

			_syntax = theFile.TransferSyntax;
			SopInstanceUid = theFile.MediaStorageSopInstanceUid;
			MetaInfoFileLength = theFile.MetaInfoFileLength;
			_infoLoaded = true;
		}
Пример #28
0
 internal override void WriteData(SwappableBinaryWriter bw, ILogger logger, TransferSyntax transferSyntax)
 {
     // Make sure to follow the UID rules
     bw.Write(Uid.UidToBytes(this.data));
 }
Пример #29
0
        protected override void OnExecute(CommandProcessor theProcessor, IUpdateContext updateContext)
        {
            // Check if the File is the same syntax as the
            TransferSyntax fileSyntax = _file.TransferSyntax;
            TransferSyntax dbSyntax   = TransferSyntax.GetTransferSyntax(_location.TransferSyntaxUid);

            // Check if the syntaxes match the location
            if ((!fileSyntax.Encapsulated && !dbSyntax.Encapsulated) ||
                (fileSyntax.LosslessCompressed && dbSyntax.LosslessCompressed) ||
                (fileSyntax.LossyCompressed && dbSyntax.LossyCompressed))
            {
                // no changes necessary, just return;
                return;
            }

            // Select the Server Transfer Syntax
            var syntaxCriteria = new ServerTransferSyntaxSelectCriteria();
            var syntaxBroker   = updateContext.GetBroker <IServerTransferSyntaxEntityBroker>();

            syntaxCriteria.Uid.EqualTo(fileSyntax.UidString);

            ServerTransferSyntax serverSyntax = syntaxBroker.FindOne(syntaxCriteria);

            if (serverSyntax == null)
            {
                Platform.Log(LogLevel.Error, "Unable to load ServerTransferSyntax for {0}.  Unable to update study status.", fileSyntax.Name);
                return;
            }

            // Get the FilesystemStudyStorage update broker ready
            var filesystemStudyStorageEntityBroker = updateContext.GetBroker <IFilesystemStudyStorageEntityBroker>();
            var filesystemStorageUpdate            = new FilesystemStudyStorageUpdateColumns();
            var filesystemStorageCritiera          = new FilesystemStudyStorageSelectCriteria();

            filesystemStorageUpdate.ServerTransferSyntaxKey = serverSyntax.Key;
            filesystemStorageCritiera.StudyStorageKey.EqualTo(_location.Key);

            // Get the StudyStorage update broker ready
            var studyStorageBroker =
                updateContext.GetBroker <IStudyStorageEntityBroker>();
            var             studyStorageUpdate = new StudyStorageUpdateColumns();
            StudyStatusEnum statusEnum         = _location.StudyStatusEnum;

            if (fileSyntax.LossyCompressed)
            {
                studyStorageUpdate.StudyStatusEnum = statusEnum = StudyStatusEnum.OnlineLossy;
            }
            else if (fileSyntax.LosslessCompressed)
            {
                studyStorageUpdate.StudyStatusEnum = statusEnum = StudyStatusEnum.OnlineLossless;
            }

            studyStorageUpdate.LastAccessedTime = Platform.Time;

            if (!filesystemStudyStorageEntityBroker.Update(filesystemStorageCritiera, filesystemStorageUpdate))
            {
                Platform.Log(LogLevel.Error, "Unable to update FilesystemQueue row: Study {0}, Server Entity {1}",
                             _location.StudyInstanceUid, _location.ServerPartitionKey);
            }
            else if (!studyStorageBroker.Update(_location.GetKey(), studyStorageUpdate))
            {
                Platform.Log(LogLevel.Error, "Unable to update StudyStorage row: Study {0}, Server Entity {1}",
                             _location.StudyInstanceUid, _location.ServerPartitionKey);
            }
            else
            {
                // Update the location, so the next time we come in here, we don't try and update the database
                // for another sop in the study.
                _location.StudyStatusEnum         = statusEnum;
                _location.TransferSyntaxUid       = fileSyntax.UidString;
                _location.ServerTransferSyntaxKey = serverSyntax.Key;
            }
        }
Пример #30
0
        void IDicomServerHandler.OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message)
        {
            if (message.CommandField == DicomCommandField.CEchoRequest)
            {
                server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.Success);
                return;
            }

            String   studyInstanceUid  = null;
            String   seriesInstanceUid = null;
            DicomUid sopInstanceUid;
            String   patientName = null;

            bool ok = message.DataSet[DicomTags.SopInstanceUid].TryGetUid(0, out sopInstanceUid);

            if (ok)
            {
                ok = message.DataSet[DicomTags.SeriesInstanceUid].TryGetString(0, out seriesInstanceUid);
            }
            if (ok)
            {
                ok = message.DataSet[DicomTags.StudyInstanceUid].TryGetString(0, out studyInstanceUid);
            }
            if (ok)
            {
                ok = message.DataSet[DicomTags.PatientsName].TryGetString(0, out patientName);
            }

            if (!ok)
            {
                Platform.Log(LogLevel.Error, "Unable to retrieve UIDs from request message, sending failure status.");

                server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID,
                                          DicomStatuses.ProcessingFailure);
                return;
            }
            TransferSyntax syntax = association.GetPresentationContext(presentationID).AcceptedTransferSyntax;

            if (List)
            {
                Platform.Log(LogLevel.Info, message.Dump());
            }

            if (Bitbucket)
            {
                Platform.Log(LogLevel.Info, "Received SOP Instance: {0} for patient {1} in syntax {2}", sopInstanceUid,
                             patientName, syntax.Name);

                server.SendCStoreResponse(presentationID, message.MessageId,
                                          sopInstanceUid.UID,
                                          DicomStatuses.Success);
                return;
            }

            if (!Directory.Exists(StorageLocation))
            {
                Directory.CreateDirectory(StorageLocation);
            }

            var path = new StringBuilder();

            path.AppendFormat("{0}{1}{2}{3}{4}", StorageLocation, Path.DirectorySeparatorChar,
                              studyInstanceUid, Path.DirectorySeparatorChar, seriesInstanceUid);

            Directory.CreateDirectory(path.ToString());

            path.AppendFormat("{0}{1}.dcm", Path.DirectorySeparatorChar, sopInstanceUid.UID);

            var dicomFile = new DicomFile(message, path.ToString())
            {
                TransferSyntaxUid            = syntax.UidString,
                MediaStorageSopInstanceUid   = sopInstanceUid.UID,
                ImplementationClassUid       = DicomImplementation.ClassUID.UID,
                ImplementationVersionName    = DicomImplementation.Version,
                SourceApplicationEntityTitle = association.CallingAE,
                MediaStorageSopClassUid      = message.SopClass.Uid
            };


            dicomFile.Save(DicomWriteOptions.None);

            Platform.Log(LogLevel.Info, "Received SOP Instance: {0} for patient {1} in syntax {2}", sopInstanceUid,
                         patientName, syntax.Name);

            server.SendCStoreResponse(presentationID, message.MessageId,
                                      sopInstanceUid.UID,
                                      DicomStatuses.Success);
        }
Пример #31
0
 private static DICOMObject GetDataObject(List <PDataTF> pDatas, TransferSyntax syntax)
 {
     byte[] dicomBytes = DIMSEReader.MergePDataTFData(pDatas);
     return(DIMSEReader.CreateDICOMObject(dicomBytes, syntax));
 }
Пример #32
0
 /// <summary>
 ///     Creates a new DICOM nested data set instance from specified
 ///     DICOM output stream using specified transfer syntax.
 /// </summary>
 public NestedDataSet(Stream stream, TransferSyntax transferSyntax) :
     base(stream, transferSyntax)
 {
 }
Пример #33
0
 internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax)
 {
     //reuse setter
     Data = System.Text.Encoding.ASCII.GetString(br.ReadBytes((int)length));
     return(length);
 }
Пример #34
0
        public void Read(RawPDU raw)
        {
            uint l = raw.Length;

            raw.ReadUInt16("Version");
            raw.SkipBytes("Reserved", 2);
            raw.SkipBytes("Reserved", 16);
            raw.SkipBytes("Reserved", 16);
            raw.SkipBytes("Reserved", 32);
            l -= 68;

            while (l > 0)
            {
                byte type = raw.ReadByte("Item-Type");
                l -= 1;

                if (type == 0x10)
                {
                    // Application Context
                    raw.SkipBytes("Reserved", 1);
                    ushort c = raw.ReadUInt16("Item-Length");
                    raw.SkipBytes("Value", (int)c);
                    l -= 3 + (uint)c;
                }
                else

                if (type == 0x21)
                {
                    // Presentation Context
                    raw.ReadByte("Reserved");
                    ushort pl = raw.ReadUInt16("Presentation Context Item-Length");
                    byte   id = raw.ReadByte("Presentation Context ID");
                    raw.ReadByte("Reserved");
                    byte res = raw.ReadByte("Presentation Context Result/Reason");
                    raw.ReadByte("Reserved");
                    l  -= (uint)pl + 3;
                    pl -= 4;

                    // Presentation Context Transfer Syntax
                    raw.ReadByte("Presentation Context Item-Type (0x40)");
                    raw.ReadByte("Reserved");
                    ushort tl = raw.ReadUInt16("Presentation Context Item-Length");
                    string tx = raw.ReadString("Presentation Context Syntax UID", tl);
                    pl -= (ushort)(tl + 4);

                    _assoc.SetPresentationContextResult(id, (DicomPresContextResult)res);
                    TransferSyntax acceptedSyntax = TransferSyntax.GetTransferSyntax(tx);
                    if (acceptedSyntax != null)
                    {
                        _assoc.SetAcceptedTransferSyntax(id, acceptedSyntax);
                    }
                    else
                    {
                        _assoc.GetPresentationContext(id).ClearTransfers();
                    }
                }
                else

                if (type == 0x50)
                {
                    // User Information
                    raw.ReadByte("Reserved");
                    ushort il = raw.ReadUInt16("User Information Item-Length");
                    l -= (uint)(il + 3);
                    while (il > 0)
                    {
                        byte ut = raw.ReadByte("User Item-Type");
                        raw.ReadByte("Reserved");
                        ushort ul = raw.ReadUInt16("User Item-Length");
                        il -= (ushort)(ul + 4);
                        if (ut == 0x51)
                        {
                            _assoc.RemoteMaximumPduLength = raw.ReadUInt32("Max PDU Length");
                        }
                        else if (ut == 0x52)
                        {
                            _assoc.ImplementationClass = DicomUids.Lookup(raw.ReadString("Implementation Class UID", ul));
                        }
                        else if (ut == 0x55)
                        {
                            _assoc.ImplementationVersion = raw.ReadString("Implementation Version", ul);
                        }
                        else
                        {
                            raw.SkipBytes("User Item Value", (int)ul);
                        }
                    }
                }

                else
                {
                    raw.SkipBytes("Reserved", 1);
                    ushort il = raw.ReadUInt16("User Item-Length");
                    raw.SkipBytes("Unknown User Item", il);
                    l -= (uint)(il + 3);
                }
            }
        }
Пример #35
0
        internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax)
        {
            //Covered by PS 3.5, Chapter 7.5 (pg. 42-45)
            bool encapImage = (Tag == DICOMTags.PixelData);

            bool done  = false;
            uint count = 0;

            while (!done)
            {
                //If explicit length, see if we're done
                if (length != 0xFFFFFFFF && count >= length)
                {
                    done = true;
                    continue;
                }

                ushort grp  = br.ReadUInt16();
                ushort elem = br.ReadUInt16();
                uint   len  = br.ReadUInt32();
                count += 8;

                //Sometimes there's retarded files that are msb swapped inside of sequences outside of the transfer syntax
                bool needMoreSwap = (grp == 0xFEFF);

                if (needMoreSwap)
                {
                    //Swap the reader for now, then swap back after the sqitem
                    br.ToggleSwapped();

                    //still have to swap the stuff we've already read by hand tho
                    grp  = MSBSwapper.SwapW(grp);
                    elem = MSBSwapper.SwapW(elem);
                    len  = MSBSwapper.SwapDW(len);
                }

                if (grp == 0xFFFE && elem == 0xE000)
                {
                    //Normal element, parse it out.
                    SQItem item = new SQItem(this);
                    count += item.ParseStream(br, logger, transferSyntax, len, encapImage);
                    Items.Add(item);
                }
                else if (grp == 0xFFFE && elem == 0xE0DD)
                {
                    //End element

                    //In case there's garbage in there, read the length bytes
                    br.ReadBytes((int)len);
                    count += len;

                    done = true;
                }
                else
                {
                    throw new NotImplementedException();
                }

                //toggle back in case it's just one SQItem that's hosed
                if (needMoreSwap)
                {
                    br.ToggleSwapped();
                }
            }

            return(count);
        }
Пример #36
0
        public void Read(RawPDU raw)
        {
            uint l = raw.Length;

            raw.ReadUInt16("Version");
            raw.SkipBytes("Reserved", 2);
            _assoc.CalledAE  = raw.ReadString("Called AE", 16);
            _assoc.CallingAE = raw.ReadString("Calling AE", 16);
            raw.SkipBytes("Reserved", 32);
            l -= 2 + 2 + 16 + 16 + 32;

            while (l > 0)
            {
                byte type = raw.ReadByte("Item-Type");
                raw.SkipBytes("Reserved", 1);
                ushort il = raw.ReadUInt16("Item-Length");

                l -= 4 + (uint)il;

                if (type == 0x10)
                {
                    // Application Context
                    raw.SkipBytes("Application Context", il);
                }
                else

                if (type == 0x20)
                {
                    // Presentation Context
                    byte id = raw.ReadByte("Presentation Context ID");
                    raw.SkipBytes("Reserved", 3);
                    il -= 4;

                    while (il > 0)
                    {
                        byte pt = raw.ReadByte("Presentation Context Item-Type");
                        raw.SkipBytes("Reserved", 1);
                        ushort pl = raw.ReadUInt16("Presentation Context Item-Length");
                        string sx = raw.ReadString("Presentation Context Syntax UID", pl);
                        if (pt == 0x30)
                        {
                            SopClass sopClass = SopClass.GetSopClass(sx);
                            if (sopClass == null)
                            {
                                sopClass = new SopClass("Private SOP Class", sx, false);
                            }
                            _assoc.AddPresentationContext(id, sopClass);
                        }
                        else if (pt == 0x40)
                        {
                            TransferSyntax transferSyntax = TransferSyntax.GetTransferSyntax(sx);
                            if (transferSyntax == null)
                            {
                                transferSyntax = new TransferSyntax("Private Syntax", sx, true, false, true, false, false, false);
                            }
                            _assoc.AddTransferSyntax(id, transferSyntax);
                        }
                        il -= (ushort)(4 + pl);
                    }
                }
                else

                if (type == 0x50)
                {
                    // User Information
                    while (il > 0)
                    {
                        byte ut = raw.ReadByte("User Information Item-Type");
                        raw.SkipBytes("Reserved", 1);
                        ushort ul = raw.ReadUInt16("User Information Item-Length");
                        il -= (ushort)(4 + ul);
                        if (ut == 0x51)
                        {
                            _assoc.RemoteMaximumPduLength = raw.ReadUInt32("Max PDU Length");
                        }
                        else if (ut == 0x52)
                        {
                            _assoc.ImplementationClass = new DicomUid(raw.ReadString("Implementation Class UID", ul), "Implementation Class UID", UidType.Unknown);
                        }
                        else if (ut == 0x53)
                        {
                            _assoc.MaxOperationsInvoked   = raw.ReadUInt16("Max Operations Invoked");
                            _assoc.MaxOperationsPerformed = raw.ReadUInt16("Max Operations Performed");
                        }
                        else if (ut == 0x55)
                        {
                            _assoc.ImplementationVersion = raw.ReadString("Implementation Version", ul);
                        }
                        else if (ut == 0x54)
                        {
                            raw.SkipBytes("SCU/SCP Role Selection", ul);

                            /*
                             * ushort rsul = raw.ReadUInt16();
                             * if ((rsul + 4) != ul) {
                             *  throw new DicomNetworkException("SCU/SCP role selection length (" + ul + " bytes) does not match uid length (" + rsul + " + 4 bytes)");
                             * }
                             * raw.ReadChars(rsul);	// Abstract Syntax
                             * raw.ReadByte();		// SCU role
                             * raw.ReadByte();		// SCP role
                             */
                        }
                        else
                        {
                            Platform.Log(LogLevel.Error, "Unhandled user item: 0x{0:x2} ({1} + 4 bytes)", ut, ul);
                            raw.SkipBytes("Unhandled User Item", ul);
                        }
                    }
                }
            }
        }
Пример #37
0
        public static DICOMObject ReadObject(DICOMBinaryReader dr, TransferSyntax syntax)
        {
            List <IDICOMElement> elements = DICOMElementReader.ReadAllElements(dr, syntax);

            return(new DICOMObject(elements));
        }
Пример #38
0
        public static DICOMObject ReadObject(byte[] objectBytes, TransferSyntax syntax)
        {
            long bytesRead;

            return(ReadObject(objectBytes, syntax, out bytesRead));
        }
Пример #39
0
 /// <summary>
 ///     Reads a DICOM file from a byte array
 /// </summary>
 /// <param name="file">the bytes of the DICOM file</param>
 /// <param name="trySyntax">the transfer syntax to use in case there is no metadata explicitly included</param>
 /// <returns></returns>
 public static DICOMObject Read(byte[] file, TransferSyntax trySyntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN)
 {
     return(DICOMFileReader.Read(file, trySyntax));
 }
Пример #40
0
    public static int Main(string[] args)
    {
        if (args.Length < 2)
        {
            System.Console.WriteLine(" input.dcm output.dcm");
            return(1);
        }
        string filename    = args[0];
        string outfilename = args[1];

        ImageReader reader = new ImageReader();

        reader.SetFileName(filename);
        if (!reader.Read())
        {
            System.Console.WriteLine("Could not read: " + filename);
            return(1);
        }

        // The output of gdcm::Reader is a gdcm::File
        File file = reader.GetFile();

        // the dataset is the the set of element we are interested in:
        DataSet ds = file.GetDataSet();

        Image image = reader.GetImage();
        //image.Print( cout );

        ImageChangeTransferSyntax change   = new ImageChangeTransferSyntax();
        TransferSyntax            targetts = new TransferSyntax(TransferSyntax.TSType.JPEGBaselineProcess1);

        change.SetTransferSyntax(targetts);

        // Setup our JPEGCodec, warning it should be compatible with JPEGBaselineProcess1
        JPEGCodec jpegcodec = new JPEGCodec();

        if (!jpegcodec.CanCode(targetts))
        {
            System.Console.WriteLine("Something went really wrong, JPEGCodec cannot handle JPEGBaselineProcess1");
            return(1);
        }
        jpegcodec.SetLossless(false);
        jpegcodec.SetQuality(50);       // poor quality !
        change.SetUserCodec(jpegcodec); // specify the codec to use to the ImageChangeTransferSyntax

        change.SetInput(image);
        bool b = change.Change();

        if (!b)
        {
            System.Console.WriteLine("Could not change the Transfer Syntax");
            return(1);
        }

        ImageWriter writer = new ImageWriter();

        writer.SetImage((gdcm.Image)change.GetOutput());
        writer.SetFile(reader.GetFile());
        writer.SetFileName(outfilename);
        if (!writer.Write())
        {
            System.Console.WriteLine("Could not write: " + outfilename);
            return(1);
        }

        return(0);
    }
Пример #41
0
 internal override void WriteData(SwappableBinaryWriter bw, ILogger logger, TransferSyntax transferSyntax)
 {
     bw.Write(data);
 }
Пример #42
0
        /// <summary>
        /// Checks for a storage location for the study in the database, and creates a new location
        /// in the database if it doesn't exist.
        /// </summary>
        /// <param name="partition">The partition where the study is being sent to</param>
        /// <param name="created"></param>
        /// <param name="studyDate"></param>
        /// <param name="studyInstanceUid"></param>
        /// <param name="syntax"></param>
        /// <param name="updateContext">The update context to create the study on</param>
        /// <returns>A <see cref="StudyStorageLocation"/> instance.</returns>
        public StudyStorageLocation GetOrCreateWritableStudyStorageLocation(string studyInstanceUid, string studyDate, TransferSyntax syntax, IUpdateContext updateContext, ServerPartition partition, out bool created)
        {
            created = false;

            StudyStorageLocation location;

            try
            {
                GetWritableStudyStorageLocation(partition.Key, studyInstanceUid, StudyRestore.True,
                                                StudyCache.True, out location);
                return(location);
            }
            catch (StudyNotFoundException)
            {
            }

            FilesystemSelector   selector   = new FilesystemSelector(Instance);
            ServerFilesystemInfo filesystem = selector.SelectFilesystem();

            if (filesystem == null)
            {
                throw new NoWritableFilesystemException();
            }

            IInsertStudyStorage          locInsert   = updateContext.GetBroker <IInsertStudyStorage>();
            InsertStudyStorageParameters insertParms = new InsertStudyStorageParameters
            {
                ServerPartitionKey = partition.GetKey(),
                StudyInstanceUid   = studyInstanceUid,
                Folder             =
                    ResolveStorageFolder(partition.Key, studyInstanceUid, studyDate,
                                         updateContext, false
                                         /* set to false for optimization because we are sure it's not in the system */),
                FilesystemKey       = filesystem.Filesystem.GetKey(),
                QueueStudyStateEnum = QueueStudyStateEnum.Idle
            };

            if (syntax.LosslessCompressed)
            {
                insertParms.TransferSyntaxUid = syntax.UidString;
                insertParms.StudyStatusEnum   = StudyStatusEnum.OnlineLossless;
            }
            else if (syntax.LossyCompressed)
            {
                insertParms.TransferSyntaxUid = syntax.UidString;
                insertParms.StudyStatusEnum   = StudyStatusEnum.OnlineLossy;
            }
            else
            {
                insertParms.TransferSyntaxUid = syntax.UidString;
                insertParms.StudyStatusEnum   = StudyStatusEnum.Online;
            }

            location = locInsert.FindOne(insertParms);
            created  = true;

            return(location);
        }
Пример #43
0
 /// <summary>
 /// Used to add a supported transfer syntax.
 /// </summary>
 /// <param name="syntax">The transfer syntax supproted by the SOP Class.</param>
 public void AddSyntax(TransferSyntax syntax)
 {
     SyntaxList.Add(syntax);
 }
Пример #44
0
 internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax)
 {
     if (length < 2)
     {
         //busted...
         data = (ushort)0;
         br.ReadBytes((int)length);
     }
     else if (length == 2)
     {
         data = br.ReadUInt16();
     }
     else if (length > 2)
     {
         uint readBytes = 0;
         DataDictionaryElement elemCheck = DataDictionary.LookupElement(this.Tag);
         if (elemCheck == null || elemCheck.VMMax > 1)
         {
             //Unknown VM or VM goes to > 1
             data = new ushort[length / 2];
             for (int i = 0; i < length / 2; i++)
             {
                 ((ushort[])data)[i] = br.ReadUInt16();
             }
             readBytes = (length / 2) * 2;
         }
         else
         {
             //VM of 1 -- force to single data point
             data      = br.ReadUInt16();
             readBytes = 2;
         }
         if (length - readBytes > 0)
         {
             br.ReadBytes((int)(length - readBytes));
         }
     }
     return(length);
 }
Пример #45
0
 internal abstract ByteBuffer GetByteBuffer(TransferSyntax syntax, String specificCharacterSet);
Пример #46
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)
                            {
                                LogAdapter.Logger.Info("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();
                                DicomDataset   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
                        {
                            LogAdapter.Logger.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)
                                {
                                    LogAdapter.Logger.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.
                                    LogAdapter.Logger.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)
                                {
                                    DicomDataset 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);
                                    }

                                    DicomElement elem;
                                    if (LastTagRead.VR.Equals(DicomVr.OWvr))
                                    {
                                        elem = new DicomElementOw(LastTagRead, reference);
                                    }
                                    else if (LastTagRead.VR.Equals(DicomVr.OBvr))
                                    {
                                        elem = new DicomElementOb(LastTagRead, reference);
                                    }
                                    else if (LastTagRead.VR.Equals(DicomVr.ODvr))
                                    {
                                        elem = new DicomElementOD(LastTagRead, reference);
                                    }
                                    else
                                    {
                                        elem = new DicomElementOf(LastTagRead, reference);
                                    }

                                    if (_sqrs.Count > 0)
                                    {
                                        SequenceRecord rec = _sqrs.Peek();
                                        DicomDataset   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);

                                    DicomElement elem = LastTagRead.CreateDicomAttribute(bb);

                                    _remain   -= _len;
                                    BytesRead += _len;

                                    if (_sqrs.Count > 0)
                                    {
                                        SequenceRecord rec = _sqrs.Peek();
                                        DicomDataset   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
                LogAdapter.Logger.Error("Unexpected exception when reading file: {0}", e.ToString());
                return(DicomReadStatus.UnknownError);
            }
        }
Пример #47
0
 /// <summary>
 ///     Reads a DICOM file from a path
 /// </summary>
 /// <param name="filePath">the path to the file</param>
 /// <param name="trySyntax">the transfer syntax to use in case there is no metadata explicitly included</param>
 /// <returns>the DICOM Object</returns>
 /// <example>
 ///<code>
 ///var dcm = DICOMObject.Read("mydcm.dcm");
 ///</code>
 ///</example>
 public static DICOMObject Read(string filePath,
                                TransferSyntax trySyntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN)
 {
     return(DICOMFileReader.Read(filePath, trySyntax));
 }
        public MimeTypeProcessorOutput Process(ImageStreamingContext context)
        {
            Platform.CheckForNullReference(context, "context");

            DicomPixelData          pd     = context.PixelData;
            MimeTypeProcessorOutput output = new MimeTypeProcessorOutput();
            int frame = context.FrameNumber;

            if (context.FrameNumber < 0)
            {
                throw new WADOException(HttpStatusCode.BadRequest, String.Format("Requested FrameNumber {0} cannot be negative.", frame));
            }
            else if (frame >= pd.NumberOfFrames)
            {
                throw new WADOException(HttpStatusCode.BadRequest, String.Format("Requested FrameNumber {0} exceeds the number of frames in the image.", frame));
            }

            output.ContentType = OutputMimeType;

            PixelDataLoader loader = new PixelDataLoader(context);

            output.Output = loader.ReadFrame(frame);
            output.IsLast = (pd.NumberOfFrames == frame + 1);

            // note: the transfer syntax of the returned pixel data may not be the same as that in the original image.
            // In the future, the clients may specify different transfer syntaxes which may mean the compressed image must be decompressed or vice versa.
            TransferSyntax transferSyntax = pd.TransferSyntax;

            output.IsCompressed = transferSyntax.LosslessCompressed || transferSyntax.LossyCompressed;

            #region Special Code

            // Note: this block of code inject special header fields to assist the clients handling the images
            // For eg, the

            if (output.IsLast)
            {
                context.Response.Headers.Add("IsLast", "true");
            }

            if (output.IsCompressed)
            {
                // Fields that can be used by the web clients to decompress the compressed images streamed by the server.

                context.Response.Headers.Add("Compressed", "true");
                context.Response.Headers.Add("TransferSyntaxUid", pd.TransferSyntax.UidString);

                context.Response.Headers.Add("BitsAllocated", pd.BitsAllocated.ToString());
                context.Response.Headers.Add("BitsStored", pd.BitsStored.ToString());
                context.Response.Headers.Add("DerivationDescription", pd.DerivationDescription);

                context.Response.Headers.Add("HighBit", pd.HighBit.ToString());
                context.Response.Headers.Add("ImageHeight", pd.ImageHeight.ToString());
                context.Response.Headers.Add("ImageWidth", pd.ImageWidth.ToString());
                context.Response.Headers.Add("LossyImageCompression", pd.LossyImageCompression);
                context.Response.Headers.Add("LossyImageCompressionMethod", pd.LossyImageCompressionMethod);
                context.Response.Headers.Add("LossyImageCompressionRatio", pd.LossyImageCompressionRatio.ToString());
                context.Response.Headers.Add("NumberOfFrames", pd.NumberOfFrames.ToString());
                context.Response.Headers.Add("PhotometricInterpretation", pd.PhotometricInterpretation);
                context.Response.Headers.Add("PixelRepresentation", pd.PixelRepresentation.ToString());
                context.Response.Headers.Add("PlanarConfiguration", pd.PlanarConfiguration.ToString());
                context.Response.Headers.Add("SamplesPerPixel", pd.SamplesPerPixel.ToString());
            }

            #endregion

            if (Platform.IsLogLevelEnabled(LogLevel.Debug))
            {
                Platform.Log(LogLevel.Debug, "Streaming {0} pixel data: {1} x {2} x {3} , {4} bits  [{5} KB] ({6})",
                             output.IsCompressed ? "compressed" : "uncompressed",
                             pd.ImageHeight,
                             pd.ImageWidth,
                             pd.SamplesPerPixel,
                             pd.BitsStored,
                             output.Output.Length / 1024,
                             pd.TransferSyntax.Name);
            }


            return(output);
        }
Пример #49
0
        public static void LosslessImageTestWithBitsAllocatedConversion(TransferSyntax syntax, DicomFile theFile)
        {
            if (File.Exists(theFile.Filename))
            {
                File.Delete(theFile.Filename);
            }

            DicomFile saveCopy = new DicomFile(theFile.Filename, theFile.MetaInfo.Copy(), theFile.DataSet.Copy());

            theFile.ChangeTransferSyntax(syntax);

            theFile.Save(DicomWriteOptions.ExplicitLengthSequence);

            DicomFile newFile = new DicomFile(theFile.Filename);

            newFile.Load(DicomReadOptions.Default);

            newFile.ChangeTransferSyntax(saveCopy.TransferSyntax);

            string failureDescription;
            var    newPd = DicomPixelData.CreateFrom(newFile);
            var    oldPd = DicomPixelData.CreateFrom(saveCopy);

            bool result = Compare(newPd, oldPd, out failureDescription);

            Assert.IsFalse(result, failureDescription);

            Assert.IsFalse(newFile.DataSet.Equals(saveCopy.DataSet));

            DicomAttributeCollection newDataSet = newFile.DataSet.Copy(true, true, true);
            DicomAttributeCollection oldDataSet = theFile.DataSet.Copy(true, true, true);

            oldDataSet.RemoveAttribute(DicomTags.BitsAllocated);
            newDataSet.RemoveAttribute(DicomTags.BitsAllocated);
            oldDataSet.RemoveAttribute(DicomTags.PixelData);
            newDataSet.RemoveAttribute(DicomTags.PixelData);

            var results = new List <DicomAttributeComparisonResult>();

            bool check = oldDataSet.Equals(newDataSet, ref results);

            Assert.IsTrue(check, results.Count > 0 ? CollectionUtils.FirstElement(results).Details : string.Empty);

            for (int i = 0; i < oldPd.NumberOfFrames; i++)
            {
                var frame          = oldPd.GetFrame(i);
                var convertedFrame = DicomUncompressedPixelData.ToggleBitDepth(frame, frame.Length,
                                                                               oldPd.UncompressedFrameSize,
                                                                               oldPd.BitsStored, oldPd.BitsAllocated);
                var newFrame = newPd.GetFrame(i);

                int     pixelsVarying  = 0;
                decimal totalVariation = 0.0m;
                for (int j = 0; j < convertedFrame.Length; j++)
                {
                    if (convertedFrame[j] != newFrame[j])
                    {
                        pixelsVarying++;
                        totalVariation += Math.Abs(convertedFrame[i] - newFrame[i]);
                    }
                }

                if (pixelsVarying > 0)
                {
                    Assert.Fail(String.Format(
                                    "Tag (7fe0,0010) Pixel Data: {0} of {1} pixels varying, average difference: {2}",
                                    pixelsVarying, convertedFrame.Length, totalVariation / pixelsVarying));
                }
            }
        }
Пример #50
0
        /// <summary>
        /// Do the restore.
        /// </summary>
        /// <param name="queueItem">The queue item to restore.</param>
        public void Run(RestoreQueue queueItem)
        {
            using (var context = new RestoreProcessorContext(queueItem))
            {
                try
                {
                    // Load up related classes.
                    using (IReadContext readContext = _hsmArchive.PersistentStore.OpenReadContext())
                    {
                        _archiveStudyStorage = ArchiveStudyStorage.Load(readContext, queueItem.ArchiveStudyStorageKey);
                        _serverSyntax        = ServerTransferSyntax.Load(readContext, _archiveStudyStorage.ServerTransferSyntaxKey);
                        _syntax = TransferSyntax.GetTransferSyntax(_serverSyntax.Uid);

                        var parms = new StudyStorageLocationQueryParameters
                        {
                            StudyStorageKey = queueItem.StudyStorageKey
                        };
                        var broker = readContext.GetBroker <IQueryStudyStorageLocation>();
                        _location = broker.FindOne(parms);
                        if (_location == null)
                        {
                            _studyStorage = StudyStorage.Load(readContext, queueItem.StudyStorageKey);
                            if (_studyStorage == null)
                            {
                                DateTime scheduleTime = Platform.Time.AddMinutes(5);
                                Platform.Log(LogLevel.Error, "Unable to find storage location, rescheduling restore request to {0}",
                                             scheduleTime);
                                queueItem.FailureDescription = "Unable to find storage location, rescheduling request.";
                                _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Pending, scheduleTime);
                                return;
                            }
                        }
                    }

                    if (_location == null)
                    {
                        Platform.Log(LogLevel.Info, "Starting restore of nearline study: {0}",
                                     _studyStorage.StudyInstanceUid);

                        // Get the zip file path from the xml data in the ArchiveStudyStorage entry
                        // Also store the "StudyFolder" for use below
                        string studyFolder;
                        string zipFile = GetZipFileName(out studyFolder);

                        // Do a test read of the zip file.  If it succeeds, the file is available, if it
                        // fails, we just set back to pending and recheck.
                        if (!CanReadZip(zipFile, queueItem))
                        {
                            return;
                        }

                        RestoreNearlineStudy(queueItem, zipFile, studyFolder);
                    }
                    else
                    {
                        Platform.Log(LogLevel.Info, "Starting restore of online study: {0}", _location.StudyInstanceUid);

                        // Get the zip file path from the xml data in the ArchiveStudyStorage entry
                        // Also store the "StudyFolder" for use below
                        string studyFolder;
                        string zipFile = GetZipFileName(out studyFolder);

                        // Do a test read of the zip file.  If it succeeds, the file is available, if it
                        // fails, we just set back to pending and recheck.
                        if (!CanReadZip(zipFile, queueItem))
                        {
                            return;
                        }

                        RestoreOnlineStudy(queueItem, zipFile, _location.GetStudyPath());
                    }
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Error, e, "Unexpected exception processing restore request for {0} on archive {1}",
                                 _studyStorage == null ? (_location == null ? string.Empty : _location.StudyInstanceUid) : _studyStorage.StudyInstanceUid,
                                 _hsmArchive.PartitionArchive.Description);
                    queueItem.FailureDescription = e.Message;
                    _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Failed, Platform.Time);
                }
            }
        }
Пример #51
0
		public static void ExpectedFailureTest(TransferSyntax syntax, DicomFile theFile)
		{
			try
			{
				theFile.ChangeTransferSyntax(syntax);
			}
			catch (DicomCodecUnsupportedSopException)
			{
				return;
			}

			Assert.IsTrue(false, "Unexpected successfull compression of object.");
		}
Пример #52
0
 public void ChangeTransferSyntax(TransferSyntax newTransferSyntax)
 {
     ChangeTransferSyntax(newTransferSyntax, null, null);
 }
Пример #53
0
        public void ChangeTransferSyntax(TransferSyntax newTransferSyntax, IDicomCodec inputCodec, DicomCodecParameters inputParameters)
        {
            IDicomCodec          codec      = inputCodec;
            DicomCodecParameters parameters = inputParameters;

            if (newTransferSyntax.Encapsulated && TransferSyntax.Encapsulated)
            {
                throw new DicomCodecException("Source and destination transfer syntaxes encapsulated");
            }

            if (newTransferSyntax.Encapsulated)
            {
                if (codec == null)
                {
                    codec = DicomCodecRegistry.GetCodec(newTransferSyntax);
                    if (codec == null)
                    {
                        LogAdapter.Logger.Error("Unable to get registered codec for {0}", newTransferSyntax);
                        throw new DicomCodecException("No registered codec for: " + newTransferSyntax.Name);
                    }
                }
                if (parameters == null)
                {
                    parameters = DicomCodecRegistry.GetCodecParameters(newTransferSyntax, DataSet);
                }

                DicomElement pixelData;
                if (DataSet.TryGetAttribute(DicomTags.PixelData, out pixelData))
                {
                    if (pixelData.IsNull)
                    {
                        throw new DicomCodecException("Sop pixel data has no valid value and cannot be compressed.");
                    }

                    new OverlayPlaneModuleIod(DataSet).ExtractEmbeddedOverlays();

                    var pd = new DicomUncompressedPixelData(DataSet);
                    using (var pixelStream = ((DicomElementBinary)pixelData).AsStream())
                    {
                        //Before compression, make the pixel data more "typical", so it's harder to mess up the codecs.
                        //NOTE: Could combine mask and align into one method so we're not iterating twice, but I prefer having the methods separate.
                        if (DicomUncompressedPixelData.RightAlign(pixelStream, pd.BitsAllocated, pd.BitsStored, pd.HighBit))
                        {
                            var newHighBit = (ushort)(pd.HighBit - pd.LowBit);
                            LogAdapter.Logger.Warn("Right aligned pixel data (High Bit: {0}->{1}).", pd.HighBit, newHighBit);

                            pd.HighBit = newHighBit;                             //correct high bit after right-aligning.
                            DataSet[DicomTags.HighBit].SetUInt16(0, newHighBit);
                        }
                        if (DicomUncompressedPixelData.ZeroUnusedBits(pixelStream, pd.BitsAllocated, pd.BitsStored, pd.HighBit))
                        {
                            LogAdapter.Logger.Warn("Zeroed some unused bits before compression.");
                        }
                    }

                    // Set transfer syntax before compression, the codecs need it.
                    var fragments = new DicomCompressedPixelData(pd)
                    {
                        TransferSyntax = newTransferSyntax
                    };
                    codec.Encode(pd, fragments, parameters);
                    fragments.UpdateMessage(this);

                    //TODO: should we validate the number of frames in the compressed data?
                    if (!DataSet.TryGetAttribute(DicomTags.PixelData, out pixelData) || pixelData.IsNull)
                    {
                        throw new DicomCodecException("Sop has no pixel data after compression.");
                    }
                }
                else
                {
                    //A bit cheap, but check for basic image attributes - if any exist
                    // and are non-empty, there should probably be pixel data too.

                    DicomElement element;
                    if (DataSet.TryGetAttribute(DicomTags.Rows, out element) && !element.IsNull)
                    {
                        throw new DicomCodecException("Suspect Sop appears to be an image (Rows is non-empty), but has no pixel data.");
                    }

                    if (DataSet.TryGetAttribute(DicomTags.Columns, out element) && !element.IsNull)
                    {
                        throw new DicomCodecException("Suspect Sop appears to be an image (Columns is non-empty), but has no pixel data.");
                    }

                    TransferSyntax = newTransferSyntax;
                }
            }
            else
            {
                if (codec == null)
                {
                    codec = DicomCodecRegistry.GetCodec(TransferSyntax);
                    if (codec == null)
                    {
                        LogAdapter.Logger.Error("Unable to get registered codec for {0}", TransferSyntax);

                        throw new DicomCodecException("No registered codec for: " + TransferSyntax.Name);
                    }

                    if (parameters == null)
                    {
                        parameters = DicomCodecRegistry.GetCodecParameters(TransferSyntax, DataSet);
                    }
                }

                DicomElement pixelData;
                if (DataSet.TryGetAttribute(DicomTags.PixelData, out pixelData))
                {
                    if (pixelData.IsNull)
                    {
                        throw new DicomCodecException("Sop pixel data has no valid value and cannot be decompressed.");
                    }

                    var fragments = new DicomCompressedPixelData(DataSet);
                    var pd        = new DicomUncompressedPixelData(fragments);

                    codec.Decode(fragments, pd, parameters);

                    pd.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;
                    TransferSyntax    = TransferSyntax.ExplicitVrLittleEndian;

                    pd.UpdateMessage(this);

                    //TODO: should we validate the number of frames in the decompressed data?
                    if (!DataSet.TryGetAttribute(DicomTags.PixelData, out pixelData) || pixelData.IsNull)
                    {
                        throw new DicomCodecException("Sop has no pixel data after decompression.");
                    }
                }
                else
                {
                    //NOTE: doing this for consistency, really.
                    DicomElement element;
                    if (DataSet.TryGetAttribute(DicomTags.Rows, out element) && !element.IsNull)
                    {
                        throw new DicomCodecException("Suspect Sop appears to be an image (Rows is non-empty), but has no pixel data.");
                    }

                    if (DataSet.TryGetAttribute(DicomTags.Columns, out element) && !element.IsNull)
                    {
                        throw new DicomCodecException("Suspect Sop appears to be an image (Columns is non-empty), but has no pixel data.");
                    }

                    TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;
                }
            }
        }
Пример #54
0
 /// <summary>
 /// Gets the <see cref="TransferSyntax"/>es of the available <see cref="IDicomCodecFactory"/> implementations.
 /// </summary>
 public static TransferSyntax[] GetCodecTransferSyntaxes()
 {
     TransferSyntax[] syntaxes = new TransferSyntax[_dictionary.Count];
     _dictionary.Keys.CopyTo(syntaxes, 0);
     return(syntaxes);
 }
Пример #55
0
		public StorageInstance(DicomMessage msg)
		{
			_sopClass = msg.SopClass;

			_syntax = msg.TransferSyntax;
			SopInstanceUid = msg.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty);

			StudyInstanceUid = msg.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty);
			SeriesInstanceUid = msg.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty);
			PatientsName = msg.DataSet[DicomTags.PatientsName].GetString(0, string.Empty);
			PatientId = msg.DataSet[DicomTags.PatientId].GetString(0, string.Empty);
			_infoLoaded = true;
		}
Пример #56
0
        /// <summary>
        ///     Generates a concrete element class from the VR, tag, data and syntax. Also directs the appropriate data
        ///     interpretation.
        /// </summary>
        /// <param name="tag">the tag of the element to be generated</param>
        /// <param name="vr">the VR of the element to be generated</param>
        /// <param name="data">the raw data to be procesed (byte array)</param>
        /// <param name="syntax">the transfer syntax by which to interepret the data</param>
        /// <returns>a concrete DICOM element that uses the interface IDICOMElement</returns>
        public static IDICOMElement GenerateElement(Tag tag, VR vr, object data, TransferSyntax syntax, StringEncoding enc)
        {
            //HANDLE NUMBERS
            if (syntax == TransferSyntax.EXPLICIT_VR_BIG_ENDIAN)
            {
                switch (vr)
                {
                case VR.AttributeTag:
                    return(new AttributeTag(tag, BigEndianReader.ReadTag(data as byte[])));

                case VR.FloatingPointDouble:
                    return(new FloatingPointDouble(tag, BigEndianReader.ReadDoublePrecision(data as byte[])));

                case VR.FloatingPointSingle:
                    return(new FloatingPointSingle(tag, BigEndianReader.ReadSinglePrecision(data as byte[])));

                case VR.SignedLong:
                    return(new SignedLong(tag, BigEndianReader.ReadSignedLong(data as byte[])));

                case VR.SignedShort:
                    return(new SignedShort(tag, BigEndianReader.ReadSignedShort(data as byte[])));

                case VR.UnsignedLong:
                    return(new UnsignedLong(tag, BigEndianReader.ReadUnsignedLong(data as byte[])));

                case VR.UnsignedShort:
                    return(new UnsignedShort(tag, BigEndianReader.ReadUnsignedShort(data as byte[])));
                }
            }
            else
            {
                switch (vr)
                {
                case VR.AttributeTag:
                    return(new AttributeTag(tag, LittleEndianReader.ReadTag(data as byte[])));

                case VR.FloatingPointDouble:
                    return(new FloatingPointDouble(tag, LittleEndianReader.ReadDoublePrecision(data as byte[])));

                case VR.FloatingPointSingle:
                    return(new FloatingPointSingle(tag, LittleEndianReader.ReadSinglePrecision(data as byte[])));

                case VR.SignedLong:
                    return(new SignedLong(tag, LittleEndianReader.ReadSignedLong(data as byte[])));

                case VR.SignedShort:
                    return(new SignedShort(tag, LittleEndianReader.ReadSignedShort(data as byte[])));

                case VR.UnsignedLong:
                    return(new UnsignedLong(tag, LittleEndianReader.ReadUnsignedLong(data as byte[])));

                case VR.UnsignedShort:
                    return(new UnsignedShort(tag, LittleEndianReader.ReadUnsignedShort(data as byte[])));
                }
            }
            //HANDLE ALL OTHERS
            switch (vr)
            {
            //HANDLE STRINGS
            case VR.AgeString:
            case VR.ApplicationEntity:
            case VR.CodeString:
            case VR.Date:
            case VR.DateTime:
            case VR.DecimalString:
            case VR.IntegerString:
            case VR.LongString:
            case VR.LongText:
            case VR.PersonName:
            case VR.ShortString:
            case VR.ShortText:
            case VR.Time:
            case VR.UnlimitedCharacter:
            case VR.UnlimitedText:
            case VR.UniversalResourceId:
            case VR.UniqueIdentifier:
                return(ReadString(vr, tag, data, enc));

            //HANDLE BYTE DATA
            case VR.Sequence:
                return(new Sequence {
                    Tag = tag, Items = SequenceReader.ReadItems(data as byte[], syntax, enc)
                });

            case VR.OtherByteString:
                return(new OtherByteString(tag, data as byte[]));

            case VR.OtherFloatString:
                return(new OtherFloatString(tag, data as byte[]));

            case VR.OtherWordString:
                return(new OtherWordString(tag, data as byte[]));

            case VR.OtherDoubleString:
                return(new OtherDoubleString(tag, data as byte[]));

            case VR.OtherLongString:
                return(new OtherLongString(tag, data as byte[]));

            default:
                var unk = new Unknown(tag, data as byte[]);
                unk.TransferSyntax = syntax;
                return(unk);
            }
        }
Пример #57
0
		public DicomWriteStatus Write(TransferSyntax syntax, DicomAttributeCollection dataset, DicomWriteOptions options)
		{
			TransferSyntax = syntax;

			foreach (DicomAttribute item in dataset)
			{
				if (item.IsEmpty)
					continue;

				if (item.Tag.Element == 0x0000)
					continue;

				if (Flags.IsSet(options, DicomWriteOptions.CalculateGroupLengths)
				    && item.Tag.Group != _group)
				{
					_group = item.Tag.Group;
					_writer.Write((ushort) _group);
					_writer.Write((ushort) 0x0000);
					if (_syntax.ExplicitVr)
					{
						_writer.Write((byte) 'U');
						_writer.Write((byte) 'L');
						_writer.Write((ushort) 4);
					}
					else
					{
						_writer.Write((uint) 4);
					}
					_writer.Write((uint) dataset.CalculateGroupWriteLength(_group, _syntax, options));
				}

				_writer.Write((ushort) item.Tag.Group);
				_writer.Write((ushort) item.Tag.Element);

				if (_syntax.ExplicitVr)
				{
					_writer.Write((byte) item.Tag.VR.Name[0]);
					_writer.Write((byte) item.Tag.VR.Name[1]);
				}

				if (item is DicomAttributeSQ)
				{
					var sq = item as DicomAttributeSQ;

					if (_syntax.ExplicitVr)
						_writer.Write((ushort) 0x0000);

					if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding))
					{
						// length field is not written when generating digital signature MAC
					}
					else if (Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequence))
					{
						int hl = _syntax.ExplicitVr ? 12 : 8;
						_writer.Write((uint) sq.CalculateWriteLength(_syntax, options & ~DicomWriteOptions.CalculateGroupLengths) - (uint) hl);
					}
					else
					{
						_writer.Write((uint) _undefinedLength);
					}

					foreach (DicomSequenceItem ids in (DicomSequenceItem[]) sq.Values)
					{
						_writer.Write((ushort) DicomTag.Item.Group);
						_writer.Write((ushort) DicomTag.Item.Element);

						if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding))
						{
							// length field is not written when generating digital signature MAC
						}
						else if (Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequenceItem))
						{
							_writer.Write((uint) ids.CalculateWriteLength(_syntax, options & ~DicomWriteOptions.CalculateGroupLengths));
						}
						else
						{
							_writer.Write((uint) _undefinedLength);
						}

						Write(TransferSyntax, ids, options & ~DicomWriteOptions.CalculateGroupLengths);

						if (!Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequenceItem)
						    && !Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding))
						{
							_writer.Write((ushort) DicomTag.ItemDelimitationItem.Group);
							_writer.Write((ushort) DicomTag.ItemDelimitationItem.Element);
							_writer.Write((uint) 0x00000000);
						}
					}

					if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding))
					{
						_writer.Write((ushort) DicomTag.SequenceDelimitationItem.Group);
						_writer.Write((ushort) DicomTag.SequenceDelimitationItem.Element);
					}
					else if (!Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequence))
					{
						_writer.Write((ushort) DicomTag.SequenceDelimitationItem.Group);
						_writer.Write((ushort) DicomTag.SequenceDelimitationItem.Element);
						_writer.Write((uint) 0x00000000);
					}
				}

				else if (item is DicomFragmentSequence)
				{
					var fs = item as DicomFragmentSequence;

					if (_syntax.ExplicitVr)
						_writer.Write((ushort) 0x0000);

					if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding))
					{
						// length field is not written when generating digital signature MAC
					}
					else
					{
						_writer.Write((uint) _undefinedLength);
					}

					_writer.Write((ushort) DicomTag.Item.Group);
					_writer.Write((ushort) DicomTag.Item.Element);

					if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding))
					{
						// length field is not written when generating digital signature MAC
						if (fs.HasOffsetTable) fs.OffsetTableBuffer.CopyTo(_writer);
					}
					else if (Flags.IsSet(options, DicomWriteOptions.WriteFragmentOffsetTable) && fs.HasOffsetTable)
					{
						_writer.Write((uint) fs.OffsetTableBuffer.Length);
						fs.OffsetTableBuffer.CopyTo(_writer);
					}
					else
					{
						_writer.Write((uint) 0x00000000);
					}

					foreach (DicomFragment bb in fs.Fragments)
					{
						_writer.Write((ushort) DicomTag.Item.Group);
						_writer.Write((ushort) DicomTag.Item.Element);

						if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding))
						{
							// length field is not written when generating digital signature MAC
						}
						else
						{
							_writer.Write((uint) bb.Length);
						}
						bb.GetByteBuffer(_syntax).CopyTo(_writer);
					}

					if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding))
					{
						_writer.Write((ushort) DicomTag.SequenceDelimitationItem.Group);
						_writer.Write((ushort) DicomTag.SequenceDelimitationItem.Element);
					}
					else
					{
						_writer.Write((ushort) DicomTag.SequenceDelimitationItem.Group);
						_writer.Write((ushort) DicomTag.SequenceDelimitationItem.Element);
						_writer.Write((uint) 0x00000000);
					}
				}
				else
				{
					DicomAttribute de = item;
					ByteBuffer theData = de.GetByteBuffer(_syntax, dataset.SpecificCharacterSet);
					if (_syntax.ExplicitVr)
					{
						if (de.Tag.VR.Is16BitLengthField)
						{
							// #10890: Can't encode the value length if the length of the data exceeds max value for a 16-bit field
							if (theData.Length > ushort.MaxValue - 1 /* must be even length so max allowed = 65534 */)
								throw new DicomDataException(string.Format(
									"Value for {0} exceeds maximum stream length allowed for a {1} VR attribute encoded using {2}",
									de.Tag, de.Tag.VR, _syntax));
							_writer.Write((ushort) theData.Length);
						}
						else
						{
							_writer.Write((ushort) 0x0000);
							_writer.Write((uint) theData.Length);
						}
					}
					else
					{
						_writer.Write((uint) theData.Length);
					}

					if (theData.Length > 0)
						theData.CopyTo(_writer);
				}
			}

			return DicomWriteStatus.Success;
		}
Пример #58
0
 internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax)
 {
     if (length < 4)
     {
         data = 0;
         br.ReadBytes((int)length);
     }
     else
     {
         data = br.ReadInt32();
         if (length > 4)
         {
             br.ReadBytes((int)length - 4);
         }
     }
     return(length);
 }
Пример #59
0
        public InstanceXml(XmlNode instanceNode, DicomAttributeCollection baseCollection)
        {
            InstanceXmlDicomAttributeCollection thisCollection = new InstanceXmlDicomAttributeCollection();

            _collection = thisCollection;
            _collection.ValidateVrValues  = false;
            _collection.ValidateVrLengths = false;

            if (baseCollection != null)
            {
                AddExcludedTagsFromBase(baseCollection);

                _baseCollectionEnumerator = baseCollection.GetEnumerator();
                if (!_baseCollectionEnumerator.MoveNext())
                {
                    _baseCollectionEnumerator = null;
                }
            }

            if (!instanceNode.HasChildNodes)
            {
                return;
            }

            _instanceXmlEnumerator = instanceNode.ChildNodes.GetEnumerator();
            if (!_instanceXmlEnumerator.MoveNext())
            {
                _instanceXmlEnumerator = null;
            }

            if (instanceNode.Attributes["UID"] != null)
            {
                _sopInstanceUid = instanceNode.Attributes["UID"].Value;
            }

            if (instanceNode.Attributes["SourceAETitle"] != null)
            {
                _sourceAETitle = XmlUnescapeString(instanceNode.Attributes["SourceAETitle"].Value);
            }

            if (instanceNode.Attributes["SopClassUID"] != null)
            {
                _sopClass = SopClass.GetSopClass(instanceNode.Attributes["SopClassUID"].Value);
            }

            _transferSyntax = instanceNode.Attributes["TransferSyntaxUID"] != null
                                ? TransferSyntax.GetTransferSyntax(instanceNode.Attributes["TransferSyntaxUID"].Value)
                                : TransferSyntax.ExplicitVrLittleEndian;

            if (instanceNode.Attributes["SourceFileName"] != null)
            {
                _sourceFileName = instanceNode.Attributes["SourceFileName"].Value;
            }

            if (instanceNode.Attributes["FileSize"] != null)
            {
                long.TryParse(instanceNode.Attributes["FileSize"].Value, out _fileSize);
            }

            // This should never happen
            if (_sopClass == null)
            {
                _sopClass = SopClass.GetSopClass(Collection[DicomTags.SopClassUid].GetString(0, String.Empty));
            }
        }
Пример #60
0
 /// <summary>
 ///     Reads a DICOM file from a path
 /// </summary>
 /// <param name="filePath">the path to the file</param>
 /// <param name="trySyntax">the transfer syntax to use in case there is no metadata explicitly included</param>
 /// <returns>the DICOM Object</returns>
 /// <example>
 ///<code>
 ///var dcm = DICOMObject.Read("mydcm.dcm");
 ///</code>
 ///</example>
 public static async Task <DICOMObject> ReadAsync(string filePath,
                                                  TransferSyntax trySyntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN)
 {
     return(await DICOMFileReader.ReadAsync(filePath, trySyntax));
 }