diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index a72ab2a2a..d9accd302 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -1,34 +1,35 @@ -using FellowOakDicom.Network; -using FellowOakDicom; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using IRaCIS.Core.SCP.Service; -using IRaCIS.Core.Domain.Models; -using IRaCIS.Core.Infra.EFCore; -using Medallion.Threading; -using IRaCIS.Core.Domain.Share; -using Serilog; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; -using Microsoft.Extensions.Options; -using System.Data; +using FellowOakDicom; using FellowOakDicom.Imaging; -using SharpCompress.Common; -using SixLabors.ImageSharp.Formats.Jpeg; -using IRaCIS.Core.Infrastructure; -using IRaCIS.Core.Infrastructure.Extention; -using Newtonsoft.Json; using FellowOakDicom.Imaging.Codec; using FellowOakDicom.IO.Buffer; -using System.Diagnostics.CodeAnalysis; +using FellowOakDicom.Network; using FellowOakDicom.Network.Client; +using IRaCIS.Core.Domain.Models; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infra.EFCore; +using IRaCIS.Core.Infrastructure; +using IRaCIS.Core.Infrastructure.Extention; +using IRaCIS.Core.SCP.Service; using MassTransit.Futures.Contracts; +using Medallion.Threading; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Microsoft.Identity.Client; +using Newtonsoft.Json; +using Serilog; +using SharpCompress.Common; +using SixLabors.ImageSharp.Formats.Jpeg; +using System; +using System.Collections.Generic; +using System.Data; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; namespace IRaCIS.Core.SCP.Service { @@ -472,209 +473,217 @@ namespace IRaCIS.Core.SCP.Service ms.Position = 0; var dicomFile = DicomFile.Open(ms); - var pixelData = DicomPixelData.Create(dicomFile.Dataset); + var numberOfFrames = dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 1); - if (pixelData != null) + //多帧处理逻辑 + if(numberOfFrames > 1) { - try + //一定要有像素数据才处理 + var pixelData = DicomPixelData.Create(dicomFile.Dataset); + + if (pixelData != null) { - - - - var syntax = pixelData.Syntax; - - // 每个 fragment 固定大小 (64KB 示例,可以自己调整) - int fragmentSize = 20 * 1024; - - var numberOfFrames = dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 1); - - var frag = dicomFile.Dataset.GetDicomItem(DicomTag.PixelData); - - int fragmentCount = frag?.Fragments?.Count() ?? 0; - - var originOffsetTable = frag?.OffsetTable; //有可能没有表,需要自己重建 - - var bot = new List(); - - uint botOffset = 0; - - //需要拆成固定片段的 - if (syntax.IsEncapsulated && fragmentCount == pixelData.NumberOfFrames && numberOfFrames > 1) + try { + Log.Logger.Warning($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE} 开始处理多帧instanceId:{instanceId}"); + + var syntax = pixelData.Syntax; + + // 每个 fragment 固定大小 (64KB 示例,可以自己调整) + int fragmentSize = 20 * 1024; - var newFragments = new DicomOtherByteFragment(DicomTag.PixelData); - #region test - //var newDicomFile = dicomFile.Clone(); + var frag = dicomFile.Dataset.GetDicomItem(DicomTag.PixelData); - //var newDataset = newDicomFile.Dataset; + int fragmentCount = frag?.Fragments?.Count() ?? 0; - //var dstPd = DicomPixelData.Create(newDataset, true); + var originOffsetTable = frag?.OffsetTable; //有可能没有表,需要自己重建 - //for (int i = 0; i < pixelData.NumberOfFrames; i++) - //{ - // var frame = pixelData.GetFrame(i); + var bot = new List(); - // dstPd.AddFrame(frame); + uint botOffset = 0; - // var data = frame.Data; - // int offset = 0; - - // while (offset < data.Length) - // { - // int size = Math.Min(fragmentSize, data.Length - offset); - // var buffer = new byte[size]; - // Buffer.BlockCopy(data, offset, buffer, 0, size); - - // newFragments.Fragments.Add(new MemoryByteBuffer(buffer)); - - // offset += size; - - // } - - - //} - //var newOffsetTable = newDataset.GetDicomItem(DicomTag.PixelData).OffsetTable; - - //newFragments.OffsetTable.AddRange(newOffsetTable.ToArray()); - #endregion - - #region test fo-dicom auto bot - //var newDicomFile = dicomFile.Clone(); - - //var newDataset = newDicomFile.Dataset; - - //var dstPd = DicomPixelData.Create(newDataset, true); - - //for (int i = 0; i < pixelData.NumberOfFrames; i++) - //{ - // var frame = pixelData.GetFrame(i); - - // dstPd.AddFrame(frame); - //} - //var newOffsetTable = newDataset.GetDicomItem(DicomTag.PixelData).OffsetTable; - - //Console.WriteLine(newOffsetTable.ToJsonStr()); - #endregion - - #region 暂时废弃 - - for (int n = 0; n < pixelData.NumberOfFrames; n++) + //需要拆成固定片段的 + if (syntax.IsEncapsulated && fragmentCount == pixelData.NumberOfFrames && numberOfFrames > 1) { - var frameData = pixelData.GetFrame(n); // 获取完整一帧 - var data = frameData.Data; - int offset = 0; - - bot.Add(botOffset); - - botOffset += (uint)data.Length; - while (offset < data.Length) + + var newFragments = new DicomOtherByteFragment(DicomTag.PixelData); + + #region test + //var newDicomFile = dicomFile.Clone(); + + //var newDataset = newDicomFile.Dataset; + + //var dstPd = DicomPixelData.Create(newDataset, true); + + //for (int i = 0; i < pixelData.NumberOfFrames; i++) + //{ + // var frame = pixelData.GetFrame(i); + + // dstPd.AddFrame(frame); + + // var data = frame.Data; + // int offset = 0; + + // while (offset < data.Length) + // { + // int size = Math.Min(fragmentSize, data.Length - offset); + // var buffer = new byte[size]; + // Buffer.BlockCopy(data, offset, buffer, 0, size); + + // newFragments.Fragments.Add(new MemoryByteBuffer(buffer)); + + // offset += size; + + // } + + + //} + //var newOffsetTable = newDataset.GetDicomItem(DicomTag.PixelData).OffsetTable; + + //newFragments.OffsetTable.AddRange(newOffsetTable.ToArray()); + #endregion + + #region test fo-dicom auto bot + //var newDicomFile = dicomFile.Clone(); + + //var newDataset = newDicomFile.Dataset; + + //var dstPd = DicomPixelData.Create(newDataset, true); + + //for (int i = 0; i < pixelData.NumberOfFrames; i++) + //{ + // var frame = pixelData.GetFrame(i); + + // dstPd.AddFrame(frame); + //} + //var newOffsetTable = newDataset.GetDicomItem(DicomTag.PixelData).OffsetTable; + + //Console.WriteLine(newOffsetTable.ToJsonStr()); + #endregion + + #region 最终使用 + + for (int n = 0; n < pixelData.NumberOfFrames; n++) { - botOffset += 8; + var frameData = pixelData.GetFrame(n); // 获取完整一帧 + var data = frameData.Data; + int offset = 0; + + bot.Add(botOffset); + + botOffset += (uint)data.Length; - int size = Math.Min(fragmentSize, data.Length - offset); - var buffer = new byte[size]; - Buffer.BlockCopy(data, offset, buffer, 0, size); + while (offset < data.Length) + { + botOffset += 8; - newFragments.Fragments.Add(new MemoryByteBuffer(buffer)); - offset += size; + int size = Math.Min(fragmentSize, data.Length - offset); + var buffer = new byte[size]; + Buffer.BlockCopy(data, offset, buffer, 0, size); + newFragments.Fragments.Add(new MemoryByteBuffer(buffer)); + + offset += size; + + } } - } - //保留原始偏移表 + //保留原始偏移表 - if (originOffsetTable.Count == pixelData.NumberOfFrames) - { - newFragments.OffsetTable.AddRange(originOffsetTable.ToArray()); - - } - else - { - newFragments.OffsetTable.AddRange(bot.ToArray()); - - //Console.WriteLine(bot.ToJsonStr()); - } - - #endregion - - - dicomFile.Dataset.AddOrUpdate(newFragments); - - - // 重新保存 dicom 到流 - ms.SetLength(0); - - dicomFile.Save(ms); - } - //传递过来的就是拆分的,但是是没有偏移表的,我需要自己创建偏移表,不然生成缩略图失败 - else if (syntax.IsEncapsulated && fragmentCount > pixelData.NumberOfFrames && originOffsetTable.Count == 0) - { - - - - uint offset = 0; - - bot.Add(offset); - - var fistSize = frag.Fragments.FirstOrDefault()?.Size ?? 0; - - //和上一个大小不一样 - var isDiffrentBefore = false; - - uint count = 0; - - // 假设你知道每帧对应的 fragment 数量 - foreach (var frameFragments in frag.Fragments) - { - count++; - - if (frameFragments.Size == fistSize) + if (originOffsetTable.Count == pixelData.NumberOfFrames) { - isDiffrentBefore = false; - // 累加这一帧所有 fragment 的大小 - offset += (uint)frameFragments.Size; - continue; + newFragments.OffsetTable.AddRange(originOffsetTable.ToArray()); + } else { - offset += (uint)frameFragments.Size; - isDiffrentBefore = true; + newFragments.OffsetTable.AddRange(bot.ToArray()); + //Console.WriteLine(bot.ToJsonStr()); } - if (isDiffrentBefore) + #endregion + + + dicomFile.Dataset.AddOrUpdate(newFragments); + + + // 重新保存 dicom 到流 + ms.SetLength(0); + + dicomFile.Save(ms); + } + //传递过来的就是拆分的,但是是没有偏移表的,我需要自己创建偏移表,不然生成缩略图失败 + else if (syntax.IsEncapsulated && fragmentCount > pixelData.NumberOfFrames && originOffsetTable.Count == 0) + { + + + + uint offset = 0; + + bot.Add(offset); + + var fistSize = frag.Fragments.FirstOrDefault()?.Size ?? 0; + + //和上一个大小不一样 + var isDiffrentBefore = false; + + uint count = 0; + + // 假设你知道每帧对应的 fragment 数量 + foreach (var frameFragments in frag.Fragments) { - //每个Fragment 也占用字节 - offset += 8 * count; - bot.Add(offset); - count = 0; + count++; + + if (frameFragments.Size == fistSize) + { + isDiffrentBefore = false; + // 累加这一帧所有 fragment 的大小 + offset += (uint)frameFragments.Size; + continue; + } + else + { + offset += (uint)frameFragments.Size; + isDiffrentBefore = true; + + } + + if (isDiffrentBefore) + { + //每个Fragment 也占用字节 + offset += 8 * count; + bot.Add(offset); + count = 0; + + } } + bot.RemoveAt(bot.Count - 1); + // 设置到新的 PixelData + frag.OffsetTable.AddRange(bot.ToArray()); + + + // 重新保存 DICOM 到流 + ms.SetLength(0); + + dicomFile.Save(ms); + } - bot.RemoveAt(bot.Count - 1); - // 设置到新的 PixelData - frag.OffsetTable.AddRange(bot.ToArray()); - - - // 重新保存 DICOM 到流 - ms.SetLength(0); - dicomFile.Save(ms); - } - - } - catch (Exception mutiEx) - { - Log.Logger.Warning($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE} 处理多帧失败,上传原始文件:{mutiEx.ToString()}"); + catch (Exception mutiEx) + { + Log.Logger.Warning($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE} 处理多帧失败,上传原始文件:{mutiEx.ToString()}"); + } } } @@ -683,6 +692,9 @@ namespace IRaCIS.Core.SCP.Service + + + #endregion