open_vector_tile/open/
image_layer.rs

1use alloc::{fmt, str::FromStr, string::String, vec::Vec};
2use pbf::{BitCast, ProtoRead, ProtoWrite, Protobuf};
3
4// TODO: This could be faster if we don't read in the grid data on parsing but only if the user needs it
5
6/// Track the image type
7#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
8pub enum ImageType {
9    /// PNG
10    #[default]
11    PNG = 0,
12    /// JPEG
13    JPG = 1,
14    /// WebP
15    WEBP = 2,
16    /// GIF
17    GIF = 3,
18    /// AVIF
19    AVIF = 4,
20    /// SVG
21    SVG = 5,
22    /// BMP
23    BMP = 6,
24    /// RAW
25    RAW = 7,
26    /// Unknown
27    UNKNOWN = 8,
28}
29impl BitCast for ImageType {
30    fn to_u64(&self) -> u64 {
31        (*self) as u64
32    }
33    fn from_u64(value: u64) -> Self {
34        match value {
35            0 => ImageType::PNG,
36            1 => ImageType::JPG,
37            2 => ImageType::WEBP,
38            3 => ImageType::GIF,
39            4 => ImageType::AVIF,
40            5 => ImageType::SVG,
41            6 => ImageType::BMP,
42            7 => ImageType::RAW,
43            8 => ImageType::UNKNOWN,
44            _ => panic!("unknown value: {}", value),
45        }
46    }
47}
48impl FromStr for ImageType {
49    type Err = &'static str;
50
51    fn from_str(s: &str) -> Result<Self, Self::Err> {
52        match s.to_uppercase().as_str() {
53            "PNG" => Ok(ImageType::PNG),
54            "JPG" | "JPEG" => Ok(ImageType::JPG),
55            "WEBP" => Ok(ImageType::WEBP),
56            "GIF" => Ok(ImageType::GIF),
57            "AVIF" => Ok(ImageType::AVIF),
58            "SVG" => Ok(ImageType::SVG),
59            "BMP" => Ok(ImageType::BMP),
60            "RAW" => Ok(ImageType::RAW),
61            "UNKNOWN" => Ok(ImageType::UNKNOWN),
62            _ => Err("Unknown image type"),
63        }
64    }
65}
66impl From<&str> for ImageType {
67    fn from(s: &str) -> Self {
68        ImageType::from_str(s.to_uppercase().as_str()).unwrap_or(ImageType::PNG)
69    }
70}
71impl fmt::Display for ImageType {
72    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73        let name = match self {
74            ImageType::PNG => "PNG",
75            ImageType::JPG => "JPG",
76            ImageType::WEBP => "WEBP",
77            ImageType::GIF => "GIF",
78            ImageType::AVIF => "AVIF",
79            ImageType::SVG => "SVG",
80            ImageType::BMP => "BMP",
81            ImageType::RAW => "RAW",
82            ImageType::UNKNOWN => "UNKNOWN",
83        };
84        write!(f, "{}", name)
85    }
86}
87
88/// Elevation object to read from
89#[derive(Debug, Default, Clone, PartialEq)]
90pub struct ImageData {
91    /// The name of the image
92    pub name: String,
93    /// The image type
94    pub image_type: ImageType,
95    /// The image width
96    pub width: u32,
97    /// The image height
98    pub height: u32,
99    /// The image data
100    pub image: Vec<u8>,
101}
102impl ImageData {
103    /// Create a new ImageData
104    pub fn new(
105        name: String,
106        image_type: ImageType,
107        width: u32,
108        height: u32,
109        image: Vec<u8>,
110    ) -> Self {
111        Self { name, image_type, width, height, image }
112    }
113}
114impl ProtoRead for ImageData {
115    fn read(&mut self, tag: u64, pb: &mut Protobuf) {
116        match tag {
117            1 => self.image_type = pb.read_varint::<ImageType>(),
118            2 => self.width = pb.read_varint(),
119            3 => self.height = pb.read_varint(),
120            4 => self.image = pb.read_bytes(),
121            5 => self.name = pb.read_string(),
122            _ => panic!("unknown tag: {}", tag),
123        }
124    }
125}
126impl ProtoWrite for ImageData {
127    fn write(&self, pb: &mut Protobuf) {
128        pb.write_varint_field(1, self.image_type);
129        pb.write_varint_field(2, self.width);
130        pb.write_varint_field(3, self.height);
131        pb.write_bytes_field(4, &self.image);
132        pb.write_string_field(5, &self.name);
133    }
134}