1use crate::encode::basic::LittleEndianBasicEncoder;
4use crate::encode::{
5 BasicEncode, Encode, Result, WriteHeaderSnafu, WriteItemDelimiterSnafu, WriteItemHeaderSnafu,
6 WriteOffsetTableSnafu, WriteSequenceDelimiterSnafu, WriteTagSnafu,
7};
8use byteordered::byteorder::{ByteOrder, LittleEndian};
9use byteordered::Endianness;
10use dicom_core::header::{DataElementHeader, HasLength, Header};
11use dicom_core::{PrimitiveValue, Tag, VR};
12use snafu::ResultExt;
13use std::io::{self, Write};
14
15#[derive(Debug, Default, Clone)]
17pub struct ExplicitVRLittleEndianEncoder {
18 basic: LittleEndianBasicEncoder,
19}
20
21impl BasicEncode for ExplicitVRLittleEndianEncoder {
22 fn endianness(&self) -> Endianness {
23 Endianness::Little
24 }
25
26 fn encode_us<S>(&self, to: S, value: u16) -> io::Result<()>
27 where
28 S: Write,
29 {
30 self.basic.encode_us(to, value)
31 }
32
33 fn encode_ul<S>(&self, to: S, value: u32) -> io::Result<()>
34 where
35 S: Write,
36 {
37 self.basic.encode_ul(to, value)
38 }
39
40 fn encode_uv<S>(&self, to: S, value: u64) -> io::Result<()>
41 where
42 S: Write,
43 {
44 self.basic.encode_uv(to, value)
45 }
46
47 fn encode_ss<S>(&self, to: S, value: i16) -> io::Result<()>
48 where
49 S: Write,
50 {
51 self.basic.encode_ss(to, value)
52 }
53
54 fn encode_sl<S>(&self, to: S, value: i32) -> io::Result<()>
55 where
56 S: Write,
57 {
58 self.basic.encode_sl(to, value)
59 }
60
61 fn encode_sv<S>(&self, to: S, value: i64) -> io::Result<()>
62 where
63 S: Write,
64 {
65 self.basic.encode_sv(to, value)
66 }
67
68 fn encode_fl<S>(&self, to: S, value: f32) -> io::Result<()>
69 where
70 S: Write,
71 {
72 self.basic.encode_fl(to, value)
73 }
74
75 fn encode_fd<S>(&self, to: S, value: f64) -> io::Result<()>
76 where
77 S: Write,
78 {
79 self.basic.encode_fd(to, value)
80 }
81}
82
83impl Encode for ExplicitVRLittleEndianEncoder {
84 fn encode_tag<W>(&self, mut to: W, tag: Tag) -> Result<()>
85 where
86 W: Write,
87 {
88 let mut buf = [0u8, 4];
89 LittleEndian::write_u16(&mut buf[..], tag.group());
90 LittleEndian::write_u16(&mut buf[2..], tag.element());
91 to.write_all(&buf).context(WriteTagSnafu)
92 }
93
94 fn encode_element_header<W>(&self, mut to: W, de: DataElementHeader) -> Result<usize>
95 where
96 W: Write,
97 {
98 match de.vr() {
99 VR::OB
100 | VR::OD
101 | VR::OF
102 | VR::OL
103 | VR::OW
104 | VR::SQ
105 | VR::UC
106 | VR::UR
107 | VR::UT
108 | VR::UN => {
109 let mut buf = [0u8; 12];
110 LittleEndian::write_u16(&mut buf[0..], de.tag().group());
111 LittleEndian::write_u16(&mut buf[2..], de.tag().element());
112 let vr_bytes = de.vr().to_bytes();
113 buf[4] = vr_bytes[0];
114 buf[5] = vr_bytes[1];
115 LittleEndian::write_u32(&mut buf[8..], de.length().0);
117 to.write_all(&buf).context(WriteHeaderSnafu)?;
118 Ok(12)
119 }
120 _ => {
121 let mut buf = [0u8; 8];
122 LittleEndian::write_u16(&mut buf[0..], de.tag().group());
123 LittleEndian::write_u16(&mut buf[2..], de.tag().element());
124 let vr_bytes = de.vr().to_bytes();
125 buf[4] = vr_bytes[0];
126 buf[5] = vr_bytes[1];
127 LittleEndian::write_u16(&mut buf[6..], de.length().0 as u16);
128 to.write_all(&buf).context(WriteHeaderSnafu)?;
129 Ok(8)
130 }
131 }
132 }
133
134 fn encode_item_header<W>(&self, mut to: W, len: u32) -> Result<()>
135 where
136 W: Write,
137 {
138 let mut buf = [0u8; 8];
139 LittleEndian::write_u16(&mut buf, 0xFFFE);
140 LittleEndian::write_u16(&mut buf[2..], 0xE000);
141 LittleEndian::write_u32(&mut buf[4..], len);
142 to.write_all(&buf).context(WriteItemHeaderSnafu)
143 }
144
145 fn encode_item_delimiter<W>(&self, mut to: W) -> Result<()>
146 where
147 W: Write,
148 {
149 let mut buf = [0u8; 8];
150 LittleEndian::write_u16(&mut buf, 0xFFFE);
151 LittleEndian::write_u16(&mut buf[2..], 0xE00D);
152 to.write_all(&buf).context(WriteItemDelimiterSnafu)
153 }
154
155 fn encode_sequence_delimiter<W>(&self, mut to: W) -> Result<()>
156 where
157 W: Write,
158 {
159 let mut buf = [0u8; 8];
160 LittleEndian::write_u16(&mut buf, 0xFFFE);
161 LittleEndian::write_u16(&mut buf[2..], 0xE0DD);
162 to.write_all(&buf).context(WriteSequenceDelimiterSnafu)
163 }
164
165 fn encode_primitive<W>(&self, to: W, value: &PrimitiveValue) -> Result<usize>
166 where
167 W: Write,
168 {
169 self.basic.encode_primitive(to, value)
170 }
171
172 fn encode_offset_table<W>(&self, mut to: W, offset_table: &[u32]) -> Result<usize>
173 where
174 W: Write,
175 {
176 for v in offset_table {
177 self.basic
178 .encode_ul(&mut to, *v)
179 .context(WriteOffsetTableSnafu)?;
180 }
181 Ok(offset_table.len() * 4)
182 }
183}
184
185#[cfg(test)]
186mod tests {
187 use super::ExplicitVRLittleEndianEncoder;
188 use crate::encode::Encode;
189 use dicom_core::header::{DataElementHeader, Length};
190 use dicom_core::{Tag, VR};
191 use std::io::{Cursor, Write};
192
193 type Result = std::result::Result<(), Box<dyn std::error::Error>>;
194
195 const RAW: &'static [u8; 62] = &[
207 0x02, 0x00, 0x02, 0x00, 0x55, 0x49, 0x1a, 0x00, 0x31, 0x2e, 0x32, 0x2e, 0x38, 0x34, 0x30,
208 0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x35, 0x2e, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e,
209 0x31, 0x2e, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x55, 0x49, 0x14, 0x00, 0x31, 0x2e, 0x32,
210 0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x31, 0x2e, 0x32, 0x2e,
211 0x31, 0x00,
212 ];
213
214 #[test]
215 fn encode_data_elements() {
216 let mut buf = [0u8; 62];
217 {
218 let enc = ExplicitVRLittleEndianEncoder::default();
219 let mut writer = Cursor::new(&mut buf[..]);
220
221 let de = DataElementHeader::new(Tag(0x0002, 0x0002), VR::UI, Length(26));
223 let len = enc
224 .encode_element_header(&mut writer, de)
225 .expect("should write it fine");
226 assert_eq!(len, 8);
227 writer
228 .write_all(b"1.2.840.10008.5.1.4.1.1.1\0".as_ref())
229 .expect("should write the value fine");
230 }
231 assert_eq!(&buf[0..8], &RAW[0..8]);
232 {
233 let enc = ExplicitVRLittleEndianEncoder::default();
234 let mut writer = Cursor::new(&mut buf[34..]);
235
236 let de = DataElementHeader::new(Tag(0x0002, 0x0010), VR::UI, Length(20));
238 let len = enc
239 .encode_element_header(&mut writer, de)
240 .expect("should write it fine");
241 assert_eq!(len, 8);
242 writer
243 .write_all(b"1.2.840.10008.1.2.1\0".as_ref())
244 .expect("should write the value fine");
245 }
246 assert_eq!(&buf[34..42], &RAW[34..42]);
247
248 assert_eq!(&buf[..], &RAW[..]);
249 }
250
251 const RAW_SEQUENCE_ITEMS: &'static [u8] = &[
267 0x08, 0x00, 0x3F, 0x10, b'S', b'Q', 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00,
268 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x0D, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF,
269 0xDD, 0xE0, 0x00, 0x00, 0x00, 0x00,
270 ];
271
272 #[test]
273 fn encode_items() -> Result {
274 let enc = ExplicitVRLittleEndianEncoder::default();
275 let mut out = Vec::new();
276
277 {
278 let bytes_written = enc.encode_element_header(
279 &mut out,
280 DataElementHeader::new(Tag(0x0008, 0x103F), VR::SQ, Length::UNDEFINED),
281 )?;
282 assert_eq!(bytes_written, 12);
283 }
284 assert_eq!(out.len(), 12);
285
286 enc.encode_item_header(&mut out, Length::UNDEFINED.0)?;
287 assert_eq!(out.len(), 20);
288
289 enc.encode_item_delimiter(&mut out)?;
290 assert_eq!(out.len(), 28);
291
292 enc.encode_sequence_delimiter(&mut out)?;
293
294 assert_eq!(&out[..], RAW_SEQUENCE_ITEMS);
295
296 Ok(())
297 }
298}