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};
12use snafu::ResultExt;
13use std::io::{self, Write};
14
15#[derive(Debug, Default, Clone)]
17pub struct ImplicitVRLittleEndianEncoder {
18 basic: LittleEndianBasicEncoder,
19}
20
21impl BasicEncode for ImplicitVRLittleEndianEncoder {
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 ImplicitVRLittleEndianEncoder {
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 let mut buf = [0u8; 8];
99 LittleEndian::write_u16(&mut buf[0..], de.tag().group());
100 LittleEndian::write_u16(&mut buf[2..], de.tag().element());
101 LittleEndian::write_u32(&mut buf[4..], de.length().0);
102 to.write_all(&buf).context(WriteHeaderSnafu)?;
103 Ok(8)
104 }
105
106 fn encode_item_header<W>(&self, mut to: W, len: u32) -> Result<()>
107 where
108 W: Write,
109 {
110 let mut buf = [0u8; 8];
111 LittleEndian::write_u16(&mut buf, 0xFFFE);
112 LittleEndian::write_u16(&mut buf[2..], 0xE000);
113 LittleEndian::write_u32(&mut buf[4..], len);
114 to.write_all(&buf).context(WriteItemHeaderSnafu)
115 }
116
117 fn encode_item_delimiter<W>(&self, mut to: W) -> Result<()>
118 where
119 W: Write,
120 {
121 let mut buf = [0u8; 8];
122 LittleEndian::write_u16(&mut buf, 0xFFFE);
123 LittleEndian::write_u16(&mut buf[2..], 0xE00D);
124 to.write_all(&buf).context(WriteItemDelimiterSnafu)
125 }
126
127 fn encode_sequence_delimiter<W>(&self, mut to: W) -> Result<()>
128 where
129 W: Write,
130 {
131 let mut buf = [0u8; 8];
132 LittleEndian::write_u16(&mut buf, 0xFFFE);
133 LittleEndian::write_u16(&mut buf[2..], 0xE0DD);
134 to.write_all(&buf).context(WriteSequenceDelimiterSnafu)
135 }
136
137 fn encode_primitive<W>(&self, to: W, value: &PrimitiveValue) -> Result<usize>
138 where
139 W: Write,
140 {
141 self.basic.encode_primitive(to, value)
142 }
143
144 fn encode_offset_table<W>(&self, mut to: W, offset_table: &[u32]) -> Result<usize>
145 where
146 W: Write,
147 {
148 for v in offset_table {
149 self.basic
150 .encode_ul(&mut to, *v)
151 .context(WriteOffsetTableSnafu)?;
152 }
153 Ok(offset_table.len() * 4)
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use super::ImplicitVRLittleEndianEncoder;
160 use crate::encode::Encode;
161 use dicom_core::header::{DataElementHeader, Length, Tag, VR};
162 use std::io::{Cursor, Write};
163
164 type Result = std::result::Result<(), Box<dyn std::error::Error>>;
165
166 const RAW: &'static [u8; 62] = &[
176 0x02, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x31, 0x2e, 0x32, 0x2e, 0x38, 0x34, 0x30,
177 0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x35, 0x2e, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e,
178 0x31, 0x2e, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x31, 0x2e, 0x32,
179 0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x31, 0x2e, 0x32, 0x2e,
180 0x31, 0x00,
181 ];
182
183 #[test]
184 fn encode_implicit_vr_le() {
185 let mut buf = [0u8; 62];
186 {
187 let enc = ImplicitVRLittleEndianEncoder::default();
188 let mut writer = Cursor::new(&mut buf[..]);
189
190 let de = DataElementHeader::new(Tag(0x0002, 0x0002), VR::UI, Length(26));
192 let len = enc
193 .encode_element_header(&mut writer, de)
194 .expect("should write it fine");
195 assert_eq!(len, 8);
196 writer
197 .write_all(b"1.2.840.10008.5.1.4.1.1.1\0".as_ref())
198 .expect("should write the value fine");
199 }
200 assert_eq!(&buf[0..8], &RAW[0..8]);
201 {
202 let enc = ImplicitVRLittleEndianEncoder::default();
203 let mut writer = Cursor::new(&mut buf[34..]);
204
205 let de = DataElementHeader::new(Tag(0x0002, 0x0010), VR::UI, Length(20));
207 let len = enc
208 .encode_element_header(&mut writer, de)
209 .expect("should write it fine");
210 assert_eq!(len, 8);
211 writer
212 .write_all(b"1.2.840.10008.1.2.1\0".as_ref())
213 .expect("should write the value fine");
214 }
215 assert_eq!(&buf[34..42], &RAW[34..42]);
216
217 assert_eq!(&buf[..], &RAW[..]);
218 }
219
220 const RAW_SEQUENCE_ITEMS: &'static [u8] = &[
236 0x08, 0x00, 0x3F, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF,
237 0xFF, 0xFE, 0xFF, 0x0D, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xDD, 0xE0, 0x00, 0x00,
238 0x00, 0x00,
239 ];
240
241 #[test]
242 fn encode_items() -> Result {
243 let enc = ImplicitVRLittleEndianEncoder::default();
244 let mut out = Vec::new();
245
246 {
247 let bytes_written = enc.encode_element_header(
248 &mut out,
249 DataElementHeader::new(Tag(0x0008, 0x103F), VR::SQ, Length::UNDEFINED),
250 )?;
251 assert_eq!(bytes_written, 8);
252 }
253 assert_eq!(out.len(), 8);
254
255 enc.encode_item_header(&mut out, Length::UNDEFINED.0)?;
256 assert_eq!(out.len(), 16);
257
258 enc.encode_item_delimiter(&mut out)?;
259 assert_eq!(out.len(), 24);
260
261 enc.encode_sequence_delimiter(&mut out)?;
262
263 assert_eq!(&out[..], RAW_SEQUENCE_ITEMS,);
264
265 Ok(())
266 }
267}