libmagie 0.1.0

A magical library for processing images.
Documentation
use std::convert::TryFrom;
use std::fmt::Error;
use std::result::Result;

use quick_error::quick_error;

use crate::color_space::Color;
use crate::image::Image;

pub mod decoder;

pub struct ImageBitmap {}

impl Image for ImageBitmap {
    fn size(self) -> (isize, isize) {
        unimplemented!()
    }

    fn width(self) -> isize {
        unimplemented!()
    }

    fn height(self) -> isize {
        unimplemented!()
    }

    fn at(self) -> Box<dyn Color> {
        unimplemented!()
    }
}

quick_error! {
    #[derive(Debug)]
    pub enum BitmapTypeError {
        Invalid(a: (u8, u8)) {
            display("'{}{}' is not a valid BitmapType", a.0 as char, a.1 as char)
        }
    }
}

#[derive(Debug)]
#[repr(u16)]
pub enum BitmapType {
    BM = (('B' as u16) << 8) + 'M' as u16,
    BA = (('B' as u16) << 8) + 'A' as u16,
    CI = (('C' as u16) << 8) + 'I' as u16,
    CP = (('C' as u16) << 8) + 'P' as u16,
    IC = (('I' as u16) << 8) + 'C' as u16,
    PT = (('P' as u16) << 8) + 'T' as u16,
}

impl TryFrom<(u8, u8)> for BitmapType {
    type Error = BitmapTypeError;

    fn try_from(value: (u8, u8)) -> Result<Self, Self::Error> {
        let _type = ((value.0 as u16) << 8) + value.1 as u16;

        const BM: u16 = (('B' as u16) << 8) + 'M' as u16;
        const BA: u16 = (('B' as u16) << 8) + 'A' as u16;
        const CI: u16 = (('C' as u16) << 8) + 'I' as u16;
        const CP: u16 = (('C' as u16) << 8) + 'P' as u16;
        const IC: u16 = (('I' as u16) << 8) + 'C' as u16;
        const PT: u16 = (('P' as u16) << 8) + 'T' as u16;

        match _type {
            BM => Ok(Self::BM),
            BA => Ok(Self::BA),
            CI => Ok(Self::CI),
            CP => Ok(Self::CP),
            IC => Ok(Self::IC),
            PT => Ok(Self::PT),
            _ => Err(BitmapTypeError::Invalid(value)),
        }
    }
}

#[derive(Debug)]
pub struct BitmapHeader {
    _type: BitmapType,
    size: u32,
}

const HEADER_SIZE: usize = 14;

impl BitmapHeader {
    fn new(header: [u8; HEADER_SIZE]) -> Result<BitmapHeader, BitmapTypeError> {
        let _type = BitmapType::try_from((header[0], header[1]))?;
        let size = BitmapHeader::extract_size(&header[2..6]);

        Ok(BitmapHeader {
            _type: BitmapType::BM,
            size,
        })
    }

    fn extract_size(header: &[u8]) -> u32 {
        let size = (header[3] as u32) << 24;
        let size = size + (header[2] as u32) << 16;
        let size = size + (header[1] as u32) << 8;

        size + (header[0] as u32)
    }
}