1 | use crate::{ImageError, ImageResult}; |
2 | use std::io::{self, BufRead, Seek}; |
3 | |
4 | /// Used for TIFF decoding |
5 | pub enum Endian { |
6 | Little, |
7 | Big, |
8 | } |
9 | |
10 | pub fn read_i32<R: BufRead + Seek>(reader: &mut R, endianness: &Endian) -> ImageResult<i32> { |
11 | let mut attr_size_buf: [u8; 4] = [0; 4]; |
12 | reader.read_exact(&mut attr_size_buf)?; |
13 | match endianness { |
14 | Endian::Little => Ok(i32::from_le_bytes(attr_size_buf)), |
15 | Endian::Big => Ok(i32::from_be_bytes(attr_size_buf)), |
16 | } |
17 | } |
18 | |
19 | pub fn read_u32<R: BufRead + Seek>(reader: &mut R, endianness: &Endian) -> ImageResult<u32> { |
20 | let mut buf: [u8; 4] = [0; 4]; |
21 | reader.read_exact(&mut buf)?; |
22 | |
23 | match endianness { |
24 | Endian::Little => Ok(((buf[3] as u32) << 24) |
25 | | ((buf[2] as u32) << 16) |
26 | | ((buf[1] as u32) << 8) |
27 | | (buf[0] as u32)), |
28 | Endian::Big => Ok(((buf[0] as u32) << 24) |
29 | | ((buf[1] as u32) << 16) |
30 | | ((buf[2] as u32) << 8) |
31 | | (buf[3] as u32)), |
32 | } |
33 | } |
34 | |
35 | pub fn read_u24<R: BufRead + Seek>(reader: &mut R, endianness: &Endian) -> ImageResult<u32> { |
36 | let mut buf: [u8; 3] = [0; 3]; |
37 | reader.read_exact(&mut buf)?; |
38 | |
39 | match endianness { |
40 | Endian::Little => Ok(((buf[2] as u32) << 16) | ((buf[1] as u32) << 8) | (buf[0] as u32)), |
41 | Endian::Big => Ok(((buf[0] as u32) << 16) | ((buf[1] as u32) << 8) | (buf[2] as u32)), |
42 | } |
43 | } |
44 | |
45 | pub fn read_u16<R: BufRead + Seek>(reader: &mut R, endianness: &Endian) -> ImageResult<u16> { |
46 | let mut buf: [u8; 2] = [0; 2]; |
47 | reader.read_exact(&mut buf)?; |
48 | |
49 | match endianness { |
50 | Endian::Little => Ok(((buf[1] as u16) << 8) | (buf[0] as u16)), |
51 | Endian::Big => Ok(((buf[0] as u16) << 8) | (buf[1] as u16)), |
52 | } |
53 | } |
54 | |
55 | pub fn read_u8<R: BufRead + Seek>(reader: &mut R) -> ImageResult<u8> { |
56 | let mut buf: [u8; 1] = [0; 1]; |
57 | reader.read_exact(&mut buf)?; |
58 | Ok(buf[0]) |
59 | } |
60 | |
61 | pub fn read_bits(source: u128, num_bits: usize, offset: usize, size: usize) -> ImageResult<usize> { |
62 | if offset + num_bits < size { |
63 | Ok((source >> offset) as usize & ((1 << num_bits) - 1)) |
64 | } else { |
65 | Err(ImageError::CorruptedImage) |
66 | } |
67 | } |
68 | |
69 | /// Assumes tags are in format of 4 char string followed by big endian size for tag |
70 | pub fn read_tag<R: BufRead + Seek>(reader: &mut R) -> ImageResult<(String, usize)> { |
71 | let mut tag_buf: [u8; 4] = [0; 4]; |
72 | let size: usize = read_u32(reader, &Endian::Big)? as usize; |
73 | reader.read_exact(&mut tag_buf)?; |
74 | |
75 | Ok((String::from_utf8_lossy(&tag_buf).into_owned(), size)) |
76 | } |
77 | |
78 | pub fn read_until_capped<R: BufRead>(reader: &mut R, delimiter: u8, max_size: usize) -> io::Result<Vec<u8>> { |
79 | let mut bytes: Vec = Vec::new(); |
80 | let mut amount_read: usize = 0; |
81 | |
82 | while amount_read < max_size { |
83 | let mut byte: [u8; 1] = [0; 1]; |
84 | reader.read_exact(&mut byte)?; |
85 | |
86 | if byte[0] == delimiter { |
87 | break; |
88 | } |
89 | |
90 | bytes.push(byte[0]); |
91 | amount_read += 1; |
92 | } |
93 | |
94 | if amount_read >= max_size { |
95 | return Err(io::Error::new(kind:io::ErrorKind::InvalidData, error:format!("Delimiter not found within {} bytes" , max_size))); |
96 | } |
97 | |
98 | Ok(bytes) |
99 | } |
100 | |
101 | /// Skips all starting whitespace characters and then reads a string until the next whitespace character |
102 | /// Example: |
103 | /// " test string" => "test" |
104 | pub fn read_until_whitespace<R: BufRead>(reader: &mut R, max_size: usize) -> io::Result<String> { |
105 | let mut bytes = Vec::new(); |
106 | let mut amount_read = 0; |
107 | let mut seen_non_whitespace = false; |
108 | |
109 | while amount_read < max_size { |
110 | amount_read += 1; |
111 | |
112 | let mut byte = [0; 1]; |
113 | reader.read_exact(&mut byte)?; |
114 | |
115 | if byte[0].is_ascii_whitespace() { |
116 | // If we've seen a non-whitespace character before then exit |
117 | if seen_non_whitespace { |
118 | break; |
119 | } |
120 | |
121 | // Skip whitespace until we found first non-whitespace character |
122 | continue; |
123 | } |
124 | |
125 | bytes.push(byte[0]); |
126 | seen_non_whitespace = true; |
127 | } |
128 | |
129 | if amount_read >= max_size { |
130 | return Err(io::Error::new(io::ErrorKind::InvalidData, format!("Delimiter not found within {} bytes" , max_size))); |
131 | } |
132 | |
133 | String::from_utf8(bytes).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) |
134 | } |
135 | |
136 | pub fn read_line_capped<R: BufRead>(reader: &mut R, max_size: usize) -> io::Result<String> { |
137 | let bytes: Vec = read_until_capped(reader, delimiter:b' \n' , max_size)?; |
138 | String::from_utf8(bytes).map_err(|e: FromUtf8Error| io::Error::new(kind:io::ErrorKind::InvalidData, error:e)) |
139 | } |
140 | |
141 | pub fn read_null_terminated_string<R: BufRead>(reader: &mut R, max_size: usize) -> io::Result<String> { |
142 | let bytes: Vec = read_until_capped(reader, delimiter:0, max_size)?; |
143 | String::from_utf8(bytes).map_err(|e: FromUtf8Error| io::Error::new(kind:io::ErrorKind::InvalidData, error:e)) |
144 | } |
145 | |