public DicomCompressCommand(DicomMessageBase file, TransferSyntax syntax, IDicomCodec codec, DicomCodecParameters parms) : base("DICOM Compress Command", true) { _file = file; _syntax = syntax; _codec = codec; _parms = parms; }
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); }
/// <summary> /// Method to send a DICOM C-STORE-RQ message. /// </summary> /// <param name="presentationID"></param> /// <param name="messageID"></param> /// <param name="priority"></param> /// <param name="moveAE"></param> /// <param name="moveMessageID"></param> /// <param name="message"></param> /// <param name="overrideParameters"></param> public void SendCStoreRequest(byte presentationID, ushort messageID, DicomPriority priority, string moveAE, ushort moveMessageID, DicomMessage message, DicomCodecParameters overrideParameters) { DicomUid affectedClass = _assoc.GetAbstractSyntax(presentationID); if (!affectedClass.UID.Equals(message.SopClass.Uid)) throw new DicomException( String.Format( "SOP Class Uid in the message {0} does not match SOP Class UID for presentation context {1}", message.SopClass.Uid, affectedClass.UID)); DicomAttributeCollection command = message.MetaInfo; message.MessageId = messageID; message.CommandField = DicomCommandField.CStoreRequest; message.AffectedSopClassUid = message.SopClass.Uid; message.DataSetType = 0x0202; message.Priority = priority; String sopInstanceUid; bool ok = message.DataSet[DicomTags.SopInstanceUid].TryGetString(0, out sopInstanceUid); if (!ok) throw new DicomException("SOP Instance UID unexpectedly not set in CStore Message being sent."); message.AffectedSopInstanceUid = sopInstanceUid; if (!string.IsNullOrEmpty(moveAE)) { message.MoveOriginatorApplicationEntityTitle = moveAE; message.MoveOriginatorMessageId = moveMessageID; } // Handle compress/decompress if necessary TransferSyntax contextSyntax = _assoc.GetAcceptedTransferSyntax(presentationID); if ((contextSyntax != message.TransferSyntax) && (contextSyntax.Encapsulated || message.TransferSyntax.Encapsulated)) { if (overrideParameters != null) message.ChangeTransferSyntax(contextSyntax, null, overrideParameters); else message.ChangeTransferSyntax(contextSyntax); } SendDimse(presentationID, command, message.DataSet); }
/// <summary> /// Method to send a DICOM C-STORE-RQ message. /// </summary> /// <param name="presentationID"></param> /// <param name="messageID"></param> /// <param name="priority"></param> /// <param name="message"></param> /// <param name="overrideParameters"></param> public void SendCStoreRequest(byte presentationID, ushort messageID, DicomPriority priority, DicomMessage message, DicomCodecParameters overrideParameters) { SendCStoreRequest(presentationID, messageID, priority, null, 0, message, overrideParameters); }
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; } } }