예제 #1
0
        /// <summary>
        /// Loads a dicom file, stopping at a certain tag
        /// </summary>
        /// <param name="file">Filename</param>
        /// <param name="stopTag">Tag to stop parsing at</param>
        /// <param name="options">DICOM read options</param>
        public DicomReadStatus Load(String file, DicomTag stopTag, DicomReadOptions options)
        {
            using (FileStream fs = File.OpenRead(file)) {
                fs.Seek(128, SeekOrigin.Begin);
                CheckFileHeader(fs);
                DicomStreamReader dsr = new DicomStreamReader(fs);

                _metainfo   = new DcmFileMetaInfo();
                dsr.Dataset = _metainfo;
                dsr.Read(DcmFileMetaInfo.StopTag, options | DicomReadOptions.FileMetaInfoOnly);

                if (_metainfo.TransferSyntax.IsDeflate)
                {
                    MemoryStream ms = StreamUtility.Deflate(fs, false);
                    dsr = new DicomStreamReader(ms);
                }

                _dataset    = new DcmDataset(_metainfo.TransferSyntax);
                dsr.Dataset = _dataset;
                DicomReadStatus status = dsr.Read(stopTag, options);

                fs.Close();

                return(status);
            }
        }
예제 #2
0
        private void ReadWriteOptionsTest(DicomFile sourceFile, DicomReadOptions readOptions, DicomWriteOptions options)
        {
            var sourceIconImageSq = (DicomAttributeSQ)sourceFile.DataSet[DicomTags.IconImageSequence];

            Assert.IsTrue(!sourceIconImageSq.IsEmpty && !sourceIconImageSq.IsNull && sourceIconImageSq.Count == 1, "File doesn't have icon image sequence");
            Assert.IsTrue(sourceFile.Save(options), "Failed to write file");

            var newFile = new DicomFile(sourceFile.Filename);

            newFile.Load(readOptions);

            var    resultList    = new List <DicomAttributeComparisonResult>();
            var    result        = sourceFile.DataSet.Equals(newFile.DataSet, ref resultList);
            string resultMessage = resultList.Count > 0 ? resultList.First().ToString() : string.Empty;

            Assert.IsTrue(result, resultMessage);

            var newIconImageSq = (DicomAttributeSQ)newFile.DataSet[DicomTags.IconImageSequence];

            Assert.IsTrue(!newIconImageSq.IsEmpty && !newIconImageSq.IsNull && newIconImageSq.Count == 1, "New file doesn't have icon image sequence");

            // update a tag, and make sure it shows they're different
            newFile.DataSet[DicomTags.PatientsName].Values = "NewPatient^First";
            Assert.IsFalse(sourceFile.DataSet.Equals(newFile.DataSet, ref resultList));

            // Now update the original file with the name, and they should be the same again
            sourceFile.DataSet[DicomTags.PatientsName].Values = "NewPatient^First";
            Assert.IsTrue(sourceFile.DataSet.Equals(newFile.DataSet));

            // Return the original string value.
            sourceFile.DataSet[DicomTags.PatientsName].SetStringValue("Patient^Test");
        }
예제 #3
0
        public void WriteOptionsTest(DicomFile sourceFile, DicomWriteOptions options)
        {
            bool result = sourceFile.Save(options);

            Assert.AreEqual(result, true);

            DicomFile newFile = new DicomFile(sourceFile.Filename);

            DicomReadOptions readOptions = DicomReadOptions.Default;

            newFile.Load(readOptions);

            Assert.AreEqual(sourceFile.DataSet.Equals(newFile.DataSet), true);

            // update a tag, and make sure it shows they're different
            newFile.DataSet[DicomTags.PatientsName].Values = "NewPatient^First";
            Assert.AreEqual(sourceFile.DataSet.Equals(newFile.DataSet), false);

            // Now update the original file with the name, and they should be the same again
            sourceFile.DataSet[DicomTags.PatientsName].Values = "NewPatient^First";
            Assert.AreEqual(sourceFile.DataSet.Equals(newFile.DataSet), true);

            // Return the original string value.
            sourceFile.DataSet[DicomTags.PatientsName].SetStringValue("Patient^Test");
        }
예제 #4
0
        /// <summary>
        /// Load a DICOM file (as set by the <see cref="Filename"/> property).
        /// </summary>
        /// <remarks>
        /// Note:  If the file does not contain DICM encoded in it, the routine will assume
        /// the file is not a Part 10 format file, and is instead encoded as just a DataSet
        /// with the transfer syntax set to Implicit VR Little Endian.
        /// </remarks>
        /// <param name="stopTag">A tag to stop at when reading the file.  See the constants in <see cref="DicomTags"/>.</param>
        /// <param name="options">The options to use when reading the file.</param>
        public void Load(uint stopTag, DicomReadOptions options)
        {
            DicomTag stopDicomTag = DicomTagDictionary.GetDicomTag(stopTag) ??
                                    new DicomTag(stopTag, "Bogus Tag", "BogusTag", DicomVr.NONE, false, 1, 1, false);

            Load(stopDicomTag, options);
        }
예제 #5
0
        /// <summary>
        /// Load a DICOM file from an input stream.
        /// </summary>
        /// <remarks>
        /// Note:  If the file does not contain DICM encoded in it, and
        /// <see cref="Stream.CanSeek"/> is true for <paramref name="stream"/>,
        /// the routine will assume the file is not a Part 10 format file, and is
        /// instead encoded as just a DataSet with the transfer syntax set to
        /// Implicit VR Little Endian.
        /// </remarks>
        /// <param name="stream">The input stream to read from.</param>
        public void Load(Stream stream)
        {
            const DicomReadOptions options = DicomReadOptions.Default;

            Platform.CheckForNullReference(stream, "stream");
            LoadCore(stream, null, null, options);
        }
예제 #6
0
        public void SimpleFileTest()
        {
            DicomFile file = new DicomFile("LittleEndianReadFileTest.dcm");

            DicomAttributeCollection dataSet = file.DataSet;

            SetupMR(dataSet);

            SetupMetaInfo(file);

            dataSet[DicomTags.StudyDescription].SetNullValue();

            // Little Endian Tests
            file.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;

            DicomReadOptions readOptions = DicomReadOptions.Default;

            bool result = file.Save(DicomWriteOptions.Default);

            Assert.AreEqual(result, true);

            DicomFile newFile = new DicomFile(file.Filename);

            newFile.Load(readOptions);

            Assert.IsTrue(newFile.DataSet[DicomTags.StudyDescription].IsNull);

            Assert.AreEqual(file.DataSet.Equals(newFile.DataSet), true);

            DicomAttributeCollection dicomAttributeCollection = new DicomAttributeCollection();

            dicomAttributeCollection[DicomTags.PatientId].SetNullValue();
            Assert.IsFalse(dicomAttributeCollection[DicomTags.PatientId].IsEmpty, "Dicom Tag is empty, won't be written in DicomStreamWriter.Write()");
        }
예제 #7
0
        /// <summary>
        /// Creates an instance of <see cref="DicomPixelData"/> from specified image path
        /// </summary>
        /// <param name="path"></param>
        /// <param name="readOptions"></param>
        /// <returns>
        /// </returns>
        public static DicomPixelData CreateFrom(string path, DicomReadOptions readOptions)
        {
            var file = new DicomFile(path);

            file.Load(readOptions);
            return(CreateFrom(file));
        }
예제 #8
0
        /// <summary>
        /// Creates an instance of <see cref="DicomPixelData"/> from specified stream
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="stream"></param>
        /// <param name="readOptions"></param>
        /// <returns>
        /// </returns>
        public static DicomPixelData CreateFrom(string filename, Stream stream, DicomReadOptions readOptions)
        {
            var file = new DicomFile(filename);

            file.Load(stream, null, readOptions);
            return(CreateFrom(file));
        }
예제 #9
0
        private DicomReadStatus InsertFragmentItem(DicomReadOptions options)
        {
            if (_tag == DicomTags.Item)
            {
                if (_len > _remain)
                {
                    return(NeedMoreData(_len));
                }

                ByteBuffer data = CurrentBuffer(options);
                _remain -= _len;
                _read   += _len;

                if (!_fragment.HasOffsetTable)
                {
                    _fragment.SetOffsetTable(data);
                }
                else
                {
                    _fragment.AddFragment(data);
                }
            }
            else if (_tag == DicomTags.SequenceDelimitationItem)
            {
                _fragment = null;
            }
            else
            {
                // unexpected tag
                return(DicomReadStatus.UnknownError);
            }
            return(DicomReadStatus.Success);
        }
예제 #10
0
 /// <summary>
 /// Load a DICOM file from an input stream, given a delegate to open the stream.
 /// </summary>
 /// <remarks>
 /// Note:  If the file does not contain DICM encoded in it, and
 /// <see cref="Stream.CanSeek"/> is true for the stream returned by <paramref name="streamOpener"/>,
 /// the routine will assume the file is not a Part 10 format file, and is
 /// instead encoded as just a DataSet with the transfer syntax set to
 /// Implicit VR Little Endian.
 ///
 /// Also, if you are using the <see cref="DicomReadOptions.StorePixelDataReferences"/> option with
 /// a <see cref="Stream"/> as opposed to simply a file name, you must use this method so that the
 /// stream can be reopenened internally whenever pixel data is accessed.
 /// </remarks>
 /// <param name="streamOpener">A delegate that opens the stream to read from.</param>
 /// <param name="stopTag">The dicom tag to stop the reading at.</param>
 /// <param name="options">The dicom read options to consider.</param>
 public void Load(DicomStreamOpener streamOpener, DicomTag stopTag, DicomReadOptions options)
 {
     Platform.CheckForNullReference(streamOpener, "streamOpener");
     StreamOpener = streamOpener;
     using (var stream = streamOpener.Open())
         LoadCore(stream, streamOpener, stopTag, options);
 }
예제 #11
0
        private void InsertDatasetItem(DcmItem item, DicomReadOptions options)
        {
            if (_sds.Count > 0 && _sds.Count == _sqs.Count)
            {
                DcmDataset ds = _sds.Peek();

                if (_tag.Element == 0x0000)
                {
                    if (Flags.IsSet(options, DicomReadOptions.KeepGroupLengths))
                    {
                        ds.AddItem(item);
                    }
                }
                else
                {
                    ds.AddItem(item);
                }

                if (ds.StreamLength != UndefinedLength)
                {
                    long end = ds.StreamPosition + ds.StreamLength;
                    if ((_stream.Position - _offset) >= end)
                    {
                        _sds.Pop();
                    }
                }
            }
            else
            {
                if (_tag.Element == 0x0000)
                {
                    if (Flags.IsSet(options, DicomReadOptions.KeepGroupLengths))
                    {
                        _dataset.AddItem(item);
                    }
                }
                else
                {
                    _dataset.AddItem(item);
                }
            }

            if (_tag == DicomTags.SpecificCharacterSet && item is DcmCodeString)
            {
                DcmCodeString cs = (DcmCodeString)item;
                if (cs.Length > 0)
                {
                    string[] values = cs.GetValues();
                    for (int i = 0; i < values.Length; i++)
                    {
                        if (String.IsNullOrEmpty(values[i]))
                        {
                            continue;
                        }
                        _encoding = DcmEncoding.GetEncodingForSpecificCharacterSet(values[i]);
                        break;
                    }
                }
            }
        }
예제 #12
0
 /// <summary>
 /// Load a DICOM file (as set by the <see cref="Filename"/> property).
 /// </summary>
 /// <remarks>
 /// Note:  If the file does not contain DICM encoded in it, the routine will assume
 /// the file is not a Part 10 format file, and is instead encoded as just a DataSet
 /// with the transfer syntax set to Implicit VR Little Endian.
 /// </remarks>
 /// <param name="stopTag"></param>
 /// <param name="options">The options to use when reading the file.</param>
 public void Load(DicomTag stopTag, DicomReadOptions options)
 {
     using (FileStream fs = File.OpenRead(Filename))
     {
         Load(fs, stopTag, options);
         fs.Close();
     }
 }
예제 #13
0
        /// <summary>
        /// Load a DICOM file (as set by the <see cref="Filename"/> property).
        /// </summary>
        /// <remarks>
        /// Note:  If the file does not contain DICM encoded in it, the routine will assume
        /// the file is not a Part 10 format file, and is instead encoded as just a DataSet
        /// with the transfer syntax set to Implicit VR Little Endian.
        /// </remarks>
        /// <param name="stopTag"></param>
        /// <param name="options">The options to use when reading the file.</param>
        public void Load(DicomTag stopTag, DicomReadOptions options)
        {
            var streamOpener = StreamOpener;

            Platform.CheckForNullReference(streamOpener, "filename");             // the only reason why stream opener is null here is because filename is empty
            using (var stream = streamOpener.Open())
                LoadCore(stream, streamOpener, stopTag, options);
        }
예제 #14
0
 /// <summary>
 /// Load a DICOM file (as set by the <see cref="Filename"/> property).
 /// </summary>
 /// <remarks>
 /// Note:  If the file does not contain DICM encoded in it, the routine will assume
 /// the file is not a Part 10 format file, and is instead encoded as just a DataSet
 /// with the transfer syntax set to Implicit VR Little Endian.
 /// </remarks>
 /// <param name="stopTag"></param>
 /// <param name="options">The options to use when reading the file.</param>
 /// <param name="file">The path of the file to load.</param>
 public void Load(DicomTag stopTag, DicomReadOptions options, string file)
 {
     if (file == null)
     {
         throw new ArgumentNullException("file");
     }
     Filename = file;
     Load(stopTag, options);
 }
예제 #15
0
        public void FixedSequenceLengthTest()
        {
            var file = new DicomFile("FixedSequenceLengthTest.dcm");

            DicomAttributeCollection dataSet = file.DataSet;

            SetupMR(dataSet);

            SetupMetaInfo(file);

            dataSet[DicomTags.StudyDescription].SetNullValue();

            // Force another empty tag
            var s = dataSet[DicomTags.ServiceEpisodeId];

            var item = new DicomSequenceItem();

            item[DicomTags.PhotometricInterpretation].AppendString("MONOCHROME1");
            item[DicomTags.Rows].AppendUInt16(256);
            item[DicomTags.Columns].AppendUInt16(256);
            item[DicomTags.BitsAllocated].AppendUInt16(8);
            item[DicomTags.BitsStored].AppendUInt16(8);
            item[DicomTags.HighBit].AppendUInt16(7);
            item[DicomTags.PixelData].Values = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };

            // Force an empty tag
            var m = item[DicomTags.LossyImageCompression];

            var privateTagSQ = new DicomTag(0x00091038, "PrivateSQ", "PrivateSQ", DicomVr.SQvr, true, 1, 10, false);

            dataSet[privateTagSQ].AddSequenceItem(item);


            // Little Endian Tests
            file.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;

            const DicomReadOptions  readOptions  = DicomReadOptions.Default;
            const DicomWriteOptions writeOptions = DicomWriteOptions.ExplicitLengthSequence | DicomWriteOptions.ExplicitLengthSequenceItem;

            bool result = file.Save(writeOptions);

            Assert.AreEqual(result, true);

            var newFile = new DicomFile(file.Filename);

            newFile.Load(readOptions);

            Assert.IsTrue(newFile.DataSet[DicomTags.StudyDescription].IsNull);

            Assert.AreEqual(file.DataSet.Equals(newFile.DataSet), true);

            var dicomAttributeCollection = new DicomAttributeCollection();

            dicomAttributeCollection[DicomTags.PatientId].SetNullValue();
            Assert.IsFalse(dicomAttributeCollection[DicomTags.PatientId].IsEmpty, "Dicom Tag is empty, won't be written in DicomStreamWriter.Write()");
        }
예제 #16
0
        private ByteBuffer CurrentBuffer(DicomReadOptions options)
        {
#if SILVERLIGHT
            ByteBuffer bb = new ByteBuffer(_endian);
            bb.CopyFrom(_stream, (int)_len);
#else
            ByteBuffer bb = null;

            if (_isFile)
            {
                bool delayLoad = false;
                if (_len >= _largeElementSize && _vr != DicomVR.SQ)
                {
                    if (Flags.IsSet(options, DicomReadOptions.DeferLoadingLargeElements))
                    {
                        delayLoad = true;
                    }
                    else if (Flags.IsSet(options, DicomReadOptions.DeferLoadingPixelData) && _tag == DicomTags.PixelData)
                    {
                        delayLoad = true;
                    }
                    else if (Flags.IsSet(options, DicomReadOptions.DeferLoadingPixelData) && _fragment != null && _fragment.Tag == DicomTags.PixelData)
                    {
                        delayLoad = true;
                    }
                }

                if (delayLoad)
                {
                    FileStream  fs      = (FileStream)_stream;
                    FileSegment segment = new FileSegment(fs.Name, fs.Position, _len);
                    _stream.Seek(_len, SeekOrigin.Current);
                    bb = new ByteBuffer(segment, _endian);
                }
            }

            if (bb == null)
            {
                bb = new ByteBuffer(_endian);
                bb.CopyFrom(_stream, (int)_len);
            }
#endif
            if (_vr.IsEncodedString)
            {
                bb.Encoding = _encoding;
            }

            return(bb);
        }
예제 #17
0
        private void ButtonLoadFile_Click(object sender, EventArgs e)
        {
            openFileDialog.DefaultExt = "dcm";
            openFileDialog.ShowDialog();

            DicomFile dicomFile = new DicomFile(openFileDialog.FileName);

            DicomReadOptions options = new DicomReadOptions();

            dicomFile.Load(options);



            _theStream.AddFile(dicomFile);
        }
예제 #18
0
        private void ButtonLoadFile_Click(object sender, EventArgs e)
        {
            openFileDialog.DefaultExt = "dcm";
            openFileDialog.ShowDialog();

            DicomFile dicomFile = new DicomFile(openFileDialog.FileName);

            DicomReadOptions options = new DicomReadOptions();

            dicomFile.Load(options);
            


            _theStream.AddFile(dicomFile);

        }
예제 #19
0
        public void PrivateAttributeTest()
        {
            DicomFile file = new DicomFile("LittleEndianPrivateReadFileTest.dcm");

            DicomAttributeCollection dataSet = file.DataSet;

            SetupMR(dataSet);
            dataSet[DicomTags.StudyDescription].SetNullValue();

            List <DicomTag> tagList = new List <DicomTag>();

            SetupPrivateGroups(tagList, dataSet);

            SetupMetaInfo(file);


            // Little Endian Tests
            file.TransferSyntax = TransferSyntax.ImplicitVrLittleEndian;

            DicomReadOptions readOptions = DicomReadOptions.Default;

            // Use ExplicitLengthSequence to force SQ attributes to UN VR when they're read back in
            Assert.IsTrue(file.Save(DicomWriteOptions.ExplicitLengthSequence));

            DicomFile newFile = new DicomFile(file.Filename);

            newFile.Load(readOptions);

            Assert.IsTrue(newFile.DataSet[DicomTags.StudyDescription].IsNull);

            Assert.AreNotEqual(file.DataSet.Equals(newFile.DataSet), true);

            foreach (DicomTag tag in tagList)
            {
                DicomAttributeUN unAttrib = newFile.DataSet[tag] as DicomAttributeUN;
                Assert.IsNotNull(unAttrib, String.Format("UN VR Attribute is not null for tag {0}", tag));

                ByteBuffer bb = unAttrib.GetByteBuffer(TransferSyntax.ImplicitVrLittleEndian,
                                                       newFile.DataSet[DicomTags.SpecificCharacterSet].ToString());
                Assert.IsNotNull(bb, String.Format("ByteBuffer not null for tag: {0}", tag));

                DicomAttribute validAttrib = tag.VR.CreateDicomAttribute(tag, bb);
                Assert.IsNotNull(validAttrib);

                Assert.IsTrue(validAttrib.Equals(file.DataSet[tag]), String.Format("Attributes equal for tag {0}", tag));
            }
        }
예제 #20
0
        public void ReadPixelDataReferencesTest()
        {
            DicomFile file = new DicomFile("LittleEndianReadFileTest2.dcm");

            DicomAttributeCollection dataSet = file.DataSet;

            SetupMR(dataSet);

            SetupMetaInfo(file);

            // Little Endian Tests
            file.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;

            DicomReadOptions readOptions = DicomReadOptions.StorePixelDataReferences;
            bool             result      = file.Save(DicomWriteOptions.Default);

            Assert.AreEqual(result, true);

            DicomFile newFile = new DicomFile(file.Filename);

            newFile.Load(readOptions);

            DicomAttribute attrib = newFile.DataSet[DicomTags.PixelData];

            Assert.IsFalse(attrib.IsEmpty);
            Assert.IsFalse(attrib.IsNull);
            Assert.AreEqual(attrib.StreamLength, dataSet[DicomTags.PixelData].StreamLength);

            // Set the pixel data to null and re-read
            dataSet[DicomTags.PixelData].SetNullValue();

            result = file.Save(DicomWriteOptions.Default);
            Assert.AreEqual(result, true);

            newFile = new DicomFile(file.Filename);

            newFile.Load(readOptions);

            attrib = newFile.DataSet[DicomTags.PixelData];

            Assert.IsFalse(attrib.IsEmpty);
            Assert.IsTrue(attrib.IsNull);
            Assert.AreEqual(attrib.StreamLength, dataSet[DicomTags.PixelData].StreamLength);
        }
예제 #21
0
        public void ReadOptionsTest(DicomFile sourceFile, DicomReadOptions options, bool areEqual)
        {
            bool result = sourceFile.Save(DicomWriteOptions.Default);

            Assert.AreEqual(result, true);

            DicomFile newFile = new DicomFile(sourceFile.Filename);

            newFile.Load(options);

            if (areEqual)
            {
                Assert.AreEqual(sourceFile.DataSet.Equals(newFile.DataSet), true);
            }
            else
            {
                Assert.AreNotEqual(sourceFile.DataSet.Equals(newFile.DataSet), true);
            }
        }
예제 #22
0
        private void ImportFile(string file, ImportStudyContext context)
        {
            // Note, we're not doing impersonation of the user's identity, so we may have failures here
            // which would be new in Marmot.
            try
            {
                EnsureMaxUsedSpaceNotExceeded();

                var dicomFile = new DicomFile(file);

                DicomReadOptions readOptions = Request.FileImportBehaviour == FileImportBehaviourEnum.Save
                                                   ? DicomReadOptions.Default
                                                   : DicomReadOptions.Default | DicomReadOptions.StorePixelDataReferences;

                dicomFile.Load(readOptions);

                var importer = new ImportFilesUtility(context);

                DicomProcessingResult result = importer.Import(dicomFile, Request.BadFileBehaviour, Request.FileImportBehaviour);

                if (result.DicomStatus == DicomStatuses.Success)
                {
                    Progress.NumberOfFilesImported++;
                }
                else
                {
                    Progress.NumberOfImportFailures++;
                    Progress.StatusDetails = result.ErrorMessage;
                }
            }
            catch (NotEnoughStorageException)
            {
                Progress.NumberOfImportFailures++;
                Progress.StatusDetails = SR.ExceptionNotEnoughStorage;
                context.FatalError     = true;
            }
            catch (Exception e)
            {
                Platform.Log(LogLevel.Warn, "Unable to import DICOM File ({0}): {1}", file, e.Message);
                Progress.NumberOfImportFailures++;
                Progress.StatusDetails = string.Format("{0}: {1}", file, e.Message);
            }
        }
예제 #23
0
        public void MultiframeReadTest()
        {
            DicomFile file = new DicomFile("LittleEndianMultiframeTest.dcm");

            DicomAttributeCollection dataSet = file.DataSet;

            SetupMultiframeXA(dataSet, 511, 511, 5);

            SetupMetaInfo(file);

            // Little Endian Tests
            file.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;

            DicomReadOptions readOptions = DicomReadOptions.Default;

            ReadOptionsTest(file, readOptions, true);

            readOptions = DicomReadOptions.StorePixelDataReferences;
            ReadOptionsTest(file, readOptions, true);

            readOptions = DicomReadOptions.DoNotStorePixelDataInDataSet;
            ReadOptionsTest(file, readOptions, false);

            readOptions = DicomReadOptions.None;
            ReadOptionsTest(file, readOptions, true);


            // Big Endian Tests
            file.Filename       = "BigEndianMultiframeTest.dcm";
            file.TransferSyntax = TransferSyntax.ExplicitVrBigEndian;

            readOptions = DicomReadOptions.Default;
            ReadOptionsTest(file, readOptions, true);

            readOptions = DicomReadOptions.StorePixelDataReferences;
            ReadOptionsTest(file, readOptions, true);

            readOptions = DicomReadOptions.DoNotStorePixelDataInDataSet;
            ReadOptionsTest(file, readOptions, false);

            readOptions = DicomReadOptions.None;
            ReadOptionsTest(file, readOptions, true);
        }
예제 #24
0
 /// <summary>
 /// Loads a dicom file, stopping at a certain tag
 /// </summary>
 /// <param name="file">Filename</param>
 /// <param name="stopTag">Tag to stop parsing at</param>
 /// <param name="options">DICOM read options</param>
 /// <param name="useIsoStore">Load file from isolated storage</param>
 public DicomReadStatus Load(String file, DicomTag stopTag, DicomReadOptions options, bool useIsoStore = false)
 {
     if (useIsoStore)
     {
         using (var store = IsolatedStorageFile.GetUserStoreForApplication())
         {
             using (var fs = store.OpenFile(file, FileMode.Open, FileAccess.Read))
             {
                 return(Load(fs, stopTag, options));
             }
         }
     }
     else
     {
         using (var fs = File.OpenRead(file))
         {
             return(Load(fs, stopTag, options));
         }
     }
 }
예제 #25
0
        private void LoadFiles(DirectoryInfo dir)
        {
         
            FileInfo[] files = dir.GetFiles();

            foreach (FileInfo file in files)
            {

                DicomFile dicomFile = new DicomFile(file.FullName);

                try
                {

                    DicomReadOptions options = new DicomReadOptions();


                    dicomFile.Load(options);
                    _theStream.AddFile(dicomFile);
                    /*
					if (true == dicomFile.Load())
					{
						_theStream.AddFile(dicomFile);
					}
                     * */
                }
                catch (DicomException) 
                {
                    // TODO:  Add some logging for failed files
                }

            }

            String[] subdirectories = Directory.GetDirectories(dir.FullName);
            foreach (String subPath in subdirectories)
            {
                DirectoryInfo subDir = new DirectoryInfo(subPath);
                LoadFiles(subDir);
                continue;
            }

        }
예제 #26
0
        public void TestRoundtripEncapsulatedImageEncapsulatedIconFileReferences()
        {
            var file = new DicomFile("TestRoundtripEncapsulatedImageEncapsulatedIconFileReferences.dcm");

            SetupEncapsulatedImageWithIconSequence(file, true);

            const DicomReadOptions readOptions = DicomReadOptions.Default | DicomReadOptions.StorePixelDataReferences;

            var writeOptions = DicomWriteOptions.WriteFragmentOffsetTable;

            ReadWriteOptionsTest(file, readOptions, writeOptions);

            writeOptions = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequence;
            ReadWriteOptionsTest(file, readOptions, writeOptions);

            writeOptions = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequenceItem;
            ReadWriteOptionsTest(file, readOptions, writeOptions);

            writeOptions = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequenceItem | DicomWriteOptions.ExplicitLengthSequence;
            ReadWriteOptionsTest(file, readOptions, writeOptions);
        }
예제 #27
0
        public void TestRoundtripEncapsulatedImageNativeIcon()
        {
            var file = new DicomFile("TestRoundtripEncapsulatedImageNativeIcon.dcm");

            SetupEncapsulatedImageWithIconSequence(file, false);

            const DicomReadOptions readOptions = DicomReadOptions.Default;

            var writeOptions = DicomWriteOptions.WriteFragmentOffsetTable;

            ReadWriteOptionsTest(file, readOptions, writeOptions);

            writeOptions = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequence;
            ReadWriteOptionsTest(file, readOptions, writeOptions);

            writeOptions = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequenceItem;
            ReadWriteOptionsTest(file, readOptions, writeOptions);

            writeOptions = DicomWriteOptions.WriteFragmentOffsetTable | DicomWriteOptions.ExplicitLengthSequenceItem | DicomWriteOptions.ExplicitLengthSequence;
            ReadWriteOptionsTest(file, readOptions, writeOptions);
        }
예제 #28
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                PrintCommandLine();
                return;
            }

            if (false == ParseArgs(args))
            {
                return;
            }

            foreach (String filename in args)
            {
                if (filename.StartsWith("-"))
                {
                    continue;
                }

                DicomFile file = new DicomFile(filename);

                DicomReadOptions readOptions = DicomReadOptions.Default;

                try
                {
                    file.Load(readOptions);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Unexpected exception when loading file: {0}", e.Message);
                }

                StringBuilder sb = new StringBuilder();

                file.Dump(sb, "", _options);

                Console.WriteLine(sb.ToString());
            }
        }
예제 #29
0
        private void CheckPixels(string filename)
        {
            DicomReadOptions readOptions = DicomReadOptions.StorePixelDataReferences;
            DicomFile        newFile     = new DicomFile(filename);

            newFile.Load(readOptions);
            DicomUncompressedPixelData pd = new DicomUncompressedPixelData(newFile.DataSet);

            for (int frame = 0; frame < pd.NumberOfFrames; frame++)
            {
                byte[] data  = pd.GetFrame(frame);
                uint   pdVal = (uint)frame + 1;
                for (int i = 0; i < pd.UncompressedFrameSize; i++, pdVal++)
                {
                    if (data[i] != pdVal % 255)
                    {
                        string val = String.Format("Value bad: frame: {0}, pixel: {1}, val1: {2}, val2: {3}", frame, i, data[i], pdVal % 255);
                        Console.Write(val);
                    }
                    Assert.AreEqual(data[i], pdVal % 255);
                }
            }
        }
예제 #30
0
        private void LoadFiles(DirectoryInfo dir)
        {
            FileInfo[] files = dir.GetFiles();

            foreach (FileInfo file in files)
            {
                DicomFile dicomFile = new DicomFile(file.FullName);

                try
                {
                    DicomReadOptions options = new DicomReadOptions();


                    dicomFile.Load(options);
                    _theStream.AddFile(dicomFile);

                    /*
                     *                  if (true == dicomFile.Load())
                     *                  {
                     *                          _theStream.AddFile(dicomFile);
                     *                  }
                     * */
                }
                catch (DicomException)
                {
                    // TODO:  Add some logging for failed files
                }
            }

            String[] subdirectories = Directory.GetDirectories(dir.FullName);
            foreach (String subPath in subdirectories)
            {
                DirectoryInfo subDir = new DirectoryInfo(subPath);
                LoadFiles(subDir);
                continue;
            }
        }
예제 #31
0
 public static bool IsSet(DicomReadOptions options, DicomReadOptions flag)
 {
     return((options & flag) == flag);
 }
예제 #32
0
        /// <summary>
        /// Load a DICOM file from an input stream.
        /// </summary>
        /// <remarks>
        /// Note:  If the file does not contain DICM encoded in it, and 
        /// <see cref="Stream.CanSeek"/> is true for <paramref name="iStream"/>, 
        /// the routine will assume the file is not a Part 10 format file, and is 
        /// instead encoded as just a DataSet with the transfer syntax set to 
        /// Implicit VR Little Endian.
        /// </remarks>
        /// <param name="iStream">The input stream to read from.</param>
        /// <param name="stopTag">The dicom tag to stop the reading at.</param>
        /// <param name="options">The dicom read options to consider.</param>
        public void Load(Stream iStream, DicomTag stopTag, DicomReadOptions options)
        {
            if (iStream == null) throw new ArgumentNullException("iStream");

            if (stopTag == null)
                stopTag = new DicomTag(0xFFFFFFFF, "Bogus Tag", "BogusTag", DicomVr.NONE, false, 1, 1, false);

            DicomStreamReader dsr;

            if (iStream.CanSeek)
            {
                iStream.Seek(128, SeekOrigin.Begin);
                if (!FileHasPart10Header(iStream))
                {
                    if (!Flags.IsSet(options, DicomReadOptions.ReadNonPart10Files))
                        throw new DicomException(String.Format("File is not part 10 format file: {0}", Filename));

                    iStream.Seek(0, SeekOrigin.Begin);
                    dsr = new DicomStreamReader(iStream)
                              {
                                  Filename = Filename,
                                  TransferSyntax = TransferSyntax.ImplicitVrLittleEndian,
                                  Dataset = DataSet
                              };
                    DicomReadStatus stat = dsr.Read(stopTag, options);
                    if (stat != DicomReadStatus.Success)
                    {
                        Platform.Log(LogLevel.Error, "Unexpected error when reading file: {0}", Filename);
                        throw new DicomException("Unexpected read error with file: " + Filename);
                    }

                    TransferSyntax = TransferSyntax.ImplicitVrLittleEndian;
                    if (DataSet.Contains(DicomTags.SopClassUid))
                        MediaStorageSopClassUid = DataSet[DicomTags.SopClassUid].ToString();
                    if (DataSet.Contains(DicomTags.SopInstanceUid))
                        MediaStorageSopInstanceUid = DataSet[DicomTags.SopInstanceUid].ToString();
                    return;
                }
            }
            else
            {
                // Read the 128 byte header first, then check for DICM
                iStream.Read(new byte[128], 0, 128);

                if (!FileHasPart10Header(iStream))
                {
                    Platform.Log(LogLevel.Error, "Reading DICOM file from stream, file does not have part 10 format header.");
                    throw new DicomException("File being read from stream is not a part 10 format file");
                }
            }

            dsr = new DicomStreamReader(iStream)
                      {
                          TransferSyntax = TransferSyntax.ExplicitVrLittleEndian,
                          Filename = Filename,
                          Dataset = MetaInfo
                      };

            DicomReadStatus readStat =
                dsr.Read(new DicomTag(0x0002FFFF, "Bogus Tag", "BogusTag", DicomVr.UNvr, false, 1, 1, false), options);
            if (readStat != DicomReadStatus.Success)
            {
                Platform.Log(LogLevel.Error, "Unexpected error when reading file Meta info for file: {0}", Filename);
                throw new DicomException("Unexpected failure reading file Meta info for file: " + Filename);
            }

	        MetaInfoFileLength = dsr.EndGroupTwo + 128 + 4;

            dsr.Dataset = DataSet;
            dsr.TransferSyntax = TransferSyntax;
            readStat = dsr.Read(stopTag, options);
            if (readStat != DicomReadStatus.Success)
            {
                Platform.Log(LogLevel.Error, "Unexpected error ({0}) when reading file at offset {2}: {1}", readStat, Filename,dsr.BytesRead);
                throw new DicomException("Unexpected failure (" + readStat + ") reading file at offset " + dsr.BytesRead + ": " + Filename);
            }

			Loaded = true;

        }
예제 #33
0
 /// <summary>
 /// Load a DICOM file (as set by the <see cref="Filename"/> property).
 /// </summary>
 /// <remarks>
 /// Note:  If the file does not contain DICM encoded in it, the routine will assume
 /// the file is not a Part 10 format file, and is instead encoded as just a DataSet
 /// with the transfer syntax set to Implicit VR Little Endian.
 /// </remarks>
 /// <param name="stopTag"></param>
 /// <param name="options">The options to use when reading the file.</param>
 /// <param name="file">The path of the file to load.</param>
 public void Load(DicomTag stopTag, DicomReadOptions options, string file)
 {
     if (file == null) throw new ArgumentNullException("file");
     Filename = file;
     Load(stopTag, options);
 }
예제 #34
0
 /// <summary>
 /// Load a DICOM file (as set by the <see cref="Filename"/> property).
 /// </summary>
 /// <remarks>
 /// Note:  If the file does not contain DICM encoded in it, the routine will assume
 /// the file is not a Part 10 format file, and is instead encoded as just a DataSet
 /// with the transfer syntax set to Implicit VR Little Endian.
 /// </remarks>
 /// <param name="options">The options to use when reading the file.</param>
 public void Load(DicomReadOptions options)
 {
     Load(null, options);
 }
예제 #35
0
		/// <summary>
		/// Load a DICOM file from an input stream.
		/// </summary>
		/// <remarks>
		/// Note:  If the file does not contain DICM encoded in it, and 
		/// <see cref="Stream.CanSeek"/> is true for <paramref name="stream"/>, 
		/// the routine will assume the file is not a Part 10 format file, and is 
		/// instead encoded as just a DataSet with the transfer syntax set to 
		/// Implicit VR Little Endian.
		/// 
		/// Also, this overload cannot be used directly with <see cref="DicomReadOptions.StorePixelDataReferences"/>,
		/// as there must be a way to re-open the same stream at a later time. If the option is required,
		/// use the <see cref="Load(Func{Stream}, DicomTag, DicomReadOptions)">overload</see> that accepts a delegate for opening the stream.
		/// </remarks>
		/// <param name="stream">The input stream to read from.</param>
		/// <param name="stopTag">The dicom tag to stop the reading at.</param>
		/// <param name="options">The dicom read options to consider.</param>
		public void Load(Stream stream, DicomTag stopTag, DicomReadOptions options)
		{
			Platform.CheckForNullReference(stream, "stream");
			LoadCore(stream, null, stopTag, options);
		}
예제 #36
0
		/// <summary>
		/// Load a DICOM file (as set by the <see cref="Filename"/> property).
		/// </summary>
		/// <remarks>
		/// Note:  If the file does not contain DICM encoded in it, the routine will assume
		/// the file is not a Part 10 format file, and is instead encoded as just a DataSet
		/// with the transfer syntax set to Implicit VR Little Endian.
		/// </remarks>
		/// <param name="stopTag"></param>
		/// <param name="options">The options to use when reading the file.</param>
		public void Load(DicomTag stopTag, DicomReadOptions options)
		{
			var streamOpener = StreamOpener;
			Platform.CheckForNullReference(streamOpener, "filename"); // the only reason why stream opener is null here is because filename is empty
			using (var stream = streamOpener.Open())
			{
				LoadCore(stream, streamOpener, stopTag, options);
				stream.Close();
			}
		}
예제 #37
0
		/// <summary>
		/// Creates an instance of <see cref="DicomPixelData"/> from specified image path
		/// </summary>
		/// <param name="path"></param>
		/// <param name="readOptions"></param>
		/// <returns>
		/// </returns>
		public static DicomPixelData CreateFrom(string path, DicomReadOptions readOptions)
		{
			var file = new DicomFile(path);
			file.Load(readOptions);
			return CreateFrom(file);
		}
예제 #38
0
        private void InsertDatasetItem(DcmItem item, DicomReadOptions options)
        {
            if (_sds.Count > 0 && _sds.Count == _sqs.Count) {
                DcmDataset ds = _sds.Peek();

                if (_tag.Element == 0x0000) {
                    if (Flags.IsSet(options, DicomReadOptions.KeepGroupLengths))
                        ds.AddItem(item);
                }
                else
                    ds.AddItem(item);

                if (ds.StreamLength != UndefinedLength) {
                    long end = ds.StreamPosition + ds.StreamLength;
                    if ((_stream.Position - _offset) >= end)
                        _sds.Pop();
                }
            }
            else {
                if (_tag.Element == 0x0000) {
                    if (Flags.IsSet(options, DicomReadOptions.KeepGroupLengths))
                        _dataset.AddItem(item);
                }
                else
                    _dataset.AddItem(item);
            }

            if (_tag == DicomTags.SpecificCharacterSet && item is DcmCodeString) {
                DcmCodeString cs = (DcmCodeString)item;
                if (cs.Length > 0) {
                    string[] values = cs.GetValues();
                    for (int i = 0; i < values.Length; i++) {
                        if (String.IsNullOrEmpty(values[i]))
                            continue;
                        _encoding = DcmEncoding.GetEncodingForSpecificCharacterSet(values[i]);
                        break;
                    }
                }
            }
        }
예제 #39
0
        private ByteBuffer CurrentBuffer(DicomReadOptions options)
        {
            ByteBuffer bb = null;

            if (_isFile) {
                bool delayLoad = false;
                if (_len >= _largeElementSize && _vr != DicomVR.SQ) {
                    if (Flags.IsSet(options, DicomReadOptions.DeferLoadingLargeElements))
                        delayLoad = true;
                    else if (Flags.IsSet(options, DicomReadOptions.DeferLoadingPixelData) && _tag == DicomTags.PixelData)
                        delayLoad = true;
                    else if (Flags.IsSet(options, DicomReadOptions.DeferLoadingPixelData) && _fragment != null && _fragment.Tag == DicomTags.PixelData)
                        delayLoad = true;
                }

                if (delayLoad) {
                    FileStream fs = (FileStream)_stream;
                    FileSegment segment = new FileSegment(fs.Name, fs.Position, _len);
                    _stream.Seek(_len, SeekOrigin.Current);
                    bb = new ByteBuffer(segment, _endian);
                }
            }

            if (bb == null) {
                bb = new ByteBuffer(_endian);
                bb.CopyFrom(_stream, (int)_len);
            }

            if (_vr.IsEncodedString)
                bb.Encoding = _encoding;

            return bb;
        }
예제 #40
0
        /// <summary>
        /// Read dataset from stream
        /// </summary>
        /// <param name="stopAtTag">End parsing at this tag</param>
        /// <param name="options">DICOM read options</param>
        /// <returns>Status code</returns>
        public DicomReadStatus Read(DicomTag stopAtTag, DicomReadOptions options)
        {
            // Counters:
            //  _remain - bytes remaining in stream
            //  _bytes - estimates bytes to end of dataset
            //  _read - number of bytes read from stream
            try {
                _need = 0;
                _remain = _stream.Length - _stream.Position;

                while (_remain > 0) {
                    DicomReadStatus status = ParseTag(stopAtTag, options);
                    if (status == DicomReadStatus.SuccessEndRead)
                        return DicomReadStatus.Success;
                    if (status != DicomReadStatus.Success)
                        return status;

                    status = ParseVR(options);
                    if (status != DicomReadStatus.Success)
                        return status;

                    status = ParseLength(options);
                    if (status != DicomReadStatus.Success)
                        return status;

                    if (_tag.IsPrivate) {
                        if (_tag.Element != 0x0000 && _tag.Element <= 0x00ff) {
                            // handle UN private creator id
                            if (_vr != DicomVR.LO && Flags.IsSet(options, DicomReadOptions.ForcePrivateCreatorToLO)) {
                                Dicom.Debug.Log.Warn("Converting Private Creator VR from '{0}' to 'LO'", _vr.VR);
                                _vr = DicomVR.LO;
                            }
                        }
                    }

                    if (_vr == DicomVR.UN && _syntax.IsExplicitVR && Flags.IsSet(options, DicomReadOptions.UseDictionaryForExplicitUN)) {
                        _vr = _tag.Entry.DefaultVR;
                    }

                    if (_fragment != null) {
                        status = InsertFragmentItem(options);
                        if (status != DicomReadStatus.Success)
                            return status;
                    }
                    else if (_sqs.Count > 0 &&
                                (_tag == DicomTags.Item ||
                                 _tag == DicomTags.ItemDelimitationItem ||
                                 _tag == DicomTags.SequenceDelimitationItem)) {
                        status = InsertSequenceItem(options);
                        if (status != DicomReadStatus.Success)
                            return status;
                    }
                    else {
                        if (_sqs.Count > 0) {
                            DcmItemSequence sq = _sqs.Peek();
                            if (sq.StreamLength != UndefinedLength) {
                                long end = sq.StreamPosition + 8 + sq.StreamLength;
                                if (_syntax.IsExplicitVR)
                                    end += 2 + 2;
                                if ((_stream.Position - _offset) >= end) {
                                    if (_sds.Count == _sqs.Count)
                                        _sds.Pop();
                                    _sqs.Pop();
                                }
                            }
                        }

                        if (_len == UndefinedLength) {
                            if (_vr == DicomVR.SQ) {
                                DcmItemSequence sq = new DcmItemSequence(_tag, _pos, _len, _endian);
                                InsertDatasetItem(sq, options);
                                _sqs.Push(sq);
                            }
                            else {
                                _fragment = new DcmFragmentSequence(_tag, _vr, _pos, _endian);
                                InsertDatasetItem(_fragment, options);
                            }
                        }
                        else {
                            if (_vr == DicomVR.SQ) {
                                DcmItemSequence sq = new DcmItemSequence(_tag, _pos, _len, _endian);
                                InsertDatasetItem(sq, options);
                                _sqs.Push(sq);
                            }
                            else {
                                if (_len > _remain)
                                    return NeedMoreData(_len);

                                DcmElement elem = DcmElement.Create(_tag, _vr, _pos, _endian, CurrentBuffer(options));
                                _remain -= _len;
                                _read += _len;

                                InsertDatasetItem(elem, options);
                            }
                        }
                    }

                    _tag = null;
                    _vr = null;
                    _len = UndefinedLength;
                }

                return DicomReadStatus.Success;
            }
            catch (EndOfStreamException) {
                // should never happen
                return DicomReadStatus.UnknownError;
            }
        }
예제 #41
0
 public static bool IsSet(DicomReadOptions options, DicomReadOptions flag)
 {
     return (options & flag) == flag;
 }
예제 #42
0
 /// <summary>
 /// Loads a dicom file, stopping at a certain tag
 /// </summary>
 /// <param name="file">Filename</param>
 /// <param name="stopTag">Tag to stop parsing at</param>
 /// <param name="options">DICOM read options</param>
 /// <param name="useIsoStore">Load file from isolated storage</param>
 public DicomReadStatus Load(String file, DicomTag stopTag, DicomReadOptions options, bool useIsoStore = false)
 {
     if (useIsoStore)
     {
         using (var store = IsolatedStorageFile.GetUserStoreForApplication())
         {
             using (var fs = store.OpenFile(file, FileMode.Open, FileAccess.Read))
             {
                 return Load(fs, stopTag, options);
             }
         }
     }
     else
     {
         using (var fs = File.OpenRead(file))
         {
             return Load(fs, stopTag, options);
         }
     }
 }
예제 #43
0
        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
                        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(Filename, _stream.Position, _len, _endian, DicomVr.OBvr);
								DicomFragment fragment =
									new DicomFragment(reference);
								_fragment.AddFragment(fragment);
								_stream.Seek(_len, SeekOrigin.Current);
							}
							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)
						{
							Dataset[_fragment.Tag] = _fragment;
							_fragment = null;
						}
						else
						{
							Platform.Log(LogLevel.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,
                                                         		Filename = Filename
                                                         	};
                            	DicomReadStatus stat = idsr.Read(null, options);
                                if (stat != DicomReadStatus.Success)
                                {
									Platform.Log(LogLevel.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.
									Platform.Log(LogLevel.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);

                                Dataset.LoadDicomFields(_fragment);
                            }
                        }
                        else
                        {
							if (_vr.Equals(DicomVr.SQvr))
							{
								if (_len == 0)
								{
									DicomAttributeCollection 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 !!
									_stream.Seek((int) _len, SeekOrigin.Current);
									_remain -= _len;
									BytesRead += _len;
								}
								else if ((LastTagRead.TagValue == DicomTags.PixelData) &&
								         Flags.IsSet(options, DicomReadOptions.StorePixelDataReferences))
								{
									FileReference reference =
										new FileReference(Filename, _stream.Position, _len, _endian,
										                  LastTagRead.VR);
									_stream.Seek((int) _len, SeekOrigin.Current);

									if (LastTagRead.VR.Equals(DicomVr.OWvr))
									{
										DicomAttributeOW elem = new DicomAttributeOW(LastTagRead, reference);
										Dataset[LastTagRead] = elem;
									}
									else if (LastTagRead.VR.Equals(DicomVr.OBvr))
									{
										DicomAttributeOB elem = new DicomAttributeOB(LastTagRead, reference);
										Dataset[LastTagRead] = elem;
									}
									else
									{
										DicomAttributeOF elem = new DicomAttributeOF(LastTagRead, reference);
										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);


									DicomAttribute elem = LastTagRead.CreateDicomAttribute(bb);

									_remain -= _len;
									BytesRead += _len;


									if (_sqrs.Count > 0)
									{
										SequenceRecord rec = _sqrs.Peek();
										DicomAttributeCollection 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
				Platform.Log(LogLevel.Error, "Unexpected exception when reading file: {0}", e.ToString());
                return DicomReadStatus.UnknownError;
            }
        }
예제 #44
0
        private DicomReadStatus InsertFragmentItem(DicomReadOptions options)
        {
            if (_tag == DicomTags.Item) {
                if (_len > _remain)
                    return NeedMoreData(_len);

                ByteBuffer data = CurrentBuffer(options);
                _remain -= _len;
                _read += _len;

                if (!_fragment.HasOffsetTable)
                    _fragment.SetOffsetTable(data);
                else
                    _fragment.AddFragment(data);
            }
            else if (_tag == DicomTags.SequenceDelimitationItem) {
                _fragment = null;
            }
            else {
                // unexpected tag
                return DicomReadStatus.UnknownError;
            }
            return DicomReadStatus.Success;
        }
예제 #45
0
		/// <summary>
		/// Creates an instance of <see cref="DicomPixelData"/> from specified stream
		/// </summary>
		/// <param name="filename"></param>
		/// <param name="stream"></param>
		/// <param name="readOptions"></param>
		/// <returns>
		/// </returns>
		public static DicomPixelData CreateFrom(string filename, Stream stream, DicomReadOptions readOptions)
		{
			var file = new DicomFile(filename);
			file.Load(stream, null, readOptions);
			return CreateFrom(file);
		}
예제 #46
0
        private DicomReadStatus InsertSequenceItem(DicomReadOptions options)
        {
            if (_tag.Equals(DicomTags.Item)) {
                if (_len != UndefinedLength && _len > _remain)
                    return NeedMoreData(_len);

                if (_sds.Count > _sqs.Count)
                    _sds.Pop();

                DcmItemSequenceItem si = new DcmItemSequenceItem(_pos, _len);

                if (_len != UndefinedLength || (_stream.CanSeek && Flags.IsSet(options, DicomReadOptions.AllowSeekingForContext))) {
                    if (_len == UndefinedLength)
                        options |= DicomReadOptions.SequenceItemOnly;

                    DcmDataset ds = null;
                    DicomReadStatus status = ParseSequenceItemDataset(TransferSyntax, _len, out ds, options);

                    if (status != DicomReadStatus.Success) {
                        Dicom.Debug.Log.Warn("Unknown error while attempting to read sequence item.  Trying again with alternate encodings.");

                        DicomTransferSyntax[] syntaxes = null;
                        if (TransferSyntax == DicomTransferSyntax.ExplicitVRBigEndian)
                            syntaxes = new DicomTransferSyntax[] { DicomTransferSyntax.ImplicitVRLittleEndian, DicomTransferSyntax.ExplicitVRLittleEndian };
                        else if (TransferSyntax.IsExplicitVR)
                            syntaxes = new DicomTransferSyntax[] { DicomTransferSyntax.ImplicitVRLittleEndian, DicomTransferSyntax.ExplicitVRBigEndian };
                        else
                            syntaxes = new DicomTransferSyntax[] { DicomTransferSyntax.ExplicitVRLittleEndian, DicomTransferSyntax.ExplicitVRBigEndian };

                        foreach (DicomTransferSyntax tx in syntaxes) {
                            status = ParseSequenceItemDataset(tx, _len, out ds, options);
                            if (status == DicomReadStatus.Success)
                                break;
                        }
                    }

                    if (status != DicomReadStatus.Success)
                        return DicomReadStatus.UnknownError;

                    si.Dataset = ds;

                    if (_len == UndefinedLength) {
                        if (8 > _remain) {
                            // need more data?
                            _sds.Push(ds);
                        }
                        else {
                            // skip delimitation item
                            _stream.Seek(8, SeekOrigin.Current);
                            _remain -= 8;
                            _bytes += 8;
                            _read += 8;
                        }
                    }
                }
                else {
                    DcmDataset ds = new DcmDataset(_pos + 8, _len, TransferSyntax);
                    _sds.Push(ds);
                }

                _sqs.Peek().AddSequenceItem(si);
            }
            else if (_tag == DicomTags.ItemDelimitationItem) {
                if (_sds.Count == _sqs.Count)
                    _sds.Pop();
            }
            else if (_tag == DicomTags.SequenceDelimitationItem) {
                if (_sds.Count == _sqs.Count)
                    _sds.Pop();
                _sqs.Pop();
            }
            return DicomReadStatus.Success;
        }
예제 #47
0
		/// <summary>
		/// Load a DICOM file (as set by the <see cref="Filename"/> property).
		/// </summary>
		/// <remarks>
		/// Note:  If the file does not contain DICM encoded in it, the routine will assume
		/// the file is not a Part 10 format file, and is instead encoded as just a DataSet
		/// with the transfer syntax set to Implicit VR Little Endian.
		/// </remarks>
		/// <param name="stopTag"></param>
		/// <param name="options">The options to use when reading the file.</param>
		/// <param name="filename">The path of the file to load.</param>
		public void Load(DicomTag stopTag, DicomReadOptions options, string filename)
		{
			Platform.CheckForEmptyString(filename, "filename");
			Filename = filename;
			Load(stopTag, options);
		}
예제 #48
0
        private DicomReadStatus ParseLength(DicomReadOptions options)
        {
            if (_len == UndefinedLength) {
                if (_syntax.IsExplicitVR) {
                    if (_tag == DicomTags.Item ||
                        _tag == DicomTags.ItemDelimitationItem ||
                        _tag == DicomTags.SequenceDelimitationItem) {
                        if (_remain >= 4) {
                            _len = _reader.ReadUInt32();
                            _remain -= 4;
                            _bytes += 4;
                            _read += 4;
                        }
                        else {
                            return NeedMoreData(4);
                        }
                    }
                    else {
                        if (_vr.Is16BitLengthField) {
                            if (_remain >= 2) {
                                _len = (uint)_reader.ReadUInt16();
                                _remain -= 2;
                                _bytes += 2;
                                _read += 2;
                            } else {
                                return NeedMoreData(2);
                            }
                        }
                        else {
                            if (_remain >= 6) {
                                _reader.ReadByte();
                                _reader.ReadByte();
                                _len = _reader.ReadUInt32();
                                _remain -= 6;
                                _bytes += 6;
                                _read += 6;
                            }
                            else {
                                return NeedMoreData(6);
                            }
                        }
                    }
                }
                else {
                    if (_remain >= 4) {
                        _len = _reader.ReadUInt32();
                        _remain -= 4;
                        _bytes += 4;
                        _read += 4;
                    }
                    else {
                        return NeedMoreData(4);
                    }
                }

                if (_len != UndefinedLength) {
                    if (_vr != DicomVR.SQ && !(_tag.Equals(DicomTags.Item) && _fragment == null))
                        _bytes += _len;
                }
            }
            return DicomReadStatus.Success;
        }
예제 #49
0
		/// <summary>
		/// Load a DICOM file from an input stream, given a delegate to open the stream.
		/// </summary>
		/// <remarks>
		/// Note:  If the file does not contain DICM encoded in it, and 
		/// <see cref="Stream.CanSeek"/> is true for the stream returned by <paramref name="streamOpener"/>, 
		/// the routine will assume the file is not a Part 10 format file, and is 
		/// instead encoded as just a DataSet with the transfer syntax set to 
		/// Implicit VR Little Endian.
		/// 
		/// Also, if you are using the <see cref="DicomReadOptions.StorePixelDataReferences"/> option with
		/// a <see cref="Stream"/> as opposed to simply a file name, you must use this method so that the
		/// stream can be reopenened internally whenever pixel data is accessed.
		/// </remarks>
		/// <param name="streamOpener">A delegate that opens the stream to read from.</param>
		/// <param name="stopTag">The dicom tag to stop the reading at.</param>
		/// <param name="options">The dicom read options to consider.</param>
		public void Load(DicomStreamOpener streamOpener, DicomTag stopTag, DicomReadOptions options)
		{
			Platform.CheckForNullReference(streamOpener, "streamOpener");
			StreamOpener = streamOpener;
			using (var stream = streamOpener.Open())
			{
				LoadCore(stream, streamOpener, stopTag, options);
				stream.Close();
			}
		}
예제 #50
0
        private DicomReadStatus ParseSequenceItemDataset(DicomTransferSyntax syntax, long len, out DcmDataset dataset, DicomReadOptions options)
        {
            long pos = _stream.Position;

            dataset = new DcmDataset(pos, (uint)len, syntax);

            Stream stream = (len != UndefinedLength) ? new SegmentStream(_stream, _stream.Position, _len) : _stream;

            DicomStreamReader idsr = new DicomStreamReader(stream);
            idsr.Dataset = dataset;
            idsr.Encoding = _encoding;
            if (len != UndefinedLength)
                idsr.PositionOffset = dataset.StreamPosition;

            DicomReadStatus status = idsr.Read(null, options);

            if (status != DicomReadStatus.Success) {
                _stream.Seek(pos, SeekOrigin.Begin);
                dataset = null;
            }
            else {
                if (len == UndefinedLength) {
                    // rewind delimitation item tag
                    _stream.Seek(-4, SeekOrigin.Current);

                    len = _stream.Position - pos;
                }

                _remain -= len;
                _bytes += len;
                _read += len;
            }

            return status;
        }
예제 #51
0
		private void LoadCore(Stream stream, DicomStreamOpener streamOpener, DicomTag stopTag, DicomReadOptions options)
		{
			// TODO CR (24 Jan 2014): DICOM stream read only uses tag value, so the real implementation should be the uint overload!
			if (stopTag == null)
				stopTag = new DicomTag(0xFFFFFFFF, "Bogus Tag", "BogusTag", DicomVr.NONE, false, 1, 1, false);

			DicomStreamReader dsr;

			var iStream = stream ?? streamOpener.Open();
			if (iStream.CanSeek)
			{
				iStream.Seek(128, SeekOrigin.Begin);
				if (!FileHasPart10Header(iStream))
				{
					if (!Flags.IsSet(options, DicomReadOptions.ReadNonPart10Files))
						throw new DicomException(String.Format("File is not part 10 format file: {0}", Filename));

					iStream.Seek(0, SeekOrigin.Begin);
					dsr = new DicomStreamReader(iStream)
					      	{
					      		StreamOpener = streamOpener,
					      		TransferSyntax = TransferSyntax.ImplicitVrLittleEndian,
					      		Dataset = DataSet
					      	};
					DicomReadStatus stat = dsr.Read(stopTag, options);
					if (stat != DicomReadStatus.Success)
					{
						Platform.Log(LogLevel.Error, "Unexpected error when reading file: {0}", Filename);
						throw new DicomException("Unexpected read error with file: " + Filename);
					}

					TransferSyntax = TransferSyntax.ImplicitVrLittleEndian;
					if (DataSet.Contains(DicomTags.SopClassUid))
						MediaStorageSopClassUid = DataSet[DicomTags.SopClassUid].ToString();
					if (DataSet.Contains(DicomTags.SopInstanceUid))
						MediaStorageSopInstanceUid = DataSet[DicomTags.SopInstanceUid].ToString();

					Loaded = true;
					return;
				}
			}
			else
			{
				// TODO CR (04 Apr 2014): this code here is almost identical to the seekable stream above, except that we use the 4CC wrapper
				// we can combine these two when we trust that the wrapper works in all cases
				iStream = FourCcReadStream.Create(iStream);

				// Read the 128 byte header first, then check for DICM
				iStream.SeekEx(128, SeekOrigin.Begin);

				if (!FileHasPart10Header(iStream))
				{
					if (!Flags.IsSet(options, DicomReadOptions.ReadNonPart10Files))
						throw new DicomException(String.Format("File is not part 10 format file: {0}", Filename));

					iStream.Seek(0, SeekOrigin.Begin);
					dsr = new DicomStreamReader(iStream)
					      	{
					      		StreamOpener = streamOpener,
					      		TransferSyntax = TransferSyntax.ImplicitVrLittleEndian,
					      		Dataset = DataSet
					      	};
					DicomReadStatus stat = dsr.Read(stopTag, options);
					if (stat != DicomReadStatus.Success)
					{
						Platform.Log(LogLevel.Error, "Unexpected error when reading file: {0}", Filename);
						throw new DicomException("Unexpected read error with file: " + Filename);
					}

					TransferSyntax = TransferSyntax.ImplicitVrLittleEndian;
					if (DataSet.Contains(DicomTags.SopClassUid))
						MediaStorageSopClassUid = DataSet[DicomTags.SopClassUid].ToString();
					if (DataSet.Contains(DicomTags.SopInstanceUid))
						MediaStorageSopInstanceUid = DataSet[DicomTags.SopInstanceUid].ToString();

					Loaded = true;
					return;
				}
			}

			dsr = new DicomStreamReader(iStream)
			      	{
			      		TransferSyntax = TransferSyntax.ExplicitVrLittleEndian,
			      		StreamOpener = streamOpener,
			      		Dataset = MetaInfo
			      	};

			DicomReadStatus readStat =
				dsr.Read(new DicomTag(0x0002FFFF, "Bogus Tag", "BogusTag", DicomVr.UNvr, false, 1, 1, false), options);
			if (readStat != DicomReadStatus.Success)
			{
				Platform.Log(LogLevel.Error, "Unexpected error when reading file Meta info for file: {0}", Filename);
				throw new DicomException("Unexpected failure reading file Meta info for file: " + Filename);
			}

			MetaInfoFileLength = dsr.EndGroupTwo + 128 + 4;

			dsr.Dataset = DataSet;
			dsr.TransferSyntax = TransferSyntax;
			readStat = dsr.Read(stopTag, options);
			if (readStat != DicomReadStatus.Success)
			{
				Platform.Log(LogLevel.Error, "Unexpected error ({0}) when reading file at offset {2}: {1}", readStat, Filename, dsr.BytesRead);
				throw new DicomException("Unexpected failure (" + readStat + ") reading file at offset " + dsr.BytesRead + ": " + Filename);
			}

			Loaded = true;
		}
예제 #52
0
        private DicomReadStatus ParseTag(DicomTag stopAtTag, DicomReadOptions options)
        {
            if (_tag == null) {
                if (_remain >= 4) {
                    _pos = _stream.Position + _offset;
                    ushort g = _reader.ReadUInt16();
                    if (Flags.IsSet(options, DicomReadOptions.FileMetaInfoOnly) && g != 0x0002) {
                        _stream.Seek(-2, SeekOrigin.Current);
                        return DicomReadStatus.SuccessEndRead;
                    }
                    ushort e = _reader.ReadUInt16();
                    if (DicomTag.IsPrivateGroup(g) && e > 0x00ff) {
                        uint card = DicomTag.GetCard(g, e);
                        if ((card & 0xffffff00) != _privateCreatorCard) {
                            _privateCreatorCard = card & 0xffffff00;
                            DicomTag pct = DicomTag.GetPrivateCreatorTag(g, e);
                            DcmDataset ds = _dataset;
                            if (_sds.Count > 0 && _sds.Count == _sqs.Count) {
                                ds = _sds.Peek();
                                if (!ds.Contains(pct))
                                    ds = _dataset;
                            }
                            _privateCreatorId = ds.GetString(pct, String.Empty);
                        }
                        _tag = new DicomTag(g, e, _privateCreatorId);
                    }
                    else {
                        _tag = new DicomTag(g, e);

                        if (g == 0xfffe) {
                            if (_tag == DicomTags.Item ||
                                _tag == DicomTags.ItemDelimitationItem ||
                                _tag == DicomTags.SequenceDelimitationItem)
                                _vr = DicomVR.NONE;
                        }
                    }
                    _remain -= 4;
                    _bytes += 4;
                    _read += 4;
                }
                else {
                    return NeedMoreData(4);
                }
            }

            if (_tag == DicomTags.ItemDelimitationItem && Flags.IsSet(options, DicomReadOptions.SequenceItemOnly))
                return DicomReadStatus.SuccessEndRead;

            if (_tag >= stopAtTag)
                return DicomReadStatus.SuccessEndRead;

            return DicomReadStatus.Success;
        }
예제 #53
0
 /// <summary>
 /// Load a DICOM file (as set by the <see cref="Filename"/> property).
 /// </summary>
 /// <remarks>
 /// Note:  If the file does not contain DICM encoded in it, the routine will assume
 /// the file is not a Part 10 format file, and is instead encoded as just a DataSet
 /// with the transfer syntax set to Implicit VR Little Endian.
 /// </remarks>
 /// <param name="stopTag">A tag to stop at when reading the file.  See the constants in <see cref="DicomTags"/>.</param>
 /// <param name="options">The options to use when reading the file.</param>
 public void Load(uint stopTag, DicomReadOptions options)
 {
     DicomTag stopDicomTag = DicomTagDictionary.GetDicomTag(stopTag) ??
                             new DicomTag(stopTag, "Bogus Tag", "BogusTag", DicomVr.NONE, false, 1, 1, false);
     Load(stopDicomTag, options);
 }
예제 #54
0
        private DicomReadStatus ParseVR(DicomReadOptions options)
        {
            if (_vr == null) {
                if (_syntax.IsExplicitVR) {
                    if (_remain >= 2) {
                        _vr = DicomVR.Lookup(_reader.ReadChars(2));
                        _remain -= 2;
                        _bytes += 2;
                        _read += 2;
                    }
                    else {
                        return NeedMoreData(2);
                    }
                }
                else {
                    if (_tag.Element == 0x0000)
                        _vr = DicomVR.UL;
                    else if (Flags.IsSet(options, DicomReadOptions.ForcePrivateCreatorToLO) &&
                        _tag.IsPrivate && _tag.Element > 0x0000 && _tag.Element <= 0x00ff)
                        _vr = DicomVR.UN;
                    else
                        _vr = _tag.Entry.DefaultVR;
                }

                if (_vr == DicomVR.UN) {
                    if (_tag.Element == 0x0000)
                        _vr = DicomVR.UL; // is this needed?
                    else if (_tag.IsPrivate) {
                        if (_tag.Element <= 0x00ff) {
                            // private creator id
                        } else if (_stream.CanSeek && Flags.IsSet(options, DicomReadOptions.AllowSeekingForContext)) {
                            // attempt to identify private sequence
                            long pos = _stream.Position;
                            if (_syntax.IsExplicitVR) {
                                if (_remain >= 2)
                                    _reader.ReadUInt16();
                                else {
                                    _vr = null;
                                    _stream.Position = pos;
                                    return NeedMoreData(2);
                                }
                            }

                            uint l = 0;
                            if (_remain >= 4) {
                                l = _reader.ReadUInt32();
                                if (l == UndefinedLength)
                                    _vr = DicomVR.SQ;
                            } else {
                                _vr = null;
                                _stream.Position = pos;
                                return NeedMoreData(4);
                            }

                            //if (l != 0 && _vr == DicomVR.UN) {
                            //    if (_remain >= 4) {
                            //        ushort g = _reader.ReadUInt16();
                            //        ushort e = _reader.ReadUInt16();
                            //        DicomTag tag = new DicomTag(g, e);
                            //        if (tag == DicomTags.Item || tag == DicomTags.SequenceDelimitationItem)
                            //            _vr = DicomVR.SQ;
                            //    } else {
                            //        _vr = null;
                            //        _stream.Position = pos;
                            //        return NeedMoreData(4);
                            //    }
                            //}

                            _stream.Position = pos;
                        }
                    }
                }
            }
            return DicomReadStatus.Success;
        }
예제 #55
0
        /// <summary>
        /// Load a DICOM file (as set by the <see cref="Filename"/> property).
        /// </summary>
        /// <remarks>
        /// Note:  If the file does not contain DICM encoded in it, the routine will assume
        /// the file is not a Part 10 format file, and is instead encoded as just a DataSet
        /// with the transfer syntax set to Implicit VR Little Endian.
        /// </remarks>
        /// <param name="stopTag"></param>
        /// <param name="options">The options to use when reading the file.</param>
		public void Load(DicomTag stopTag, DicomReadOptions options)
        {
        	using (FileStream fs = File.OpenRead(Filename))
        	{
        		Load(fs, stopTag, options);
				fs.Close();
        	}
        }
예제 #56
0
        public void ReadOptionsTest(DicomFile sourceFile, DicomReadOptions options, bool areEqual)
        {
            bool result = sourceFile.Save(DicomWriteOptions.Default);

            Assert.AreEqual(result, true);

            DicomFile newFile = new DicomFile(sourceFile.Filename);

            newFile.Load(options);

            if (areEqual)
                Assert.AreEqual(sourceFile.DataSet.Equals(newFile.DataSet), true);
            else
                Assert.AreNotEqual(sourceFile.DataSet.Equals(newFile.DataSet), true);
        }
예제 #57
0
		/// <summary>
		/// Loads a dicom file
		/// </summary>
		/// <param name="file">Filename</param>
		/// <param name="options">DICOM read options</param>
		public DicomReadStatus Load(String file, DicomReadOptions options) {
			return Load(file, null, options);
		}
예제 #58
0
 /// <summary>
 /// Loads a dicom file
 /// </summary>
 /// <param name="fs">File stream to read</param>
 /// <param name="options">DICOM read options</param>
 public DicomReadStatus Load(Stream fs, DicomReadOptions options)
 {
     return Load(fs, null, options);
 }
예제 #59
0
        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)
                            {
                                Platform.Log(LogLevel.Debug, "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();
                                DicomAttributeCollection 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
                        {
                            Platform.Log(LogLevel.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)
                                {
                                    Platform.Log(LogLevel.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.
                                    Platform.Log(LogLevel.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)
                                {
                                    DicomAttributeCollection 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);
                                    }

                                    DicomAttribute elem;
                                    if (LastTagRead.VR.Equals(DicomVr.OWvr))
                                    {
                                        elem = new DicomAttributeOW(LastTagRead, reference);
                                    }
                                    else if (LastTagRead.VR.Equals(DicomVr.OBvr))
                                    {
                                        elem = new DicomAttributeOB(LastTagRead, reference);
                                    }
                                    else if (LastTagRead.VR.Equals(DicomVr.ODvr))
                                    {
                                        elem = new DicomAttributeOD(LastTagRead, reference);
                                    }
                                    else
                                    {
                                        elem = new DicomAttributeOF(LastTagRead, reference);
                                    }

                                    if (_sqrs.Count > 0)
                                    {
                                        SequenceRecord           rec = _sqrs.Peek();
                                        DicomAttributeCollection 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);

                                    DicomAttribute elem = LastTagRead.CreateDicomAttribute(bb);

                                    _remain   -= _len;
                                    BytesRead += _len;

                                    if (_sqrs.Count > 0)
                                    {
                                        SequenceRecord           rec = _sqrs.Peek();
                                        DicomAttributeCollection 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
                Platform.Log(LogLevel.Error, "Unexpected exception when reading file: {0}", e.ToString());
                return(DicomReadStatus.UnknownError);
            }
        }
예제 #60
0
		/// <summary>
		/// Loads a dicom file, stopping at a certain tag
		/// </summary>
		/// <param name="file">Filename</param>
		/// <param name="stopTag">Tag to stop parsing at</param>
		/// <param name="options">DICOM read options</param>
		public DicomReadStatus Load(String file, DicomTag stopTag, DicomReadOptions options) {
			using (FileStream fs = File.OpenRead(file)) {
				fs.Seek(128, SeekOrigin.Begin);
				CheckFileHeader(fs);
				DicomStreamReader dsr = new DicomStreamReader(fs);

				_metainfo = new DcmFileMetaInfo();
				dsr.Dataset = _metainfo;
				dsr.Read(DcmFileMetaInfo.StopTag, options | DicomReadOptions.FileMetaInfoOnly);

				if (_metainfo.TransferSyntax.IsDeflate) {
					MemoryStream ms = StreamUtility.Deflate(fs, false);
					dsr = new DicomStreamReader(ms);
				}

				_dataset = new DcmDataset(_metainfo.TransferSyntax);
				dsr.Dataset = _dataset;
				DicomReadStatus status = dsr.Read(stopTag, options);

				fs.Close();

				return status;
			}
		}