1use crate::decode::basic::LittleEndianBasicDecoder;
4use crate::decode::{
5 BadSequenceHeaderSnafu, BasicDecode, Decode, DecodeFrom, ReadHeaderTagSnafu,
6 ReadItemHeaderSnafu, ReadItemLengthSnafu, ReadLengthSnafu, ReadReservedSnafu, ReadTagSnafu,
7 ReadVrSnafu, Result,
8};
9use byteordered::byteorder::{ByteOrder, LittleEndian};
10use dicom_core::header::{DataElementHeader, Length, SequenceItemHeader};
11use dicom_core::{Tag, VR};
12use snafu::ResultExt;
13use std::io::Read;
14
15#[derive(Debug, Default, Clone)]
17pub struct ExplicitVRLittleEndianDecoder {
18 basic: LittleEndianBasicDecoder,
19}
20
21impl Decode for ExplicitVRLittleEndianDecoder {
22 fn decode_header<S>(&self, mut source: &mut S) -> Result<(DataElementHeader, usize)>
23 where
24 S: ?Sized + Read,
25 {
26 let Tag(group, element) = self
28 .basic
29 .decode_tag(&mut source)
30 .context(ReadHeaderTagSnafu)?;
31
32 let mut buf = [0u8; 4];
33 if group == 0xFFFE {
34 source.read_exact(&mut buf).context(ReadItemLengthSnafu)?;
36 let len = LittleEndian::read_u32(&buf);
37 return Ok((
38 DataElementHeader::new((group, element), VR::UN, Length(len)),
39 8, ));
41 }
42
43 source.read_exact(&mut buf[0..2]).context(ReadVrSnafu)?;
45 let vr = VR::from_binary([buf[0], buf[1]]).unwrap_or(VR::UN);
46 let bytes_read;
47
48 let len = match vr {
50 VR::OB
51 | VR::OD
52 | VR::OF
53 | VR::OL
54 | VR::OW
55 | VR::SQ
56 | VR::UC
57 | VR::UR
58 | VR::UT
59 | VR::UN => {
60 source
62 .read_exact(&mut buf[0..2])
63 .context(ReadReservedSnafu)?;
64 source.read_exact(&mut buf).context(ReadLengthSnafu)?;
65 bytes_read = 12;
66 LittleEndian::read_u32(&buf)
67 }
68 _ => {
69 source.read_exact(&mut buf[0..2]).context(ReadLengthSnafu)?;
71 bytes_read = 8;
72 u32::from(LittleEndian::read_u16(&buf[0..2]))
73 }
74 };
75
76 Ok((
77 DataElementHeader::new((group, element), vr, Length(len)),
78 bytes_read,
79 ))
80 }
81
82 fn decode_item_header<S>(&self, source: &mut S) -> Result<SequenceItemHeader>
83 where
84 S: ?Sized + Read,
85 {
86 let mut buf = [0u8; 8];
87 source.read_exact(&mut buf).context(ReadItemHeaderSnafu)?;
88 let group = LittleEndian::read_u16(&buf[0..2]);
90 let element = LittleEndian::read_u16(&buf[2..4]);
91 let len = LittleEndian::read_u32(&buf[4..8]);
92
93 SequenceItemHeader::new((group, element), Length(len)).context(BadSequenceHeaderSnafu)
94 }
95
96 fn decode_tag<S>(&self, source: &mut S) -> Result<Tag>
97 where
98 S: ?Sized + Read,
99 {
100 let mut buf = [0u8; 4];
101 source.read_exact(&mut buf).context(ReadTagSnafu)?;
102 Ok(Tag(
103 LittleEndian::read_u16(&buf[0..2]),
104 LittleEndian::read_u16(&buf[2..4]),
105 ))
106 }
107}
108
109impl<S: ?Sized> DecodeFrom<S> for ExplicitVRLittleEndianDecoder
110where
111 S: Read,
112{
113 #[inline]
114 fn decode_header(&self, source: &mut S) -> Result<(DataElementHeader, usize)> {
115 Decode::decode_header(self, source)
116 }
117
118 #[inline]
119 fn decode_item_header(&self, source: &mut S) -> Result<SequenceItemHeader> {
120 Decode::decode_item_header(self, source)
121 }
122
123 #[inline]
124 fn decode_tag(&self, source: &mut S) -> Result<Tag> {
125 Decode::decode_tag(self, source)
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::ExplicitVRLittleEndianDecoder;
132 use crate::decode::Decode;
133 use dicom_core::header::{HasLength, Header, Length};
134 use dicom_core::{Tag, VR};
135 use std::io::{Cursor, Read, Seek, SeekFrom};
136
137 const RAW: &'static [u8; 62] = &[
149 0x02, 0x00, 0x02, 0x00, 0x55, 0x49, 0x1a, 0x00, 0x31, 0x2e, 0x32, 0x2e, 0x38, 0x34, 0x30,
150 0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x35, 0x2e, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e,
151 0x31, 0x2e, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x55, 0x49, 0x14, 0x00, 0x31, 0x2e, 0x32,
152 0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x31, 0x2e, 0x32, 0x2e,
153 0x31, 0x00,
154 ];
155
156 #[test]
157 fn decode_data_elements() {
158 let dec = ExplicitVRLittleEndianDecoder::default();
159 let mut cursor = Cursor::new(RAW.as_ref());
160 {
161 let (elem, bytes_read) = dec
163 .decode_header(&mut cursor)
164 .expect("should find an element");
165 assert_eq!(elem.tag(), Tag(2, 2));
166 assert_eq!(elem.vr(), VR::UI);
167 assert_eq!(elem.length(), Length(26));
168 assert_eq!(bytes_read, 8);
169 let mut buffer = [0; 13];
171 cursor.read_exact(&mut buffer).expect("should read it fine");
172 assert_eq!(&buffer, b"1.2.840.10008".as_ref());
173 }
174 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 21);
176 assert_eq!(cursor.seek(SeekFrom::Current(13)).unwrap(), 34);
178 {
179 let (elem, _bytes_read) = dec
181 .decode_header(&mut cursor)
182 .expect("should find an element");
183 assert_eq!(elem.tag(), Tag(2, 16));
184 assert_eq!(elem.vr(), VR::UI);
185 assert_eq!(elem.length(), Length(20));
186 let mut buffer = [0; 20];
188 cursor.read_exact(&mut buffer).expect("should read it fine");
189 assert_eq!(&buffer, b"1.2.840.10008.1.2.1\0".as_ref());
190 }
191 }
192
193 const RAW_SEQUENCE_ITEMS: &'static [u8] = &[
209 0x08, 0x00, 0x3F, 0x10, b'S', b'Q', 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00,
210 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x0D, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF,
211 0xDD, 0xE0, 0x00, 0x00, 0x00, 0x00,
212 ];
213
214 #[test]
215 fn decode_items() {
216 let dec = ExplicitVRLittleEndianDecoder::default();
217 let mut cursor = Cursor::new(RAW_SEQUENCE_ITEMS);
218 {
219 let (elem, bytes_read) = dec
221 .decode_header(&mut cursor)
222 .expect("should find an element header");
223 assert_eq!(elem.tag(), Tag(8, 0x103F));
224 assert_eq!(elem.vr(), VR::SQ);
225 assert!(elem.length().is_undefined());
226 assert_eq!(bytes_read, 12);
227 }
228 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 12);
230 {
231 let elem = dec
232 .decode_item_header(&mut cursor)
233 .expect("should find an item header");
234 assert!(elem.is_item());
235 assert_eq!(elem.tag(), Tag(0xFFFE, 0xE000));
236 assert!(elem.length().is_undefined());
237 }
238 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 20);
240 {
241 let elem = dec
242 .decode_item_header(&mut cursor)
243 .expect("should find an item header");
244 assert!(elem.is_item_delimiter());
245 assert_eq!(elem.tag(), Tag(0xFFFE, 0xE00D));
246 assert_eq!(elem.length(), Length(0));
247 }
248 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 28);
250 {
251 let elem = dec
252 .decode_item_header(&mut cursor)
253 .expect("should find an item header");
254 assert!(elem.is_sequence_delimiter());
255 assert_eq!(elem.tag(), Tag(0xFFFE, 0xE0DD));
256 assert_eq!(elem.length(), Length(0));
257 }
258 }
259}