-
-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathmod.rs
94 lines (90 loc) · 2.33 KB
/
mod.rs
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
pub mod encoder;
#[cfg(feature = "ski")]
pub mod ski;
use crate::anim::settings::AnimSettings;
use crate::app::AppResult;
use crate::gif::encoder::{Encoder, EncoderConfig};
use crate::image::Image;
use crate::util::state::InputState;
use gif::{Encoder as BaseEncoder, Frame, Repeat};
use image::ExtendedColorType;
use std::io::{self, Write};
/* GIF encoder and settings */
pub struct GifEncoder<'a, Output: Write> {
fps: u32,
encoder: BaseEncoder<Output>,
settings: &'a AnimSettings,
}
impl<'a, Output: Write> Encoder<'a, Output> for GifEncoder<'a, Output> {
/**
* Create a new GifEncoder object.
*
* @param config
* @return GifEncoder (Result)
*/
fn new(config: EncoderConfig<'a, Output>) -> AppResult<Self> {
let mut encoder = BaseEncoder::new(
config.output,
config.geometry.width.try_into().unwrap_or_default(),
config.geometry.height.try_into().unwrap_or_default(),
&[],
)?;
encoder.set_repeat(match config.settings.repeat {
n if n >= 0 => Repeat::Finite(n.try_into().unwrap_or_default()),
_ => Repeat::Infinite,
})?;
Ok(Self {
fps: config.fps,
encoder,
settings: config.settings,
})
}
/**
* Encode images as frame and write to the GIF file.
*
* @param images
* @param input_state (Option)
* @param Result
*/
fn save(
mut self,
images: Vec<Image>,
input_state: Option<&'static InputState>,
) -> AppResult<()> {
let speed = 30
- self.settings.map_range(
self.settings.quality.into(),
(1., 100.),
(0., 29.),
) as i32;
for (i, image) in images.iter().enumerate() {
let percentage = ((i + 1) as f64 / images.len() as f64) * 100.;
info!("Saving... ({:.1}%)\r", percentage);
debug!(
"Encoding... ({:.1}%) [{}/{}]\r",
percentage,
i + 1,
images.len()
);
io::stdout().flush()?;
if let Some(state) = input_state {
if state.check_cancel_keys() {
info!("\n");
warn!("User interrupt detected.");
panic!("Failed to write the frames")
}
}
let mut frame = Frame::from_rgba_speed(
image.geometry.width.try_into().unwrap_or_default(),
image.geometry.height.try_into().unwrap_or_default(),
&mut image.get_data(ExtendedColorType::Rgba8),
speed,
);
frame.delay = (1e2 / self.fps as f32) as u16;
frame.make_lzw_pre_encoded();
self.encoder.write_lzw_pre_encoded_frame(&frame)?;
}
info!("\n");
Ok(())
}
}