1use crate::decode::basic::BigEndianBasicDecoder;
4use crate::decode::{
5 BadSequenceHeaderSnafu, BasicDecode, Decode, DecodeFrom, ReadHeaderTagSnafu,
6 ReadItemHeaderSnafu, ReadItemLengthSnafu, ReadLengthSnafu, ReadReservedSnafu, ReadTagSnafu,
7 ReadVrSnafu, Result,
8};
9use byteordered::byteorder::{BigEndian, ByteOrder};
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 ExplicitVRBigEndianDecoder {
18 basic: BigEndianBasicDecoder,
19}
20
21impl Decode for ExplicitVRBigEndianDecoder {
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 = BigEndian::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
47 let bytes_read;
48
49 let len = match vr {
51 VR::OB
52 | VR::OD
53 | VR::OF
54 | VR::OL
55 | VR::OW
56 | VR::SQ
57 | VR::UC
58 | VR::UR
59 | VR::UT
60 | VR::UN => {
61 source
63 .read_exact(&mut buf[0..2])
64 .context(ReadReservedSnafu)?;
65 source.read_exact(&mut buf).context(ReadLengthSnafu)?;
66 bytes_read = 12;
67 BigEndian::read_u32(&buf)
68 }
69 _ => {
70 source
72 .read_exact(&mut buf[0..2])
73 .context(ReadItemLengthSnafu)?;
74 bytes_read = 8;
75 u32::from(BigEndian::read_u16(&buf[0..2]))
76 }
77 };
78
79 Ok((
80 DataElementHeader::new((group, element), vr, Length(len)),
81 bytes_read,
82 ))
83 }
84
85 fn decode_item_header<S>(&self, source: &mut S) -> Result<SequenceItemHeader>
86 where
87 S: ?Sized + Read,
88 {
89 let mut buf = [0u8; 8];
90 source.read_exact(&mut buf).context(ReadItemHeaderSnafu)?;
91 let group = BigEndian::read_u16(&buf[0..2]);
93 let element = BigEndian::read_u16(&buf[2..4]);
94 let len = BigEndian::read_u32(&buf[4..8]);
95
96 SequenceItemHeader::new((group, element), Length(len)).context(BadSequenceHeaderSnafu)
97 }
98
99 fn decode_tag<S>(&self, source: &mut S) -> Result<Tag>
100 where
101 S: ?Sized + Read,
102 {
103 let mut buf = [0u8; 4];
104 source.read_exact(&mut buf).context(ReadTagSnafu)?;
105 Ok(Tag(
106 BigEndian::read_u16(&buf[0..2]),
107 BigEndian::read_u16(&buf[2..4]),
108 ))
109 }
110}
111
112impl<S: ?Sized> DecodeFrom<S> for ExplicitVRBigEndianDecoder
113where
114 S: Read,
115{
116 #[inline]
117 fn decode_header(&self, source: &mut S) -> Result<(DataElementHeader, usize)> {
118 Decode::decode_header(self, source)
119 }
120
121 #[inline]
122 fn decode_item_header(&self, source: &mut S) -> Result<SequenceItemHeader> {
123 Decode::decode_item_header(self, source)
124 }
125
126 #[inline]
127 fn decode_tag(&self, source: &mut S) -> Result<Tag> {
128 Decode::decode_tag(self, source)
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::ExplicitVRBigEndianDecoder;
135 use crate::decode::Decode;
136 use dicom_core::header::{HasLength, Header, Length};
137 use dicom_core::{Tag, VR};
138 use std::io::{Cursor, Read, Seek, SeekFrom};
139
140 const RAW: &'static [u8; 62] = &[
152 0x00, 0x02, 0x00, 0x02, 0x55, 0x49, 0x00, 0x1a, 0x31, 0x2e, 0x32, 0x2e, 0x38, 0x34, 0x30,
153 0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x35, 0x2e, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e,
154 0x31, 0x2e, 0x31, 0x00, 0x00, 0x02, 0x00, 0x10, 0x55, 0x49, 0x00, 0x14, 0x31, 0x2e, 0x32,
155 0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x31, 0x2e, 0x32, 0x2e,
156 0x31, 0x00,
157 ];
158
159 #[test]
160 fn decode_explicit_vr_be() {
161 let reader = ExplicitVRBigEndianDecoder::default();
162 let mut cursor = Cursor::new(RAW.as_ref());
163 {
164 let (elem, bytes_read) = reader
166 .decode_header(&mut cursor)
167 .expect("should find an element");
168 assert_eq!(elem.tag(), Tag(2, 2));
169 assert_eq!(elem.vr(), VR::UI);
170 assert_eq!(elem.length(), Length(26));
171 assert_eq!(bytes_read, 8);
172 let mut buffer = [0; 13];
174 cursor.read_exact(&mut buffer).expect("should read it fine");
175 assert_eq!(&buffer, b"1.2.840.10008".as_ref());
176 }
177 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 21);
179 assert_eq!(cursor.seek(SeekFrom::Current(13)).unwrap(), 34);
181 {
182 let (elem, _bytes_read) = reader
184 .decode_header(&mut cursor)
185 .expect("should find an element");
186 assert_eq!(elem.tag(), Tag(2, 16));
187 assert_eq!(elem.vr(), VR::UI);
188 assert_eq!(elem.length(), Length(20));
189 let mut buffer = [0; 20];
191 cursor.read_exact(&mut buffer).expect("should read it fine");
192 assert_eq!(&buffer, b"1.2.840.10008.1.2.1\0".as_ref());
193 }
194 }
195
196 const RAW_SEQUENCE_ITEMS: &'static [u8] = &[
212 0x00, 0x08, 0x10, 0x3F, b'S', b'Q', 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xE0,
213 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xE0, 0x0D, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE,
214 0xE0, 0xDD, 0x00, 0x00, 0x00, 0x00,
215 ];
216
217 #[test]
218 fn decode_items() {
219 let dec = ExplicitVRBigEndianDecoder::default();
220 let mut cursor = Cursor::new(RAW_SEQUENCE_ITEMS);
221 {
222 let (elem, _bytes_read) = dec
224 .decode_header(&mut cursor)
225 .expect("should find an element header");
226 assert_eq!(elem.tag(), Tag(8, 0x103F));
227 assert_eq!(elem.vr(), VR::SQ);
228 assert!(elem.length().is_undefined());
229 }
230 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 12);
232 {
233 let elem = dec
234 .decode_item_header(&mut cursor)
235 .expect("should find an item header");
236 assert!(elem.is_item());
237 assert_eq!(elem.tag(), Tag(0xFFFE, 0xE000));
238 assert!(elem.length().is_undefined());
239 }
240 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 20);
242 {
243 let elem = dec
244 .decode_item_header(&mut cursor)
245 .expect("should find an item header");
246 assert!(elem.is_item_delimiter());
247 assert_eq!(elem.tag(), Tag(0xFFFE, 0xE00D));
248 assert_eq!(elem.length(), Length(0));
249 }
250 assert_eq!(cursor.seek(SeekFrom::Current(0)).unwrap(), 28);
252 {
253 let elem = dec
254 .decode_item_header(&mut cursor)
255 .expect("should find an item header");
256 assert!(elem.is_sequence_delimiter());
257 assert_eq!(elem.tag(), Tag(0xFFFE, 0xE0DD));
258 assert_eq!(elem.length(), Length(0));
259 }
260 }
261}