1use crate::decode::basic::LittleEndianBasicDecoder;
4use crate::decode::{
5 BadSequenceHeaderSnafu, BasicDecode, DecodeFrom, ReadHeaderTagSnafu, ReadLengthSnafu,
6 ReadTagSnafu, Result,
7};
8use crate::Decode;
9use byteordered::byteorder::{ByteOrder, LittleEndian};
10use dicom_core::dictionary::{DataDictionary, DataDictionaryEntry};
11use dicom_core::header::{DataElementHeader, Length, SequenceItemHeader};
12use dicom_core::{Tag, VR};
13use dicom_dictionary_std::StandardDataDictionary;
14use snafu::ResultExt;
15use std::fmt;
16use std::io::Read;
17
18pub type StandardImplicitVRLittleEndianDecoder =
20 ImplicitVRLittleEndianDecoder<StandardDataDictionary>;
21
22pub struct ImplicitVRLittleEndianDecoder<D> {
26 dict: D,
27 basic: LittleEndianBasicDecoder,
28}
29
30impl<D> fmt::Debug for ImplicitVRLittleEndianDecoder<D> {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 f.debug_struct("ImplicitVRLittleEndianDecoder")
33 .field("dict", &"«omitted»")
34 .field("basic", &self.basic)
35 .finish()
36 }
37}
38
39impl ImplicitVRLittleEndianDecoder<StandardDataDictionary> {
40 pub fn with_std_dict() -> Self {
42 ImplicitVRLittleEndianDecoder {
43 dict: StandardDataDictionary,
44 basic: LittleEndianBasicDecoder,
45 }
46 }
47
48 pub fn new() -> Self {
50 Self::with_std_dict()
51 }
52}
53
54impl Default for ImplicitVRLittleEndianDecoder<StandardDataDictionary> {
55 fn default() -> Self {
56 ImplicitVRLittleEndianDecoder::with_std_dict()
57 }
58}
59
60impl<D> ImplicitVRLittleEndianDecoder<D>
61where
62 D: DataDictionary,
63{
64 pub fn with_dict(dictionary: D) -> Self {
66 ImplicitVRLittleEndianDecoder {
67 dict: dictionary,
68 basic: LittleEndianBasicDecoder,
69 }
70 }
71}
72
73impl<D> Decode for ImplicitVRLittleEndianDecoder<D>
74where
75 D: DataDictionary,
76{
77 fn decode_header<S>(&self, mut source: &mut S) -> Result<(DataElementHeader, usize)>
78 where
79 S: ?Sized + Read,
80 {
81 let tag = self
83 .basic
84 .decode_tag(&mut source)
85 .context(ReadHeaderTagSnafu)?;
86
87 let mut buf = [0u8; 4];
88 source.read_exact(&mut buf).context(ReadLengthSnafu)?;
89 let len = LittleEndian::read_u32(&buf);
90
91 let vr = if tag == Tag(0x7FE0, 0x0010) || (tag.0 >> 8 == 0x60 && tag.1 == 0x3000) {
97 VR::OW
98 } else {
99 self.dict
100 .by_tag(tag)
101 .map(|entry| entry.vr().relaxed())
102 .unwrap_or(VR::UN)
103 };
104 Ok((DataElementHeader::new(tag, vr, Length(len)), 8))
105 }
106
107 fn decode_item_header<S>(&self, mut source: &mut S) -> Result<SequenceItemHeader>
108 where
109 S: ?Sized + Read,
110 {
111 let mut buf = [0u8; 4];
112
113 let tag = self
115 .basic
116 .decode_tag(&mut source)
117 .context(ReadHeaderTagSnafu)?;
118
119 source.read_exact(&mut buf).context(ReadLengthSnafu)?;
120 let len = LittleEndian::read_u32(&buf);
121 SequenceItemHeader::new(tag, Length(len)).context(BadSequenceHeaderSnafu)
122 }
123
124 #[inline]
125 fn decode_tag<S>(&self, source: &mut S) -> Result<Tag>
126 where
127 S: ?Sized + Read,
128 {
129 self.basic.decode_tag(source).context(ReadTagSnafu)
130 }
131}
132
133impl<S: ?Sized, D> DecodeFrom<S> for ImplicitVRLittleEndianDecoder<D>
134where
135 S: Read,
136 D: DataDictionary,
137{
138 #[inline]
139 fn decode_header(&self, source: &mut S) -> Result<(DataElementHeader, usize)> {
140 Decode::decode_header(self, source)
141 }
142
143 #[inline]
144 fn decode_item_header(&self, source: &mut S) -> Result<SequenceItemHeader> {
145 Decode::decode_item_header(self, source)
146 }
147
148 #[inline]
149 fn decode_tag(&self, source: &mut S) -> Result<Tag> {
150 Decode::decode_tag(self, source)
151 }
152}
153
154#[cfg(test)]
155mod tests {
156 use super::ImplicitVRLittleEndianDecoder;
157 use crate::decode::Decode;
158 use dicom_core::dictionary::stub::StubDataDictionary;
159 use dicom_core::header::{HasLength, Header, Length, VR};
160 use dicom_core::Tag;
161 use std::io::{Cursor, Read, Seek, SeekFrom};
162
163 const RAW: &[u8; 62] = &[
173 0x02, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x31, 0x2e, 0x32, 0x2e, 0x38, 0x34, 0x30,
174 0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x35, 0x2e, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e,
175 0x31, 0x2e, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x31, 0x2e, 0x32,
176 0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x31, 0x2e, 0x32, 0x2e,
177 0x31, 0x00,
178 ];
179
180 const DICT: &StubDataDictionary = &StubDataDictionary;
181
182 #[test]
183 fn implicit_vr_le() {
184 let reader = ImplicitVRLittleEndianDecoder::with_dict(DICT);
185 let mut cursor = Cursor::new(RAW.as_ref());
186 {
187 let (elem, bytes_read) = reader
189 .decode_header(&mut cursor)
190 .expect("should find an element");
191 assert_eq!(elem.tag(), Tag(0x0002, 0x0002));
192 assert_eq!(elem.vr(), VR::UN);
193 assert_eq!(elem.length(), Length(26));
194 assert_eq!(bytes_read, 8);
195 let mut buffer: Vec<u8> = vec![0; 13];
197 cursor
198 .read_exact(buffer.as_mut_slice())
199 .expect("should read it fine");
200 assert_eq!(buffer.as_slice(), b"1.2.840.10008".as_ref());
201 }
202 assert_eq!(cursor.stream_position().unwrap(), 21);
204 assert_eq!(cursor.seek(SeekFrom::Current(13)).unwrap(), 34);
206 {
207 let (elem, _bytes_read) = reader
209 .decode_header(&mut cursor)
210 .expect("should find an element");
211 assert_eq!(elem.tag(), Tag(0x0002, 0x0010));
212 assert_eq!(elem.vr(), VR::UN);
213 assert_eq!(elem.length(), Length(20));
214 let mut buffer: Vec<u8> = vec![0; 20];
216 cursor
217 .read_exact(buffer.as_mut_slice())
218 .expect("should read it fine");
219 assert_eq!(buffer.as_slice(), b"1.2.840.10008.1.2.1\0".as_ref());
220 }
221 }
222
223 #[test]
224 fn implicit_vr_le_with_standard_dictionary() {
225 let reader = ImplicitVRLittleEndianDecoder::with_std_dict();
226 let mut cursor = Cursor::new(RAW.as_ref());
227 {
228 let (elem, _bytes_read) = reader
230 .decode_header(&mut cursor)
231 .expect("should find an element");
232 assert_eq!(elem.tag(), Tag(2, 2));
233 assert_eq!(elem.vr(), VR::UI);
234 assert_eq!(elem.length(), Length(26));
235 assert_eq!(cursor.stream_position().unwrap(), 8);
237 assert_eq!(
240 cursor
241 .seek(SeekFrom::Current(elem.length().0 as i64))
242 .unwrap(),
243 34
244 );
245 }
246 {
247 let (elem, _bytes_read) = reader
249 .decode_header(&mut cursor)
250 .expect("should find an element");
251 assert_eq!(elem.tag(), Tag(2, 16));
252 assert_eq!(elem.vr(), VR::UI);
253 assert_eq!(elem.length(), Length(20));
254 let mut buffer: Vec<u8> = vec![0; 20];
256 cursor
257 .read_exact(buffer.as_mut_slice())
258 .expect("should read it fine");
259 assert_eq!(buffer.as_slice(), b"1.2.840.10008.1.2.1\0".as_ref());
260 }
261 }
262
263 const RAW_SEQUENCE_ITEMS: &[u8] = &[
279 0x08, 0x00, 0x3F, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF,
280 0xFF, 0xFE, 0xFF, 0x0D, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xDD, 0xE0, 0x00, 0x00,
281 0x00, 0x00,
282 ];
283
284 #[test]
285 fn decode_items() {
286 let dec = ImplicitVRLittleEndianDecoder::default();
287 let mut cursor = Cursor::new(RAW_SEQUENCE_ITEMS);
288 {
289 let (elem, bytes_read) = dec
291 .decode_header(&mut cursor)
292 .expect("should find an element header");
293 assert_eq!(elem.tag(), Tag(8, 0x103F));
294 assert_eq!(elem.vr(), VR::SQ);
295 assert!(elem.length().is_undefined());
296 assert_eq!(bytes_read, 8);
297 }
298 assert_eq!(cursor.stream_position().unwrap(), 8);
300 {
301 let elem = dec
302 .decode_item_header(&mut cursor)
303 .expect("should find an item header");
304 assert!(elem.is_item());
305 assert_eq!(elem.tag(), Tag(0xFFFE, 0xE000));
306 assert!(elem.length().is_undefined());
307 }
308 assert_eq!(cursor.stream_position().unwrap(), 16);
310 {
311 let elem = dec
312 .decode_item_header(&mut cursor)
313 .expect("should find an item header");
314 assert!(elem.is_item_delimiter());
315 assert_eq!(elem.tag(), Tag(0xFFFE, 0xE00D));
316 assert_eq!(elem.length(), Length(0));
317 }
318 assert_eq!(cursor.stream_position().unwrap(), 24);
320 {
321 let elem = dec
322 .decode_item_header(&mut cursor)
323 .expect("should find an item header");
324 assert!(elem.is_sequence_delimiter());
325 assert_eq!(elem.tag(), Tag(0xFFFE, 0xE0DD));
326 assert_eq!(elem.length(), Length(0));
327 }
328 }
329}