1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#![warn(missing_docs)]
#![doc(html_logo_url = "http://plopgrizzly.com/icon.png",
html_favicon_url = "http://plopgrizzly.com/icon.png",
html_root_url = "http://plopgrizzly.com/aci_png/")]
extern crate afi;
extern crate byteorder;
mod png;
use std::io::{ Read, Seek, Cursor };
use afi::*;
pub struct PngEncoder {
wh: (u16, u16),
format: ColorChannels,
}
impl EncoderV for PngEncoder {
fn new(video: &Video) -> PngEncoder {
let wh = video.wh();
let format = video.format();
PngEncoder {
wh, format
}
}
fn run(&mut self, frame: &VFrame) -> Vec<u8> {
let alpha = self.format.n_channels() == 4;
let mut out = vec![];
png::write(&mut out, self.wh.0, self.wh.1, &frame.0, alpha)
.unwrap();
out
}
fn end(self) -> Vec<u8> {
vec![]
}
}
pub struct PngDecoder<T: Read + Seek> {
#[allow(unused)]
data: T,
channels: ColorChannels,
wh: (u16, u16),
n_frames: u32,
out: Vec<u8>,
}
impl<T> Decoder<T> for PngDecoder<T> where T: Read + Seek {
fn new(mut data: T, channels: afi::ColorChannels)
-> Option<PngDecoder<T>>
{
let n_frames = 1;
let i: Result<png::Image<u8>, png::Error> = {
png::read(&mut data)
};
let image = if let Result::Ok(p) = i { p }
else { return None };
let bytes: Vec<u8> = image.buf;
let size = image.w as usize * image.h as usize;
let mut out: Vec<u8> = Vec::with_capacity(size
* channels.n_channels());
for i in 0..size {
let rgba = channels.from(Rgba,
[bytes[i*4+0], bytes[i*4+1],
bytes[i*4+2], bytes[i*4+3]]);
for i in 0..channels.n_channels() {
out.push(rgba[i]);
}
}
let wh = (image.w, image.h);
Some(PngDecoder { data, channels, wh, n_frames, out })
}
fn run(&mut self, audio: &mut Option<Audio>, video: &mut Option<Video>)
-> Option<bool>
{
if audio.is_none() && video.is_none() {
*video = Some(Video::new(
self.channels, self.wh, self.n_frames
));
Some(true)
} else {
let video = video.as_mut().unwrap();
video.add(VFrame(self.out.clone()));
Some(false)
}
}
fn get(&self) -> Index {
Index(0)
}
fn set(&mut self, _index: Index) {
}
}
pub fn decode(file: &[u8], channels: ColorChannels) -> Option<Video> {
let mut image = None;
let mut decoder = PngDecoder::new(Cursor::new(file), channels)?;
decoder.run(&mut None, &mut image).unwrap();
decoder.run(&mut None, &mut image).unwrap();
image
}