예제 #1
0
        /// <summary>
        /// Returns a newly created  instance of a stream byte source class.
        /// The actual class depends on the stream capabilities.
        /// </summary>
        /// <param name="stream">Stream to read from.</param>
        /// <param name="readOption">Defines the handling of large tags.</param>
        /// <param name="largeObjectSize">Custom limit of what are large values and what are not.
        /// If 0 is passed, then the default of 64k is used.</param>
        public static IByteSource Create(Stream stream, FileReadOption readOption = FileReadOption.Default,
                                         int largeObjectSize = 0)
        {
            if (stream.CanSeek)
            {
                return(new StreamByteSource(stream, readOption, largeObjectSize));
            }

            return(new UnseekableStreamByteSource(stream, readOption, largeObjectSize));
        }
예제 #2
0
 //=======================================
 //関数
 //=======================================
 /// <summary>
 ///
 /// </summary>
 public FileBuilder(
     IFileWriter <T> writer, IFileParser <T> parser,
     FileReadOption readOption   = FileReadOption.None,
     FileWriteOption writeOption = FileWriteOption.None
     )
 {
     Writer      = writer;
     Parser      = parser;
     ReadOption  = readOption;
     WriteOption = writeOption;
 }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of <see cref="StreamByteSource"/>.
        /// </summary>
        /// <param name="stream">Stream to read from.</param>
        public StreamByteSource(Stream stream, FileReadOption readOption = FileReadOption.Default)
        {
            _stream = stream;
            _endian = Endian.LocalMachine;
            _reader = EndianBinaryReader.Create(_stream, _endian);
            _mark   = 0;
            // here the mapping of the default option is applied - may be extracted into some GlobalSettings class or similar
            _readOption = (readOption == FileReadOption.Default) ? FileReadOption.ReadLargeOnDemand : readOption;

            LargeObjectSize = 64 * 1024;

            _milestones = new Stack <long>();
            _lock       = new object();
        }
예제 #4
0
        /// <summary>
        /// Initializes an instance of <see cref="FileByteSource"/>.
        /// </summary>
        /// <param name="file">File to read from.</param>
        /// <param name="readOption">Option how to deal with large values, if they should be loaded directly into memory or lazy loaded on demand</param>
        /// <param name="largeObjectSize">Custom limit of what are large values and what are not. If 0 is passend, then the default of 64k is used.</param>
        public FileByteSource(IFileReference file, FileReadOption readOption, int largeObjectSize)
        {
            _file   = file;
            _stream = _file.OpenRead();
            _endian = Endian.LocalMachine;
            _reader = EndianBinaryReader.Create(_stream, _endian);
            Marker  = 0;
            // here the mapping of the default option is applied - may be extracted into some GlobalSettings class or similar
            _readOption = (readOption == FileReadOption.Default) ? FileReadOption.ReadLargeOnDemand : readOption;

            LargeObjectSize = largeObjectSize <= 0 ? 64 * 1024 : largeObjectSize;

            _milestones = new Stack <long>();
            _lock       = new object();
            _disposed   = false;
        }
예제 #5
0
        /// <summary>
        /// Interrogates directory tree for dicom files and produces series info and individual file info
        /// </summary>
        /// <param name="options"></param>
        /// <param name="fileSystemOptions"></param>
        /// <param name="seriesMessageProducerModel"></param>
        /// <param name="fileMessageProducerModel"></param>
        /// <param name="fs">File system to use</param>
        public TagReaderBase(DicomTagReaderOptions options, FileSystemOptions fileSystemOptions, IProducerModel seriesMessageProducerModel, IProducerModel fileMessageProducerModel, IFileSystem fs)
        {
            Logger = LogManager.GetLogger(GetType().Name);

            _filesystemRoot     = fileSystemOptions.FileSystemRoot;
            NackIfAnyFileErrors = options.NackIfAnyFileErrors;
            _searchPattern      = fileSystemOptions.DicomSearchPattern;

            _fileReadOption = options.GetReadOption();

            Logger.Debug($"FileReadOption is: {_fileReadOption}");

            _seriesMessageProducerModel = seriesMessageProducerModel;
            _fileMessageProducerModel   = fileMessageProducerModel;
            _fs = fs;

            Logger.Info($"Stopwatch implementation - IsHighResolution: {Stopwatch.IsHighResolution}. Frequency: {Stopwatch.Frequency} ticks/s");
        }
        /// <summary>
        /// Initializes a new instance of <see cref="UnseekableStreamByteSource"/>.
        /// </summary>
        /// <param name="stream">Stream to read from.</param>
        /// <param name="readOption">Defines the handling of large tags.</param>
        /// <param name="largeObjectSize">Custom limit of what are large values and what are not.
        /// If 0 is passed, then the default of 64k is used.</param>
        public UnseekableStreamByteSource(Stream stream, FileReadOption readOption = FileReadOption.Default, int largeObjectSize = 0)
        {
            if (readOption == FileReadOption.Default || readOption == FileReadOption.ReadLargeOnDemand)
            {
                var logger = Setup.ServiceProvider.GetRequiredService <ILogManager>().GetLogger("FellowOakDicom.IO");
                logger.Warn("Reading large files on demand is not possible with unseekable streams, reading all tags immediately instead.");
                readOption = FileReadOption.ReadAll;
            }

            _byteSource   = new StreamByteSource(stream, readOption, largeObjectSize);
            _buffer       = new MemoryStream();
            _bufferReader = EndianBinaryReader.Create(_buffer, Endian.LocalMachine);
            _bufferWriter = EndianBinaryWriter.Create(_buffer, Endian.LocalMachine);
            _bufferState  = BufferState.Unused;
            // we cannot use the milestones of the stream byte source, as these don't
            // account for the buffer
            _milestones = new Stack <long>();
        }
예제 #7
0
        /// <summary>
        /// Reads the specified filename and returns a DicomFile object.  Note that the values for large
        /// DICOM elements (e.g. PixelData) are read in "on demand" to conserve memory.  Large DICOM elements
        /// are determined by their size in bytes - see the default value for this in the FileByteSource._largeObjectSize
        /// </summary>
        /// <param name="fileName">The filename of the DICOM file</param>
        /// <param name="fallbackEncoding">Encoding to apply when attribute Specific Character Set is not available.</param>
        /// <param name="stop">Stop criterion in dataset.</param>
        /// <returns>DicomFile instance</returns>
        public static DicomFile Open(string fileName, Encoding fallbackEncoding, Func <ParseState, bool> stop = null, FileReadOption readOption = FileReadOption.Default)
        {
            if (fallbackEncoding == null)
            {
                throw new ArgumentNullException(nameof(fallbackEncoding));
            }
            DicomFile df = new DicomFile();

            try
            {
                df.File = IOManager.CreateFileReference(fileName);

                using (var source = new FileByteSource(df.File, readOption))
                {
                    var reader = new DicomFileReader();
                    var result = reader.Read(
                        source,
                        new DicomDatasetReaderObserver(df.FileMetaInfo),
                        new DicomDatasetReaderObserver(df.Dataset, fallbackEncoding),
                        stop);

                    if (result == DicomReaderResult.Processing)
                    {
                        throw new DicomFileException(df, "Invalid read return state: {state}", result);
                    }
                    if (result == DicomReaderResult.Error)
                    {
                        return(null);
                    }
                    df.IsPartial = result == DicomReaderResult.Stopped || result == DicomReaderResult.Suspended;

                    df.Format = reader.FileFormat;

                    df.Dataset.InternalTransferSyntax = reader.Syntax;

                    return(df);
                }
            }
            catch (Exception e)
            {
                throw new DicomFileException(df, e.Message, e);
            }
        }
예제 #8
0
 /// <summary>
 /// Reads the specified filename and returns a DicomFile object.  Note that the values for large
 /// DICOM elements (e.g. PixelData) are read in "on demand" to conserve memory.  Large DICOM elements
 /// are determined by their size in bytes - see the default value for this in the FileByteSource._largeObjectSize
 /// </summary>
 /// <param name="fileName">The filename of the DICOM file</param>
 /// <param name="readOption">An option how to deal with large dicom tags like pixel data.</param>
 /// <returns>DicomFile instance</returns>
 public static DicomFile Open(string fileName, FileReadOption readOption = FileReadOption.Default)
 {
     return(Open(fileName, DicomEncoding.Default, readOption: readOption));
 }
예제 #9
0
 /// <summary>
 /// Read a DICOM file from stream.
 /// </summary>
 /// <param name="stream">Stream to read.</param>
 /// <param name="readOption">The option how to deal with large DICOM tags like pixel data.</param>
 /// <returns>Read <see cref="DicomFile"/>.</returns>
 public static DicomFile Open(Stream stream, FileReadOption readOption = FileReadOption.Default)
 {
     return(Open(stream, DicomEncoding.Default, readOption: readOption));
 }
예제 #10
0
        /// <summary>
        /// Reads the specified file and returns a DicomFile object.  Note that the values for large
        /// DICOM elements (e.g. PixelData) are read in "on demand" to conserve memory.  Large DICOM elements
        /// are determined by their size in bytes - see the default value for this in the FileByteSource._largeObjectSize
        /// </summary>
        /// <param name="file">The file reference of the DICOM file</param>
        /// <param name="fallbackEncoding">Encoding to apply when attribute Specific Character Set is not available.</param>
        /// <param name="readOption">Option how to deal with large values, if they should be loaded directly into memory or lazy loaded on demand</param>
        /// <param name="largeObjectSize">Custom limit of what are large values and what are not. If 0 is passend, then the default of 64k is used.</param>
        /// <returns>DicomFile instance</returns>
        internal static DicomFile Open(IFileReference file, Encoding fallbackEncoding, FileReadOption readOption = FileReadOption.Default, int largeObjectSize = 0)
        {
            if (fallbackEncoding == null)
            {
                throw new ArgumentNullException(nameof(fallbackEncoding));
            }
            var df = new DicomFile();

            try
            {
                df.File = file;

                using var source      = new FileByteSource(file, readOption, largeObjectSize);
                using var unvalidated = new UnvalidatedScope(df.Dataset);
                var reader = new DicomFileReader();
                var result = reader.Read(
                    source,
                    new DicomDatasetReaderObserver(df.FileMetaInfo),
                    new DicomDatasetReaderObserver(df.Dataset, fallbackEncoding));

                HandleOpenError(df, result);

                df.IsPartial = result == DicomReaderResult.Stopped || result == DicomReaderResult.Suspended;
                df.Format    = reader.FileFormat;
                df.Dataset.InternalTransferSyntax = reader.Syntax;

                return(df);
            }
            catch (Exception e)
            {
                throw new DicomFileException(df, e.Message, e);
            }
        }
예제 #11
0
 /// <summary>
 /// Asynchronously read a DICOM file from stream.
 /// </summary>
 /// <param name="stream">Stream to read.</param>
 /// <param name="readOption">The option how to deal with large DICOM tags like pixel data.</param>
 /// <param name="largeObjectSize">Custom limit of what are large values and what are not. If 0 is passend, then the default of 64k is used.</param>
 /// <returns>Awaitable <see cref="DicomFile"/> instance.</returns>
 public static Task <DicomFile> OpenAsync(Stream stream, FileReadOption readOption = FileReadOption.Default, int largeObjectSize = 0)
 => OpenAsync(stream, DicomEncoding.Default, readOption: readOption, largeObjectSize: largeObjectSize);
예제 #12
0
        /// <summary>
        /// Asynchronously read a DICOM file from stream.
        /// </summary>
        /// <param name="stream">Stream to read.</param>
        /// <param name="fallbackEncoding">Encoding to use if encoding cannot be obtained from DICOM file.</param>
        /// <param name="stop">Stop criterion in dataset.</param>
        /// <param name="readOption">The option how to deal with large DICOM tags like pixel data.</param>
        /// <param name="largeObjectSize">Custom limit of what are large values and what are not. If 0 is passend, then the default of 64k is used.</param>
        /// <returns>Awaitable <see cref="DicomFile"/> instance.</returns>
        public static async Task <DicomFile> OpenAsync(Stream stream, Encoding fallbackEncoding, Func <ParseState, bool> stop = null, FileReadOption readOption = FileReadOption.Default, int largeObjectSize = 0)
        {
            if (fallbackEncoding == null)
            {
                throw new ArgumentNullException(nameof(fallbackEncoding));
            }
            var df = new DicomFile();

            try
            {
                var source = StreamByteSourceFactory.Create(stream, readOption, largeObjectSize);
                using var unvalidated = new UnvalidatedScope(df.Dataset);
                var reader = new DicomFileReader();
                var result =
                    await
                    reader.ReadAsync(
                        source,
                        new DicomDatasetReaderObserver(df.FileMetaInfo),
                        new DicomDatasetReaderObserver(df.Dataset, fallbackEncoding),
                        stop).ConfigureAwait(false);

                HandleOpenError(df, result);

                df.IsPartial = result == DicomReaderResult.Stopped || result == DicomReaderResult.Suspended;
                df.Format    = reader.FileFormat;
                df.Dataset.InternalTransferSyntax = reader.Syntax;

                return(df);
            }
            catch (Exception e)
            {
                throw new DicomFileException(df, e.Message, e);
            }
        }
예제 #13
0
 /// <summary>
 /// Reads the specified filename and returns a DicomFile object.  Note that the values for large
 /// DICOM elements (e.g. PixelData) are read in "on demand" to conserve memory.  Large DICOM elements
 /// are determined by their size in bytes - see the default value for this in the FileByteSource._largeObjectSize
 /// </summary>
 /// <param name="fileName">The filename of the DICOM file</param>
 /// <param name="readOption">An option how to deal with large dicom tags like pixel data.</param>
 /// <param name="largeObjectSize">Custom limit of what are large values and what are not. If 0 is passend, then the default of 64k is used.</param>
 /// <returns>DicomFile instance</returns>
 public static DicomFile Open(string fileName, FileReadOption readOption = FileReadOption.Default, int largeObjectSize = 0)
 => Open(fileName, DicomEncoding.Default, readOption: readOption, largeObjectSize: largeObjectSize);
예제 #14
0
 /// <summary>
 /// Asynchronously reads the specified filename and returns a DicomFile object.  Note that the values for large
 /// DICOM elements (e.g. PixelData) are read in "on demand" to conserve memory.  Large DICOM elements
 /// are determined by their size in bytes - see the default value for this in the FileByteSource._largeObjectSize
 /// </summary>
 /// <param name="fileName">The filename of the DICOM file</param>
 /// <param name="readOption">The option how to deal with large dicom tags like pixel data.</param>
 /// <returns>Awaitable <see cref="DicomFile"/> instance.</returns>
 public static Task <DicomFile> OpenAsync(string fileName, FileReadOption readOption = FileReadOption.Default)
 {
     return(OpenAsync(fileName, DicomEncoding.Default, readOption: readOption));
 }
예제 #15
0
        /// <summary>
        /// Reads the specified file and returns a DicomFile object.  Note that the values for large
        /// DICOM elements (e.g. PixelData) are read in "on demand" to conserve memory.  Large DICOM elements
        /// are determined by their size in bytes - see the default value for this in the FileByteSource._largeObjectSize
        /// </summary>
        /// <param name="file">The file reference of the DICOM file</param>
        /// <param name="fallbackEncoding">Encoding to apply when attribute Specific Character Set is not available.</param>
        /// <returns>DicomFile instance</returns>
        internal static DicomFile Open(IFileReference file, Encoding fallbackEncoding, FileReadOption readOption = FileReadOption.Default)
        {
            if (fallbackEncoding == null)
            {
                throw new ArgumentNullException(nameof(fallbackEncoding));
            }
            DicomFile df = new DicomFile();

            try
            {
                df.File = file;

                using (var source = new FileByteSource(file, readOption))
                    using (var unvalidated = new UnvalidatedScope(df.Dataset))
                    {
                        DicomFileReader reader = new DicomFileReader();
                        var             result = reader.Read(
                            source,
                            new DicomDatasetReaderObserver(df.FileMetaInfo),
                            new DicomDatasetReaderObserver(df.Dataset, fallbackEncoding));

                        if (result == DicomReaderResult.Processing)
                        {
                            throw new DicomFileException(df, $"Invalid read return state: {result}");
                        }
                        if (result == DicomReaderResult.Error)
                        {
                            return(null);
                        }
                        df.IsPartial = result == DicomReaderResult.Stopped || result == DicomReaderResult.Suspended;

                        df.Format = reader.FileFormat;

                        df.Dataset.InternalTransferSyntax = reader.Syntax;

                        return(df);
                    }
            }
            catch (Exception e)
            {
                throw new DicomFileException(df, e.Message, e);
            }
        }
예제 #16
0
        /// <summary>
        /// Asynchronously read a DICOM file from stream.
        /// </summary>
        /// <param name="stream">Stream to read.</param>
        /// <param name="fallbackEncoding">Encoding to use if encoding cannot be obtained from DICOM file.</param>
        /// <param name="stop">Stop criterion in dataset.</param>
        /// <param name="readOption">The option how to deal with large DICOM tags like pixel data.</param>
        /// <returns>Awaitable <see cref="DicomFile"/> instance.</returns>
        public static async Task <DicomFile> OpenAsync(Stream stream, Encoding fallbackEncoding, Func <ParseState, bool> stop = null, FileReadOption readOption = FileReadOption.Default)
        {
            if (fallbackEncoding == null)
            {
                throw new ArgumentNullException(nameof(fallbackEncoding));
            }
            var df = new DicomFile();

            try
            {
                var source = new StreamByteSource(stream, readOption);
                using (var unvalidated = new UnvalidatedScope(df.Dataset))
                {
                    var reader = new DicomFileReader();
                    var result =
                        await
                        reader.ReadAsync(
                            source,
                            new DicomDatasetReaderObserver(df.FileMetaInfo),
                            new DicomDatasetReaderObserver(df.Dataset, fallbackEncoding),
                            stop).ConfigureAwait(false);

                    if (result == DicomReaderResult.Processing)
                    {
                        throw new DicomFileException(df, $"Invalid read return state: {result}");
                    }
                    if (result == DicomReaderResult.Error)
                    {
                        return(null);
                    }
                    df.IsPartial = result == DicomReaderResult.Stopped || result == DicomReaderResult.Suspended;

                    df.Format = reader.FileFormat;
                    df.Dataset.InternalTransferSyntax = reader.Syntax;

                    return(df);
                }
            }
            catch (Exception e)
            {
                throw new DicomFileException(df, e.Message, e);
            }
        }
예제 #17
0
 /// <summary>
 /// Asynchronously read a DICOM file from stream.
 /// </summary>
 /// <param name="stream">Stream to read.</param>
 /// <param name="readOption">The option how to deal with large DICOM tags like pixel data.</param>
 /// <returns>Awaitable <see cref="DicomFile"/> instance.</returns>
 public static Task <DicomFile> OpenAsync(Stream stream, FileReadOption readOption = FileReadOption.Default)
 {
     return(OpenAsync(stream, DicomEncoding.Default, readOption: readOption));
 }