lifehash_lib/
lib.rs

1extern crate core;
2
3use crate::colors::rgb::Color;
4use png::ColorType;
5use std::fs::File;
6use std::io::{BufWriter, Error, ErrorKind};
7use std::path::Path;
8
9mod colors;
10mod grids;
11pub mod lifehash;
12mod utils;
13
14#[derive(Copy, Clone, Eq, PartialEq)]
15struct Dimensions {
16    pub width: i32,
17    pub height: i32,
18}
19
20#[derive(Copy, Clone, Eq, PartialEq)]
21struct Point {
22    pub x: i32,
23    pub y: i32,
24}
25
26trait ColorValues<T> {
27    fn color_for_value(value: &T) -> Color;
28}
29
30const ZERO: Point = Point { x: 0, y: 0 };
31
32#[derive(Debug, Copy, Clone, Eq, PartialEq)]
33pub enum Version {
34    Version1, // DEPRECATED. Uses HSB gamut. Not CMYK-friendly. Has some minor gradient bugs.
35    Version2, // CMYK-friendly gamut. Recommended for most purposes.
36    Detailed, // Double resolution. CMYK-friendly gamut gamut.
37    Fiducial, // Optimized for generating machine-vision fiducials. High-contrast. CMYK-friendly gamut.
38    GrayscaleFiducial, // Optimized for generating machine-vision fiducials. High-contrast.
39}
40impl From<u8> for Version {
41    fn from(version: u8) -> Self {
42        match version {
43            1 => Version::Version1,
44            2 => Version::Version2,
45            3 => Version::Detailed,
46            4 => Version::Fiducial,
47            5 => Version::GrayscaleFiducial,
48            _ => Version::Version2,
49        }
50    }
51}
52
53#[derive(Copy, Clone, Eq, PartialEq)]
54enum Pattern {
55    Snowflake, // Mirror around central axes.
56    Pinwheel,  // Rotate around center.
57    Fiducial,  // Identity.
58}
59
60pub struct Image {
61    pub width: usize,
62    pub height: usize,
63    pub channels: usize,
64    pub pixels: Vec<u8>,
65}
66
67pub fn save_image(bitmap: &Image, filename: &Path) -> Result<(), Error> {
68    let file = File::create(filename)?;
69    let buffer = BufWriter::new(file);
70    let mut png = png::Encoder::new(buffer, bitmap.width as u32, bitmap.height as u32);
71    if bitmap.channels == 4 {
72        png.set_color(ColorType::Rgba);
73    } else if bitmap.channels == 3 {
74        png.set_color(ColorType::Rgb);
75    } else {
76        png.set_color(ColorType::Grayscale);
77    }
78    let mut writer = png.write_header()?;
79    writer.write_image_data(&bitmap.pixels).map_err(|e| {
80        Error::new(
81            ErrorKind::Other,
82            format!("failed to write image data: {}", e),
83        )
84    })?;
85    writer.finish().map_err(|e| {
86        Error::new(
87            ErrorKind::Other,
88            format!("failed to finish image data: {}", e),
89        )
90    })
91}