rpgmv_tool/command/
encrypt_png.rs

1use anyhow::Context;
2use std::fs::File;
3use std::io::BufReader;
4use std::io::BufWriter;
5use std::io::Write;
6use std::path::PathBuf;
7
8#[derive(Debug, argh::FromArgs)]
9#[argh(subcommand, name = "encrypt-png", description = "encrypt a png")]
10pub struct Options {
11    #[argh(option, long = "input", short = 'i', description = "a png to encrypt")]
12    pub input: PathBuf,
13
14    #[argh(option, long = "output", short = 'o', description = "the output file")]
15    pub output: PathBuf,
16
17    #[argh(option, long = "key", short = 'k', description = "the key, as hex")]
18    pub key: String,
19}
20
21pub fn exec(options: Options) -> anyhow::Result<()> {
22    let input = File::open(&options.input).with_context(|| {
23        format!(
24            "failed to open \"{}\" for reading",
25            &options.input.display()
26        )
27    })?;
28    let mut input = BufReader::new(input);
29
30    let output = File::create(&options.output).with_context(|| {
31        format!(
32            "failed to open \"{}\" for writing",
33            &options.output.display()
34        )
35    })?;
36    let mut output = BufWriter::new(output);
37
38    let mut key = [0; 16];
39    base16ct::mixed::decode(&options.key, &mut key)
40        .with_context(|| format!("failed to decode hex \"{}\"", options.key))?;
41
42    let mut writer = rpgmvp::Writer::new(&mut output, key);
43    writer.write_header()?;
44    std::io::copy(&mut input, &mut writer)?;
45
46    output.flush().context("failed to flush")?;
47    let output = output.into_inner()?;
48    output.sync_all()?;
49
50    Ok(())
51}