Skip to content

Commit

Permalink
[core] Add OpAction::Truncate
Browse files Browse the repository at this point in the history
  • Loading branch information
Enet4 committed Sep 26, 2023
1 parent a4acc3f commit a838e0e
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 3 deletions.
15 changes: 15 additions & 0 deletions core/src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,21 @@ pub enum AttributeAction {
/// Append a 64-bit floating point number as an additional numeric value,
/// creating the attribute if it does not exist yet.
PushF64(f64),
/// Truncate a value or a sequence to the given number of items,
/// removing extraneous items from the end of the list.
///
/// On primitive values, this truncates the value
/// by the number of individual value items
/// (note that bytes in a [`PrimitiveValue::U8`]
/// are treated as individual items).
/// On data set sequences and pixel data fragment sequences,
/// this operation is applied to
/// the data set items (or fragments) in the sequence.
///
/// Does nothing if the attribute does not exist
/// or the cardinality of the element is already lower than or equal to
/// the given size.
Truncate(usize),
}

impl AttributeAction {
Expand Down
55 changes: 55 additions & 0 deletions object/src/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,6 +1063,10 @@ where
AttributeAction::PushU16(integer) => self.apply_push_u16_impl(tag, integer),
AttributeAction::PushF32(number) => self.apply_push_f32_impl(tag, number),
AttributeAction::PushF64(number) => self.apply_push_f64_impl(tag, number),
AttributeAction::Truncate(limit) => {
self.update_value(tag, |value| value.truncate(limit));
Ok(())
}
_ => UnsupportedActionSnafu.fail(),
}
}
Expand Down Expand Up @@ -2932,6 +2936,57 @@ mod tests {
}
}

/// Test that operations on in-memory DICOM objects
/// can truncate sequences.
#[test]
fn inmem_ops_can_truncate_seq() {
let mut obj = InMemDicomObject::from_element_iter([
DataElement::new(
tags::SEQUENCE_OF_ULTRASOUND_REGIONS,
VR::SQ,
DataSetSequence::from(vec![InMemDicomObject::new_empty()]),
),
DataElement::new_with_len(
tags::PIXEL_DATA,
VR::OB,
Length::UNDEFINED,
PixelFragmentSequence::new(vec![], vec![vec![0xcc; 8192], vec![0x55; 1024]]),
),
]);

// removes the single item in the sequences
obj.apply(AttributeOp::new(
tags::SEQUENCE_OF_ULTRASOUND_REGIONS,
AttributeAction::Truncate(0),
))
.unwrap();

{
let sequence_ultrasound = obj
.get(tags::SEQUENCE_OF_ULTRASOUND_REGIONS)
.expect("should have sequence element");
assert_eq!(sequence_ultrasound.items().as_deref(), Some(&[][..]),);
}

// remove one of the fragments
obj.apply(AttributeOp::new(
tags::PIXEL_DATA,
AttributeAction::Truncate(1),
))
.unwrap();

{
// pixel data should now have a single fragment
assert_eq!(
obj.get(tags::PIXEL_DATA)
.unwrap()
.fragments()
.map(|fragments| fragments.len()),
Some(1),
);
}
}

#[test]
fn inmem_obj_reset_defined_length() {
let mut entries: BTreeMap<Tag, InMemElement<StandardDataDictionary>> = BTreeMap::new();
Expand Down
10 changes: 7 additions & 3 deletions object/src/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,13 @@ impl FileMetaTable {
tags::PRIVATE_INFORMATION_CREATOR_UID => {
Self::apply_optional_string(op, &mut self.private_information_creator_uid)
}
_ if matches!(op.action, AttributeAction::Remove | AttributeAction::Empty) => {
_ if matches!(
op.action,
AttributeAction::Remove | AttributeAction::Empty | AttributeAction::Truncate(_)
) =>
{
// any other attribute is not supported
// (ignore Remove and Empty)
// (ignore Remove, Empty, Truncate)
Ok(())
}
_ => UnsupportedAttributeSnafu.fail(),
Expand All @@ -301,7 +305,7 @@ impl FileMetaTable {
fn apply_required_string(op: AttributeOp, target_attribute: &mut String) -> ApplyResult {
match op.action {
AttributeAction::Remove | AttributeAction::Empty => MandatorySnafu.fail(),
AttributeAction::SetVr(_) => {
AttributeAction::SetVr(_) | AttributeAction::Truncate(_) => {
// ignore
Ok(())
}
Expand Down

0 comments on commit a838e0e

Please sign in to comment.