Added some utils + Farbfeld reader
Getty Ritter
8 years ago
1 | use glium::texture::{RawImage2d,Texture2dDataSource}; | |
2 | use therm_util::reader::ByteReader; | |
3 | ||
4 | #[derive(Debug,Clone)] | |
5 | pub struct FFImage { | |
6 | pixels: Vec<Vec<(u16,u16,u16,u16)>> | |
7 | } | |
8 | ||
9 | fn parse_pixel<Rd>(r: &mut ByteReader<Rd>) -> Result<(u16,u16,u16,u16), String> | |
10 | where Rd: Iterator<Item=u8> | |
11 | { | |
12 | Ok((try!(r.read_u16be()), | |
13 | try!(r.read_u16be()), | |
14 | try!(r.read_u16be()), | |
15 | try!(r.read_u16be()))) | |
16 | } | |
17 | ||
18 | impl FFImage { | |
19 | pub fn from_bz2_file(path: &str) -> Result<FFImage, String> { | |
20 | let mut r = match ByteReader::from_compressed_file(path) { | |
21 | Ok(x) => x, | |
22 | Err(_) => return Err("Unable to open file".to_string()), | |
23 | }; | |
24 | FFImage::from_reader(&mut r) | |
25 | } | |
26 | ||
27 | pub fn from_file(path: &str) -> Result<FFImage, String> { | |
28 | let mut r = match ByteReader::from_file(path) { | |
29 | Ok(x) => x, | |
30 | Err(_) => return Err("Unable to open file".to_string()), | |
31 | }; | |
32 | FFImage::from_reader(&mut r) | |
33 | } | |
34 | ||
35 | ||
36 | pub fn from_reader<Rd>(r: &mut ByteReader<Rd>) -> Result<FFImage, String> | |
37 | where Rd: Iterator<Item=u8> | |
38 | { | |
39 | assert!(try!(r.next()) == 'f' as u8); | |
40 | assert!(try!(r.next()) == 'a' as u8); | |
41 | assert!(try!(r.next()) == 'r' as u8); | |
42 | assert!(try!(r.next()) == 'b' as u8); | |
43 | assert!(try!(r.next()) == 'f' as u8); | |
44 | assert!(try!(r.next()) == 'e' as u8); | |
45 | assert!(try!(r.next()) == 'l' as u8); | |
46 | assert!(try!(r.next()) == 'd' as u8); | |
47 | ||
48 | let w = try!(r.read_u32be()); | |
49 | let h = try!(r.read_u32be()); | |
50 | ||
51 | let mut pixels = vec![]; | |
52 | for _ in 0..h { | |
53 | let mut row = vec![]; | |
54 | for _ in 0..w { | |
55 | row.push(try!(parse_pixel(r))); | |
56 | } | |
57 | pixels.push(row) | |
58 | } | |
59 | pixels.reverse(); | |
60 | ||
61 | Ok(FFImage { pixels: pixels }) | |
62 | } | |
63 | ||
64 | pub fn get_raw_data(self) -> Vec<Vec<(u16,u16,u16,u16)>> { | |
65 | self.pixels | |
66 | } | |
67 | } | |
68 | ||
69 | impl <'a> Texture2dDataSource<'a> for FFImage { | |
70 | type Data = (u16, u16, u16, u16); | |
71 | ||
72 | fn into_raw(self) -> RawImage2d<'a, (u16, u16, u16, u16)> { | |
73 | self.pixels.into_raw() | |
74 | } | |
75 | } |
1 |
use std::{fs,io,iter, |
|
1 | use std::{fs,io,iter,mem,slice,vec}; | |
2 | use bzip2::bufread::BzDecoder; | |
2 | 3 | |
3 | 4 | /// A `ByteReader` is just a tiny wrapper over a mutable byte iterator, so we |
4 | 5 | /// can parse things more easily. |
6 | 7 | bytes: Rd, |
7 | 8 | } |
8 | 9 | |
9 | impl<R: io::Read> | |
10 | ByteReader<iter::FilterMap<io::Bytes<R>, | |
11 |
|
|
10 | impl<R: io::Read> ByteReader<iter::FilterMap<io::Bytes<R>, &'static Fn(io::Result<u8>) -> Option<u8>>> | |
12 | 11 | { |
13 | 12 | /// Create a ByteReader from any type that implement Read |
14 | 13 | pub fn from_reader(r: R) -> Self { |
35 | 34 | } |
36 | 35 | } |
37 | 36 | |
38 |
impl<'a> ByteReader<iter:: |
|
37 | impl<'a> ByteReader<iter::Cloned<slice::Iter<'a, u8>>> { | |
39 | 38 | /// Create a reader from a borrowed slice, with a copy on each access |
40 | 39 | pub fn from_slice(lst: &'a [u8]) -> Self { |
41 | const DEREF: &'static Fn(&u8) -> u8 = &|s| *s; | |
42 | ByteReader { bytes: lst.iter().map(DEREF) } | |
40 | ByteReader { bytes: lst.iter().cloned() } | |
41 | } | |
42 | } | |
43 | ||
44 | impl<R: io::BufRead> ByteReader<iter::FilterMap<io::Bytes<BzDecoder<R>>, &'static Fn(io::Result<u8>) -> Option<u8>>> { | |
45 | pub fn from_compressed_reader(r: R) -> Self { | |
46 | ByteReader::from_reader(BzDecoder::new(r)) | |
47 | } | |
48 | } | |
49 | ||
50 | impl ByteReader<iter::FilterMap<io::Bytes<BzDecoder<io::BufReader<fs::File>>>, &'static Fn(io::Result<u8>) -> Option<u8>>> { | |
51 | pub fn from_compressed_file(path: &str) -> io::Result<Self> { | |
52 | let f = try!(fs::File::open(path)); | |
53 | Ok(ByteReader::from_compressed_reader(io::BufReader::new(f))) | |
43 | 54 | } |
44 | 55 | } |
45 | 56 | |
79 | 90 | pub fn read_ratio(&mut self) -> Result<f32, String> { |
80 | 91 | let b = try!(self.next()); |
81 | 92 | Ok(b as f32 / 255.0) |
93 | } | |
94 | ||
95 | pub fn read_u32be(&mut self) -> Result<u32, String> { | |
96 | let a = try!(self.next()); | |
97 | let b = try!(self.next()); | |
98 | let c = try!(self.next()); | |
99 | let d = try!(self.next()); | |
100 | let rs = [ d, c, b, a ]; | |
101 | unsafe { Ok(mem::transmute::<[u8;4],u32>(rs)) } | |
102 | } | |
103 | ||
104 | pub fn read_u16be(&mut self) -> Result<u16, String> { | |
105 | let a = try!(self.next()); | |
106 | let b = try!(self.next()); | |
107 | let rs = [ b, a ]; | |
108 | unsafe { Ok(mem::transmute::<[u8;2],u16>(rs)) } | |
82 | 109 | } |
83 | 110 | |
84 | 111 | /// This reads a 64-bit int with a packed PrefixInteger representation. |