public static DicomFile Open(Stream stream, Encoding fallbackEncoding) { if (fallbackEncoding == null) { throw new ArgumentNullException("fallbackEncoding"); } var df = new DicomFile(); try { var source = new StreamByteSource(stream); var reader = new DicomFileReader(); reader.Read(source, new DicomDatasetReaderObserver(df.FileMetaInfo), new DicomDatasetReaderObserver(df.Dataset, fallbackEncoding)); df.Format = reader.FileFormat; df.Dataset.InternalTransferSyntax = reader.Syntax; return(df); } catch (Exception e) { throw new DicomFileException(df, e.Message, e); } }
/// <summary> /// Asynchronously read DICOM Directory from stream. /// </summary> /// <param name="stream">Stream to read.</param> /// <param name="fallbackEncoding">Encoding to apply if it cannot be identified from DICOM directory.</param> /// <param name="stop">Stop criterion in dataset.</param> /// <returns>Awaitable <see cref="DicomDirectory"/> instance.</returns> public static new async Task <DicomDirectory> OpenAsync(Stream stream, Encoding fallbackEncoding, Func <ParseState, bool> stop = null) { if (fallbackEncoding == null) { throw new ArgumentNullException(nameof(fallbackEncoding)); } var df = new DicomDirectory(); try { var source = new StreamByteSource(stream); var reader = new DicomFileReader(); var dirObserver = new DicomDirectoryReaderObserver(df.Dataset); var result = await reader.ReadAsync( source, new DicomDatasetReaderObserver(df.FileMetaInfo), new DicomReaderMultiObserver( new DicomDatasetReaderObserver(df.Dataset, fallbackEncoding), dirObserver), stop).ConfigureAwait(false); return(FinalizeDicomDirectoryLoad(df, reader, dirObserver, result)); } catch (Exception e) { throw new DicomFileException(df, e.Message, e); } }
public void Read_ValidExplicitVRSequence_YieldsSuccess(byte[] bytes) { var stream = new MemoryStream(bytes); var source = new StreamByteSource(stream); var reader = new DicomReader { IsExplicitVR = true }; var observer = new MockObserver(); var result = reader.Read(source, observer); Assert.Equal(DicomReaderResult.Success, result); }
public void EndRead_ValidSource_ReturnsSuccess() { using (var stream = File.OpenRead(@".\Test Data\CT1_J2KI")) { var source = new StreamByteSource(stream); var reader = new DicomFileReader(); const DicomReaderResult expected = DicomReaderResult.Success; var actual = reader.EndRead( reader.BeginRead(source, new MockObserver(), new MockObserver(), null, null)); Assert.Equal(expected, actual); } }
public void BeginRead_ValidExplicitVRData_YieldsSuccess(DicomTag tag, DicomVR vr, string data, byte[] bytes) { var stream = new MemoryStream(bytes); var source = new StreamByteSource(stream); var reader = new DicomReader { IsExplicitVR = true }; var observer = new LastElementObserver(); var result = reader.EndRead(reader.BeginRead(source, observer, null, null, null)); Assert.Equal(DicomReaderResult.Success, result); Assert.Equal(tag, observer.Tag); Assert.Equal(vr, observer.VR); Assert.Equal(data, observer.Data); }
public void Read_CompressedImage_RecognizeTransferSyntax() { using var stream = File.OpenRead(TestData.Resolve("CT1_J2KI")); var source = new StreamByteSource(stream); var reader = new DicomFileReader(); var fileMetaInfo = new DicomFileMetaInformation(); var dataset = new DicomDataset(); reader.Read( source, new DicomDatasetReaderObserver(fileMetaInfo), new DicomDatasetReaderObserver(dataset)); var expected = DicomTransferSyntax.JPEG2000Lossy; var actual = reader.Syntax; Assert.Equal(expected, actual); }
/// <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); } }
public void Read_CompressedImage_RecognizeTransferSyntax() { using (var stream = File.OpenRead(@".\Test Data\CT1_J2KI")) { var source = new StreamByteSource(stream); var reader = new DicomFileReader(); var fileMetaInfo = new DicomFileMetaInformation(); var dataset = new DicomDataset(); reader.Read( source, new DicomDatasetReaderObserver(fileMetaInfo), new DicomDatasetReaderObserver(dataset)); var expected = DicomTransferSyntax.JPEG2000Lossy; var actual = reader.Syntax; Assert.Equal(expected, actual); } }
public static DicomFile Open(Stream stream) { var df = new DicomFile(); try { var source = new StreamByteSource(stream); var reader = new DicomFileReader(); reader.Read(source, new DicomDatasetReaderObserver(df.FileMetaInfo), new DicomDatasetReaderObserver(df.Dataset)); df.Format = reader.FileFormat; df.Dataset.InternalTransferSyntax = reader.Syntax; return(df); } catch (Exception e) { throw new DicomFileException(df, e.Message, e); } }
public async Task ReadAsync_CompressedImage_RecognizeTransferSyntax() { using (var stream = File.OpenRead(@".\Test Data\CT1_J2KI")) { var source = new StreamByteSource(stream); var reader = new DicomFileReader(); var fileMetaInfo = new DicomFileMetaInformation(); var dataset = new DicomDataset(); await reader.ReadAsync( source, new DicomDatasetReaderObserver(fileMetaInfo), new DicomDatasetReaderObserver(dataset)); var expected = DicomTransferSyntax.JPEG2000Lossy; var actual = reader.Syntax; Assert.Equal(expected, actual); } }
public void Read_ValidSource_ReturnsSuccess() { using var stream = File.OpenRead(TestData.Resolve("CT1_J2KI")); var source = new StreamByteSource(stream); var reader = new DicomFileReader(); var fileMetaInfo = new DicomFileMetaInformation(); var dataset = new DicomDataset(); const DicomReaderResult expected = DicomReaderResult.Success; var actual = reader.Read( source, new DicomDatasetReaderObserver(fileMetaInfo), new DicomDatasetReaderObserver(dataset)); Assert.Equal(expected, actual); var modality = dataset.GetString(DicomTag.Modality); Assert.Equal("CT", modality); }
/// <summary> /// 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> /// <returns>Read <see cref="DicomFile"/>.</returns> public static DicomFile Open(Stream stream, Encoding fallbackEncoding, Func <ParseState, bool> stop = null) { if (fallbackEncoding == null) { throw new ArgumentNullException("fallbackEncoding"); } var df = new DicomFile(); try { var source = new StreamByteSource(stream); 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); } }
public void Read_ValidSource_ReturnsSuccess() { using (var stream = File.OpenRead(@".\Test Data\CT1_J2KI")) { var source = new StreamByteSource(stream); var reader = new DicomFileReader(); var fileMetaInfo = new DicomFileMetaInformation(); var dataset = new DicomDataset(); const DicomReaderResult expected = DicomReaderResult.Success; var actual = reader.Read( source, new DicomDatasetReaderObserver(fileMetaInfo), new DicomDatasetReaderObserver(dataset)); Assert.Equal(expected, actual); var modality = dataset.Get<string>(DicomTag.Modality); Assert.Equal("CT", modality); } }
private void ProcessPDataTF(object state) { var pdu = (PDataTF)state; try { foreach (var pdv in pdu.PDVs) { if (_dimse == null) { // create stream for receiving command if (_dimseStream == null) { _dimseStream = new MemoryStream(); } } else { // create stream for receiving dataset if (_dimseStream == null) { if (_dimse.Type == DicomCommandField.CStoreRequest) { var pc = Association.PresentationContexts.FirstOrDefault(x => x.ID == pdv.PCID); var file = new DicomFile(); file.FileMetaInfo.MediaStorageSOPClassUID = pc.AbstractSyntax; file.FileMetaInfo.MediaStorageSOPInstanceUID = _dimse.Command.Get <DicomUID>(DicomTag.AffectedSOPInstanceUID); file.FileMetaInfo.TransferSyntax = pc.AcceptedTransferSyntax; file.FileMetaInfo.ImplementationClassUID = Association.RemoteImplemetationClassUID; file.FileMetaInfo.ImplementationVersionName = Association.RemoteImplementationVersion; file.FileMetaInfo.SourceApplicationEntityTitle = Association.CallingAE; _dimseStream = CreateCStoreReceiveStream(file); } else { _dimseStream = new MemoryStream(); } } } _dimseStream.Write(pdv.Value, 0, pdv.Value.Length); if (pdv.IsLastFragment) { if (pdv.IsCommand) { _dimseStream.Seek(0, SeekOrigin.Begin); var command = new DicomDataset(); var reader = new DicomReader(); reader.IsExplicitVR = false; reader.Read(new StreamByteSource(_dimseStream), new DicomDatasetReaderObserver(command)); _dimseStream = null; var type = command.Get <DicomCommandField>(DicomTag.CommandField); switch (type) { case DicomCommandField.CStoreRequest: _dimse = new DicomCStoreRequest(command); break; case DicomCommandField.CStoreResponse: _dimse = new DicomCStoreResponse(command); break; case DicomCommandField.CFindRequest: _dimse = new DicomCFindRequest(command); break; case DicomCommandField.CFindResponse: _dimse = new DicomCFindResponse(command); break; case DicomCommandField.CMoveRequest: _dimse = new DicomCMoveRequest(command); break; case DicomCommandField.CMoveResponse: _dimse = new DicomCMoveResponse(command); break; case DicomCommandField.CEchoRequest: _dimse = new DicomCEchoRequest(command); break; case DicomCommandField.CEchoResponse: _dimse = new DicomCEchoResponse(command); break; case DicomCommandField.NActionRequest: _dimse = new DicomNActionRequest(command); break; case DicomCommandField.NActionResponse: _dimse = new DicomNActionResponse(command); break; case DicomCommandField.NCreateRequest: _dimse = new DicomNCreateRequest(command); break; case DicomCommandField.NCreateResponse: _dimse = new DicomNCreateResponse(command); break; case DicomCommandField.NDeleteRequest: _dimse = new DicomNDeleteRequest(command); break; case DicomCommandField.NDeleteResponse: _dimse = new DicomNDeleteResponse(command); break; case DicomCommandField.NEventReportRequest: _dimse = new DicomNEventReportRequest(command); break; case DicomCommandField.NEventReportResponse: _dimse = new DicomNEventReportResponse(command); break; case DicomCommandField.NGetRequest: _dimse = new DicomNGetRequest(command); break; case DicomCommandField.NGetResponse: _dimse = new DicomNGetResponse(command); break; case DicomCommandField.NSetRequest: _dimse = new DicomNSetRequest(command); break; case DicomCommandField.NSetResponse: _dimse = new DicomNSetResponse(command); break; default: _dimse = new DicomMessage(command); break; } _dimse.PresentationContext = Association.PresentationContexts.FirstOrDefault(x => x.ID == pdv.PCID); if (!_dimse.HasDataset) { if (DicomMessage.IsRequest(_dimse.Type)) { ThreadPool.QueueUserWorkItem(PerformDimseCallback, _dimse); } else { _processQueue.Queue((_dimse as DicomResponse).RequestMessageID, PerformDimseCallback, _dimse); } _dimse = null; return; } } else { if (_dimse.Type != DicomCommandField.CStoreRequest) { _dimseStream.Seek(0, SeekOrigin.Begin); var pc = Association.PresentationContexts.FirstOrDefault(x => x.ID == pdv.PCID); _dimse.Dataset = new DicomDataset(); _dimse.Dataset.InternalTransferSyntax = pc.AcceptedTransferSyntax; var source = new StreamByteSource(_dimseStream); source.Endian = pc.AcceptedTransferSyntax.Endian; var reader = new DicomReader(); reader.IsExplicitVR = pc.AcceptedTransferSyntax.IsExplicitVR; reader.Read(source, new DicomDatasetReaderObserver(_dimse.Dataset)); _dimseStream = null; } else { var request = _dimse as DicomCStoreRequest; try { var dicomFile = GetCStoreDicomFile(); _dimseStream = null; _isTempFile = false; // NOTE: dicomFile will be valid with the default implementation of CreateCStoreReceiveStream() and // GetCStoreDicomFile(), but can be null if a child class overrides either method and changes behavior. // See documentation on CreateCStoreReceiveStream() and GetCStoreDicomFile() for information about why // this might be desired. request.File = dicomFile; if (request.File != null) { request.Dataset = request.File.Dataset; } } catch (Exception e) { var fileName = ""; if (_dimseStream is FileStream) { fileName = (_dimseStream as FileStream).Name; } // failed to parse received DICOM file; send error response instead of aborting connection SendResponse(new DicomCStoreResponse(request, new DicomStatus(DicomStatus.ProcessingFailure, e.Message))); Logger.Error("Error parsing C-Store dataset: " + e.ToString()); (this as IDicomCStoreProvider).OnCStoreRequestException(fileName, e); return; } } if (DicomMessage.IsRequest(_dimse.Type)) { ThreadPool.QueueUserWorkItem(PerformDimseCallback, _dimse); } else { _processQueue.Queue((_dimse as DicomResponse).RequestMessageID, PerformDimseCallback, _dimse); } _dimse = null; } } } } catch (Exception e) { SendAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified); Logger.Error("Exception processing P-Data-TF PDU: " + e.ToString()); } finally { SendNextMessage(); } }
private void ProcessPDataTF(PDataTF pdu) { try { foreach (var pdv in pdu.PDVs) { if (_dimse == null) { // create stream for receiving command if (_dimseStream == null) { _dimseStream = new MemoryStream(); } } else { // create stream for receiving dataset if (_dimseStream == null) { if (_dimse.Type == DicomCommandField.CStoreRequest) { var pc = Association.PresentationContexts.FirstOrDefault(x => x.ID == pdv.PCID); var file = new DicomFile(); file.FileMetaInfo.MediaStorageSOPClassUID = pc.AbstractSyntax; file.FileMetaInfo.MediaStorageSOPInstanceUID = _dimse.Command.Get <DicomUID>(DicomTag.AffectedSOPInstanceUID); file.FileMetaInfo.TransferSyntax = pc.AcceptedTransferSyntax; file.FileMetaInfo.ImplementationClassUID = Association.RemoteImplemetationClassUID; file.FileMetaInfo.ImplementationVersionName = Association.RemoteImplementationVersion; file.FileMetaInfo.SourceApplicationEntityTitle = Association.CallingAE; string fileName; if (this is IDicomCStoreProvider) { fileName = (this as IDicomCStoreProvider).GetTempFileName(file.FileMetaInfo.MediaStorageSOPInstanceUID); } else { throw new DicomNetworkException("C-Store SCP not implemented"); } file.Save(fileName); _dimseStream = File.OpenWrite(fileName); _dimseStream.Seek(0, SeekOrigin.End); } else { _dimseStream = new MemoryStream(); } } } _dimseStream.Write(pdv.Value, 0, pdv.Value.Length); if (pdv.IsLastFragment) { if (pdv.IsCommand) { _dimseStream.Seek(0, SeekOrigin.Begin); var command = new DicomDataset(); var reader = new DicomReader(); reader.IsExplicitVR = false; reader.Read(new StreamByteSource(_dimseStream), new DicomDatasetReaderObserver(command)); _dimseStream = null; var type = command.Get <DicomCommandField>(DicomTag.CommandField); switch (type) { case DicomCommandField.CStoreRequest: _dimse = new DicomCStoreRequest(command); break; case DicomCommandField.CStoreResponse: _dimse = new DicomCStoreResponse(command); break; case DicomCommandField.CFindRequest: _dimse = new DicomCFindRequest(command); break; case DicomCommandField.CFindResponse: _dimse = new DicomCFindResponse(command); break; case DicomCommandField.CMoveRequest: _dimse = new DicomCMoveRequest(command); break; case DicomCommandField.CMoveResponse: _dimse = new DicomCMoveResponse(command); break; case DicomCommandField.CEchoRequest: _dimse = new DicomCEchoRequest(command); break; case DicomCommandField.CEchoResponse: _dimse = new DicomCEchoResponse(command); break; default: _dimse = new DicomMessage(command); break; } if (!_dimse.HasDataset) { ThreadPool.QueueUserWorkItem(PerformDimseCallback, _dimse); _dimse = null; return; } } else { if (_dimse.Type != DicomCommandField.CStoreRequest) { _dimseStream.Seek(0, SeekOrigin.Begin); _dimse.Dataset = new DicomDataset(); _dimse.Dataset.InternalTransferSyntax = _dimse.Command.InternalTransferSyntax; var source = new StreamByteSource(_dimseStream); source.Endian = _dimse.Command.InternalTransferSyntax.Endian; var reader = new DicomReader(); reader.IsExplicitVR = _dimse.Command.InternalTransferSyntax.IsExplicitVR; reader.Read(source, new DicomDatasetReaderObserver(_dimse.Dataset)); _dimseStream = null; } else { var fileName = (_dimseStream as FileStream).Name; _dimseStream.Close(); _dimseStream = null; var request = _dimse as DicomCStoreRequest; request.File = DicomFile.Open(fileName); request.File.File.IsTempFile = true; request.Dataset = request.File.Dataset; } ThreadPool.QueueUserWorkItem(PerformDimseCallback, _dimse); _dimse = null; } } } } catch (Exception e) { SendAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified); Logger.Log(LogLevel.Error, e.ToString()); } finally { SendNextMessage(); } }