Skip to content

Commit bbbdc2c

Browse files
committed
[backend.rs] Add support for ppm rendering.
* Closes: #12 * Thanks to AmusedAstronaut in our matrix room for patching ppm support in * Fixes a regression where `--stdout` would not respect `--extension` provided by user Signed-off-by: Shinyzenith <aakashsensharma@gmail.com>
1 parent 9a1f277 commit bbbdc2c

File tree

4 files changed

+72
-52
lines changed

4 files changed

+72
-52
lines changed

Cargo.lock

+14-26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ keywords = ["screenshot", "wayland", "wlroots"]
88
license = "BSD-2-Clause"
99
name = "wayshot"
1010
repository = "https://git.sr.ht/~shinyzenith/wayshot"
11-
version = "1.1.8"
11+
version = "1.1.9"
1212
exclude = [
1313
"CODE_OF_CONDUCT.md",
1414
"CONTRIBUTING.md",
@@ -20,7 +20,7 @@ exclude = [
2020
[dependencies]
2121
clap = "3.1.18"
2222
env_logger = { version = "0.9.0", default-features = false, features = ["atty", "termcolor"] }
23-
image = { version = "0.24", default-features = false, features = ["jpeg", "png"] }
23+
image = { version = "0.24", default-features = false, features = ["jpeg", "png", "pnm"] }
2424
log = "0.4.17"
2525
memmap2 = "0.5.3"
2626
nix = "0.24.1"

src/backend.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ use nix::{
1919
};
2020

2121
use image::{
22-
codecs::{jpeg::JpegEncoder, png::PngEncoder},
22+
codecs::{
23+
jpeg::JpegEncoder,
24+
png::PngEncoder,
25+
pnm::{self, PnmEncoder},
26+
},
2327
ColorType,
2428
ColorType::Rgba8,
2529
ImageEncoder,
@@ -84,6 +88,8 @@ pub enum EncodingFormat {
8488
Jpg,
8589
/// Png encoder.
8690
Png,
91+
/// Ppm encoder
92+
Ppm,
8793
}
8894

8995
/// Get a FrameCopy instance with screenshot pixel data for any wl_output object.
@@ -375,6 +381,28 @@ pub fn write_to_file(
375381
)?;
376382
let _ = output_file.flush()?;
377383
}
384+
EncodingFormat::Ppm => {
385+
let rgb8_data = if let ColorType::Rgba8 = frame_copy.frame_color_type {
386+
let data = frame_copy
387+
.frame_mmap
388+
.iter()
389+
.enumerate()
390+
.filter_map(|(i, &v)| if i % 4 != 3 { Some(v) } else { None })
391+
.collect::<Vec<u8>>();
392+
data
393+
} else {
394+
unimplemented!("Currently only ColorType::Rgba8 is supported")
395+
};
396+
PnmEncoder::new(&mut output_file)
397+
.with_subtype(pnm::PnmSubtype::Pixmap(pnm::SampleEncoding::Binary))
398+
.write_image(
399+
&rgb8_data,
400+
frame_copy.frame_format.width,
401+
frame_copy.frame_format.height,
402+
ColorType::Rgb8,
403+
)?;
404+
let _ = output_file.flush()?;
405+
}
378406
}
379407

380408
Ok(())

src/wayshot.rs

+27-23
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ fn main() -> Result<(), Box<dyn Error>> {
2929
log::trace!("Logger initialized.");
3030

3131
let display = Display::connect_to_env()?;
32-
let mut extension = backend::EncodingFormat::Png;
3332

3433
let mut cursor_overlay: i32 = 0;
3534
if args.is_present("cursor") {
@@ -111,14 +110,32 @@ fn main() -> Result<(), Box<dyn Error>> {
111110
backend::capture_output_frame(display, cursor_overlay, output, None)?
112111
};
113112

113+
let extension = if args.is_present("extension") {
114+
let ext = args.value_of("extension").unwrap().trim();
115+
match ext {
116+
"jpeg" | "jpg" => backend::EncodingFormat::Jpg,
117+
"png" => backend::EncodingFormat::Png,
118+
"ppm" => backend::EncodingFormat::Ppm,
119+
_ => {
120+
log::error!("Invalid extension provided.\nValid extensions:\n1) jpeg\n2) jpg\n3) png\n4) ppm");
121+
exit(1);
122+
}
123+
}
124+
} else {
125+
backend::EncodingFormat::Png
126+
};
127+
128+
if extension != backend::EncodingFormat::Png {
129+
log::debug!("Using custom extension: {:#?}", extension);
130+
}
131+
114132
if args.is_present("stdout") {
115133
let stdout = stdout();
116134
let writer = BufWriter::new(stdout.lock());
117135
backend::write_to_file(writer, extension, frame_copy)?;
118136
} else {
119-
let path: String;
120-
if args.is_present("file") {
121-
path = args.value_of("file").unwrap().trim().to_string();
137+
let path = if args.is_present("file") {
138+
args.value_of("file").unwrap().trim().to_string()
122139
} else {
123140
let time = match SystemTime::now().duration_since(UNIX_EPOCH) {
124141
Ok(n) => n.as_secs().to_string(),
@@ -128,28 +145,15 @@ fn main() -> Result<(), Box<dyn Error>> {
128145
}
129146
};
130147

131-
if args.is_present("extension") {
132-
let ext = args.value_of("extension").unwrap().trim();
133-
match ext {
134-
"jpeg" | "jpg" => {
135-
extension = backend::EncodingFormat::Jpg;
136-
log::debug!("Using custom extension: {:#?}", extension);
137-
}
138-
"png" => {}
139-
_ => {
140-
log::error!("Invalid extension provided.\nValid extensions:\n1) jpeg\n2) jpg\n3) png");
141-
exit(1);
142-
}
143-
}
148+
time + match extension {
149+
backend::EncodingFormat::Png => "-wayshot.png",
150+
backend::EncodingFormat::Jpg => "-wayshot.jpg",
151+
backend::EncodingFormat::Ppm => "-wayshot.ppm",
144152
}
145-
path = time
146-
+ match extension {
147-
backend::EncodingFormat::Png => "-wayshot.png",
148-
backend::EncodingFormat::Jpg => "-wayshot.jpg",
149-
};
150-
}
153+
};
151154

152155
backend::write_to_file(File::create(path)?, extension, frame_copy)?;
153156
}
157+
154158
Ok(())
155159
}

0 commit comments

Comments
 (0)