png_codec 0.1.1

A minimal pure Rust PNG encoder
Documentation
use crate::{consts, encoder::Enc};

/// Standard PNG color types.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u8)]
#[allow(dead_code)]
pub(crate) enum ColorType {
    /// greyscale: 1, 2, 4, 8, 16 bit
    Grey = 0u8,
    /// RGB: 8, 16 bit
    Rgb = 2,
    /// palette: 1, 2, 4, 8 bit
    Palette = 3,
    /// greyscale with alpha: 8, 16 bit
    GreyAlpha = 4,
    /// RGB with alpha: 8, 16 bit
    Rgba = 6,
}

impl ColorType {
    /// channels * bytes per channel = bytes per pixel
    pub(crate) fn channels(self) -> u8 {
        match self {
            ColorType::Grey | ColorType::Palette => 1,
            ColorType::GreyAlpha => 2,
            ColorType::Rgb => 3,
            ColorType::Rgba => 4,
        }
    }

    /// get the total amount of bits per pixel, based on colortype and bitdepth
    /// in the struct
    pub(crate) fn bpp(self, bit_depth: u8) -> u8 {
        assert!((1..=16).contains(&bit_depth));
        /* bits per pixel is amount of channels * bits per channel */
        let ch = self.channels();
        ch * if ch > 1 {
            if bit_depth == 8 {
                8
            } else {
                16
            }
        } else {
            bit_depth
        }
    }
}

/// Image Header Chunk Data (IHDR)
#[derive(Copy, Clone, Debug)]
pub(crate) struct ImageHeader {
    /// Width of the image
    pub(crate) width: u32,
    /// Height of the image
    pub(crate) height: u32,
    /// The colortype of the image
    pub(crate) color_type: ColorType,
    /// How many bits per channel
    pub(crate) bit_depth: u8,
    /// True for adam7 interlacing, false for no interlacing.
    pub(crate) interlace: bool,
}

impl ImageHeader {
    pub(crate) fn write(&self, enc: &mut Enc) {
        enc.prepare(13, consts::IMAGE_HEADER);
        enc.u32(self.width);
        enc.u32(self.height);
        enc.u8(self.bit_depth);
        enc.u8(self.color_type as u8);
        enc.u8(0);
        enc.u8(0);
        enc.u8(self.interlace as u8);
        enc.write_crc();
    }
}