1use std::io::{self, Read};
2
3#[derive(Debug, Clone)]
4pub struct DataElement {
5 pub tag: (u16, u16),
6 pub vr: [u8; 2],
7 pub length: u32,
8 pub value: Vec<u8>,
9}
10
11pub fn read_element_explicit_le<R: Read>(reader: &mut R) -> io::Result<Option<DataElement>> {
13 let mut tag_bytes = [0u8; 4];
14 if !fill(reader, &mut tag_bytes)? {
15 return Ok(None);
16 }
17
18 let group = u16::from_le_bytes([tag_bytes[0], tag_bytes[1]]);
19 let element = u16::from_le_bytes([tag_bytes[2], tag_bytes[3]]);
20
21 let mut vr = [0u8; 2];
22 fill(reader, &mut vr)?;
23
24 let length = if uses_32bit_length(&vr) {
25 let mut reserved = [0u8; 2];
26 fill(reader, &mut reserved)?;
27
28 let mut len_bytes = [0u8; 4];
29 fill(reader, &mut len_bytes)?;
30 u32::from_le_bytes(len_bytes)
31 } else {
32 let mut len_bytes = [0u8; 2];
33 fill(reader, &mut len_bytes)?;
34 u16::from_le_bytes(len_bytes) as u32
35 };
36
37 let mut value = vec![0u8; length as usize];
38 if length > 0 {
39 read_exact(reader, &mut value)?;
40 }
41
42 Ok(Some(DataElement {
43 tag: (group, element),
44 vr,
45 length,
46 value,
47 }))
48}
49
50pub fn read_transfer_syntax_uid<R: Read>(reader: &mut R) -> io::Result<Option<String>> {
51 while let Some(element) = read_element_explicit_le(reader)? {
52 if element.tag.0 != 0x0002 {
53 return Ok(None);
55 }
56
57 if element.tag == (0x0002, 0x0010) {
58 let trimmed = element
59 .value
60 .split(|&b| b == 0)
61 .next()
62 .unwrap_or(&[])
63 .to_vec();
64 let as_str = String::from_utf8_lossy(&trimmed).to_string();
65 return Ok(Some(as_str));
66 }
67 }
68
69 Ok(None)
70}
71
72fn uses_32bit_length(vr: &[u8; 2]) -> bool {
73 matches!(
74 std::str::from_utf8(vr).ok(),
75 Some("OB" | "OD" | "OF" | "OL" | "OW" | "SQ" | "UC" | "UR" | "UT" | "UN")
76 )
77}
78
79fn fill<R: Read>(reader: &mut R, buf: &mut [u8]) -> io::Result<bool> {
80 let mut read = 0usize;
81 while read < buf.len() {
82 match reader.read(&mut buf[read..])? {
83 0 if read == 0 => return Ok(false),
84 0 => {
85 return Err(io::Error::new(
86 io::ErrorKind::UnexpectedEof,
87 "unexpected EOF while reading element",
88 ))
89 }
90 n => read += n,
91 }
92 }
93 Ok(true)
94}
95
96fn read_exact<R: Read>(reader: &mut R, buf: &mut [u8]) -> io::Result<()> {
97 let mut offset = 0usize;
98 while offset < buf.len() {
99 match reader.read(&mut buf[offset..])? {
100 0 => {
101 return Err(io::Error::new(
102 io::ErrorKind::UnexpectedEof,
103 "unexpected EOF while reading element value",
104 ))
105 }
106 n => offset += n,
107 }
108 }
109 Ok(())
110}