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>(
|
79 | reader: &mut R,
|
80 | delimiter: u8,
|
81 | max_size: usize,
|
82 | ) -> io::Result<Vec<u8>> {
|
83 | let mut bytes = Vec::new();
|
84 | let mut amount_read = 0;
|
85 |
|
86 | while amount_read < max_size {
|
87 | let mut byte = [0; 1];
|
88 | reader.read_exact(&mut byte)?;
|
89 |
|
90 | if byte[0] == delimiter {
|
91 | break;
|
92 | }
|
93 |
|
94 | bytes.push(byte[0]);
|
95 | amount_read += 1;
|
96 | }
|
97 |
|
98 | if amount_read >= max_size {
|
99 | return Err(io::Error::new(
|
100 | io::ErrorKind::InvalidData,
|
101 | format!("Delimiter not found within {} bytes" , max_size),
|
102 | ));
|
103 | }
|
104 |
|
105 | Ok(bytes)
|
106 | }
|
107 |
|
108 | /// Skips all starting whitespace characters and then reads a string until the next whitespace character
|
109 | /// Example:
|
110 | /// " test string" => "test"
|
111 | pub fn read_until_whitespace<R: BufRead>(reader: &mut R, max_size: usize) -> io::Result<String> {
|
112 | let mut bytes = Vec::new();
|
113 | let mut amount_read = 0;
|
114 | let mut seen_non_whitespace = false;
|
115 |
|
116 | while amount_read < max_size {
|
117 | amount_read += 1;
|
118 |
|
119 | let mut byte = [0; 1];
|
120 | reader.read_exact(&mut byte)?;
|
121 |
|
122 | if byte[0].is_ascii_whitespace() {
|
123 | // If we've seen a non-whitespace character before then exit
|
124 | if seen_non_whitespace {
|
125 | break;
|
126 | }
|
127 |
|
128 | // Skip whitespace until we found first non-whitespace character
|
129 | continue;
|
130 | }
|
131 |
|
132 | bytes.push(byte[0]);
|
133 | seen_non_whitespace = true;
|
134 | }
|
135 |
|
136 | if amount_read >= max_size {
|
137 | return Err(io::Error::new(
|
138 | io::ErrorKind::InvalidData,
|
139 | format!("Delimiter not found within {} bytes" , max_size),
|
140 | ));
|
141 | }
|
142 |
|
143 | String::from_utf8(bytes).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
|
144 | }
|
145 |
|
146 | pub fn read_line_capped<R: BufRead>(reader: &mut R, max_size: usize) -> io::Result<String> {
|
147 | let bytes: Vec = read_until_capped(reader, delimiter:b' \n' , max_size)?;
|
148 | String::from_utf8(bytes).map_err(|e: FromUtf8Error| io::Error::new(kind:io::ErrorKind::InvalidData, error:e))
|
149 | }
|
150 |
|
151 | pub fn read_null_terminated_string<R: BufRead>(
|
152 | reader: &mut R,
|
153 | max_size: usize,
|
154 | ) -> io::Result<String> {
|
155 | let bytes: Vec = read_until_capped(reader, delimiter:0, max_size)?;
|
156 | String::from_utf8(bytes).map_err(|e: FromUtf8Error| io::Error::new(kind:io::ErrorKind::InvalidData, error:e))
|
157 | }
|
158 | |