public static int Main(string[] args) { string filename = args[0]; string outfilename = args[1]; using( var sfcts = FileChangeTransferSyntax.New() ) { FileChangeTransferSyntax fcts = sfcts.__ref__(); //SimpleSubjectWatcher watcher = new SimpleSubjectWatcher(fcts, "FileChangeTransferSyntax"); gdcm.TransferSyntax ts = new TransferSyntax( TransferSyntax.TSType.JPEG2000 ); fcts.SetTransferSyntax( ts ); ImageCodec ic = fcts.GetCodec(); JPEG2000Codec jpeg2000 = JPEG2000Codec.Cast( ic ); jpeg2000.SetReversible( false ); jpeg2000.SetQuality(0, 55); fcts.SetInputFileName( filename ); fcts.SetOutputFileName( outfilename ); if( !fcts.Change() ) { return 1; } } return 0; }
/// <summary> /// Read explicit VR little endian up to transfer syntax element and determines transfer syntax for rest of elements /// </summary> /// <param name="dr">the binary reader which is reading the DICOM object</param> /// <param name="syntax">the transfer syntax of the DICOM file</param> /// <returns>elements preceeding and including transfer syntax element</returns> public static List<IDICOMElement> ReadFileMetadata(DICOMBinaryReader dr, ref TransferSyntax syntax) { var elements = new List<IDICOMElement>(); syntax = syntax != TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN ? syntax : TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN; while (dr.StreamPosition < dr.StreamLength) { long position = dr.StreamPosition; if (TagReader.ReadLittleEndian(dr).Group == _metaGroup) { dr.StreamPosition = position; IDICOMElement el = DICOMElementReader.ReadElementExplicitLittleEndian(dr); Tag uid = TagHelper.TRANSFER_SYNTAX_UID; if (el.Tag == uid) { syntax = TransferSyntaxHelper.GetSyntax(el); } elements.Add(el); } else { dr.StreamPosition = position; break; } } return elements; }
public static int Main(string[] args) { string filename = args[0]; string outfilename = args[1]; using( var sfcts = FileChangeTransferSyntax.New() ) { FileChangeTransferSyntax fcts = sfcts.__ref__(); //SimpleSubjectWatcher watcher = new SimpleSubjectWatcher(fcts, "FileChangeTransferSyntax"); gdcm.TransferSyntax ts = new TransferSyntax( TransferSyntax.TSType.JPEGLSNearLossless ); fcts.SetTransferSyntax( ts ); ImageCodec ic = fcts.GetCodec(); JPEGLSCodec jpegls = JPEGLSCodec.Cast( ic ); jpegls.SetLossless( false ); jpegls.SetLossyError( 2 ); fcts.SetInputFileName( filename ); fcts.SetOutputFileName( outfilename ); if( !fcts.Change() ) { return 1; } } return 0; }
/// <summary> /// Read explicit VR little endian up to transfer syntax element and determines transfer syntax for rest of elements /// </summary> /// <param name="dr">the binary reader which is reading the DICOM object</param> /// <param name="syntax">the transfer syntax of the DICOM file</param> /// <returns>elements preceeding and including transfer syntax element</returns> private static List<IDICOMElement> ReadFileMetadata(DICOMBinaryReader dr, out TransferSyntax syntax) { List<IDICOMElement> elements = new List<IDICOMElement>(); syntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN; while (dr.StreamPosition < dr.StreamLength) { long position = dr.StreamPosition; if (TagReader.ReadLittleEndian(dr).Group == _MetaGroup) { dr.StreamPosition = position; IDICOMElement el = DICOMElementReader.ReadElementExplicitLittleEndian(dr); if (el.Tag.CompleteID == TagHelper.TRANSFER_SYNTAX_UID.CompleteID) { syntax = TransferSyntaxHelper.GetSyntax(el); } elements.Add(el); } else { dr.StreamPosition = position; break; } } return elements; }
public static void SkipItemLittleEndian(DICOMBinaryReader dr, TransferSyntax syntax) { int length = LengthReader.ReadLittleEndian(VR.Null, dr.Skip(4)); if (length != -1) { dr.Skip(length); } else { if (syntax == TransferSyntax.EXPLICIT_VR_LITTLE_ENDIAN) { while (!IsEndOfSequenceItemLittleEndian(dr)) { dr.StreamPosition -= 8; DICOMElementReader.SkipElementExplicitLittleEndian(dr); } } else { while (!IsEndOfSequenceItemLittleEndian(dr)) { dr.StreamPosition -= 8; DICOMElementReader.SkipElementImplicitLittleEndian(dr); } } } }
public static void LosslessImageTest(TransferSyntax syntax, DicomFile theFile) { if (File.Exists(theFile.Filename)) File.Delete(theFile.Filename); DicomFile saveCopy = new DicomFile(theFile.Filename, theFile.MetaInfo.Copy(), theFile.DataSet.Copy()); theFile.ChangeTransferSyntax(syntax); theFile.Save(DicomWriteOptions.ExplicitLengthSequence); DicomFile newFile = new DicomFile(theFile.Filename); newFile.Load(DicomReadOptions.Default); newFile.ChangeTransferSyntax(saveCopy.TransferSyntax); List<DicomAttributeComparisonResult> list = new List<DicomAttributeComparisonResult>(); bool result = newFile.DataSet.Equals(saveCopy.DataSet, ref list); StringBuilder sb = new StringBuilder(); foreach (DicomAttributeComparisonResult compareResult in list) sb.AppendFormat("Comparison Failure: {0}, ", compareResult.Details); Assert.IsTrue(result,sb.ToString()); }
public static int Main(string[] args) { string filename = args[0]; string outfilename = args[1]; using( var sfcts = FileChangeTransferSyntax.New() ) { FileChangeTransferSyntax fcts = sfcts.__ref__(); //SimpleSubjectWatcher watcher = new SimpleSubjectWatcher(fcts, "FileChangeTransferSyntax"); gdcm.TransferSyntax ts = new TransferSyntax( TransferSyntax.TSType.RLELossless ); fcts.SetTransferSyntax( ts ); ImageCodec ic = fcts.GetCodec(); RLECodec rle = RLECodec.Cast( ic ); // need to call at least one member func to check not NULL: long val = rle.GetBufferLength(); System.Console.WriteLine( val ); // use val to remove a warning fcts.SetInputFileName( filename ); fcts.SetOutputFileName( outfilename ); if( !fcts.Change() ) { return 1; } } return 0; }
public void ChangeSyntax(TransferSyntax syntax) { try { if (!_dicomFile.TransferSyntax.Encapsulated) { // Check if Overlay is embedded in pixels OverlayPlaneModuleIod overlayIod = new OverlayPlaneModuleIod(_dicomFile.DataSet); for (int i = 0; i < 16; i++) { if (overlayIod.HasOverlayPlane(i)) { OverlayPlane overlay = overlayIod[i]; if (overlay.OverlayData == null) { DicomUncompressedPixelData pd = new DicomUncompressedPixelData(_dicomFile); overlay.ConvertEmbeddedOverlay(pd); } } } } else if (syntax.Encapsulated) { // Must decompress first. _dicomFile.ChangeTransferSyntax(TransferSyntax.ExplicitVrLittleEndian); } _dicomFile.ChangeTransferSyntax(syntax); } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unexpected exception compressing/decompressing DICOM file"); } }
public DicomCompressCommand(DicomMessageBase file, TransferSyntax syntax, IDicomCodec codec, DicomCodecParameters parms) : base("DICOM Compress Command", true) { _file = file; _syntax = syntax; _codec = codec; _parms = parms; }
public static DICOMObject ReadObject(byte[] objectBytes, TransferSyntax syntax) { List<IDICOMElement> elements; using (DICOMBinaryReader dr = new DICOMBinaryReader(objectBytes)) { elements = DICOMElementReader.ReadAllElements(dr, syntax); } return new DICOMObject(elements); }
internal DicomPresContext(byte pcid, SopClass abstractSyntax, TransferSyntax transferSyntax, DicomPresContextResult result) { _pcid = pcid; _result = result; _roles = DicomRoleSelection.Disabled; _abstract = abstractSyntax; if (abstractSyntax.Uid.Length == 0) throw new DicomException("Invalid abstract syntax for presentation context, UID is zero length."); _transfers = new List<TransferSyntax>(); _transfers.Add(transferSyntax); }
public static int ReadIndefiniteLengthLittleEndian(DICOMBinaryReader dr, TransferSyntax syntax) { long startingPos = dr.StreamPosition; while (!IsEndOfSequenceLittleEndian(dr)) { dr.StreamPosition -= 8; SequenceItemReader.SkipItemLittleEndian(dr, syntax); } return CalculateLength(dr, startingPos)-8; }
/// <summary> /// Reads the length from a series of bytes in a stream. The number of bytes is automatically determined from /// VR. /// </summary> /// <param name="vr">the value representation of the element</param> /// <param name="dr">the binary stream with a current position on the length parameter</param> /// <param name="syntax">the transfer syntax of this element</param> /// <returns></returns> public static int Read(VR vr, DICOMBinaryReader dr, TransferSyntax syntax) { switch (syntax) { case TransferSyntax.EXPLICIT_VR_BIG_ENDIAN: return ReadBigEndian(vr, dr); default: return ReadLittleEndian(vr, dr); } }
public static DICOMObject ReadObject(byte[] objectBytes, TransferSyntax syntax, out long bytesRead) { List<IDICOMElement> elements; using (var dr = new DICOMBinaryReader(objectBytes)) { elements = DICOMElementReader.ReadAllElements(dr, syntax); bytesRead = dr.StreamPosition; } return new DICOMObject(elements); }
/// <summary> /// Reads the data from an element encoded in little endian byte order /// </summary> /// <param name="lengthToRead">the length of the data</param> /// <param name="dr">the binary reader which is reading the DICOM object</param> /// <returns>the data from this element</returns> public static byte[] ReadLittleEndian(int lengthToRead, DICOMBinaryReader dr, TransferSyntax syntax) { if (lengthToRead != -1) { return dr.ReadBytes(lengthToRead); } int length = SequenceReader.ReadIndefiniteLengthLittleEndian(dr, syntax); byte[] seqBytes = dr.ReadBytes(length); dr.Skip(8); return seqBytes; }
/// <summary> /// Reads a DICOM file from a byte array /// </summary> /// <param name="fileBytes">the bytes of the DICOM file</param> /// <returns>a DICOM object containing all elements</returns> public static DICOMObject Read(byte[] fileBytes, TransferSyntax trySyntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN) { TransferSyntax syntax = trySyntax; //Will keep if metadata doesn't exist List<IDICOMElement> elements; using (var dr = new DICOMBinaryReader(fileBytes)) { DICOMPreambleReader.Read(dr); List<IDICOMElement> metaElements = ReadFileMetadata(dr, ref syntax); elements = metaElements.Concat(DICOMElementReader.ReadAllElements(dr, syntax)).ToList(); } return new DICOMObject(elements); }
/// <summary> /// Reads a DICOM file from a path /// </summary> /// <param name="stream">the stream to the DICOM file</param> /// <returns>a DICOM object containing all elements</returns> public static DICOMObject Read(Stream stream, TransferSyntax trySyntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN) { TransferSyntax syntax = trySyntax; List<IDICOMElement> elements; using (var dr = new DICOMBinaryReader(stream)) { DICOMPreambleReader.Read(dr); List<IDICOMElement> metaElements = ReadFileMetadata(dr, ref syntax); elements = metaElements.Concat(DICOMElementReader.ReadAllElements(dr, syntax)).ToList(); } return new DICOMObject(elements); }
public static DICOMObject ReadBigEndian(DICOMBinaryReader dr, TransferSyntax syntax) { DICOMObject d; int length = LengthReader.ReadLittleEndian(VR.Null, dr.Skip(4)); if (LengthReader.IsIndefinite(length)) { d = ReadIndefiniteBigEndian(dr, syntax); } else { d = DICOMObjectReader.ReadObject(dr.ReadBytes(length), syntax); } return d; }
/// <summary> /// Asynchronously reads a DICOM file from a path /// </summary> /// <param name="filePath">the path to the DICOM file</param> /// <returns>a DICOM object containing all elements</returns> public static async Task<DICOMObject> ReadAsync(string filePath, TransferSyntax trySyntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN) { return await Task.Run(() => { TransferSyntax syntax = trySyntax; List<IDICOMElement> elements; using (var dr = new DICOMBinaryReader(filePath)) { DICOMPreambleReader.Read(dr); List<IDICOMElement> metaElements = ReadFileMetadata(dr, ref syntax); elements = metaElements.Concat(DICOMElementReader.ReadAllElements(dr, syntax)).ToList(); } return new DICOMObject(elements); }); }
public void TestRegister() { const string uid = "1.2.3"; var registered = new TransferSyntax("a", "1.2.3", true, true, true, false, false, true); TransferSyntax.RegisterTransferSyntax(registered); Assert.IsTrue(TransferSyntax.TransferSyntaxes.Contains(registered)); var retrieved = TransferSyntax.GetTransferSyntax(uid); Assert.AreEqual(uid, retrieved.UidString); TransferSyntax.UnregisterTransferSyntax(registered); Assert.IsFalse(TransferSyntax.TransferSyntaxes.Contains(registered)); TransferSyntax.UnregisterTransferSyntax(registered); }
public static List<IDICOMElement> ReadAllElements(DICOMBinaryReader dr, TransferSyntax syntax) { List<IDICOMElement> elements; switch (syntax) { case TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN: elements = ReadAllElementsImplicitLittleEndian(dr); break; case TransferSyntax.EXPLICIT_VR_BIG_ENDIAN: elements = ReadAllElementsExplicitBigEndian(dr); break; default: elements = ReadAllElementsExplicitLittleEndian(dr); break; } return elements; }
public static List<DICOMObject> ReadItems(byte[] data, TransferSyntax syntax) { List<DICOMObject> objects = new List<DICOMObject>(); using (DICOMBinaryReader dr = new DICOMBinaryReader(data)) { while (dr.StreamPosition < dr.StreamLength) { switch (syntax) { case TransferSyntax.EXPLICIT_VR_BIG_ENDIAN: objects.Add(SequenceItemReader.ReadBigEndian(dr,syntax)); break; default: objects.Add(SequenceItemReader.ReadLittleEndian(dr,syntax)); break; } } } return objects; }
public DicomCompressCommand(DicomMessageBase file, XmlDocument parms, bool failOnCodecException) : base("DICOM Compress Command", true) { _file = file; _failOnCodecException = failOnCodecException; 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); }
public void TestEquality() { // ReSharper disable ExpressionIsAlwaysNull var ts0 = (TransferSyntax) null; var tsA = new TransferSyntax("a", "1.2.3", true, true, true, false, false, true); var tsA2 = new TransferSyntax("a2", "1.2.3", true, true, true, false, false, true); var tsA3 = tsA; var tsB = new TransferSyntax("b", "1.2.3.4", true, true, true, false, false, true); Assert.IsTrue(null == ts0); Assert.IsTrue(ts0 == null); Assert.IsTrue(Equals(null, ts0)); Assert.IsTrue(Equals(ts0, null)); Assert.IsTrue(tsA == tsA2); Assert.IsTrue(tsA2 == tsA); Assert.IsTrue(Equals(tsA, tsA2)); Assert.IsTrue(Equals(tsA2, tsA)); Assert.IsTrue(tsA == tsA3); Assert.IsTrue(tsA3 == tsA); Assert.IsTrue(Equals(tsA, tsA3)); Assert.IsTrue(Equals(tsA3, tsA)); Assert.IsFalse(ts0 == tsA); Assert.IsFalse(tsA == ts0); Assert.IsFalse(Equals(ts0, tsA)); Assert.IsFalse(Equals(tsA, ts0)); Assert.IsFalse(tsA == tsB); Assert.IsFalse(tsB == tsA); Assert.IsFalse(Equals(tsA, tsB)); Assert.IsFalse(Equals(tsB, tsA)); // ReSharper restore ExpressionIsAlwaysNull }
public void Read(RawPDU raw) { uint l = raw.Length; raw.ReadUInt16("Version"); raw.SkipBytes("Reserved", 2); _assoc.CalledAE = raw.ReadString("Called AE", 16); _assoc.CallingAE = raw.ReadString("Calling AE", 16); raw.SkipBytes("Reserved", 32); l -= 2 + 2 + 16 + 16 + 32; while (l > 0) { byte type = raw.ReadByte("Item-Type"); raw.SkipBytes("Reserved", 1); ushort il = raw.ReadUInt16("Item-Length"); l -= 4 + (uint)il; if (type == 0x10) { // Application Context raw.SkipBytes("Application Context", il); } else if (type == 0x20) { // Presentation Context byte id = raw.ReadByte("Presentation Context ID"); raw.SkipBytes("Reserved", 3); il -= 4; while (il > 0) { byte pt = raw.ReadByte("Presentation Context Item-Type"); raw.SkipBytes("Reserved", 1); ushort pl = raw.ReadUInt16("Presentation Context Item-Length"); string sx = raw.ReadString("Presentation Context Syntax UID", pl); if (pt == 0x30) { SopClass sopClass = SopClass.GetSopClass(sx); if (sopClass == null) sopClass = new SopClass("Private SOP Class", sx, false); _assoc.AddPresentationContext(id, sopClass); } else if (pt == 0x40) { TransferSyntax transferSyntax = TransferSyntax.GetTransferSyntax(sx); if (transferSyntax == null) transferSyntax = new TransferSyntax("Private Syntax", sx, true, false, true, false, false, false); _assoc.AddTransferSyntax(id, transferSyntax); } il -= (ushort)(4 + pl); } } else if (type == 0x50) { // User Information while (il > 0) { byte ut = raw.ReadByte("User Information Item-Type"); raw.SkipBytes("Reserved", 1); ushort ul = raw.ReadUInt16("User Information Item-Length"); il -= (ushort)(4 + ul); if (ut == 0x51) { _assoc.RemoteMaximumPduLength = raw.ReadUInt32("Max PDU Length"); } else if (ut == 0x52) { _assoc.ImplementationClass = new DicomUid(raw.ReadString("Implementation Class UID", ul), "Implementation Class UID", UidType.Unknown); } else if (ut == 0x53) { _assoc.RemoteMaxOperationsInvoked = raw.ReadUInt16("Max Operations Invoked"); _assoc.RemoteMaxOperationsPerformed = raw.ReadUInt16("Max Operations Performed"); } else if (ut == 0x55) { _assoc.ImplementationVersion = raw.ReadString("Implementation Version", ul); } else if (ut == 0x54) { raw.SkipBytes("SCU/SCP Role Selection", ul); /* ushort rsul = raw.ReadUInt16(); if ((rsul + 4) != ul) { throw new DicomNetworkException("SCU/SCP role selection length (" + ul + " bytes) does not match uid length (" + rsul + " + 4 bytes)"); } raw.ReadChars(rsul); // Abstract Syntax raw.ReadByte(); // SCU role raw.ReadByte(); // SCP role */ } else { Platform.Log(LogLevel.Error, "Unhandled user item: 0x{0:x2} ({1} + 4 bytes)", ut, ul); raw.SkipBytes("Unhandled User Item", ul); } } } } }
/// <summary> /// Constructor. /// </summary> /// <param name="dicomFile"></param> public StorageInstance(DicomFile dicomFile) { _dicomFile = dicomFile; string sopClassInFile = _dicomFile.DataSet[DicomTags.SopClassUid].ToString(); if (!sopClassInFile.Equals(_dicomFile.SopClass.Uid)) { Platform.Log(LogLevel.Warn, "SOP Class in Meta Info ({0}) does not match SOP Class in DataSet ({1})", _dicomFile.SopClass.Uid, sopClassInFile); _sopClass = SopClass.GetSopClass(sopClassInFile); if (_sopClass == null) { Platform.Log(LogLevel.Warn, "Unknown SOP Class in dataset, reverting to meta info: {0}", sopClassInFile); _sopClass = _dicomFile.SopClass; } } else _sopClass = _dicomFile.SopClass; _syntax = _dicomFile.TransferSyntax; SopInstanceUid = _dicomFile.MediaStorageSopInstanceUid; _filename = dicomFile.Filename; StudyInstanceUid = _dicomFile.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty); SeriesInstanceUid = _dicomFile.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty); PatientsName = _dicomFile.DataSet[DicomTags.PatientsName].GetString(0, string.Empty); PatientId = _dicomFile.DataSet[DicomTags.PatientId].GetString(0, string.Empty); _infoLoaded = true; }
/// <summary> /// Load enough information from the file to allow negotiation of the association. /// </summary> public void LoadInfo() { if (_infoLoaded) return; DicomFile theFile = new DicomFile(_filename); theFile.Load(DicomTags.RelatedGeneralSopClassUid, DicomReadOptions.Default); string sopClassInFile = theFile.DataSet[DicomTags.SopClassUid].ToString(); if (!sopClassInFile.Equals(theFile.SopClass.Uid)) { Platform.Log(LogLevel.Warn, "SOP Class in Meta Info ({0}) does not match SOP Class in DataSet ({1})", theFile.SopClass.Uid, sopClassInFile); _sopClass = SopClass.GetSopClass(sopClassInFile); if (_sopClass == null) { Platform.Log(LogLevel.Warn,"Unknown SOP Class in dataset, reverting to meta info: {0}", sopClassInFile); _sopClass = theFile.SopClass; } } else _sopClass = theFile.SopClass; _syntax = theFile.TransferSyntax; SopInstanceUid = theFile.MediaStorageSopInstanceUid; MetaInfoFileLength = theFile.MetaInfoFileLength; _infoLoaded = true; }
internal override void WriteData(SwappableBinaryWriter bw, ILogger logger, TransferSyntax transferSyntax) { // Make sure to follow the UID rules bw.Write(Uid.UidToBytes(this.data)); }
protected override void OnExecute(CommandProcessor theProcessor, IUpdateContext updateContext) { // Check if the File is the same syntax as the TransferSyntax fileSyntax = _file.TransferSyntax; TransferSyntax dbSyntax = TransferSyntax.GetTransferSyntax(_location.TransferSyntaxUid); // Check if the syntaxes match the location if ((!fileSyntax.Encapsulated && !dbSyntax.Encapsulated) || (fileSyntax.LosslessCompressed && dbSyntax.LosslessCompressed) || (fileSyntax.LossyCompressed && dbSyntax.LossyCompressed)) { // no changes necessary, just return; return; } // Select the Server Transfer Syntax var syntaxCriteria = new ServerTransferSyntaxSelectCriteria(); var syntaxBroker = updateContext.GetBroker <IServerTransferSyntaxEntityBroker>(); syntaxCriteria.Uid.EqualTo(fileSyntax.UidString); ServerTransferSyntax serverSyntax = syntaxBroker.FindOne(syntaxCriteria); if (serverSyntax == null) { Platform.Log(LogLevel.Error, "Unable to load ServerTransferSyntax for {0}. Unable to update study status.", fileSyntax.Name); return; } // Get the FilesystemStudyStorage update broker ready var filesystemStudyStorageEntityBroker = updateContext.GetBroker <IFilesystemStudyStorageEntityBroker>(); var filesystemStorageUpdate = new FilesystemStudyStorageUpdateColumns(); var filesystemStorageCritiera = new FilesystemStudyStorageSelectCriteria(); filesystemStorageUpdate.ServerTransferSyntaxKey = serverSyntax.Key; filesystemStorageCritiera.StudyStorageKey.EqualTo(_location.Key); // Get the StudyStorage update broker ready var studyStorageBroker = updateContext.GetBroker <IStudyStorageEntityBroker>(); var studyStorageUpdate = new StudyStorageUpdateColumns(); StudyStatusEnum statusEnum = _location.StudyStatusEnum; if (fileSyntax.LossyCompressed) { studyStorageUpdate.StudyStatusEnum = statusEnum = StudyStatusEnum.OnlineLossy; } else if (fileSyntax.LosslessCompressed) { studyStorageUpdate.StudyStatusEnum = statusEnum = StudyStatusEnum.OnlineLossless; } studyStorageUpdate.LastAccessedTime = Platform.Time; if (!filesystemStudyStorageEntityBroker.Update(filesystemStorageCritiera, filesystemStorageUpdate)) { Platform.Log(LogLevel.Error, "Unable to update FilesystemQueue row: Study {0}, Server Entity {1}", _location.StudyInstanceUid, _location.ServerPartitionKey); } else if (!studyStorageBroker.Update(_location.GetKey(), studyStorageUpdate)) { Platform.Log(LogLevel.Error, "Unable to update StudyStorage row: Study {0}, Server Entity {1}", _location.StudyInstanceUid, _location.ServerPartitionKey); } else { // Update the location, so the next time we come in here, we don't try and update the database // for another sop in the study. _location.StudyStatusEnum = statusEnum; _location.TransferSyntaxUid = fileSyntax.UidString; _location.ServerTransferSyntaxKey = serverSyntax.Key; } }
void IDicomServerHandler.OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message) { if (message.CommandField == DicomCommandField.CEchoRequest) { server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.Success); return; } String studyInstanceUid = null; String seriesInstanceUid = null; DicomUid sopInstanceUid; String patientName = null; 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) { Platform.Log(LogLevel.Error, "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; if (List) { Platform.Log(LogLevel.Info, message.Dump()); } if (Bitbucket) { Platform.Log(LogLevel.Info, "Received SOP Instance: {0} for patient {1} in syntax {2}", sopInstanceUid, patientName, syntax.Name); server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID, DicomStatuses.Success); return; } if (!Directory.Exists(StorageLocation)) { Directory.CreateDirectory(StorageLocation); } var path = new StringBuilder(); path.AppendFormat("{0}{1}{2}{3}{4}", StorageLocation, Path.DirectorySeparatorChar, studyInstanceUid, Path.DirectorySeparatorChar, seriesInstanceUid); 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); Platform.Log(LogLevel.Info, "Received SOP Instance: {0} for patient {1} in syntax {2}", sopInstanceUid, patientName, syntax.Name); server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID, DicomStatuses.Success); }
private static DICOMObject GetDataObject(List <PDataTF> pDatas, TransferSyntax syntax) { byte[] dicomBytes = DIMSEReader.MergePDataTFData(pDatas); return(DIMSEReader.CreateDICOMObject(dicomBytes, syntax)); }
/// <summary> /// Creates a new DICOM nested data set instance from specified /// DICOM output stream using specified transfer syntax. /// </summary> public NestedDataSet(Stream stream, TransferSyntax transferSyntax) : base(stream, transferSyntax) { }
internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { //reuse setter Data = System.Text.Encoding.ASCII.GetString(br.ReadBytes((int)length)); return(length); }
public void Read(RawPDU raw) { uint l = raw.Length; raw.ReadUInt16("Version"); raw.SkipBytes("Reserved", 2); raw.SkipBytes("Reserved", 16); raw.SkipBytes("Reserved", 16); raw.SkipBytes("Reserved", 32); l -= 68; while (l > 0) { byte type = raw.ReadByte("Item-Type"); l -= 1; if (type == 0x10) { // Application Context raw.SkipBytes("Reserved", 1); ushort c = raw.ReadUInt16("Item-Length"); raw.SkipBytes("Value", (int)c); l -= 3 + (uint)c; } else if (type == 0x21) { // Presentation Context raw.ReadByte("Reserved"); ushort pl = raw.ReadUInt16("Presentation Context Item-Length"); byte id = raw.ReadByte("Presentation Context ID"); raw.ReadByte("Reserved"); byte res = raw.ReadByte("Presentation Context Result/Reason"); raw.ReadByte("Reserved"); l -= (uint)pl + 3; pl -= 4; // Presentation Context Transfer Syntax raw.ReadByte("Presentation Context Item-Type (0x40)"); raw.ReadByte("Reserved"); ushort tl = raw.ReadUInt16("Presentation Context Item-Length"); string tx = raw.ReadString("Presentation Context Syntax UID", tl); pl -= (ushort)(tl + 4); _assoc.SetPresentationContextResult(id, (DicomPresContextResult)res); TransferSyntax acceptedSyntax = TransferSyntax.GetTransferSyntax(tx); if (acceptedSyntax != null) { _assoc.SetAcceptedTransferSyntax(id, acceptedSyntax); } else { _assoc.GetPresentationContext(id).ClearTransfers(); } } else if (type == 0x50) { // User Information raw.ReadByte("Reserved"); ushort il = raw.ReadUInt16("User Information Item-Length"); l -= (uint)(il + 3); while (il > 0) { byte ut = raw.ReadByte("User Item-Type"); raw.ReadByte("Reserved"); ushort ul = raw.ReadUInt16("User Item-Length"); il -= (ushort)(ul + 4); if (ut == 0x51) { _assoc.RemoteMaximumPduLength = raw.ReadUInt32("Max PDU Length"); } else if (ut == 0x52) { _assoc.ImplementationClass = DicomUids.Lookup(raw.ReadString("Implementation Class UID", ul)); } else if (ut == 0x55) { _assoc.ImplementationVersion = raw.ReadString("Implementation Version", ul); } else { raw.SkipBytes("User Item Value", (int)ul); } } } else { raw.SkipBytes("Reserved", 1); ushort il = raw.ReadUInt16("User Item-Length"); raw.SkipBytes("Unknown User Item", il); l -= (uint)(il + 3); } } }
internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { //Covered by PS 3.5, Chapter 7.5 (pg. 42-45) bool encapImage = (Tag == DICOMTags.PixelData); bool done = false; uint count = 0; while (!done) { //If explicit length, see if we're done if (length != 0xFFFFFFFF && count >= length) { done = true; continue; } ushort grp = br.ReadUInt16(); ushort elem = br.ReadUInt16(); uint len = br.ReadUInt32(); count += 8; //Sometimes there's retarded files that are msb swapped inside of sequences outside of the transfer syntax bool needMoreSwap = (grp == 0xFEFF); if (needMoreSwap) { //Swap the reader for now, then swap back after the sqitem br.ToggleSwapped(); //still have to swap the stuff we've already read by hand tho grp = MSBSwapper.SwapW(grp); elem = MSBSwapper.SwapW(elem); len = MSBSwapper.SwapDW(len); } if (grp == 0xFFFE && elem == 0xE000) { //Normal element, parse it out. SQItem item = new SQItem(this); count += item.ParseStream(br, logger, transferSyntax, len, encapImage); Items.Add(item); } else if (grp == 0xFFFE && elem == 0xE0DD) { //End element //In case there's garbage in there, read the length bytes br.ReadBytes((int)len); count += len; done = true; } else { throw new NotImplementedException(); } //toggle back in case it's just one SQItem that's hosed if (needMoreSwap) { br.ToggleSwapped(); } } return(count); }
public void Read(RawPDU raw) { uint l = raw.Length; raw.ReadUInt16("Version"); raw.SkipBytes("Reserved", 2); _assoc.CalledAE = raw.ReadString("Called AE", 16); _assoc.CallingAE = raw.ReadString("Calling AE", 16); raw.SkipBytes("Reserved", 32); l -= 2 + 2 + 16 + 16 + 32; while (l > 0) { byte type = raw.ReadByte("Item-Type"); raw.SkipBytes("Reserved", 1); ushort il = raw.ReadUInt16("Item-Length"); l -= 4 + (uint)il; if (type == 0x10) { // Application Context raw.SkipBytes("Application Context", il); } else if (type == 0x20) { // Presentation Context byte id = raw.ReadByte("Presentation Context ID"); raw.SkipBytes("Reserved", 3); il -= 4; while (il > 0) { byte pt = raw.ReadByte("Presentation Context Item-Type"); raw.SkipBytes("Reserved", 1); ushort pl = raw.ReadUInt16("Presentation Context Item-Length"); string sx = raw.ReadString("Presentation Context Syntax UID", pl); if (pt == 0x30) { SopClass sopClass = SopClass.GetSopClass(sx); if (sopClass == null) { sopClass = new SopClass("Private SOP Class", sx, false); } _assoc.AddPresentationContext(id, sopClass); } else if (pt == 0x40) { TransferSyntax transferSyntax = TransferSyntax.GetTransferSyntax(sx); if (transferSyntax == null) { transferSyntax = new TransferSyntax("Private Syntax", sx, true, false, true, false, false, false); } _assoc.AddTransferSyntax(id, transferSyntax); } il -= (ushort)(4 + pl); } } else if (type == 0x50) { // User Information while (il > 0) { byte ut = raw.ReadByte("User Information Item-Type"); raw.SkipBytes("Reserved", 1); ushort ul = raw.ReadUInt16("User Information Item-Length"); il -= (ushort)(4 + ul); if (ut == 0x51) { _assoc.RemoteMaximumPduLength = raw.ReadUInt32("Max PDU Length"); } else if (ut == 0x52) { _assoc.ImplementationClass = new DicomUid(raw.ReadString("Implementation Class UID", ul), "Implementation Class UID", UidType.Unknown); } else if (ut == 0x53) { _assoc.MaxOperationsInvoked = raw.ReadUInt16("Max Operations Invoked"); _assoc.MaxOperationsPerformed = raw.ReadUInt16("Max Operations Performed"); } else if (ut == 0x55) { _assoc.ImplementationVersion = raw.ReadString("Implementation Version", ul); } else if (ut == 0x54) { raw.SkipBytes("SCU/SCP Role Selection", ul); /* * ushort rsul = raw.ReadUInt16(); * if ((rsul + 4) != ul) { * throw new DicomNetworkException("SCU/SCP role selection length (" + ul + " bytes) does not match uid length (" + rsul + " + 4 bytes)"); * } * raw.ReadChars(rsul); // Abstract Syntax * raw.ReadByte(); // SCU role * raw.ReadByte(); // SCP role */ } else { Platform.Log(LogLevel.Error, "Unhandled user item: 0x{0:x2} ({1} + 4 bytes)", ut, ul); raw.SkipBytes("Unhandled User Item", ul); } } } } }
public static DICOMObject ReadObject(DICOMBinaryReader dr, TransferSyntax syntax) { List <IDICOMElement> elements = DICOMElementReader.ReadAllElements(dr, syntax); return(new DICOMObject(elements)); }
public static DICOMObject ReadObject(byte[] objectBytes, TransferSyntax syntax) { long bytesRead; return(ReadObject(objectBytes, syntax, out bytesRead)); }
/// <summary> /// Reads a DICOM file from a byte array /// </summary> /// <param name="file">the bytes of the DICOM file</param> /// <param name="trySyntax">the transfer syntax to use in case there is no metadata explicitly included</param> /// <returns></returns> public static DICOMObject Read(byte[] file, TransferSyntax trySyntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN) { return(DICOMFileReader.Read(file, trySyntax)); }
public static int Main(string[] args) { if (args.Length < 2) { System.Console.WriteLine(" input.dcm output.dcm"); return(1); } string filename = args[0]; string outfilename = args[1]; ImageReader reader = new ImageReader(); reader.SetFileName(filename); if (!reader.Read()) { System.Console.WriteLine("Could not read: " + filename); return(1); } // The output of gdcm::Reader is a gdcm::File File file = reader.GetFile(); // the dataset is the the set of element we are interested in: DataSet ds = file.GetDataSet(); Image image = reader.GetImage(); //image.Print( cout ); ImageChangeTransferSyntax change = new ImageChangeTransferSyntax(); TransferSyntax targetts = new TransferSyntax(TransferSyntax.TSType.JPEGBaselineProcess1); change.SetTransferSyntax(targetts); // Setup our JPEGCodec, warning it should be compatible with JPEGBaselineProcess1 JPEGCodec jpegcodec = new JPEGCodec(); if (!jpegcodec.CanCode(targetts)) { System.Console.WriteLine("Something went really wrong, JPEGCodec cannot handle JPEGBaselineProcess1"); return(1); } jpegcodec.SetLossless(false); jpegcodec.SetQuality(50); // poor quality ! change.SetUserCodec(jpegcodec); // specify the codec to use to the ImageChangeTransferSyntax change.SetInput(image); bool b = change.Change(); if (!b) { System.Console.WriteLine("Could not change the Transfer Syntax"); return(1); } ImageWriter writer = new ImageWriter(); writer.SetImage((gdcm.Image)change.GetOutput()); writer.SetFile(reader.GetFile()); writer.SetFileName(outfilename); if (!writer.Write()) { System.Console.WriteLine("Could not write: " + outfilename); return(1); } return(0); }
internal override void WriteData(SwappableBinaryWriter bw, ILogger logger, TransferSyntax transferSyntax) { bw.Write(data); }
/// <summary> /// Checks for a storage location for the study in the database, and creates a new location /// in the database if it doesn't exist. /// </summary> /// <param name="partition">The partition where the study is being sent to</param> /// <param name="created"></param> /// <param name="studyDate"></param> /// <param name="studyInstanceUid"></param> /// <param name="syntax"></param> /// <param name="updateContext">The update context to create the study on</param> /// <returns>A <see cref="StudyStorageLocation"/> instance.</returns> public StudyStorageLocation GetOrCreateWritableStudyStorageLocation(string studyInstanceUid, string studyDate, TransferSyntax syntax, IUpdateContext updateContext, ServerPartition partition, out bool created) { created = false; StudyStorageLocation location; try { GetWritableStudyStorageLocation(partition.Key, studyInstanceUid, StudyRestore.True, StudyCache.True, out location); return(location); } catch (StudyNotFoundException) { } FilesystemSelector selector = new FilesystemSelector(Instance); ServerFilesystemInfo filesystem = selector.SelectFilesystem(); if (filesystem == null) { throw new NoWritableFilesystemException(); } IInsertStudyStorage locInsert = updateContext.GetBroker <IInsertStudyStorage>(); InsertStudyStorageParameters insertParms = new InsertStudyStorageParameters { ServerPartitionKey = partition.GetKey(), StudyInstanceUid = studyInstanceUid, Folder = ResolveStorageFolder(partition.Key, studyInstanceUid, studyDate, updateContext, false /* set to false for optimization because we are sure it's not in the system */), FilesystemKey = filesystem.Filesystem.GetKey(), QueueStudyStateEnum = QueueStudyStateEnum.Idle }; if (syntax.LosslessCompressed) { insertParms.TransferSyntaxUid = syntax.UidString; insertParms.StudyStatusEnum = StudyStatusEnum.OnlineLossless; } else if (syntax.LossyCompressed) { insertParms.TransferSyntaxUid = syntax.UidString; insertParms.StudyStatusEnum = StudyStatusEnum.OnlineLossy; } else { insertParms.TransferSyntaxUid = syntax.UidString; insertParms.StudyStatusEnum = StudyStatusEnum.Online; } location = locInsert.FindOne(insertParms); created = true; return(location); }
/// <summary> /// Used to add a supported transfer syntax. /// </summary> /// <param name="syntax">The transfer syntax supproted by the SOP Class.</param> public void AddSyntax(TransferSyntax syntax) { SyntaxList.Add(syntax); }
internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { if (length < 2) { //busted... data = (ushort)0; br.ReadBytes((int)length); } else if (length == 2) { data = br.ReadUInt16(); } else if (length > 2) { uint readBytes = 0; DataDictionaryElement elemCheck = DataDictionary.LookupElement(this.Tag); if (elemCheck == null || elemCheck.VMMax > 1) { //Unknown VM or VM goes to > 1 data = new ushort[length / 2]; for (int i = 0; i < length / 2; i++) { ((ushort[])data)[i] = br.ReadUInt16(); } readBytes = (length / 2) * 2; } else { //VM of 1 -- force to single data point data = br.ReadUInt16(); readBytes = 2; } if (length - readBytes > 0) { br.ReadBytes((int)(length - readBytes)); } } return(length); }
internal abstract ByteBuffer GetByteBuffer(TransferSyntax syntax, String specificCharacterSet);
public DicomReadStatus Read(DicomTag stopAtTag, DicomReadOptions options) { if (stopAtTag == null) { stopAtTag = new DicomTag(0xFFFFFFFF, "Bogus Tag", "BogusTag", DicomVr.UNvr, false, 1, 1, false); } // Counters: // _remain - bytes remaining in stream // _bytes - estimates bytes to end of dataset // _read - number of bytes read from stream try { BytesNeeded = 0; _remain = _stream.Length - _stream.Position; while (_remain > 0) { if (_inGroup2 && BytesRead >= _endGroup2) { _inGroup2 = false; // Only change if we're still reading the meta info if (Dataset.StartTagValue < DicomTags.TransferSyntaxUid) { TransferSyntax group2Syntax = TransferSyntax.GetTransferSyntax( Dataset[DicomTags.TransferSyntaxUid].GetString(0, String.Empty)); if (group2Syntax == null) { throw new DicomException("Unsupported transfer syntax in group 2 elements"); } TransferSyntax = group2Syntax; } } uint tagValue; if (LastTagRead == null) { if (_remain < 4) { return(NeedMoreData(4)); } _pos = _stream.Position; ushort g = _reader.ReadUInt16(); ushort e = _reader.ReadUInt16(); tagValue = DicomTag.GetTagValue(g, e); if (DicomTag.IsPrivateGroup(g) && e > 0x00ff) { SaveTagRead = LastTagRead = DicomTagDictionary.GetDicomTag(g, e) ?? new DicomTag((uint)g << 16 | e, "Private Tag", "PrivateTag", DicomVr.UNvr, false, 1, uint.MaxValue, false); } else { if (e == 0x0000) { SaveTagRead = LastTagRead = new DicomTag((uint)g << 16 | e, "Group Length", "GroupLength", DicomVr.ULvr, false, 1, 1, false); } else { SaveTagRead = LastTagRead = DicomTagDictionary.GetDicomTag(g, e) ?? new DicomTag((uint)g << 16 | e, "Private Tag", "PrivateTag", DicomVr.UNvr, false, 1, uint.MaxValue, false); } } _remain -= 4; BytesEstimated += 4; BytesRead += 4; } else { tagValue = LastTagRead.TagValue; } if ((tagValue >= stopAtTag.TagValue) && (_sqrs.Count == 0)) // only exit in root message when after stop tag { if (_inGroup2 && tagValue > 0x0002FFFF) { if (_endGroup2 != BytesRead - 4) { LogAdapter.Logger.Info("File Meta Info Length, {0}, not equal to actual bytes read in file, {1}, overwriting length.", EndGroupTwo, BytesRead - 4); _endGroup2 = BytesRead - 4; } _inGroup2 = false; } EncounteredStopTag = true; return(DicomReadStatus.Success); } bool twoByteLength; if (_vr == null) { if (_syntax.ExplicitVr) { if (LastTagRead == DicomTag.Item || LastTagRead == DicomTag.ItemDelimitationItem || LastTagRead == DicomTag.SequenceDelimitationItem) { _vr = DicomVr.NONE; twoByteLength = _vr.Is16BitLengthField; } else { if (_remain < 2) { return(NeedMoreData(2)); } string vr = new string(_reader.ReadChars(2)); _vr = DicomVr.GetVR(vr); twoByteLength = _vr.Is16BitLengthField; _remain -= 2; BytesEstimated += 2; BytesRead += 2; if (LastTagRead.VR.Equals(DicomVr.UNvr)) { LastTagRead = new DicomTag(LastTagRead.TagValue, "Private Tag", "PrivateTag", _vr, false, 1, uint.MaxValue, false); if (vr.Equals("??")) { twoByteLength = true; } } else if (!LastTagRead.VR.Equals(_vr)) { if (!vr.Equals(" ")) { DicomTag tag = new DicomTag(LastTagRead.TagValue, LastTagRead.Name, LastTagRead.VariableName, _vr, LastTagRead.MultiVR, LastTagRead.VMLow, LastTagRead.VMHigh, LastTagRead.Retired); LastTagRead = tag; ; // TODO, log something } } } } else { _vr = LastTagRead.VR; twoByteLength = _vr.Is16BitLengthField; } if (_vr == DicomVr.UNvr) { if (LastTagRead.IsPrivate) { if (LastTagRead.Element <= 0x00ff && LastTagRead.Element >= 0x0010) { // Reset the tag with the right VR and a more descriptive name. LastTagRead = new DicomTag(LastTagRead.TagValue, "Private Creator Code", "PrivateCreatorCode", DicomVr.LOvr, false, 1, uint.MaxValue, false); // private creator id // Only set the VR to LO for Implicit VR, if we do it for // Explicit VR syntaxes, we would incorrectly read the tag // length below. if (!_syntax.ExplicitVr) { _vr = DicomVr.LOvr; } } else if (_stream.CanSeek && Flags.IsSet(options, DicomReadOptions.AllowSeekingForContext)) { // attempt to identify private sequence by checking if the tag has // an undefined length long pos = _stream.Position; int bytesToCheck = _syntax.ExplicitVr ? 6 : 4; if (_remain >= bytesToCheck) { if (_syntax.ExplicitVr) { _reader.ReadUInt16(); } uint l = _reader.ReadUInt32(); if (l == UndefinedLength) { _vr = DicomVr.SQvr; } } _stream.Position = pos; } } } } else { twoByteLength = _vr.Is16BitLengthField; } // Read the value length if (_len == UndefinedLength) { if (_syntax.ExplicitVr) { if (LastTagRead == DicomTag.Item || LastTagRead == DicomTag.ItemDelimitationItem || LastTagRead == DicomTag.SequenceDelimitationItem) { if (_remain < 4) { return(NeedMoreData(4)); } _len = _reader.ReadUInt32(); _remain -= 4; BytesEstimated += 4; BytesRead += 4; } else { if (twoByteLength) { if (_remain < 2) { return(NeedMoreData(2)); } _len = _reader.ReadUInt16(); _remain -= 2; BytesEstimated += 2; BytesRead += 2; } else { if (_remain < 6) { return(NeedMoreData(6)); } _reader.ReadByte(); _reader.ReadByte(); _len = _reader.ReadUInt32(); _remain -= 6; BytesEstimated += 6; BytesRead += 6; } } } else { if (_remain < 4) { return(NeedMoreData(4)); } _len = _reader.ReadUInt32(); _remain -= 4; BytesEstimated += 4; BytesRead += 4; } if ((_len != UndefinedLength) && !_vr.Equals(DicomVr.SQvr) && !(LastTagRead.Equals(DicomTag.Item) && _fragment == null)) { BytesEstimated += _len; } } // If we have a private creator code, set the VR to LO, because // that is what it is. We must do this after we read the length // so that the 32 bit length is read properly. if ((LastTagRead.IsPrivate) && (_vr.Equals(DicomVr.UNvr)) && (LastTagRead.Element <= 0x00ff)) { _vr = DicomVr.LOvr; } if (_fragment != null) { // In the middle of parsing pixels if (LastTagRead == DicomTag.Item) { if (_remain < _len) { return(NeedMoreData(_remain - _len)); } if (Flags.IsSet(options, DicomReadOptions.StorePixelDataReferences) && _fragment.HasOffsetTable) { FileReference reference = new FileReference(StreamOpener, _stream.Position, _len, _endian, DicomVr.OBvr); DicomFragment fragment = new DicomFragment(reference); _fragment.AddFragment(fragment); if (_stream.CanSeek) { _stream.Seek(_len, SeekOrigin.Current); } else { ConsumeStreamBytes(_stream, _len); } } else { ByteBuffer data = new ByteBuffer(_endian, _len); data.CopyFrom(_stream, (int)_len); if (!_fragment.HasOffsetTable) { _fragment.SetOffsetTable(data); } else { DicomFragment fragment = new DicomFragment(data); _fragment.AddFragment(fragment); } } _remain -= _len; BytesRead += _len; } else if (LastTagRead == DicomTag.SequenceDelimitationItem) { if (_sqrs.Count > 0) { SequenceRecord rec = _sqrs.Peek(); DicomDataset ds = rec.Current; ds[_fragment.Tag] = _fragment; if (rec.Curlen != UndefinedLength) { long end = rec.Curpos + rec.Curlen; if (_stream.Position >= end) { rec.Current = null; } } } else { Dataset[_fragment.Tag] = _fragment; } _fragment = null; } else { LogAdapter.Logger.Error("Encountered unexpected tag in stream: {0}", LastTagRead.ToString()); // unexpected tag return(DicomReadStatus.UnknownError); } } else if (_sqrs.Count > 0 && (LastTagRead == DicomTag.Item || LastTagRead == DicomTag.ItemDelimitationItem || LastTagRead == DicomTag.SequenceDelimitationItem)) { SequenceRecord rec = _sqrs.Peek(); if (LastTagRead.Equals(DicomTag.Item)) { if (_len != UndefinedLength) { if (_len > _remain) { return(NeedMoreData(_remain - _len)); } } DicomSequenceItem ds; if (rec.Tag.TagValue.Equals(DicomTags.DirectoryRecordSequence)) { DirectoryRecordSequenceItem dr = new DirectoryRecordSequenceItem { Offset = (uint)_pos }; ds = dr; } else { ds = new DicomSequenceItem(); } rec.Current = ds; if (rec.Tag.VR.Equals(DicomVr.UNvr)) { DicomTag tag = new DicomTag(rec.Tag.TagValue, rec.Tag.Name, rec.Tag.VariableName, DicomVr.SQvr, rec.Tag.MultiVR, rec.Tag.VMLow, rec.Tag.VMHigh, rec.Tag.Retired); rec.Parent[tag].AddSequenceItem(ds); } else { rec.Parent[rec.Tag].AddSequenceItem(ds); } // Specific character set is inherited, save it. It will be overwritten // if a new value of the tag is encountered in the sequence. rec.Current.SpecificCharacterSet = rec.Parent.SpecificCharacterSet; // save the sequence length rec.Curpos = _pos + 8; rec.Curlen = _len; _sqrs.Pop(); _sqrs.Push(rec); if (_len != UndefinedLength) { ByteBuffer data = new ByteBuffer(_endian, _len); data.CopyFrom(_stream, (int)_len); data.Stream.Position = 0; _remain -= _len; BytesRead += _len; DicomStreamReader idsr = new DicomStreamReader(data.Stream) { Dataset = ds, TransferSyntax = rec.Tag.VR.Equals(DicomVr.UNvr) ? TransferSyntax.ImplicitVrLittleEndian : _syntax, StreamOpener = StreamOpener }; DicomReadStatus stat = idsr.Read(null, options & ~DicomReadOptions.StorePixelDataReferences); if (stat != DicomReadStatus.Success) { LogAdapter.Logger.Error("Unexpected parsing error ({0}) when reading sequence attribute: {1}.", stat, rec.Tag.ToString()); return(stat); } } } else if (LastTagRead == DicomTag.ItemDelimitationItem) { } else if (LastTagRead == DicomTag.SequenceDelimitationItem) { SequenceRecord rec2 = _sqrs.Pop(); if (rec2.Current == null) { rec2.Parent[rec.Tag].SetNullValue(); } } if (rec.Len != UndefinedLength) { long end = rec.Pos + 8 + rec.Len; if (_syntax.ExplicitVr) { end += 2 + 2; } if (_stream.Position >= end) { _sqrs.Pop(); } } } else { if (_len == UndefinedLength) { if (_vr.Equals(DicomVr.UNvr)) { if (!_syntax.ExplicitVr) { _vr = DicomVr.SQvr; LastTagRead = LastTagRead.IsPrivate ? new DicomTag(LastTagRead.TagValue, "Private Tag", "PrivateTag", DicomVr.SQvr, false, 1, uint.MaxValue, false) : new DicomTag(LastTagRead.TagValue, "Unknown Tag", "UnknownTag", DicomVr.SQvr, false, 1, uint.MaxValue, false); } else { // To handle this case, we'd have to add a new mechanism to transition the parser to implicit VR parsing, // and then return back to implicit once the parsing of the SQ is complete. LogAdapter.Logger.Error( "Encountered unknown tag {0}, encoded as undefined length in an Explicit VR transfer syntax at offset {1}. Unable to parse.", LastTagRead, _stream.Position); return(DicomReadStatus.UnknownError); } } if (_vr.Equals(DicomVr.SQvr)) { SequenceRecord rec = new SequenceRecord { Parent = _sqrs.Count > 0 ? _sqrs.Peek().Current : Dataset, Current = null, Tag = LastTagRead, Len = UndefinedLength }; _sqrs.Push(rec); } else { _fragment = new DicomFragmentSequence(LastTagRead); } } else { if (_vr.Equals(DicomVr.SQvr)) { if (_len == 0) { DicomDataset ds; if (_sqrs.Count > 0) { SequenceRecord rec = _sqrs.Peek(); ds = rec.Current; } else { ds = Dataset; } ds[LastTagRead].SetNullValue(); } else { SequenceRecord rec = new SequenceRecord { Len = _len, Pos = _pos, Tag = LastTagRead, Parent = _sqrs.Count > 0 ? _sqrs.Peek().Current : Dataset }; _sqrs.Push(rec); } } else { if (_remain < _len) { return(NeedMoreData(_len - _remain)); } if ((LastTagRead.TagValue == DicomTags.PixelData) && Flags.IsSet(options, DicomReadOptions.DoNotStorePixelDataInDataSet)) { // Skip PixelData !! if (_stream.CanSeek) { _stream.Seek((int)_len, SeekOrigin.Current); } else { ConsumeStreamBytes(_stream, _len); } _remain -= _len; BytesRead += _len; } else if ((LastTagRead.TagValue == DicomTags.PixelData) && Flags.IsSet(options, DicomReadOptions.StorePixelDataReferences)) { var reference = new FileReference(StreamOpener, _stream.Position, _len, _endian, LastTagRead.VR); if (_stream.CanSeek) { _stream.Seek((int)_len, SeekOrigin.Current); } else { ConsumeStreamBytes(_stream, _len); } DicomElement elem; if (LastTagRead.VR.Equals(DicomVr.OWvr)) { elem = new DicomElementOw(LastTagRead, reference); } else if (LastTagRead.VR.Equals(DicomVr.OBvr)) { elem = new DicomElementOb(LastTagRead, reference); } else if (LastTagRead.VR.Equals(DicomVr.ODvr)) { elem = new DicomElementOD(LastTagRead, reference); } else { elem = new DicomElementOf(LastTagRead, reference); } if (_sqrs.Count > 0) { SequenceRecord rec = _sqrs.Peek(); DicomDataset ds = rec.Current; ds[LastTagRead] = elem; if (rec.Curlen != UndefinedLength) { long end = rec.Curpos + rec.Curlen; if (_stream.Position >= end) { rec.Current = null; } } } else { Dataset[LastTagRead] = elem; } _remain -= _len; BytesRead += _len; } else { ByteBuffer bb = new ByteBuffer(_len); // If the tag is impacted by specific character set, // set the encoding properly. if (LastTagRead.VR.SpecificCharacterSet) { if (_sqrs.Count > 0) { SequenceRecord rec = _sqrs.Peek(); bb.SpecificCharacterSet = rec.Current.SpecificCharacterSet; } else { bb.SpecificCharacterSet = Dataset.SpecificCharacterSet; } } if (LastTagRead.VR.Equals(DicomVr.UNvr) && !SaveTagRead.VR.Equals(DicomVr.UNvr) && !SaveTagRead.VR.Equals(DicomVr.SQvr) && Flags.IsSet(options, DicomReadOptions.UseDictionaryForExplicitUN)) { LastTagRead = SaveTagRead; bb.Endian = Endian.Little; } else { bb.Endian = _endian; } bb.CopyFrom(_stream, (int)_len); DicomElement elem = LastTagRead.CreateDicomAttribute(bb); _remain -= _len; BytesRead += _len; if (_sqrs.Count > 0) { SequenceRecord rec = _sqrs.Peek(); DicomDataset ds = rec.Current; if (elem.Tag.TagValue == DicomTags.SpecificCharacterSet) { ds.SpecificCharacterSet = elem.ToString(); } if (LastTagRead.Element == 0x0000) { if (Flags.IsSet(options, DicomReadOptions.KeepGroupLengths)) { ds[LastTagRead] = elem; } } else { ds[LastTagRead] = elem; } if (rec.Curlen != UndefinedLength) { long end = rec.Curpos + rec.Curlen; if (_stream.Position >= end) { rec.Current = null; } } } else { if (LastTagRead.TagValue == DicomTags.FileMetaInformationGroupLength) { // Save the end of the group 2 elements, so that we can automatically // check and change our transfer syntax when needed. _inGroup2 = true; uint group2Len; elem.TryGetUInt32(0, out group2Len); _endGroup2 = BytesRead + group2Len; } else if (LastTagRead.TagValue == DicomTags.SpecificCharacterSet) { Dataset.SpecificCharacterSet = elem.ToString(); } if (LastTagRead.Element == 0x0000) { if (Flags.IsSet(options, DicomReadOptions.KeepGroupLengths)) { Dataset[LastTagRead] = elem; } } else { Dataset[LastTagRead] = elem; } } } } } } LastTagRead = null; _vr = null; _len = UndefinedLength; } return(DicomReadStatus.Success); } catch (EndOfStreamException e) { // should never happen LogAdapter.Logger.Error("Unexpected exception when reading file: {0}", e.ToString()); return(DicomReadStatus.UnknownError); } }
/// <summary> /// Reads a DICOM file from a path /// </summary> /// <param name="filePath">the path to the file</param> /// <param name="trySyntax">the transfer syntax to use in case there is no metadata explicitly included</param> /// <returns>the DICOM Object</returns> /// <example> ///<code> ///var dcm = DICOMObject.Read("mydcm.dcm"); ///</code> ///</example> public static DICOMObject Read(string filePath, TransferSyntax trySyntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN) { return(DICOMFileReader.Read(filePath, trySyntax)); }
public MimeTypeProcessorOutput Process(ImageStreamingContext context) { Platform.CheckForNullReference(context, "context"); DicomPixelData pd = context.PixelData; MimeTypeProcessorOutput output = new MimeTypeProcessorOutput(); int frame = context.FrameNumber; if (context.FrameNumber < 0) { throw new WADOException(HttpStatusCode.BadRequest, String.Format("Requested FrameNumber {0} cannot be negative.", frame)); } else if (frame >= pd.NumberOfFrames) { throw new WADOException(HttpStatusCode.BadRequest, String.Format("Requested FrameNumber {0} exceeds the number of frames in the image.", frame)); } output.ContentType = OutputMimeType; PixelDataLoader loader = new PixelDataLoader(context); output.Output = loader.ReadFrame(frame); output.IsLast = (pd.NumberOfFrames == frame + 1); // note: the transfer syntax of the returned pixel data may not be the same as that in the original image. // In the future, the clients may specify different transfer syntaxes which may mean the compressed image must be decompressed or vice versa. TransferSyntax transferSyntax = pd.TransferSyntax; output.IsCompressed = transferSyntax.LosslessCompressed || transferSyntax.LossyCompressed; #region Special Code // Note: this block of code inject special header fields to assist the clients handling the images // For eg, the if (output.IsLast) { context.Response.Headers.Add("IsLast", "true"); } if (output.IsCompressed) { // Fields that can be used by the web clients to decompress the compressed images streamed by the server. context.Response.Headers.Add("Compressed", "true"); context.Response.Headers.Add("TransferSyntaxUid", pd.TransferSyntax.UidString); context.Response.Headers.Add("BitsAllocated", pd.BitsAllocated.ToString()); context.Response.Headers.Add("BitsStored", pd.BitsStored.ToString()); context.Response.Headers.Add("DerivationDescription", pd.DerivationDescription); context.Response.Headers.Add("HighBit", pd.HighBit.ToString()); context.Response.Headers.Add("ImageHeight", pd.ImageHeight.ToString()); context.Response.Headers.Add("ImageWidth", pd.ImageWidth.ToString()); context.Response.Headers.Add("LossyImageCompression", pd.LossyImageCompression); context.Response.Headers.Add("LossyImageCompressionMethod", pd.LossyImageCompressionMethod); context.Response.Headers.Add("LossyImageCompressionRatio", pd.LossyImageCompressionRatio.ToString()); context.Response.Headers.Add("NumberOfFrames", pd.NumberOfFrames.ToString()); context.Response.Headers.Add("PhotometricInterpretation", pd.PhotometricInterpretation); context.Response.Headers.Add("PixelRepresentation", pd.PixelRepresentation.ToString()); context.Response.Headers.Add("PlanarConfiguration", pd.PlanarConfiguration.ToString()); context.Response.Headers.Add("SamplesPerPixel", pd.SamplesPerPixel.ToString()); } #endregion if (Platform.IsLogLevelEnabled(LogLevel.Debug)) { Platform.Log(LogLevel.Debug, "Streaming {0} pixel data: {1} x {2} x {3} , {4} bits [{5} KB] ({6})", output.IsCompressed ? "compressed" : "uncompressed", pd.ImageHeight, pd.ImageWidth, pd.SamplesPerPixel, pd.BitsStored, output.Output.Length / 1024, pd.TransferSyntax.Name); } return(output); }
public static void LosslessImageTestWithBitsAllocatedConversion(TransferSyntax syntax, DicomFile theFile) { if (File.Exists(theFile.Filename)) { File.Delete(theFile.Filename); } DicomFile saveCopy = new DicomFile(theFile.Filename, theFile.MetaInfo.Copy(), theFile.DataSet.Copy()); theFile.ChangeTransferSyntax(syntax); theFile.Save(DicomWriteOptions.ExplicitLengthSequence); DicomFile newFile = new DicomFile(theFile.Filename); newFile.Load(DicomReadOptions.Default); newFile.ChangeTransferSyntax(saveCopy.TransferSyntax); string failureDescription; var newPd = DicomPixelData.CreateFrom(newFile); var oldPd = DicomPixelData.CreateFrom(saveCopy); bool result = Compare(newPd, oldPd, out failureDescription); Assert.IsFalse(result, failureDescription); Assert.IsFalse(newFile.DataSet.Equals(saveCopy.DataSet)); DicomAttributeCollection newDataSet = newFile.DataSet.Copy(true, true, true); DicomAttributeCollection oldDataSet = theFile.DataSet.Copy(true, true, true); oldDataSet.RemoveAttribute(DicomTags.BitsAllocated); newDataSet.RemoveAttribute(DicomTags.BitsAllocated); oldDataSet.RemoveAttribute(DicomTags.PixelData); newDataSet.RemoveAttribute(DicomTags.PixelData); var results = new List <DicomAttributeComparisonResult>(); bool check = oldDataSet.Equals(newDataSet, ref results); Assert.IsTrue(check, results.Count > 0 ? CollectionUtils.FirstElement(results).Details : string.Empty); for (int i = 0; i < oldPd.NumberOfFrames; i++) { var frame = oldPd.GetFrame(i); var convertedFrame = DicomUncompressedPixelData.ToggleBitDepth(frame, frame.Length, oldPd.UncompressedFrameSize, oldPd.BitsStored, oldPd.BitsAllocated); var newFrame = newPd.GetFrame(i); int pixelsVarying = 0; decimal totalVariation = 0.0m; for (int j = 0; j < convertedFrame.Length; j++) { if (convertedFrame[j] != newFrame[j]) { pixelsVarying++; totalVariation += Math.Abs(convertedFrame[i] - newFrame[i]); } } if (pixelsVarying > 0) { Assert.Fail(String.Format( "Tag (7fe0,0010) Pixel Data: {0} of {1} pixels varying, average difference: {2}", pixelsVarying, convertedFrame.Length, totalVariation / pixelsVarying)); } } }
/// <summary> /// Do the restore. /// </summary> /// <param name="queueItem">The queue item to restore.</param> public void Run(RestoreQueue queueItem) { using (var context = new RestoreProcessorContext(queueItem)) { try { // Load up related classes. using (IReadContext readContext = _hsmArchive.PersistentStore.OpenReadContext()) { _archiveStudyStorage = ArchiveStudyStorage.Load(readContext, queueItem.ArchiveStudyStorageKey); _serverSyntax = ServerTransferSyntax.Load(readContext, _archiveStudyStorage.ServerTransferSyntaxKey); _syntax = TransferSyntax.GetTransferSyntax(_serverSyntax.Uid); var parms = new StudyStorageLocationQueryParameters { StudyStorageKey = queueItem.StudyStorageKey }; var broker = readContext.GetBroker <IQueryStudyStorageLocation>(); _location = broker.FindOne(parms); if (_location == null) { _studyStorage = StudyStorage.Load(readContext, queueItem.StudyStorageKey); if (_studyStorage == null) { DateTime scheduleTime = Platform.Time.AddMinutes(5); Platform.Log(LogLevel.Error, "Unable to find storage location, rescheduling restore request to {0}", scheduleTime); queueItem.FailureDescription = "Unable to find storage location, rescheduling request."; _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Pending, scheduleTime); return; } } } if (_location == null) { Platform.Log(LogLevel.Info, "Starting restore of nearline study: {0}", _studyStorage.StudyInstanceUid); // Get the zip file path from the xml data in the ArchiveStudyStorage entry // Also store the "StudyFolder" for use below string studyFolder; string zipFile = GetZipFileName(out studyFolder); // Do a test read of the zip file. If it succeeds, the file is available, if it // fails, we just set back to pending and recheck. if (!CanReadZip(zipFile, queueItem)) { return; } RestoreNearlineStudy(queueItem, zipFile, studyFolder); } else { Platform.Log(LogLevel.Info, "Starting restore of online study: {0}", _location.StudyInstanceUid); // Get the zip file path from the xml data in the ArchiveStudyStorage entry // Also store the "StudyFolder" for use below string studyFolder; string zipFile = GetZipFileName(out studyFolder); // Do a test read of the zip file. If it succeeds, the file is available, if it // fails, we just set back to pending and recheck. if (!CanReadZip(zipFile, queueItem)) { return; } RestoreOnlineStudy(queueItem, zipFile, _location.GetStudyPath()); } } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unexpected exception processing restore request for {0} on archive {1}", _studyStorage == null ? (_location == null ? string.Empty : _location.StudyInstanceUid) : _studyStorage.StudyInstanceUid, _hsmArchive.PartitionArchive.Description); queueItem.FailureDescription = e.Message; _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Failed, Platform.Time); } } }
public static void ExpectedFailureTest(TransferSyntax syntax, DicomFile theFile) { try { theFile.ChangeTransferSyntax(syntax); } catch (DicomCodecUnsupportedSopException) { return; } Assert.IsTrue(false, "Unexpected successfull compression of object."); }
public void ChangeTransferSyntax(TransferSyntax newTransferSyntax) { ChangeTransferSyntax(newTransferSyntax, null, null); }
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) { LogAdapter.Logger.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); } DicomElement 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 = ((DicomElementBinary)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); LogAdapter.Logger.Warn("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)) { LogAdapter.Logger.Warn("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. DicomElement element; if (DataSet.TryGetAttribute(DicomTags.Rows, out element) && !element.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 element) && !element.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) { LogAdapter.Logger.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); } } DicomElement 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. DicomElement element; if (DataSet.TryGetAttribute(DicomTags.Rows, out element) && !element.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 element) && !element.IsNull) { throw new DicomCodecException("Suspect Sop appears to be an image (Columns is non-empty), but has no pixel data."); } TransferSyntax = TransferSyntax.ExplicitVrLittleEndian; } } }
/// <summary> /// Gets the <see cref="TransferSyntax"/>es of the available <see cref="IDicomCodecFactory"/> implementations. /// </summary> public static TransferSyntax[] GetCodecTransferSyntaxes() { TransferSyntax[] syntaxes = new TransferSyntax[_dictionary.Count]; _dictionary.Keys.CopyTo(syntaxes, 0); return(syntaxes); }
public StorageInstance(DicomMessage msg) { _sopClass = msg.SopClass; _syntax = msg.TransferSyntax; SopInstanceUid = msg.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty); StudyInstanceUid = msg.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty); SeriesInstanceUid = msg.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty); PatientsName = msg.DataSet[DicomTags.PatientsName].GetString(0, string.Empty); PatientId = msg.DataSet[DicomTags.PatientId].GetString(0, string.Empty); _infoLoaded = true; }
/// <summary> /// Generates a concrete element class from the VR, tag, data and syntax. Also directs the appropriate data /// interpretation. /// </summary> /// <param name="tag">the tag of the element to be generated</param> /// <param name="vr">the VR of the element to be generated</param> /// <param name="data">the raw data to be procesed (byte array)</param> /// <param name="syntax">the transfer syntax by which to interepret the data</param> /// <returns>a concrete DICOM element that uses the interface IDICOMElement</returns> public static IDICOMElement GenerateElement(Tag tag, VR vr, object data, TransferSyntax syntax, StringEncoding enc) { //HANDLE NUMBERS if (syntax == TransferSyntax.EXPLICIT_VR_BIG_ENDIAN) { switch (vr) { case VR.AttributeTag: return(new AttributeTag(tag, BigEndianReader.ReadTag(data as byte[]))); case VR.FloatingPointDouble: return(new FloatingPointDouble(tag, BigEndianReader.ReadDoublePrecision(data as byte[]))); case VR.FloatingPointSingle: return(new FloatingPointSingle(tag, BigEndianReader.ReadSinglePrecision(data as byte[]))); case VR.SignedLong: return(new SignedLong(tag, BigEndianReader.ReadSignedLong(data as byte[]))); case VR.SignedShort: return(new SignedShort(tag, BigEndianReader.ReadSignedShort(data as byte[]))); case VR.UnsignedLong: return(new UnsignedLong(tag, BigEndianReader.ReadUnsignedLong(data as byte[]))); case VR.UnsignedShort: return(new UnsignedShort(tag, BigEndianReader.ReadUnsignedShort(data as byte[]))); } } else { switch (vr) { case VR.AttributeTag: return(new AttributeTag(tag, LittleEndianReader.ReadTag(data as byte[]))); case VR.FloatingPointDouble: return(new FloatingPointDouble(tag, LittleEndianReader.ReadDoublePrecision(data as byte[]))); case VR.FloatingPointSingle: return(new FloatingPointSingle(tag, LittleEndianReader.ReadSinglePrecision(data as byte[]))); case VR.SignedLong: return(new SignedLong(tag, LittleEndianReader.ReadSignedLong(data as byte[]))); case VR.SignedShort: return(new SignedShort(tag, LittleEndianReader.ReadSignedShort(data as byte[]))); case VR.UnsignedLong: return(new UnsignedLong(tag, LittleEndianReader.ReadUnsignedLong(data as byte[]))); case VR.UnsignedShort: return(new UnsignedShort(tag, LittleEndianReader.ReadUnsignedShort(data as byte[]))); } } //HANDLE ALL OTHERS switch (vr) { //HANDLE STRINGS case VR.AgeString: case VR.ApplicationEntity: case VR.CodeString: case VR.Date: case VR.DateTime: case VR.DecimalString: case VR.IntegerString: case VR.LongString: case VR.LongText: case VR.PersonName: case VR.ShortString: case VR.ShortText: case VR.Time: case VR.UnlimitedCharacter: case VR.UnlimitedText: case VR.UniversalResourceId: case VR.UniqueIdentifier: return(ReadString(vr, tag, data, enc)); //HANDLE BYTE DATA case VR.Sequence: return(new Sequence { Tag = tag, Items = SequenceReader.ReadItems(data as byte[], syntax, enc) }); case VR.OtherByteString: return(new OtherByteString(tag, data as byte[])); case VR.OtherFloatString: return(new OtherFloatString(tag, data as byte[])); case VR.OtherWordString: return(new OtherWordString(tag, data as byte[])); case VR.OtherDoubleString: return(new OtherDoubleString(tag, data as byte[])); case VR.OtherLongString: return(new OtherLongString(tag, data as byte[])); default: var unk = new Unknown(tag, data as byte[]); unk.TransferSyntax = syntax; return(unk); } }
public DicomWriteStatus Write(TransferSyntax syntax, DicomAttributeCollection dataset, DicomWriteOptions options) { TransferSyntax = syntax; foreach (DicomAttribute item in dataset) { if (item.IsEmpty) continue; if (item.Tag.Element == 0x0000) continue; if (Flags.IsSet(options, DicomWriteOptions.CalculateGroupLengths) && item.Tag.Group != _group) { _group = item.Tag.Group; _writer.Write((ushort) _group); _writer.Write((ushort) 0x0000); if (_syntax.ExplicitVr) { _writer.Write((byte) 'U'); _writer.Write((byte) 'L'); _writer.Write((ushort) 4); } else { _writer.Write((uint) 4); } _writer.Write((uint) dataset.CalculateGroupWriteLength(_group, _syntax, options)); } _writer.Write((ushort) item.Tag.Group); _writer.Write((ushort) item.Tag.Element); if (_syntax.ExplicitVr) { _writer.Write((byte) item.Tag.VR.Name[0]); _writer.Write((byte) item.Tag.VR.Name[1]); } if (item is DicomAttributeSQ) { var sq = item as DicomAttributeSQ; if (_syntax.ExplicitVr) _writer.Write((ushort) 0x0000); if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding)) { // length field is not written when generating digital signature MAC } else if (Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequence)) { int hl = _syntax.ExplicitVr ? 12 : 8; _writer.Write((uint) sq.CalculateWriteLength(_syntax, options & ~DicomWriteOptions.CalculateGroupLengths) - (uint) hl); } else { _writer.Write((uint) _undefinedLength); } foreach (DicomSequenceItem ids in (DicomSequenceItem[]) sq.Values) { _writer.Write((ushort) DicomTag.Item.Group); _writer.Write((ushort) DicomTag.Item.Element); if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding)) { // length field is not written when generating digital signature MAC } else if (Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequenceItem)) { _writer.Write((uint) ids.CalculateWriteLength(_syntax, options & ~DicomWriteOptions.CalculateGroupLengths)); } else { _writer.Write((uint) _undefinedLength); } Write(TransferSyntax, ids, options & ~DicomWriteOptions.CalculateGroupLengths); if (!Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequenceItem) && !Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding)) { _writer.Write((ushort) DicomTag.ItemDelimitationItem.Group); _writer.Write((ushort) DicomTag.ItemDelimitationItem.Element); _writer.Write((uint) 0x00000000); } } if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding)) { _writer.Write((ushort) DicomTag.SequenceDelimitationItem.Group); _writer.Write((ushort) DicomTag.SequenceDelimitationItem.Element); } else if (!Flags.IsSet(options, DicomWriteOptions.ExplicitLengthSequence)) { _writer.Write((ushort) DicomTag.SequenceDelimitationItem.Group); _writer.Write((ushort) DicomTag.SequenceDelimitationItem.Element); _writer.Write((uint) 0x00000000); } } else if (item is DicomFragmentSequence) { var fs = item as DicomFragmentSequence; if (_syntax.ExplicitVr) _writer.Write((ushort) 0x0000); if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding)) { // length field is not written when generating digital signature MAC } else { _writer.Write((uint) _undefinedLength); } _writer.Write((ushort) DicomTag.Item.Group); _writer.Write((ushort) DicomTag.Item.Element); if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding)) { // length field is not written when generating digital signature MAC if (fs.HasOffsetTable) fs.OffsetTableBuffer.CopyTo(_writer); } else if (Flags.IsSet(options, DicomWriteOptions.WriteFragmentOffsetTable) && fs.HasOffsetTable) { _writer.Write((uint) fs.OffsetTableBuffer.Length); fs.OffsetTableBuffer.CopyTo(_writer); } else { _writer.Write((uint) 0x00000000); } foreach (DicomFragment bb in fs.Fragments) { _writer.Write((ushort) DicomTag.Item.Group); _writer.Write((ushort) DicomTag.Item.Element); if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding)) { // length field is not written when generating digital signature MAC } else { _writer.Write((uint) bb.Length); } bb.GetByteBuffer(_syntax).CopyTo(_writer); } if (Flags.IsSet(options, DicomWriteOptions.DigitalSignatureMacEncoding)) { _writer.Write((ushort) DicomTag.SequenceDelimitationItem.Group); _writer.Write((ushort) DicomTag.SequenceDelimitationItem.Element); } else { _writer.Write((ushort) DicomTag.SequenceDelimitationItem.Group); _writer.Write((ushort) DicomTag.SequenceDelimitationItem.Element); _writer.Write((uint) 0x00000000); } } else { DicomAttribute de = item; ByteBuffer theData = de.GetByteBuffer(_syntax, dataset.SpecificCharacterSet); if (_syntax.ExplicitVr) { if (de.Tag.VR.Is16BitLengthField) { // #10890: Can't encode the value length if the length of the data exceeds max value for a 16-bit field if (theData.Length > ushort.MaxValue - 1 /* must be even length so max allowed = 65534 */) throw new DicomDataException(string.Format( "Value for {0} exceeds maximum stream length allowed for a {1} VR attribute encoded using {2}", de.Tag, de.Tag.VR, _syntax)); _writer.Write((ushort) theData.Length); } else { _writer.Write((ushort) 0x0000); _writer.Write((uint) theData.Length); } } else { _writer.Write((uint) theData.Length); } if (theData.Length > 0) theData.CopyTo(_writer); } } return DicomWriteStatus.Success; }
internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax) { if (length < 4) { data = 0; br.ReadBytes((int)length); } else { data = br.ReadInt32(); if (length > 4) { br.ReadBytes((int)length - 4); } } return(length); }
public InstanceXml(XmlNode instanceNode, DicomAttributeCollection baseCollection) { InstanceXmlDicomAttributeCollection thisCollection = new InstanceXmlDicomAttributeCollection(); _collection = thisCollection; _collection.ValidateVrValues = false; _collection.ValidateVrLengths = false; if (baseCollection != null) { AddExcludedTagsFromBase(baseCollection); _baseCollectionEnumerator = baseCollection.GetEnumerator(); if (!_baseCollectionEnumerator.MoveNext()) { _baseCollectionEnumerator = null; } } if (!instanceNode.HasChildNodes) { return; } _instanceXmlEnumerator = instanceNode.ChildNodes.GetEnumerator(); if (!_instanceXmlEnumerator.MoveNext()) { _instanceXmlEnumerator = null; } if (instanceNode.Attributes["UID"] != null) { _sopInstanceUid = instanceNode.Attributes["UID"].Value; } if (instanceNode.Attributes["SourceAETitle"] != null) { _sourceAETitle = XmlUnescapeString(instanceNode.Attributes["SourceAETitle"].Value); } if (instanceNode.Attributes["SopClassUID"] != null) { _sopClass = SopClass.GetSopClass(instanceNode.Attributes["SopClassUID"].Value); } _transferSyntax = instanceNode.Attributes["TransferSyntaxUID"] != null ? TransferSyntax.GetTransferSyntax(instanceNode.Attributes["TransferSyntaxUID"].Value) : TransferSyntax.ExplicitVrLittleEndian; if (instanceNode.Attributes["SourceFileName"] != null) { _sourceFileName = instanceNode.Attributes["SourceFileName"].Value; } if (instanceNode.Attributes["FileSize"] != null) { long.TryParse(instanceNode.Attributes["FileSize"].Value, out _fileSize); } // This should never happen if (_sopClass == null) { _sopClass = SopClass.GetSopClass(Collection[DicomTags.SopClassUid].GetString(0, String.Empty)); } }
/// <summary> /// Reads a DICOM file from a path /// </summary> /// <param name="filePath">the path to the file</param> /// <param name="trySyntax">the transfer syntax to use in case there is no metadata explicitly included</param> /// <returns>the DICOM Object</returns> /// <example> ///<code> ///var dcm = DICOMObject.Read("mydcm.dcm"); ///</code> ///</example> public static async Task <DICOMObject> ReadAsync(string filePath, TransferSyntax trySyntax = TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN) { return(await DICOMFileReader.ReadAsync(filePath, trySyntax)); }