dicom_core/value/
fragments.rs1use crate::value::{InMemFragment, PixelFragmentSequence, C};
3
4#[derive(Debug)]
38pub struct Fragments {
39 fragments: Vec<InMemFragment>,
40}
41
42impl Fragments {
43 pub fn new(data: Vec<u8>, fragment_size: u32) -> Self {
44 let fragment_size: u32 = if fragment_size == 0 {
45 data.len() as u32
46 } else {
47 fragment_size
48 };
49
50 let fragment_size = if fragment_size % 2 == 0 {
51 fragment_size
52 } else {
53 fragment_size + 1
54 };
55
56 let number_of_fragments = (data.len() as f32 / fragment_size as f32).ceil() as u32;
57
58 let mut data = data;
61 let encapsulated_size = (fragment_size * number_of_fragments) as usize;
62 if encapsulated_size > data.len() {
63 data.resize(encapsulated_size, 0);
64 }
65
66 let fragments = data
67 .chunks_exact(fragment_size as usize)
68 .map(|fragment| fragment.to_vec())
69 .collect::<Vec<InMemFragment>>();
70
71 Fragments { fragments }
72 }
73
74 pub fn is_empty(&self) -> bool {
75 self.fragments.len() == 0
76 }
77
78 pub fn is_multiframe(&self) -> bool {
79 self.fragments.len() > 1
80 }
81
82 pub fn len(&self) -> u32 {
83 self.fragments
84 .iter()
85 .fold(0u32, |acc, fragment| acc + fragment.len() as u32 + 8u32)
86 }
87}
88
89impl From<Vec<Fragments>> for PixelFragmentSequence<InMemFragment> {
90 fn from(value: Vec<Fragments>) -> Self {
91 let mut offset_table = C::with_capacity(value.len() + 1);
92 offset_table.push(0u32);
93 let mut current_offset = 0u32;
94
95 let mut fragments = Vec::new();
96 let is_multiframe = value.len() > 1;
97 let last_frame = value.len() - 1;
98
99 for (index, mut frame) in value.into_iter().enumerate() {
100 if frame.is_multiframe() && is_multiframe {
101 panic!("More than 1 fragment per frame is invalid for multi frame pixel data");
102 }
103
104 if index < last_frame {
105 let offset = frame.len();
106 offset_table.push(current_offset + offset);
107 current_offset += offset;
108 }
109
110 fragments.append(&mut frame.fragments);
111 }
112
113 PixelFragmentSequence {
114 offset_table,
115 fragments: C::from_vec(fragments),
116 }
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use crate::value::fragments::Fragments;
123 use crate::value::{InMemFragment, PixelFragmentSequence};
124
125 #[test]
126 fn test_fragment_frame() {
127 let fragment = Fragments::new(vec![150, 164, 200], 0);
128 assert_eq!(fragment.fragments.len(), 1, "1 fragment should be present");
129 assert_eq!(
130 fragment.fragments[0].len(),
131 4,
132 "The fragment size should be 4"
133 );
134 assert_eq!(
135 fragment.fragments[0],
136 vec![150, 164, 200, 0],
137 "The data should be 0 padded"
138 );
139
140 let fragment = Fragments::new(vec![150, 164, 200, 222], 4);
141 assert_eq!(fragment.fragments.len(), 1, "1 fragment should be present");
142 assert_eq!(
143 fragment.fragments[0].len(),
144 4,
145 "The fragment size should be 4"
146 );
147 assert_eq!(
148 fragment.fragments[0],
149 vec![150, 164, 200, 222],
150 "The data should be what was sent"
151 );
152
153 let fragment = Fragments::new(vec![150, 164, 200, 222], 2);
154 assert_eq!(fragment.fragments.len(), 2, "2 fragments should be present");
155 assert_eq!(fragment.fragments[0].len(), 2);
156 assert_eq!(fragment.fragments[1].len(), 2);
157 assert_eq!(fragment.fragments[0], vec![150, 164]);
158 assert_eq!(fragment.fragments[1], vec![200, 222]);
159
160 let fragment = Fragments::new(vec![150, 164, 200], 1);
161 assert_eq!(
162 fragment.fragments.len(),
163 2,
164 "2 fragments should be present as fragment_size < 2"
165 );
166 assert_eq!(fragment.fragments[0].len(), 2);
167 assert_eq!(fragment.fragments[0], vec![150, 164]);
168 assert_eq!(fragment.fragments[1].len(), 2);
169 assert_eq!(fragment.fragments[1], vec![200, 0]);
170
171 let fragment = Fragments::new(vec![150, 164, 200, 222], 1);
172 assert_eq!(
173 fragment.fragments.len(),
174 2,
175 "2 fragments should be present as fragment_size < 2"
176 );
177 assert_eq!(fragment.fragments[0].len(), 2);
178 assert_eq!(fragment.fragments[0], vec![150, 164]);
179 assert_eq!(fragment.fragments[1].len(), 2);
180 assert_eq!(fragment.fragments[1], vec![200, 222]);
181 }
182
183 #[test]
184 fn test_bot_single_fragment_generation() {
185 let data = vec![Fragments::new(vec![0u8; 2], 2)];
186 let fragment_sequence: PixelFragmentSequence<InMemFragment> = data.into();
187 assert_eq!(fragment_sequence.offset_table.len(), 1);
188 assert_eq!(fragment_sequence.offset_table[0], 0);
189 }
190
191 #[test]
192 fn test_bot_multi_fragments_generation() {
193 let data = vec![Fragments::new(vec![0u8; 4], 2)];
194 let fragment_sequence: PixelFragmentSequence<InMemFragment> = data.into();
195 assert_eq!(fragment_sequence.offset_table.len(), 1);
196 assert_eq!(fragment_sequence.offset_table[0], 0);
197 }
198
199 #[test]
200 fn test_bot_multi_frame_generation() {
201 let data = vec![
202 Fragments::new(vec![0u8; 4], 0),
203 Fragments::new(vec![1u8; 6], 0),
204 ];
205 let fragment_sequence: PixelFragmentSequence<InMemFragment> = data.into();
206 assert_eq!(fragment_sequence.offset_table.len(), 2);
207 assert_eq!(fragment_sequence.offset_table[0], 0);
208 assert_eq!(fragment_sequence.offset_table[1], 12); }
210}