libmosh/
ops.rs

1//! File operations
2
3use png::{BitDepth, ColorType, Encoder};
4
5use std::{
6    fs::File,
7    io::{BufReader, BufWriter, Read},
8    path::Path,
9};
10
11use crate::{MoshData, MoshError, MoshOptions};
12
13/// Reads provided file
14///
15/// # Errors
16///
17/// It may fail if input format is not supported.
18pub fn read_file(file: impl AsRef<Path>) -> Result<Vec<u8>, MoshError> {
19    let input = File::open(file)?;
20    let mut reader = BufReader::new(input);
21    let mut buffer = Vec::new();
22
23    reader.read_to_end(&mut buffer)?;
24
25    Ok(buffer)
26}
27
28/// Writes a new file from the provided buffer
29///
30/// # Errors
31///
32/// It may fail if parameters are invalid, palette is missing, or there is an I/O error.
33pub fn write_file(dest: &str, data: &MoshData, options: &MoshOptions) -> Result<(), MoshError> {
34    let path = Path::new(&dest);
35    let output = File::create(path)?;
36    let buf_writer = &mut BufWriter::new(output);
37    let mut encoder = Encoder::new(buf_writer, data.width, data.height);
38
39    encoder.set_color(if options.ansi {
40        ColorType::Indexed
41    } else {
42        data.color_type
43    });
44
45    encoder.set_depth(if options.ansi {
46        BitDepth::Eight
47    } else {
48        data.bit_depth
49    });
50
51    if data.color_type == ColorType::Indexed {
52        if options.ansi {
53            encoder.set_palette(crate::generate_palette());
54        } else {
55            match &data.palette {
56                Some(palette) => encoder.set_palette(palette),
57                None => return Err(MoshError::InvalidPalette),
58            }
59        }
60    }
61
62    if options.ansi {
63        encoder.set_palette(crate::generate_palette());
64    }
65
66    let mut writer = encoder.write_header()?;
67    writer.write_image_data(&data.buf)?;
68
69    Ok(())
70}