1use crate::{ImageError, ImageResult};
2use std::io::{self, BufRead, Seek};
3
4pub enum Endian {
6 Little,
7 Big,
8}
9
10pub fn read_u64<R: BufRead + Seek>(reader: &mut R, endianness: &Endian) -> ImageResult<u64> {
11 let mut buf = [0; 8];
12 reader.read_exact(&mut buf)?;
13
14 match endianness {
15 Endian::Little => Ok(u64::from_le_bytes(buf)),
16 Endian::Big => Ok(u64::from_be_bytes(buf)),
17 }
18}
19
20pub fn read_i32<R: BufRead + Seek>(reader: &mut R, endianness: &Endian) -> ImageResult<i32> {
21 let mut attr_size_buf = [0; 4];
22 reader.read_exact(&mut attr_size_buf)?;
23 match endianness {
24 Endian::Little => Ok(i32::from_le_bytes(attr_size_buf)),
25 Endian::Big => Ok(i32::from_be_bytes(attr_size_buf)),
26 }
27}
28
29pub fn read_u32<R: BufRead + Seek>(reader: &mut R, endianness: &Endian) -> ImageResult<u32> {
30 let mut buf = [0; 4];
31 reader.read_exact(&mut buf)?;
32
33 match endianness {
34 Endian::Little => Ok(u32::from_le_bytes(buf)),
35 Endian::Big => Ok(u32::from_be_bytes(buf)),
36 }
37}
38
39pub fn read_u24<R: BufRead + Seek>(reader: &mut R, endianness: &Endian) -> ImageResult<u32> {
40 let mut buf = [0; 3];
41 reader.read_exact(&mut buf)?;
42
43 match endianness {
44 Endian::Little => Ok(((buf[2] as u32) << 16) | ((buf[1] as u32) << 8) | (buf[0] as u32)),
45 Endian::Big => Ok(((buf[0] as u32) << 16) | ((buf[1] as u32) << 8) | (buf[2] as u32)),
46 }
47}
48
49pub fn read_u16<R: BufRead + Seek>(reader: &mut R, endianness: &Endian) -> ImageResult<u16> {
50 let mut buf = [0; 2];
51 reader.read_exact(&mut buf)?;
52
53 match endianness {
54 Endian::Little => Ok(u16::from_le_bytes(buf)),
55 Endian::Big => Ok(u16::from_be_bytes(buf)),
56 }
57}
58
59pub fn read_u8<R: BufRead + Seek>(reader: &mut R) -> ImageResult<u8> {
60 let mut buf = [0; 1];
61 reader.read_exact(&mut buf)?;
62 Ok(buf[0])
63}
64
65pub fn read_bits(source: u128, num_bits: usize, offset: usize, size: usize) -> ImageResult<usize> {
66 if offset + num_bits < size {
67 Ok((source >> offset) as usize & ((1 << num_bits) - 1))
68 } else {
69 Err(ImageError::CorruptedImage)
70 }
71}
72
73pub fn read_tag<R: BufRead + Seek>(reader: &mut R) -> ImageResult<(String, usize)> {
75 let mut tag_buf = [0; 4];
76 let size = read_u32(reader, &Endian::Big)? as usize;
77 reader.read_exact(&mut tag_buf)?;
78
79 Ok((String::from_utf8_lossy(&tag_buf).into_owned(), size))
80}
81
82pub fn read_until_capped<R: BufRead>(
83 reader: &mut R,
84 delimiter: u8,
85 max_size: usize,
86) -> io::Result<Vec<u8>> {
87 let mut bytes = Vec::new();
88 let mut amount_read = 0;
89
90 while amount_read < max_size {
91 let mut byte = [0; 1];
92 reader.read_exact(&mut byte)?;
93
94 if byte[0] == delimiter {
95 break;
96 }
97
98 bytes.push(byte[0]);
99 amount_read += 1;
100 }
101
102 if amount_read >= max_size {
103 return Err(io::Error::new(
104 io::ErrorKind::InvalidData,
105 format!("Delimiter not found within {} bytes", max_size),
106 ));
107 }
108
109 Ok(bytes)
110}
111
112pub fn read_until_whitespace<R: BufRead>(reader: &mut R, max_size: usize) -> io::Result<String> {
116 let mut bytes = Vec::new();
117 let mut amount_read = 0;
118 let mut seen_non_whitespace = false;
119
120 while amount_read < max_size {
121 amount_read += 1;
122
123 let mut byte = [0; 1];
124 reader.read_exact(&mut byte)?;
125
126 if byte[0].is_ascii_whitespace() {
127 if seen_non_whitespace {
129 break;
130 }
131
132 continue;
134 }
135
136 bytes.push(byte[0]);
137 seen_non_whitespace = true;
138 }
139
140 if amount_read >= max_size {
141 return Err(io::Error::new(
142 io::ErrorKind::InvalidData,
143 format!("Delimiter not found within {} bytes", max_size),
144 ));
145 }
146
147 String::from_utf8(bytes).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
148}
149
150pub fn read_line_capped<R: BufRead>(reader: &mut R, max_size: usize) -> io::Result<String> {
151 let bytes = read_until_capped(reader, b'\n', max_size)?;
152 String::from_utf8(bytes).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
153}
154
155pub fn read_null_terminated_string<R: BufRead>(
156 reader: &mut R,
157 max_size: usize,
158) -> io::Result<String> {
159 let bytes = read_until_capped(reader, 0, max_size)?;
160 String::from_utf8(bytes).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
161}