| 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 | |