private void InitializeFrameData(DicomUncompressedPixelData owner, DicomAttribute pixelDataAttribute) { var obAttrib = pixelDataAttribute as DicomAttributeOB; if (obAttrib != null && obAttrib.StreamLength > 0) { for (var n = 0; n < NumberOfFrames; ++n) _fd.Add(new FrameDataOB(owner, obAttrib, n)); } var owAttrib = pixelDataAttribute as DicomAttributeOW; if (owAttrib != null && owAttrib.StreamLength > 0) { for (var n = 0; n < NumberOfFrames; ++n) _fd.Add(new FrameDataOW(owner, owAttrib, n)); } }
/// <summary> /// Initializes the frame data container from the specified byte buffer. /// </summary> public FrameDataBytes(DicomUncompressedPixelData owner, byte[] frameData, bool copyRequired = true) : base(owner) { if (copyRequired) { var buffer = new byte[frameData.Length]; Array.Copy(frameData, buffer, buffer.Length); _buffer = buffer; } else { _buffer = frameData; } }
/// <summary> /// Initializes the frame data container from an OW Pixel Data attribute. /// </summary> public FrameDataOW(DicomUncompressedPixelData owner, DicomAttributeOW pixelDataAttribute, int frameIndex) : base(owner) { _owAttrib = pixelDataAttribute; _frameIndex = frameIndex; }
/// <summary> /// Called by the base class to create a new byte buffer containing normalized pixel data /// for this frame (8 or 16-bit grayscale, or 32-bit ARGB). /// </summary> /// <returns>A new byte buffer containing the normalized pixel data.</returns> protected override byte[] CreateNormalizedPixelData() { DicomMessageBase message = Parent.SourceMessage; #if DEBUG CodeClock clock = new CodeClock(); clock.Start(); #endif PhotometricInterpretation photometricInterpretation; byte[] rawPixelData = null; if (!message.TransferSyntax.Encapsulated) { DicomUncompressedPixelData pixelData = new DicomUncompressedPixelData(message); // DICOM library uses zero-based frame numbers MemoryManager.Execute(delegate { rawPixelData = pixelData.GetFrame(_frameIndex); }); ExtractOverlayFrames(rawPixelData, pixelData.BitsAllocated); photometricInterpretation = PhotometricInterpretation.FromCodeString(message.DataSet[DicomTags.PhotometricInterpretation]); } else if (DicomCodecRegistry.GetCodec(message.TransferSyntax) != null) { DicomCompressedPixelData pixelData = new DicomCompressedPixelData(message); string pi = null; MemoryManager.Execute(delegate { rawPixelData = pixelData.GetFrame(_frameIndex, out pi); }); photometricInterpretation = PhotometricInterpretation.FromCodeString(pi); } else throw new DicomCodecException("Unsupported transfer syntax"); if (photometricInterpretation.IsColor) rawPixelData = ToArgb(message.DataSet, rawPixelData, photometricInterpretation); else NormalizeGrayscalePixels(message.DataSet, rawPixelData); #if DEBUG clock.Stop(); PerformanceReportBroker.PublishReport("DicomMessageSopDataSource", "CreateFrameNormalizedPixelData", clock.Seconds); #endif return rawPixelData; }
/// <summary> /// Initializes the frame data container. /// </summary> protected FrameData(DicomUncompressedPixelData owner) { _owner = owner; }
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; } } }
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; } } }
//private static void WriteLog(string s) //{ // File.AppendAllText("C:\\_store.txt", string.Format("{0}\n",s)); //} /// <summary> /// Hàm xử lý khi nhận xong dữ liệu Dicom /// </summary> /// <param name="server"></param> /// <param name="association"></param> /// <param name="presentationId"></param> /// <param name="message"></param> void IDicomServerHandler.OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationId, DicomMessage message) { //wc.Stop(); //WriteLog(wc.ElapsedMilliseconds.ToString()); if (message.CommandField == DicomCommandField.CEchoRequest) { server.SendCEchoResponse(presentationId, message.MessageId, DicomStatuses.Success); return; } String studyInstanceUid = null; String seriesInstanceUid = null; DicomUid sopInstanceUid; //String patientName = null; String sex = null; sex = message.DataSet[DicomTags.PatientsSex].GetString(0, "O"); bool ok = message.DataSet[DicomTags.SopInstanceUid].TryGetUid(0, out sopInstanceUid); if (ok) ok = message.DataSet[DicomTags.SeriesInstanceUid].TryGetString(0, out seriesInstanceUid); if (ok) ok = message.DataSet[DicomTags.StudyInstanceUid].TryGetString(0, out studyInstanceUid); //if (ok) ok = message.DataSet[DicomTags.PatientsName].TryGetString(0, out patientName); if (!ok) { VBLogger.LogError("Unable to retrieve UIDs from request message, sending failure status."); server.SendCStoreResponse(presentationId, message.MessageId, sopInstanceUid.UID, DicomStatuses.ProcessingFailure); return; } TransferSyntax syntax = association.GetPresentationContext(presentationId).AcceptedTransferSyntax; server.SendCStoreResponse(presentationId, message.MessageId, sopInstanceUid.UID, DicomStatuses.Success); string pathImage = ""; var path = new StringBuilder(); path.AppendFormat("{0}{1}{2}{3}{4}", StorageLocation, Path.DirectorySeparatorChar, studyInstanceUid, Path.DirectorySeparatorChar, seriesInstanceUid); try { // Save File if (!Directory.Exists(StorageLocation)) Directory.CreateDirectory(StorageLocation); if (!Directory.Exists(path.ToString())) Directory.CreateDirectory(path.ToString()); path.AppendFormat("{0}{1}.dcm", Path.DirectorySeparatorChar, sopInstanceUid.UID); var dicomFile = new DicomFile(message, path.ToString()) { TransferSyntaxUid = syntax.UidString, MediaStorageSopInstanceUid = sopInstanceUid.UID, ImplementationClassUid = DicomImplementation.ClassUID.UID, ImplementationVersionName = DicomImplementation.Version, SourceApplicationEntityTitle = association.CallingAE, MediaStorageSopClassUid = message.SopClass.Uid }; dicomFile.Save(DicomWriteOptions.None); //WriteLog(string.Format("Save File OK!: {0}", wc.ElapsedMilliseconds)); var pd = new DicomUncompressedPixelData(message.DataSet); pathImage = path.ToString(); byte[] thePixels = pd.GetFrame(0); var pixData = new UInt16[thePixels.Length/2]; int h = dicomFile.DataSet[DicomTags.Rows].GetUInt16(0, 0); int w = dicomFile.DataSet[DicomTags.Columns].GetUInt16(0, 0); UInt16 max = 0, min = UInt16.MaxValue; //min = pd.ge unsafe { fixed (byte* pixPointer = thePixels) { var pP = (UInt16*) pixPointer; for (int i = 0; i < w*h; ++i) { pixData[i] = *pP; if (min > pixData[i]) min = pixData[i]; if (max < pixData[i]) max = pixData[i]; pP++; } } } int indexOf = pathImage.LastIndexOf(".dcm"); pathImage = pathImage.Substring(0, indexOf); pathImage = string.Concat(pathImage, "_thumb.jpg"); string photometricInterpretation; message.DataSet[DicomTags.PhotometricInterpretation].TryGetString(0, out photometricInterpretation); Bitmap bmp = CreateBitmap(pixData, min, max, w, h, photometricInterpretation); bmp.Save(pathImage, ImageFormat.Jpeg); bmp.Dispose(); } catch (Exception ex) { // File.WriteAllText(@"C:\log.txt", ex.ToString()); } //WriteLog(string.Format(" Create Thumbnail OK: {0}", wc.ElapsedMilliseconds)); String patientName = message.DataSet[DicomTags.PatientsName].GetString(0, ""); //Xóa các ký tự thừa trong Patient Name patientName = patientName.Replace('^', ' '); VBLogger.LogInfo("Received SOP Instance: {0} for patient {1}", sopInstanceUid, patientName); //Insert Install To DB //InsertInstanceToImageServer(association, message.DataSet); // FeedBack to Rislink string patientId = message.DataSet[DicomTags.PatientId].GetString(0, ""); string bodyPart = message.DataSet[DicomTags.BodyPartExamined].GetString(0, ""); string viewPosition = message.DataSet[DicomTags.ViewPosition].GetString(0, ""); string accessionNumber = message.DataSet[DicomTags.AccessionNumber].GetString(0, "").Trim(); accessionNumber = accessionNumber == "" ? patientId : accessionNumber; //var t = message.DataSet[DicomTags.SourceSerialNumber].GetString(0, "").Trim(); string requestingAe = association.CallingAE; if (viewPosition.Trim() == "") viewPosition = message.DataSet[DicomTags.PatientOrientation].GetString(0, ""); //WriteLog(string.Format("Finish time: {0}",wc.ElapsedMilliseconds)); var updateOk = SpMergeData(bodyPart, patientId, patientName, path.ToString(), sex, studyInstanceUid, seriesInstanceUid, sopInstanceUid.ToString(), viewPosition, accessionNumber, requestingAe); Console.WriteLine(updateOk.ToString(CultureInfo.InvariantCulture)); }
/// <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(); }
/// <summary> /// Constructor from a <see cref="DicomUncompressedPixeldata"/> instance. /// </summary> /// <param name="pd">The uuncompressed pixel data attribute to initialize the object from.</param> public DicomCompressedPixelData(DicomUncompressedPixelData pd) : base(pd) { _sq = new DicomFragmentSequence(DicomTags.PixelData); }