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: &'static [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: &'static 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::with_capacity(13);
197 buffer.resize(13, 0);
198 cursor
199 .read_exact(buffer.as_mut_slice())
200 .expect("should read it fine");
201 assert_eq!(buffer.as_slice(), b"1.2.840.10008".as_ref());
202 }
203 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 21);
205 assert_eq!(cursor.seek(SeekFrom::Current(13)).unwrap(), 34);
207 {
208 let (elem, _bytes_read) = reader
210 .decode_header(&mut cursor)
211 .expect("should find an element");
212 assert_eq!(elem.tag(), Tag(0x0002, 0x0010));
213 assert_eq!(elem.vr(), VR::UN);
214 assert_eq!(elem.length(), Length(20));
215 let mut buffer: Vec<u8> = Vec::with_capacity(20);
217 buffer.resize(20, 0);
218 cursor
219 .read_exact(buffer.as_mut_slice())
220 .expect("should read it fine");
221 assert_eq!(buffer.as_slice(), b"1.2.840.10008.1.2.1\0".as_ref());
222 }
223 }
224
225 #[test]
226 fn implicit_vr_le_with_standard_dictionary() {
227 let reader = ImplicitVRLittleEndianDecoder::with_std_dict();
228 let mut cursor = Cursor::new(RAW.as_ref());
229 {
230 let (elem, _bytes_read) = reader
232 .decode_header(&mut cursor)
233 .expect("should find an element");
234 assert_eq!(elem.tag(), Tag(2, 2));
235 assert_eq!(elem.vr(), VR::UI);
236 assert_eq!(elem.length(), Length(26));
237 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 8);
239 assert_eq!(
242 cursor
243 .seek(SeekFrom::Current(elem.length().0 as i64))
244 .unwrap(),
245 34
246 );
247 }
248 {
249 let (elem, _bytes_read) = reader
251 .decode_header(&mut cursor)
252 .expect("should find an element");
253 assert_eq!(elem.tag(), Tag(2, 16));
254 assert_eq!(elem.vr(), VR::UI);
255 assert_eq!(elem.length(), Length(20));
256 let mut buffer: Vec<u8> = Vec::with_capacity(20);
258 buffer.resize(20, 0);
259 cursor
260 .read_exact(buffer.as_mut_slice())
261 .expect("should read it fine");
262 assert_eq!(buffer.as_slice(), b"1.2.840.10008.1.2.1\0".as_ref());
263 }
264 }
265
266 const RAW_SEQUENCE_ITEMS: &'static [u8] = &[
282 0x08, 0x00, 0x3F, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF,
283 0xFF, 0xFE, 0xFF, 0x0D, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xDD, 0xE0, 0x00, 0x00,
284 0x00, 0x00,
285 ];
286
287 #[test]
288 fn decode_items() {
289 let dec = ImplicitVRLittleEndianDecoder::default();
290 let mut cursor = Cursor::new(RAW_SEQUENCE_ITEMS);
291 {
292 let (elem, bytes_read) = dec
294 .decode_header(&mut cursor)
295 .expect("should find an element header");
296 assert_eq!(elem.tag(), Tag(8, 0x103F));
297 assert_eq!(elem.vr(), VR::SQ);
298 assert!(elem.length().is_undefined());
299 assert_eq!(bytes_read, 8);
300 }
301 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 8);
303 {
304 let elem = dec
305 .decode_item_header(&mut cursor)
306 .expect("should find an item header");
307 assert!(elem.is_item());
308 assert_eq!(elem.tag(), Tag(0xFFFE, 0xE000));
309 assert!(elem.length().is_undefined());
310 }
311 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 16);
313 {
314 let elem = dec
315 .decode_item_header(&mut cursor)
316 .expect("should find an item header");
317 assert!(elem.is_item_delimiter());
318 assert_eq!(elem.tag(), Tag(0xFFFE, 0xE00D));
319 assert_eq!(elem.length(), Length(0));
320 }
321 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 24);
323 {
324 let elem = dec
325 .decode_item_header(&mut cursor)
326 .expect("should find an item header");
327 assert!(elem.is_sequence_delimiter());
328 assert_eq!(elem.tag(), Tag(0xFFFE, 0xE0DD));
329 assert_eq!(elem.length(), Length(0));
330 }
331 }
332}