Exemplo n.º 1
0
        private static DicomDataset Decode(
            DicomDataset oldDataset,
            DicomTransferSyntax outSyntax,
            IDicomCodec codec,
            DicomCodecParams parameters)
        {
            if (codec == null)
            {
                throw new DicomCodecException("Decoding dataset with transfer syntax: {0} is not supported. See here to get help resolving the reason: https://github.com/fo-dicom/fo-dicom/wiki/Native-codecs-on-.NET",
                                              oldDataset.InternalTransferSyntax);
            }

            var oldPixelData = DicomPixelData.Create(oldDataset);

            var newDataset = oldDataset.Clone();

            newDataset.InternalTransferSyntax = outSyntax;
            var newPixelData = DicomPixelData.Create(newDataset, true);

            codec.Decode(oldPixelData, newPixelData, parameters);

            ProcessOverlays(oldDataset, newDataset);

            newDataset.RecalculateGroupLengths(false);

            return(newDataset);
        }
Exemplo n.º 2
0
        private static DicomDataset Decode(
            DicomDataset oldDataset,
            DicomTransferSyntax outSyntax,
            IDicomCodec codec,
            DicomCodecParams parameters)
        {
            if (codec == null)
            {
                throw new DicomCodecException("Decoding dataset with transfer syntax: {0} is not supported.",
                                              oldDataset.InternalTransferSyntax);
            }

            var oldPixelData = DicomPixelData.Create(oldDataset);

            var newDataset = oldDataset.Clone();

            newDataset.InternalTransferSyntax = outSyntax;
            var newPixelData = DicomPixelData.Create(newDataset, true);

            codec.Decode(oldPixelData, newPixelData, parameters);

            ProcessOverlays(oldDataset, newDataset);

            newDataset.RecalculateGroupLengths(false);

            return(newDataset);
        }
        /// <summary>
        /// Implementation of method to load codecs from assembly(ies) at the specified <paramref name="path"/> and
        /// with the specified <paramref name="search"/> pattern.
        /// </summary>
        /// <param name="path">Directory path to codec assemblies.</param>
        /// <param name="search">Search pattern for codec assemblies.</param>
        protected override void LoadCodecsImpl(string path, string search)
        {
            if (IsLoaded)
            {
                return;
            }

            Codecs.Clear();

            var foundAnyCodecs = false;
            var assembly       = Assembly.GetExecutingAssembly();
            var types          = assembly.GetTypes();
            var codecTypes     = types.Where(t => typeof(IDicomCodec).IsAssignableFrom(t) && !t.IsAbstract);
            var log            = LogManager.GetLogger("Efferent.Native.Codec");

            foreach (var codecType in codecTypes)
            {
                foundAnyCodecs = true;
                IDicomCodec codec = (IDicomCodec)Activator.CreateInstance(codecType);
                Codecs[codec.TransferSyntax] = codec;
            }

            if (!foundAnyCodecs)
            {
                log.Warn("No Dicom codecs were found after searching {path}\\{wildcard}", path, search);
            }
            else
            {
                IsLoaded = true;

                var codecNames = string.Join("\n", Codecs.Keys.Select(k => "- " + k.ToString()));
                System.Diagnostics.Debug.WriteLine($"Codecs found:\n{codecNames}");
            }
        }
Exemplo n.º 4
0
 public DicomCompressCommand(DicomMessageBase file, TransferSyntax syntax, IDicomCodec codec, DicomCodecParameters parms)
     : base("DICOM Compress Command", true)
 {
     _file   = file;
     _syntax = syntax;
     _codec  = codec;
     _parms  = parms;
 }
Exemplo n.º 5
0
		public DicomCompressCommand(DicomMessageBase file, TransferSyntax syntax, IDicomCodec codec, DicomCodecParameters parms)
			: base("DICOM Compress Command", true)
		{

			_file = file;
			_syntax = syntax;
			_codec = codec;
			_parms = parms;
		}
Exemplo n.º 6
0
    	/// <summary>
    	/// Gets an array of <see cref="IDicomCodec"/>s (one from each available <see cref="IDicomCodecFactory"/>).
    	/// </summary>
		public static IDicomCodec[] GetCodecs()
		{
			IDicomCodec[] codecs = new IDicomCodec[_dictionary.Count];
			int i = 0;
			foreach (IDicomCodecFactory factory in _dictionary.Values)
				codecs[i++] = factory.GetDicomCodec();

			return codecs;
		}
Exemplo n.º 7
0
        public static IDicomCodec GetCodec(DicomTransferSyntax syntax)
        {
            IDicomCodec codec = null;

            if (!_codecs.TryGetValue(syntax, out codec))
            {
                throw new DicomCodecException("No codec registered for tranfer syntax: {0}", syntax);
            }
            return(codec);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Gets an array of <see cref="IDicomCodec"/>s (one from each available <see cref="IDicomCodecFactory"/>).
        /// </summary>
        public static IDicomCodec[] GetCodecs()
        {
            IDicomCodec[] codecs = new IDicomCodec[_dictionary.Count];
            int           i      = 0;

            foreach (IDicomCodecFactory factory in _dictionary.Values)
            {
                codecs[i++] = factory.GetDicomCodec();
            }

            return(codecs);
        }
Exemplo n.º 9
0
        static public unsafe void GetAverageValue(this DicomDataset original, IDicomCodec codec, out double average, out double dispersion, out ushort min, out ushort max)
        {
            DicomDataset dataset = new DicomDataset();

            original.CopyTo(dataset);

            DicomPixelData pixelData       = DicomPixelData.Create(dataset, true);
            DicomPixelData pixelDataSource = DicomPixelData.Create(original, false);

            codec.Decode(pixelDataSource, pixelData, new DicomJpegParams {
            });
            GetAverageValue(dataset, out average, out dispersion, out min, out max);
        }
Exemplo n.º 10
0
        static public DicomDataset Uncompress(this DicomDataset original, IDicomCodec codec)
        {
            DicomDataset dataset = new DicomDataset();

            original.CopyTo(dataset);

            DicomPixelData pixelData = DicomPixelData.Create(dataset, true);

            DicomPixelData pixelDataSource = DicomPixelData.Create(original, false);

            codec.Decode(pixelDataSource, pixelData, new DicomJpeg2000Params {
            });

            return(dataset);
        }
Exemplo n.º 11
0
        private static DicomDataset Encode(
            DicomDataset oldDataset,
            DicomTransferSyntax outSyntax,
            IDicomCodec codec,
            DicomCodecParams parameters)
        {
            if (codec == null)
            {
                throw new DicomCodecException($"Encoding dataset to transfer syntax {outSyntax} is not supported.");
            }

            var oldPixelData = DicomPixelData.Create(oldDataset);

            var newDataset = oldDataset.Clone();

            newDataset.InternalTransferSyntax = outSyntax;
            var newPixelData = DicomPixelData.Create(newDataset, true);

            codec.Encode(oldPixelData, newPixelData, parameters);

            if (outSyntax.IsLossy && newPixelData.NumberOfFrames > 0)
            {
                newDataset.AddOrUpdate(new DicomCodeString(DicomTag.LossyImageCompression, "01"));

                var methods = new List <string>();
                if (newDataset.Contains(DicomTag.LossyImageCompressionMethod))
                {
                    methods.AddRange(newDataset.GetValues <string>(DicomTag.LossyImageCompressionMethod));
                }

                methods.Add(outSyntax.LossyCompressionMethod);
                newDataset.AddOrUpdate(new DicomCodeString(DicomTag.LossyImageCompressionMethod, methods.ToArray()));

                double oldSize = oldPixelData.GetFrame(0).Size;
                double newSize = newPixelData.GetFrame(0).Size;
                var    ratio   = string.Format(CultureInfo.InvariantCulture, "{0:0.000}", oldSize / newSize);
                newDataset.AddOrUpdate(new DicomDecimalString(DicomTag.LossyImageCompressionRatio, ratio));
            }

            ProcessOverlays(oldDataset, newDataset);

            newDataset.RecalculateGroupLengths(false);

            return(newDataset);
        }
Exemplo n.º 12
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);
        }
Exemplo n.º 13
0
        private static DicomDataset Decode(
            DicomDataset oldDataset,
            DicomTransferSyntax outSyntax,
            IDicomCodec codec,
            DicomCodecParams parameters)
        {
            var oldPixelData = DicomPixelData.Create(oldDataset, false);

            var newDataset = oldDataset.Clone();

            newDataset.InternalTransferSyntax = outSyntax;
            var newPixelData = DicomPixelData.Create(newDataset, true);

            codec.Decode(oldPixelData, newPixelData, parameters);

            ProcessOverlays(oldDataset, newDataset);

            newDataset.RecalculateGroupLengths(false);

            return(newDataset);
        }
Exemplo n.º 14
0
        private static DicomDataset Encode(
            DicomDataset oldDataset,
            DicomTransferSyntax inSyntax,
            IDicomCodec codec,
            DicomCodecParams parameters)
        {
            var oldPixelData = DicomPixelData.Create(oldDataset, false);

            var newDataset = oldDataset.Clone();

            newDataset.InternalTransferSyntax = codec.TransferSyntax;
            var newPixelData = DicomPixelData.Create(newDataset, true);

            codec.Encode(oldPixelData, newPixelData, parameters);

            if (codec.TransferSyntax.IsLossy && newPixelData.NumberOfFrames > 0)
            {
                newDataset.AddOrUpdate(new DicomCodeString(DicomTag.LossyImageCompression, "01"));

                var methods = new List <string>();
                if (newDataset.Contains(DicomTag.LossyImageCompressionMethod))
                {
                    methods.AddRange(newDataset.Get <string[]>(DicomTag.LossyImageCompressionMethod));
                }
                methods.Add(codec.TransferSyntax.LossyCompressionMethod);
                newDataset.AddOrUpdate(new DicomCodeString(DicomTag.LossyImageCompressionMethod, methods.ToArray()));

                double oldSize = oldPixelData.GetFrame(0).Size;
                double newSize = newPixelData.GetFrame(0).Size;
                var    ratio   = String.Format("{0:0.000}", oldSize / newSize);
                newDataset.AddOrUpdate(new DicomDecimalString(DicomTag.LossyImageCompressionRatio, ratio));
            }

            ProcessOverlays(oldDataset, newDataset);

            newDataset.RecalculateGroupLengths(false);

            return(newDataset);
        }
        /// <summary>
        /// Get a specific frame's data in uncompressed format.
        /// </summary>
        /// <remarks>
        /// <para>
        /// If a DICOM file is loaded with the <see cref="DicomReadOptions.StorePixelDataReferences"/>
        /// option set, this method will only load the specific frame's data from the source file to
        /// do the decompress, thus reducing memory usage to only the frame being decompressed.
        /// </para>
        /// </remarks>
        /// <param name="frame">A zero offset frame to request.</param>
        /// <param name="photometricInterpretation">The photometric interpretation of the output data</param>
        /// <returns>A byte array containing the frame.</returns>
        public override byte[] GetFrame(int frame, out string photometricInterpretation)
        {
            DicomUncompressedPixelData pd = new DicomUncompressedPixelData(this);

            IDicomCodec codec = DicomCodecRegistry.GetCodec(TransferSyntax);

            if (codec == null)
            {
                Platform.Log(LogLevel.Error, "Unable to get registered codec for {0}", TransferSyntax);

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

            DicomCodecParameters parameters = DicomCodecRegistry.GetCodecParameters(TransferSyntax, null);

            codec.DecodeFrame(frame, this, pd, parameters);

            pd.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;

            photometricInterpretation = pd.PhotometricInterpretation;

            return(pd.GetData());
        }
Exemplo n.º 16
0
		public DicomCompressCommand(DicomMessageBase file, XmlDocument parms)
			: base("DICOM Compress Command", true)
		{
			_file = file;

			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);
		}
Exemplo n.º 17
0
        protected void ProcessFile(Model.WorkQueue item, WorkQueueUid sop, string path, StudyXml studyXml, IDicomCodecFactory theCodecFactory)
        {
            DicomFile file = null;

            _instanceStats = new CompressInstanceStatistics();

            _instanceStats.ProcessTime.Start();

            // Use the command processor for rollback capabilities.
            using (ServerCommandProcessor processor = new ServerCommandProcessor("Processing WorkQueue Compress DICOM File"))
            {
                string modality = String.Empty;

                try
                {
                    file = new DicomFile(path);

                    _instanceStats.FileLoadTime.Start();
                    file.Load(DicomReadOptions.StorePixelDataReferences | DicomReadOptions.Default);
                    _instanceStats.FileLoadTime.End();

                    modality = file.DataSet[DicomTags.Modality].GetString(0, String.Empty);

                    FileInfo fileInfo = new FileInfo(path);
                    _instanceStats.FileSize = (ulong)fileInfo.Length;

                    // Get the Patients Name for processing purposes.
                    String patientsName = file.DataSet[DicomTags.PatientsName].GetString(0, "");

                    if (file.TransferSyntax.Equals(theCodecFactory.CodecTransferSyntax))
                    {
                        // Delete the WorkQueueUid item
                        processor.AddCommand(new DeleteWorkQueueUidCommand(sop));

                        // Do the actual processing
                        if (!processor.Execute())
                        {
                            Platform.Log(LogLevel.Warn, "Failure deleteing WorkQueueUid: {0} for SOP: {1}", processor.Description, file.MediaStorageSopInstanceUid);
                            Platform.Log(LogLevel.Warn, "Compression file that failed: {0}", file.Filename);
                        }
                        else
                        {
                            Platform.Log(LogLevel.Warn, "Skip compressing SOP {0}. Its current transfer syntax is {1}",
                                         file.MediaStorageSopInstanceUid, file.TransferSyntax.Name);
                        }
                    }
                    else
                    {
                        IDicomCodec codec = theCodecFactory.GetDicomCodec();

                        // Create a context for applying actions from the rules engine
                        var context = new ServerActionContext(file, StorageLocation.FilesystemKey, ServerPartition, item.StudyStorageKey);
                        context.CommandProcessor = processor;

                        var parms           = theCodecFactory.GetCodecParameters(item.Data);
                        var compressCommand =
                            new DicomCompressCommand(context.Message, theCodecFactory.CodecTransferSyntax, codec, parms);
                        processor.AddCommand(compressCommand);

                        var save = new SaveDicomFileCommand(file.Filename, file, false);
                        processor.AddCommand(save);

                        // Update the StudyStream object, must be done after compression
                        // and after the compressed image has been successfully saved
                        var insertStudyXmlCommand = new UpdateStudyXmlCommand(file, studyXml, StorageLocation);
                        processor.AddCommand(insertStudyXmlCommand);

                        // Delete the WorkQueueUid item
                        processor.AddCommand(new DeleteWorkQueueUidCommand(sop));

                        // Do the actual processing
                        if (!processor.Execute())
                        {
                            EventManager.FireEvent(this, new FailedUpdateSopEventArgs {
                                File = file, ServerPartitionEntry = context.ServerPartition, WorkQueueUidEntry = sop, WorkQueueEntry = WorkQueueItem, FileLength = (ulong)insertStudyXmlCommand.FileSize, FailureMessage = processor.FailureReason
                            });

                            _instanceStats.CompressTime.Add(compressCommand.CompressTime);
                            Platform.Log(LogLevel.Error, "Failure compressing command {0} for SOP: {1}", processor.Description, file.MediaStorageSopInstanceUid);
                            Platform.Log(LogLevel.Error, "Compression file that failed: {0}", file.Filename);
                            throw new ApplicationException("Unexpected failure (" + processor.FailureReason + ") executing command for SOP: " + file.MediaStorageSopInstanceUid, processor.FailureException);
                        }
                        _instanceStats.CompressTime.Add(compressCommand.CompressTime);
                        Platform.Log(ServerPlatform.InstanceLogLevel, "Compress SOP: {0} for Patient {1}", file.MediaStorageSopInstanceUid,
                                     patientsName);

                        EventManager.FireEvent(this, new UpdateSopEventArgs {
                            File = file, ServerPartitionEntry = context.ServerPartition, WorkQueueUidEntry = sop, WorkQueueEntry = WorkQueueItem, FileLength = (ulong)insertStudyXmlCommand.FileSize
                        });
                    }
                }
                catch (Exception e)
                {
                    EventManager.FireEvent(this, new FailedUpdateSopEventArgs {
                        File = file, ServerPartitionEntry = ServerPartition, WorkQueueUidEntry = sop, WorkQueueEntry = WorkQueueItem, FileLength = (ulong)new FileInfo(path).Length, FailureMessage = processor.FailureReason
                    });

                    Platform.Log(LogLevel.Error, e, "Unexpected exception when {0}.  Rolling back operation.",
                                 processor.Description);
                    processor.Rollback();

                    throw;
                }
                finally
                {
                    _instanceStats.ProcessTime.End();
                    _studyStats.AddSubStats(_instanceStats);

                    _studyStats.StudyInstanceUid = StorageLocation.StudyInstanceUid;
                    if (String.IsNullOrEmpty(modality) == false)
                    {
                        _studyStats.Modality = modality;
                    }

                    // Update the statistics
                    _studyStats.NumInstances++;
                }
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// Scan the files to send, and create presentation contexts for each abstract syntax to send.
        /// </summary>
        protected override void SetPresentationContexts()
        {
            foreach (StorageInstance sendStruct in _storageInstanceList)
            {
                // skip if failed in LoadStorageInstanceInfo, ie file not found
                if (sendStruct.SendStatus == DicomStatuses.ProcessingFailure)
                {
                    continue;
                }

                if (sendStruct.TransferSyntax.Encapsulated)
                {
                    // If the image is encapsulated, make sure there's an exact match of the transfer
                    // syntax, if not, just make sure there's an unencapsulated transfer syntax.
                    byte pcid = AssociationParameters.FindAbstractSyntaxWithTransferSyntax(sendStruct.SopClass,
                                                                                           sendStruct.TransferSyntax);

                    if (pcid == 0)
                    {
                        pcid = AssociationParameters.AddPresentationContext(sendStruct.SopClass);

                        AssociationParameters.AddTransferSyntax(pcid, sendStruct.TransferSyntax);
                    }

                    // Check for a codec, and if it exists, also register an uncompressed context.
                    IDicomCodec codec = DicomCodecRegistry.GetCodec(sendStruct.TransferSyntax);
                    if (codec != null)
                    {
                        pcid = AssociationParameters.FindAbstractSyntaxWithTransferSyntax(sendStruct.SopClass,
                                                                                          TransferSyntax.ExplicitVrLittleEndian);
                        if (pcid == 0)
                        {
                            pcid = AssociationParameters.AddPresentationContext(sendStruct.SopClass);

                            AssociationParameters.AddTransferSyntax(pcid, TransferSyntax.ExplicitVrLittleEndian);
                            AssociationParameters.AddTransferSyntax(pcid, TransferSyntax.ImplicitVrLittleEndian);
                        }
                    }
                }
                else
                {
                    byte pcid = AssociationParameters.FindAbstractSyntaxWithTransferSyntax(sendStruct.SopClass,
                                                                                           TransferSyntax.ExplicitVrLittleEndian);

                    if (pcid == 0)
                    {
                        pcid = AssociationParameters.AddPresentationContext(sendStruct.SopClass);

                        AssociationParameters.AddTransferSyntax(pcid, TransferSyntax.ExplicitVrLittleEndian);
                        AssociationParameters.AddTransferSyntax(pcid, TransferSyntax.ImplicitVrLittleEndian);
                    }
                }

                // Now add the preferred syntaxes, if its been set.
                if (_preferredSyntaxes != null)
                {
                    SupportedSop supportedSop;
                    if (_preferredSyntaxes.TryGetValue(sendStruct.SopClass.Uid, out supportedSop))
                    {
                        foreach (TransferSyntax syntax in supportedSop.SyntaxList)
                        {
                            byte pcid = AssociationParameters.FindAbstractSyntaxWithTransferSyntax(sendStruct.SopClass,
                                                                                                   syntax);

                            // If we have more than 1 transfer syntax associated with the preferred, we want to
                            // have a dedicated presentation context for the preferred, so that we ensure it
                            // gets accepted if the SCP supports it.  This is only really going to happen if
                            // the preferred is Explicit VR Little Endian or Implicit VR Little Endian.
                            if ((pcid == 0) ||
                                (AssociationParameters.GetPresentationContextTransferSyntaxes(pcid).Count > 1))
                            {
                                pcid = AssociationParameters.AddPresentationContext(sendStruct.SopClass);

                                AssociationParameters.AddTransferSyntax(pcid, syntax);
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 19
0
        private DicomDataset Encode(DicomDataset oldDataset, DicomTransferSyntax inSyntax, IDicomCodec codec, DicomCodecParams parameters)
        {
            DicomPixelData oldPixelData = DicomPixelData.Create(oldDataset, false);

            DicomDataset newDataset = oldDataset.Clone();

            newDataset.InternalTransferSyntax = codec.TransferSyntax;
            DicomPixelData newPixelData = DicomPixelData.Create(newDataset, true);

            codec.Encode(oldPixelData, newPixelData, parameters);

            if (codec.TransferSyntax.IsLossy && newPixelData.NumberOfFrames > 0)
            {
                newDataset.Add(new DicomCodeString(DicomTag.LossyImageCompression, "01"));

                List <string> methods = new List <string>();
                if (newDataset.Exists(DicomTag.LossyImageCompressionMethod))
                {
                    methods.AddRange(newDataset.Get <string[]>(DicomTag.LossyImageCompressionMethod));
                }
                methods.Add(codec.TransferSyntax.LossyCompressionMethod);
                newDataset.Add(new DicomCodeString(DicomTag.LossyImageCompressionMethod, methods.ToArray()));

                double oldSize = oldPixelData.GetFrame(0).Size;
                double newSize = newPixelData.GetFrame(0).Size;
                string ratio   = String.Format("{0:0.000}", oldSize / newSize);
                newDataset.Add(new DicomDecimalString(DicomTag.LossyImageCompressionRatio, ratio));
            }

            return(newDataset);
        }
Exemplo n.º 20
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)
                    {
                        Platform.Log(LogLevel.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);

            	DicomAttribute 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 = ((DicomAttributeBinary) 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);
							Platform.Log(LogLevel.Debug, "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))
						{
							Platform.Log(LogLevel.Debug, "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.

                    DicomAttribute attribute;
                    if (DataSet.TryGetAttribute(DicomTags.Rows, out attribute) && !attribute.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 attribute) && !attribute.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)
                    {
                        Platform.Log(LogLevel.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);
                }

				DicomAttribute 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.
					DicomAttribute attribute;
					if (DataSet.TryGetAttribute(DicomTags.Rows, out attribute) && !attribute.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 attribute) && !attribute.IsNull)
						throw new DicomCodecException("Suspect Sop appears to be an image (Columns is non-empty), but has no pixel data.");
					
					TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;
                }
            }
        }
Exemplo n.º 21
0
        static public DicomDataset Compress(this DicomDataset original, DicomTransferSyntax dicomTransferSyntax, IDicomCodec codec, DicomCodecParams jpegParams)
        {
            DicomDataset dataset = new DicomDataset(dicomTransferSyntax);

            original.CopyTo(dataset);

            DicomPixelData pixelData = DicomPixelData.Create(dataset, true);

            DicomPixelData pixelDataSource = DicomPixelData.Create(original, false);

            codec.Encode(pixelDataSource, pixelData, jpegParams);

            return(dataset);
        }
Exemplo n.º 22
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)
                    {
                        Platform.Log(LogLevel.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);
                }

                DicomAttribute 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.");
                    }

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

                    // Set before compression, the codecs need it.
                    fragments.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.

                    DicomAttribute attribute;
                    if (DataSet.TryGetAttribute(DicomTags.Rows, out attribute) && !attribute.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 attribute) && !attribute.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)
                    {
                        Platform.Log(LogLevel.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);
                    }
                }

                DicomAttribute 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.");
                    }

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

                    codec.Decode(fragments, pd, parameters);

                    pd.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.
                    DicomAttribute attribute;
                    if (DataSet.TryGetAttribute(DicomTags.Rows, out attribute) && !attribute.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 attribute) && !attribute.IsNull)
                    {
                        throw new DicomCodecException("Suspect Sop appears to be an image (Columns is non-empty), but has no pixel data.");
                    }

                    TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;
                }
            }
        }
Exemplo n.º 23
0
		private DicomDataset Encode(DicomDataset oldDataset, DicomTransferSyntax inSyntax, IDicomCodec codec, DicomCodecParams parameters) {
			DicomPixelData oldPixelData = DicomPixelData.Create(oldDataset, false);

			DicomDataset newDataset = oldDataset.Clone();
			newDataset.InternalTransferSyntax = codec.TransferSyntax;
			DicomPixelData newPixelData = DicomPixelData.Create(newDataset, true);

			codec.Encode(oldPixelData, newPixelData, parameters);

			if (codec.TransferSyntax.IsLossy && newPixelData.NumberOfFrames > 0) {
				newDataset.Add(new DicomCodeString(DicomTag.LossyImageCompression, "01"));

				List<string> methods = new List<string>();
				if (newDataset.Contains(DicomTag.LossyImageCompressionMethod))
					methods.AddRange(newDataset.Get<string[]>(DicomTag.LossyImageCompressionMethod));
				methods.Add(codec.TransferSyntax.LossyCompressionMethod);
				newDataset.Add(new DicomCodeString(DicomTag.LossyImageCompressionMethod, methods.ToArray()));

				double oldSize = oldPixelData.GetFrame(0).Size;
				double newSize = newPixelData.GetFrame(0).Size;
				string ratio = String.Format("{0:0.000}", oldSize / newSize);
				newDataset.Add(new DicomDecimalString(DicomTag.LossyImageCompressionRatio, ratio));
			}

			ProcessOverlays(oldDataset, newDataset);

			newDataset.RecalculateGroupLengths(false);

			return newDataset;
		}
Exemplo n.º 24
0
		private DicomDataset Decode(DicomDataset oldDataset, DicomTransferSyntax outSyntax, IDicomCodec codec, DicomCodecParams parameters) {
			DicomPixelData oldPixelData = DicomPixelData.Create(oldDataset, false);

			DicomDataset newDataset = oldDataset.Clone();
			newDataset.InternalTransferSyntax = outSyntax;
			DicomPixelData newPixelData = DicomPixelData.Create(newDataset, true);

			codec.Decode(oldPixelData, newPixelData, parameters);

			ProcessOverlays(oldDataset, newDataset);

			newDataset.RecalculateGroupLengths(false);

			return newDataset;
		}
Exemplo n.º 25
0
        private DicomDataset Decode(DicomDataset oldDataset, DicomTransferSyntax outSyntax, IDicomCodec codec, DicomCodecParams parameters)
        {
            DicomPixelData oldPixelData = DicomPixelData.Create(oldDataset, false);

            DicomDataset newDataset = oldDataset.Clone();

            newDataset.InternalTransferSyntax = outSyntax;
            DicomPixelData newPixelData = DicomPixelData.Create(newDataset, true);

            codec.Decode(oldPixelData, newPixelData, parameters);

            newDataset.RecalculateGroupLengths(false);

            return(newDataset);
        }
Exemplo n.º 26
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)
                    {
                        Platform.Log(LogLevel.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);
                }

                DicomAttribute 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);
                    var rawPixelData = (byte[])pixelData.Values;

                    //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(rawPixelData, pd.BitsAllocated, pd.BitsStored, pd.HighBit))
                    {
                        var newHighBit = (ushort)(pd.HighBit - pd.LowBit);
                        Platform.Log(LogLevel.Debug, "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(rawPixelData, pd.BitsAllocated, pd.BitsStored, pd.HighBit))
                    {
                        Platform.Log(LogLevel.Debug, "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.

                    DicomAttribute attribute;
                    if (DataSet.TryGetAttribute(DicomTags.Rows, out attribute) && !attribute.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 attribute) && !attribute.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)
                    {
                        Platform.Log(LogLevel.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);
                    }
                }

                DicomAttribute 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.
                    DicomAttribute attribute;
                    if (DataSet.TryGetAttribute(DicomTags.Rows, out attribute) && !attribute.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 attribute) && !attribute.IsNull)
                    {
                        throw new DicomCodecException("Suspect Sop appears to be an image (Columns is non-empty), but has no pixel data.");
                    }

                    TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;
                }
            }
        }
Exemplo n.º 27
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)
                    {
                        Platform.Log(LogLevel.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);

            	DicomAttribute 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.");

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

					// Set before compression, the codecs need it.
					fragments.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.

					DicomAttribute attribute;
					if (DataSet.TryGetAttribute(DicomTags.Rows, out attribute) && !attribute.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 attribute) && !attribute.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)
                    {
                        Platform.Log(LogLevel.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);
                }

				DicomAttribute 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.");

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

                    codec.Decode(fragments, pd, parameters);

                    pd.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.
					DicomAttribute attribute;
					if (DataSet.TryGetAttribute(DicomTags.Rows, out attribute) && !attribute.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 attribute) && !attribute.IsNull)
						throw new DicomCodecException("Suspect Sop appears to be an image (Columns is non-empty), but has no pixel data.");
					
					TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;
                }
            }
        }