diff options
Diffstat (limited to 'alligator_tvg/src/header.rs')
| -rw-r--r-- | alligator_tvg/src/header.rs | 149 |
1 files changed, 0 insertions, 149 deletions
diff --git a/alligator_tvg/src/header.rs b/alligator_tvg/src/header.rs deleted file mode 100644 index b3be494..0000000 --- a/alligator_tvg/src/header.rs +++ /dev/null @@ -1,149 +0,0 @@ -use std::io::{self, Read}; - -use byteorder::{LittleEndian, ReadBytesExt}; -use num_enum::TryFromPrimitive; -use raise::yeet; - -use crate::colors::ColorEncoding; -use crate::read_varuint; -use crate::TvgError; - -const MAGIC: [u8; 2] = [0x72, 0x56]; -pub const SUPPORTED_VERSION: u8 = 1; - -/// The coordinate range defines how many bits a Unit value uses. -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)] -#[repr(u8)] -pub enum CoordinateRange { - /// Each [`Unit`] takes up 16 bits. - #[default] - Default = 0, - /// Each [`Unit`] takes up 8 bits. - Reduced = 1, - /// Each [`Unit`] takes up 32 bits. - Enhanced = 2, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)] -#[repr(u8)] -pub enum Scale { - _1 = 0, - _2 = 1, - _4 = 2, - _8 = 3, - _16 = 4, - _32 = 5, - _64 = 6, - _128 = 7, - _256 = 8, - _512 = 9, - _1024 = 10, - _2048 = 11, - _4096 = 12, - _8192 = 13, - _16384 = 14, - _32768 = 15, -} - -/// Each TVG file starts with a header defining some global values for the file -/// like scale and image size. This is a representation of the header, but not -/// necessarily an exact representation of the bits of a TVG header. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct TvgHeader { - /// Must always be [0x72, 0x56] - magic: [u8; 2], - /// Must be 1. For future versions, this field might decide how the rest of - /// the format looks like. - version: u8, - /// Defines the number of fraction bits in a Unit value. - scale: Scale, - /// Defines the type of color information that is used in the - /// [`ColorTable`]. - color_encoding: ColorEncoding, - /// Defines the number of total bits in a Unit value and thus the overall - /// precision of the file. - coordinate_range: CoordinateRange, - /// Encodes the maximum width of the output file in *display units*. - /// - /// A value of 0 indicates that the image has the maximum possible width. - width: u32, - /// Encodes the maximum height of the output file in *display units*. - /// - /// A value of 0 indicates that the image has the maximum possible height. - height: u32, - /// The number of colors in the color table. - color_count: u32, -} - -impl TvgHeader { - pub fn read<R: Read>(reader: &mut R) -> Result<Self, TvgError> { - // magic number is used as a first line defense against invalid data - let magic = [reader.read_u8()?, reader.read_u8()?]; - if magic != MAGIC { - yeet!(TvgError::InvalidFile); - } - - // the version of tvg being used - let version = reader.read_u8()?; - if version != SUPPORTED_VERSION { - yeet!(TvgError::UnsupportedVersion(version)) - } - - // scale, color_encoding, and coordinate_range are stored in one byte - let byte = reader.read_u8()?; - let scale = Scale::try_from_primitive(byte & 0b0000_1111).expect("invalid scale"); - let color_encoding = ColorEncoding::try_from_primitive((byte & 0b0011_0000) >> 4) - .expect("invalid color encoding"); - let coordinate_range = CoordinateRange::try_from_primitive((byte & 0b1100_0000) >> 6) - .expect("invalid coordinate range"); - - // width and height depend on the coordinate range - let width = read_unsigned_unit(coordinate_range, reader)?; - let height = read_unsigned_unit(coordinate_range, reader)?; - - let color_count = read_varuint(reader)?; - - Ok(Self { - magic, - version, - scale, - color_encoding, - coordinate_range, - width, - height, - color_count, - }) - } - - /// Defines the number of total bits in a Unit value and thus the overall - /// precision of the file. - pub fn coordinate_range(&self) -> CoordinateRange { - self.coordinate_range - } - - /// Defines the type of color information that is used in the [`ColorTable`]. - pub fn color_encoding(&self) -> ColorEncoding { - self.color_encoding - } - - /// Defines the number of fraction bits in a Unit value. - pub fn scale(&self) -> Scale { - self.scale - } - - /// The number of colors in the [`ColorTable`]. - pub fn color_count(&self) -> u32 { - self.color_count - } -} - -fn read_unsigned_unit<R: Read>( - coordinate_range: CoordinateRange, - bytes: &mut R, -) -> io::Result<u32> { - Ok(match coordinate_range { - CoordinateRange::Reduced => bytes.read_u8()? as u32, - CoordinateRange::Default => bytes.read_u16::<LittleEndian>()? as u32, - CoordinateRange::Enhanced => bytes.read_u32::<LittleEndian>()?, - }) -} |
