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