/// <summary>
		/// Recalculates the group lengths for all groups in the <paramref name="dataset"/>. Removes any group lengths for groups with out elements.
		/// </summary>
		/// <remarks>For most use cases, this method will be called by the library as needed and will not need to be called by the user.</remarks>
		/// <param name="dataset">DICOM dataset</param>
		/// <param name="createIfMissing">If set to <c>true</c>, group length elements will be created if missing. If set to <c>false</c>, only groups with existing group lengths will be recalculated.</param>
		public static void RecalculateGroupLengths(this DicomDataset dataset, bool createIfMissing = true) {
			// recalculate group lengths for sequences first
			foreach (var sq in dataset.Where(x => x.ValueRepresentation == DicomVR.SQ).Cast<DicomSequence>()) {
				foreach (var item in sq.Items) {
					item.RecalculateGroupLengths(createIfMissing);
				}
			}

			var calculator = new DicomWriteLengthCalculator(dataset.InternalTransferSyntax, DicomWriteOptions.Default);

			IEnumerable<ushort> groups = null;
			if (createIfMissing)
				groups = dataset.Select(x => x.Tag.Group).Distinct();
			else
				groups = dataset.Where(x => x.Tag.Element == 0x0000).Select(x => x.Tag.Group);

			foreach (var group in groups.ToList()) {
				var items = dataset.EnumerateGroup(group).ToList();

				if (items.Count == 0) {
					// no items exist for the specified group; remove
					dataset.Remove(new DicomTag(group, 0x0000));
					return;
				}

				uint length = calculator.Calculate(items);
				dataset.Add(new DicomTag(group, 0x0000), length);
			}
		}
Example #2
0
		public bool OnBeginSequenceItem(DicomDataset dataset) {
			uint length = UndefinedLength;

			if (_options.ExplicitLengthSequenceItems) {
				DicomWriteLengthCalculator calc = new DicomWriteLengthCalculator(_syntax, _options);
				length = calc.Calculate(dataset);
			}

			WriteTagHeader(DicomTag.Item, DicomVR.NONE, length);
			return true;
		}
Example #3
0
        /// <summary>
        /// Handler for traversing beginning of sequence item.
        /// </summary>
        /// <param name="dataset">Item dataset.</param>
        /// <returns>true if traversing completed without issues, false otherwise.</returns>
        /// <remarks>On false return value, the method will invoke the callback method passed in <see cref="IDicomDatasetWalker.OnBeginWalk"/> before returning.</remarks>
        public bool OnBeginSequenceItem(DicomDataset dataset)
        {
            uint length = UndefinedLength;

            if (_options.ExplicitLengthSequenceItems)
            {
                DicomWriteLengthCalculator calc = new DicomWriteLengthCalculator(_syntax, _options);
                length = calc.Calculate(dataset);
            }

            WriteTagHeader(DicomTag.Item, DicomVR.NONE, length);
            return(true);
        }
Example #4
0
		public bool OnBeginSequence(DicomSequence sequence) {
			uint length = UndefinedLength;

			if (_options.ExplicitLengthSequences || sequence.Tag.IsPrivate) {
				DicomWriteLengthCalculator calc = new DicomWriteLengthCalculator(_syntax, _options);
				length = calc.Calculate(sequence);
			}

			_sequences.Push(sequence);

			WriteTagHeader(sequence.Tag, DicomVR.SQ, length);
			return true;
		}
		/// <summary>
		/// Recalculates the group length element for the specified group. Removes the group length element if no elements exist for the specified group.
		/// </summary>
		/// <remarks>For most use cases, this method will be called by the library as needed and will not need to be called by the user.</remarks>
		/// <param name="dataset">DICOM dataset</param>
		/// <param name="group">DICOM tag group</param>
		/// <param name="createIfMissing">If set to <c>true</c>, the group length element will be created if missing. If set to <c>false</c>, the group length will only be calculated if the group length element exists.</param>
		public static void RecalculateGroupLength(this DicomDataset dataset, ushort group, bool createIfMissing = true) {
			var items = dataset.EnumerateGroup(group).ToList();

			if (items.Count == 0) {
				// no items exist for the specified group; remove
				dataset.Remove(new DicomTag(group, 0x0000));
				return;
			}

			var calculator = new DicomWriteLengthCalculator(dataset.InternalTransferSyntax, DicomWriteOptions.Default);

			uint length = calculator.Calculate(items);
			dataset.Add(new DicomTag(group, 0x0000), length);
		}
		protected override void OnSave() {
			if (RootDirectoryRecord == null)
				throw new InvalidOperationException("No DICOM files added, cannot save DICOM directory");

			_directoryRecordSequence.Items.Clear();
			var calculator = new DicomWriteLengthCalculator(FileMetaInfo.TransferSyntax, DicomWriteOptions.Default);

			// ensure write length calculator does not include end of sequence item
            //Dataset.Remove(DicomTag.DirectoryRecordSequence);

            //_fileOffset = 128 + calculator.Calculate(FileMetaInfo) + calculator.Calculate(Dataset);

			//Add the offset for the Directory Record sequence tag itself
            //_fileOffset += 4;//sequence element tag
            if (FileMetaInfo.TransferSyntax.IsExplicitVR)
            {
                _fileOffset = 128 + calculator.Calculate(FileMetaInfo) + calculator.Calculate(Dataset);
				_fileOffset += 2; // vr
				_fileOffset += 2; // padding
				_fileOffset += 4; // length
            }
            else
            {
                _fileOffset = 128 + 4 + calculator.Calculate(FileMetaInfo) + calculator.Calculate(Dataset);
                
                _fileOffset += 4;//sequence element tag
				_fileOffset += 4; //length
			}

			AddDirectoryRecordsToSequenceItem(RootDirectoryRecord);

			if (RootDirectoryRecord != null) {
				CalculateOffsets(calculator);

				SetOffsets(RootDirectoryRecord);

				Dataset.Add<uint>(DicomTag.OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity, RootDirectoryRecord.Offset);

				var lastRoot = RootDirectoryRecord;

				while (lastRoot.NextDirectoryRecord != null)
					lastRoot = lastRoot.NextDirectoryRecord;

				Dataset.Add<uint>(DicomTag.OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity, lastRoot.Offset);
			} else {
				Dataset.Add<uint>(DicomTag.OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity, 0);
				Dataset.Add<uint>(DicomTag.OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity, 0);
			}
		}
Example #7
0
        /// <summary>
        /// Handler for traversing beginning of sequence.
        /// </summary>
        /// <param name="sequence">Sequence to traverse.</param>
        /// <returns>true if traversing completed without issues, false otherwise.</returns>
        /// <remarks>On false return value, the method will invoke the callback method passed in <see cref="IDicomDatasetWalker.OnBeginWalk"/> before returning.</remarks>
        public bool OnBeginSequence(DicomSequence sequence)
        {
            uint length = UndefinedLength;

            if (_options.ExplicitLengthSequences || sequence.Tag.IsPrivate)
            {
                DicomWriteLengthCalculator calc = new DicomWriteLengthCalculator(_syntax, _options);
                length = calc.Calculate(sequence);
            }

            _sequences.Push(sequence);

            WriteTagHeader(sequence.Tag, DicomVR.SQ, length);
            return(true);
        }
        /// <summary>
        /// Recalculates the group length element for the specified group. Removes the group length element if no elements exist for the specified group.
        /// </summary>
        /// <remarks>For most use cases, this method will be called by the library as needed and will not need to be called by the user.</remarks>
        /// <param name="dataset">DICOM dataset</param>
        /// <param name="group">DICOM tag group</param>
        /// <param name="createIfMissing">If set to <c>true</c>, the group length element will be created if missing. If set to <c>false</c>, the group length will only be calculated if the group length element exists.</param>
        public static void RecalculateGroupLength(this DicomDataset dataset, ushort group, bool createIfMissing = true)
        {
            var items = dataset.EnumerateGroup(group).ToList();

            if (items.Count == 0)
            {
                // no items exist for the specified group; remove
                dataset.Remove(new DicomTag(group, 0x0000));
                return;
            }

            var calculator = new DicomWriteLengthCalculator(dataset.InternalTransferSyntax, DicomWriteOptions.Default);

            uint length = calculator.Calculate(items);

            dataset.AddOrUpdate(new DicomTag(group, 0x0000), length);
        }
        /// <summary>
        /// Recalculates the group lengths for all groups in the <paramref name="dataset"/>. Removes any group lengths for groups with out elements.
        /// </summary>
        /// <remarks>For most use cases, this method will be called by the library as needed and will not need to be called by the user.</remarks>
        /// <param name="dataset">DICOM dataset</param>
        /// <param name="createIfMissing">If set to <c>true</c>, group length elements will be created if missing. If set to <c>false</c>, only groups with existing group lengths will be recalculated.</param>
        public static void RecalculateGroupLengths(this DicomDataset dataset, bool createIfMissing = true)
        {
            // recalculate group lengths for sequences first
            foreach (var sq in dataset.Where(x => x.ValueRepresentation == DicomVR.SQ).Cast <DicomSequence>())
            {
                foreach (var item in sq.Items)
                {
                    item.RecalculateGroupLengths(createIfMissing);
                }
            }

            var calculator = new DicomWriteLengthCalculator(dataset.InternalTransferSyntax, DicomWriteOptions.Default);

            IEnumerable <ushort> groups = null;

            if (createIfMissing)
            {
                groups = dataset.Select(x => x.Tag.Group).Distinct();
            }
            else
            {
                groups = dataset.Where(x => x.Tag.Element == 0x0000).Select(x => x.Tag.Group);
            }

            foreach (var group in groups.ToList())
            {
                var items = dataset.EnumerateGroup(group).ToList();

                if (items.Count == 0)
                {
                    // no items exist for the specified group; remove
                    dataset.Remove(new DicomTag(group, 0x0000));
                    return;
                }

                uint length = calculator.Calculate(items);
                dataset.AddOrUpdate(new DicomTag(group, 0x0000), length);
            }
        }
Example #10
0
		private void CalculateOffsets(DicomWriteLengthCalculator calculator) {
			foreach (var item in Dataset.Get<DicomSequence>(DicomTag.DirectoryRecordSequence)) {
				var record = item as DicomDirectoryRecord;
				if (record == null)
					throw new InvalidOperationException("Unexpected type for directory record: " + item.GetType());

				record.Offset = _fileOffset;

				_fileOffset += 4 + 4;//Sequence item tag;

				_fileOffset += calculator.Calculate(record);

				_fileOffset += 4 + 4; // Sequence Item Delimitation Item
			}

			_fileOffset += 4 + 4; // Sequence Delimitation Item
		}