1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use crate::errors::IndexedImageError;
use crate::errors::IndexedImageError::*;
use crate::file::FileType::*;

//0 is file version
pub(crate) const HEADER: [u8; 4] = [b'I', b'C', b'I', 1];

#[derive(Debug, Clone, Eq, PartialEq)]
pub enum FileType {
    Image,
    Animated,
    Atlas,
}

impl FileType {
    pub(crate) fn to_byte(&self) -> u8 {
        match self {
            Image => 1,
            Animated => 2,
            Atlas => 3,
        }
    }

    pub(crate) fn from_byte(byte: u8) -> Option<FileType> {
        match byte {
            1 => Some(Image),
            2 => Some(Animated),
            3 => Some(Atlas),
            _ => None,
        }
    }

    pub fn name(&self) -> &'static str {
        match self {
            Image => "Image",
            Animated => "Animated Image",
            Atlas => "Image Atlas",
        }
    }

    pub fn ext(&self) -> &'static str {
        match self {
            Image => "ici",
            Animated => "ica",
            Atlas => "iat",
        }
    }
}

pub(super) fn verify_format(bytes: &[u8]) -> Result<FileType, IndexedImageError> {
    if bytes.len() < 10 {
        return Err(NotIciFile);
    }
    if bytes[0..HEADER.len()] != HEADER {
        return Err(NotIciFile);
    }
    let format = bytes[HEADER.len()];
    match FileType::from_byte(format) {
        None => Err(UnknownIciVersion(format)),
        Some(file_type) => Ok(file_type),
    }
}