From 861b467b95be55db3a42182b77dba944869bf49f Mon Sep 17 00:00:00 2001 From: Micha White Date: Mon, 13 Feb 2023 00:24:07 -0500 Subject: Rename the subdirectories --- alligator_tvg/Cargo.toml | 12 - alligator_tvg/src/colors.rs | 333 ----------- alligator_tvg/src/commands.rs | 613 --------------------- alligator_tvg/src/header.rs | 149 ----- alligator_tvg/src/lib.rs | 151 ----- alligator_tvg/src/path.rs | 294 ---------- alligator_tvg/tests/examples/tvg/everything-32.tvg | Bin 2637 -> 0 bytes alligator_tvg/tests/examples/tvg/everything.tvg | Bin 1447 -> 0 bytes alligator_tvg/tests/examples/tvg/shield-16.tvg | Bin 203 -> 0 bytes alligator_tvg/tests/examples/tvg/shield-32.tvg | Bin 371 -> 0 bytes alligator_tvg/tests/examples/tvg/shield-8.tvg | Bin 119 -> 0 bytes alligator_tvg/tests/parse.rs | 14 - 12 files changed, 1566 deletions(-) delete mode 100644 alligator_tvg/Cargo.toml delete mode 100644 alligator_tvg/src/colors.rs delete mode 100644 alligator_tvg/src/commands.rs delete mode 100644 alligator_tvg/src/header.rs delete mode 100644 alligator_tvg/src/lib.rs delete mode 100644 alligator_tvg/src/path.rs delete mode 100644 alligator_tvg/tests/examples/tvg/everything-32.tvg delete mode 100644 alligator_tvg/tests/examples/tvg/everything.tvg delete mode 100644 alligator_tvg/tests/examples/tvg/shield-16.tvg delete mode 100644 alligator_tvg/tests/examples/tvg/shield-32.tvg delete mode 100644 alligator_tvg/tests/examples/tvg/shield-8.tvg delete mode 100644 alligator_tvg/tests/parse.rs (limited to 'alligator_tvg') diff --git a/alligator_tvg/Cargo.toml b/alligator_tvg/Cargo.toml deleted file mode 100644 index d7e7a6b..0000000 --- a/alligator_tvg/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "alligator_tvg" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -byteorder = "1" -thiserror = "1" -raise = "2" -num_enum = "0.5" diff --git a/alligator_tvg/src/colors.rs b/alligator_tvg/src/colors.rs deleted file mode 100644 index 10bc41c..0000000 --- a/alligator_tvg/src/colors.rs +++ /dev/null @@ -1,333 +0,0 @@ -use std::io::{self, Read}; - -use byteorder::{BigEndian, LittleEndian, ReadBytesExt}; -use num_enum::TryFromPrimitive; - -/// The color table encodes the palette for this file. -/// -/// It’s binary content is defined by the `color_encoding` field in the header. -/// For the three defined color encodings, each will yield a list of -/// `color_count` RGBA tuples. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ColorTable { - colors: Box<[C]>, -} - -impl ColorTable { - /// Read in one encoding, and convert it to another - pub fn read_from_encoding( - reader: &mut impl Read, - color_count: u32, - encoding: ColorEncoding, - ) -> io::Result { - Ok(match encoding { - ColorEncoding::Rgba8888 => (&ColorTable::::read(reader, color_count)?).into(), - ColorEncoding::Rgb565 => (&ColorTable::::read(reader, color_count)?).into(), - ColorEncoding::RgbaF32 => (&ColorTable::::read(reader, color_count)?).into(), - ColorEncoding::Custom => (&ColorTable::::read(reader, color_count)?).into(), - }) - } - - /// Parse a color table. - fn read(reader: &mut impl Read, color_count: u32) -> io::Result { - let mut colors = Vec::with_capacity(color_count as usize); - for _ in 0..color_count { - colors.push(C::parse_bytes(reader)?); - } - - let colors = colors.into_boxed_slice(); - Ok(Self { colors }) - } - - /// Returns the number of colors in the table. - fn len(&self) -> usize { - self.colors.len() - } - - /// Returns a reference to a color, or `None` if out-of-bounds. - fn get(&self, index: usize) -> Option<&C> { - self.colors.get(index) - } - - fn iter(&self) -> impl Iterator { - self.colors.iter() - } -} - -impl ColorTable {} - -impl From<&ColorTable> for ColorTable { - fn from(value: &ColorTable) -> Self { - let mut colors = Vec::with_capacity(value.len()); - - for color in value.iter() { - let r = color.red_u16(); - let g = color.green_u16(); - let b = color.blue_u16(); - let a = color.alpha_u16(); - colors.push(New::from_rgba16_lossy(r, g, b, a)); - } - - let colors = colors.into_boxed_slice(); - Self { colors } - } -} - -/// The color encoding defines which format the colors in the color table will -/// have. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)] -#[repr(u8)] -pub enum ColorEncoding { - /// Each color is a 4-tuple (red, green, blue, alpha) of bytes with the - /// color channels encoded in sRGB and the alpha as linear alpha. - Rgba8888 = 0, - /// Each color is encoded as a 3-tuple (red, green, blue) with 16 bits per - /// color. - /// - /// While red and blue both use 5 bits, the green channel uses 6 bits. Red - /// uses bit range 0...4, green bits 5...10 and blue bits 11...15. This - /// color also uses the sRGB color space. - Rgb565 = 1, - /// Each color is a 4-tuple (red, green, blue, alpha) of binary32 IEEE 754 - /// floating point value with the color channels encoded in scRGB and the - /// alpha as linear alpha. A color value of 1.0 is full intensity, while a - /// value of 0.0 is zero intensity. - RgbaF32 = 2, - /// The custom color encoding is defined *undefined*. The information how - /// these colors are encoded must be implemented via external means. - Custom = 3, -} - -pub trait Color: Sized { - /// The size of the color's representation in bits - const SIZE: usize; - - /// Attempt to read the color. Returns `Err` if an error occurred while - /// attempting to read [`SIZE`] bytes from `bytes`. - fn parse_bytes(reader: &mut impl Read) -> io::Result; - - /// Convert from the RGBA16 format to this format. This may be lossy. - fn from_rgba16_lossy(red: u16, green: u16, blue: u16, alpha: u16) -> Self; - - fn red_u16(&self) -> u16; - fn blue_u16(&self) -> u16; - fn green_u16(&self) -> u16; - fn alpha_u16(&self) -> u16; -} - -/// Each color value is encoded as a sequence of four bytes. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -struct Rgba8888 { - /// Red color channel between 0 and 100% intensity, mapped to byte values 0 - /// to 255. - red: u8, - /// Green color channel between 0 and 100% intensity, mapped to byte values - /// 0 to 255. - green: u8, - /// Blue color channel between 0 and 100% intensity, mapped to byte values - /// 0 to 255. - blue: u8, - /// Transparency channel between 0 and 100% transparency, mapped to byte - /// values 0 to 255. - alpha: u8, -} - -impl Color for Rgba8888 { - const SIZE: usize = 4; - - fn parse_bytes(reader: &mut impl Read) -> io::Result { - Ok(Self { - red: reader.read_u8()?, - green: reader.read_u8()?, - blue: reader.read_u8()?, - alpha: reader.read_u8()?, - }) - } - - fn from_rgba16_lossy(red: u16, green: u16, blue: u16, alpha: u16) -> Self { - Self { - red: (red >> 8) as u8, - green: (green >> 8) as u8, - blue: (blue >> 8) as u8, - alpha: (alpha >> 8) as u8, - } - } - - fn red_u16(&self) -> u16 { - (self.red as u16) << 8 - } - - fn green_u16(&self) -> u16 { - (self.green as u16) << 8 - } - - fn blue_u16(&self) -> u16 { - (self.blue as u16) << 8 - } - - fn alpha_u16(&self) -> u16 { - (self.alpha as u16) << 8 - } -} - -/// Each color value is encoded as a sequence of 2 bytes. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -struct Rgb565 { - /// Red color channel between 0 and 100% intensity, mapped to integer - /// values 0 to 31. - red: u8, - /// Green color channel between 0 and 100% intensity, mapped to integer - /// values 0 to 63. - green: u8, - /// Blue color channel between 0 and 100% intensity, mapped to integer - /// values 0 to 31. - blue: u8, -} - -impl Color for Rgb565 { - const SIZE: usize = 2; - - fn parse_bytes(reader: &mut impl Read) -> io::Result { - let color = reader.read_u16::()?; - - let red = ((color & 0x001F) << 3) as u8; - let green = ((color & 0x07E0) >> 3) as u8; - let blue = ((color & 0xF800) >> 8) as u8; - - Ok(Self { red, blue, green }) - } - - fn from_rgba16_lossy(red: u16, green: u16, blue: u16, _a: u16) -> Self { - Self { - red: (red >> 11) as u8, - green: (green >> 10) as u8, - blue: (blue >> 11) as u8, - } - } - - fn red_u16(&self) -> u16 { - (self.red as u16) << 11 - } - - fn green_u16(&self) -> u16 { - (self.green as u16) << 11 - } - - fn blue_u16(&self) -> u16 { - (self.blue as u16) << 10 - } - - fn alpha_u16(&self) -> u16 { - 0 - } -} - -/// Each color value is encoded as a sequence of 16 bytes. -#[derive(Debug, Clone, Copy, PartialEq)] -struct RgbaF32 { - /// Red color channel, using 0.0 for 0% intensity and 1.0 for 100% - /// intensity. - red: f32, - /// Green color channel, using 0.0 for 0% intensity and 1.0 for 100% - /// intensity. - green: f32, - /// Blue color channel, using 0.0 for 0% intensity and 1.0 for 100% - /// intensity. - blue: f32, - /// Transparency channel between 0 and 100% transparency, mapped to byte - /// values 0.0 to 1.0. - alpha: f32, -} - -impl Color for RgbaF32 { - const SIZE: usize = 16; - - fn parse_bytes(reader: &mut impl Read) -> io::Result { - Ok(Self { - red: reader.read_f32::()?, - green: reader.read_f32::()?, - blue: reader.read_f32::()?, - alpha: reader.read_f32::()?, - }) - } - - fn from_rgba16_lossy(red: u16, green: u16, blue: u16, alpha: u16) -> Self { - Self { - red: (red as f32) / (u16::MAX as f32), - green: (green as f32) / (u16::MAX as f32), - blue: (blue as f32) / (u16::MAX as f32), - alpha: (alpha as f32) / (u16::MAX as f32), - } - } - - fn red_u16(&self) -> u16 { - (self.red * (u16::MAX as f32)) as u16 - } - - fn green_u16(&self) -> u16 { - (self.green * (u16::MAX as f32)) as u16 - } - - fn blue_u16(&self) -> u16 { - (self.blue * (u16::MAX as f32)) as u16 - } - - fn alpha_u16(&self) -> u16 { - (self.alpha * (u16::MAX as f32)) as u16 - } -} - -/// Each color value is encoded as a sequence of 8 bytes. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Rgba16 { - /// Red color channel between 0 and 100% intensity, mapped to a big-endian - /// 16-bit integer. - red: u16, - /// Green color channel between 0 and 100% intensity, mapped to a - /// big-endian 16-bit integer. - green: u16, - /// Blue color channel between 0 and 100% intensity, mapped to a big-endian - /// 16-bit integer. - blue: u16, - /// Transparency channel between 0 and 100% intensity, mapped to a - /// big-endian 16-bit integer. - alpha: u16, -} - -impl Color for Rgba16 { - const SIZE: usize = 8; - - fn parse_bytes(reader: &mut impl Read) -> io::Result { - Ok(Self { - red: reader.read_u16::()?, - green: reader.read_u16::()?, - blue: reader.read_u16::()?, - alpha: reader.read_u16::()?, - }) - } - - fn from_rgba16_lossy(red: u16, green: u16, blue: u16, alpha: u16) -> Self { - Self { - red, - green, - blue, - alpha, - } - } - - fn red_u16(&self) -> u16 { - self.red - } - - fn green_u16(&self) -> u16 { - self.green - } - - fn blue_u16(&self) -> u16 { - self.blue - } - - fn alpha_u16(&self) -> u16 { - self.alpha - } -} diff --git a/alligator_tvg/src/commands.rs b/alligator_tvg/src/commands.rs deleted file mode 100644 index f316a53..0000000 --- a/alligator_tvg/src/commands.rs +++ /dev/null @@ -1,613 +0,0 @@ -use std::io::{self, Read}; - -use byteorder::ReadBytesExt; -use raise::yeet; - -use crate::{header::TvgHeader, path::Path, read_unit, read_varuint, Decode, Point, TvgError}; - -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct Rectangle { - /// Horizontal distance of the left side to the origin. - x: f64, - /// Vertical distance of the upper side to the origin. - y: f64, - /// Horizontal extent of the rectangle. - width: f64, - /// Vertical extent of the rectangle. - height: f64, -} - -impl Decode for Rectangle { - fn read(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - Ok(Self { - x: read_unit(reader, header)?, - y: read_unit(reader, header)?, - width: read_unit(reader, header)?, - height: read_unit(reader, header)?, - }) - } -} - -#[derive(Debug, Clone, Copy)] -pub struct Line { - /// Start point of the line. - start: Point, - /// End point of the line. - end: Point, -} - -impl Decode for Line { - fn read(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - Ok(Self { - start: Point::read(reader, header)?, - end: Point::read(reader, header)?, - }) - } -} - -/// A command that can be encoded. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[repr(u8)] -enum CommandName { - /// Determines end of file. - EndOfDocument = 0, - /// Fills an N-gon. - FillPolygon = 1, - /// Fills a set of [`Rectangle`]s. - FillRectangles = 2, - /// Fills a free-form [`Path`]. - FillPath = 3, - /// Draws a set of lines. - DrawLines = 4, - /// Draws the outline of a polygon. - DrawLineLoop = 5, - /// Draws a list of end-to-end lines. - DrawLineStrip = 6, - /// Draws a free-form [`Path`]. - DrawLinePath = 7, - /// Draws a filled polygon with an outline. - OutlineFillPolygon = 8, - /// Draws several filled [`Rectangle`]s with an outline. - OutlineFillRectangles = 9, - /// This command combines the [`FillPath`] and [`DrawLinePath`] command - /// into one. - OutlineFillPath = 10, -} - -impl TryFrom for CommandName { - type Error = TvgError; - - fn try_from(value: u8) -> Result { - match value { - 0 => Ok(Self::EndOfDocument), - 1 => Ok(Self::FillPolygon), - 2 => Ok(Self::FillRectangles), - 3 => Ok(Self::FillPath), - 4 => Ok(Self::DrawLines), - 5 => Ok(Self::DrawLineLoop), - 6 => Ok(Self::DrawLineStrip), - 7 => Ok(Self::DrawLinePath), - 8 => Ok(Self::OutlineFillPolygon), - 9 => Ok(Self::OutlineFillRectangles), - 10 => Ok(Self::OutlineFillPath), - v => Err(TvgError::InvalidCommand(v)), - } - } -} - -/// The type of style the command uses as a primary style. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[repr(u8)] -pub enum StyleKind { - /// The shape is uniformly colored with a single color. - FlatColored = 0, - /// The shape is colored with a linear gradient. - LinearGradient = 1, - /// The shape is colored with a radial gradient. - RadialGradient = 2, -} - -impl TryFrom for StyleKind { - type Error = TvgError; - - fn try_from(value: u8) -> Result { - match value { - 0 => Ok(Self::FlatColored), - 1 => Ok(Self::LinearGradient), - 2 => Ok(Self::RadialGradient), - _ => Err(TvgError::InvalidStyleKind), - } - } -} - -/// The style kind, along with the colors and points used to render the style. -#[derive(Debug, Clone, Copy)] -pub enum Style { - /// The shape is uniformly colored with the color at `color_index` in the - /// [`ColorTable`]. - FlatColored { - /// The index in the [`ColorTable`]. - color_index: u32, - }, - /// The gradient is formed by a mental line between `point_0` and - /// `point_1`. - /// - /// The color at `point_0` is the color at `color_index_0` in the color - /// table. The color at `point_1` is the color at `color_index_1` in the - /// [`ColorTable`]. On the line, the color is interpolated between the two - /// points. Each point that is not on the line is orthogonally projected to - /// the line and the color at that point is sampled. Points that are not - /// projectable onto the line have either the color at `point_0` if they - /// are closed to `point_0` or vice versa for `point_1`. - LinearGradient { - /// The start point of the gradient. - point_0: Point, - /// The end point of the gradient. - point_1: Point, - /// The color at [`point_0`]. - color_index_0: u32, - /// The color at [`point_1`]. - color_index_1: u32, - }, - /// The gradient is formed by a mental circle with the center at `point_0` - /// and `point_1` being somewhere on the circle outline. Thus, the radius - /// of said circle is the distance between `point_0` and `point_1`. - /// - /// The color at `point_0` is the color at `color_index_0` in the color - /// table. The color on the circle outline is the color at `color_index_1` - /// in the [`ColorTable`]. If a sampled point is inside the circle, the - /// color is interpolated based on the distance to the center and the - /// radius. If the point is not in the circle itself, the color at - /// `color_index_1` is always taken. - RadialGradient { - /// The center point of the mental circle. - point_0: Point, - /// The end point of the gradient. - point_1: Point, - /// The color at `point_0`. - color_index_0: u32, - /// The color at `point_1`. - color_index_1: u32, - }, -} - -impl Style { - fn read(reader: &mut impl Read, header: &TvgHeader, kind: StyleKind) -> io::Result { - match kind { - StyleKind::FlatColored => Self::read_flat_colored(reader), - StyleKind::LinearGradient => Self::read_linear_gradient(reader, header), - StyleKind::RadialGradient => Self::read_radial_gradient(reader, header), - } - } - - fn read_flat_colored(reader: &mut impl Read) -> io::Result { - Ok(Self::FlatColored { - color_index: read_varuint(reader)?, - }) - } - - fn read_linear_gradient(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - Ok(Self::LinearGradient { - point_0: Point::read(reader, header)?, - point_1: Point::read(reader, header)?, - color_index_0: read_varuint(reader)?, - color_index_1: read_varuint(reader)?, - }) - } - - fn read_radial_gradient(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - Ok(Self::RadialGradient { - point_0: Point::read(reader, header)?, - point_1: Point::read(reader, header)?, - color_index_0: read_varuint(reader)?, - color_index_1: read_varuint(reader)?, - }) - } -} - -/// TinyVG files contain a sequence of draw commands that must be executed in -/// the defined order to get the final result. Each draw command adds a new 2D -/// primitive to the graphic. -#[derive(Debug, Clone)] -pub enum Command { - /// If this command is read, the TinyVG file has ended. - /// - /// This command must have prim_style_kind to be set to 0, so the last byte - /// of every TinyVG file is `0x00`. Every byte after this command is - /// considered not part of the TinyVG data and can be used for other - /// purposes like metadata or similar. - EndOfDocument, - /// Fills a polygon with N [`Point`]s. - /// - /// The number of points must be at least 3. Files that encode a lower - /// value must be discarded as ”invalid” by a conforming implementation. - /// - /// The polygon specified in polygon must be drawn using the even-odd rule. - /// That means that if for any point to be inside the polygon, a line to - /// infinity must cross an odd number of polygon segments. - FillPolygon { - /// The style that is used to fill the polygon. - fill_style: Style, - /// The points of the polygon. - polygon: Box<[Point]>, - }, - /// Fills a list of [`Rectangle`]s. - /// - /// The rectangles must be drawn first to last, which is the order they - /// appear in the file. - FillRectangles { - /// The style that is used to fill all rectangles. - fill_style: Style, - /// The list of rectangles to be filled. - rectangles: Box<[Rectangle]>, - }, - /// Fills a [`Path`]. - /// - /// For the filling, all path segments are considered a polygon each (drawn - /// with even-odd rule) that, when overlap, also perform the even odd rule. - /// This allows the user to carve out parts of the path and create - /// arbitrarily shaped surfaces. - FillPath { - /// The style that is used to fill the path. - fill_style: Style, - /// A [`Path`] with `segment_count` segments. - path: Path, - }, - /// Draws a set of [`Line`]s. - /// - /// Each line is `line_width` units wide, and at least a single display - /// pixel. This means that line_width of 0 is still visible, even though - /// only marginally. This allows very thin outlines. - DrawLines { - /// The style that is used to draw the all lines. - line_style: Style, - /// The width of the lines. - line_width: f64, - /// The list of lines. - lines: Box<[Line]>, - }, - /// Draws a polygon. - /// - /// Each line is `line_width` units wide. The lines are drawn between - /// consecutive points as well as the first and the last point. - DrawLineLoop { - /// The style that is used to draw the all lines. - line_style: Style, - /// The width of the line. - line_width: f64, - /// The points of the polygon. - points: Box<[Point]>, - }, - /// Draws a list of consecutive lines. - /// - /// The lines are drawn between consecutive points, but contrary to - /// [`DrawLineLoop`], the first and the last point are not connected. - DrawLineStrip { - /// The style that is used to draw the all rectangles. - line_style: Style, - /// The width of the line. - line_width: f64, - /// The points of the line strip. - points: Box<[Point]>, - }, - /// Draws a [`Path`]. - /// - /// The outline of the path is `line_width` units wide. - DrawLinePath { - /// The style that is used to draw the path. - line_style: Style, - /// The width of the line. - line_width: f64, - /// A path with `segment_count` segments. - path: Path, - }, - /// Fills a polygon and draws an outline at the same time. - /// - /// This command is a combination of [`FillPolygon`] and [`DrawLineLoop`]. - /// It first performs a [`FillPolygon`] with the `fill_style`, then - /// performs [`DrawLineLoop`] with `line_style` and `line_width`. - /// - /// The outline commands use a reduced number of elements. The maximum - /// number of points is 64. - OutlineFillPolygon { - /// The style that is used to fill the polygon. - fill_style: Style, - /// The style that is used to draw the outline of the polygon. - line_style: Style, - /// The width of the line. - line_width: f64, - /// The set of points of this polygon. - points: Box<[Point]>, - }, - /// Fills and outlines a list of [`Rectangle`]s. - /// - /// For each rectangle, it is first filled, then its outline is drawn, then - /// the next rectangle is drawn. - /// - /// The outline commands use a reduced number of elements, the maximum - /// number of points is 64. - OutlineFillRectangles { - /// The style that is used to fill the rectangles. - fill_style: Style, - /// The style that is used to draw the outline of the rectangles. - line_style: Style, - /// The width of the line. - line_width: f64, - /// The list of rectangles to be drawn. - rectangles: Box<[Rectangle]>, - }, - /// Fills a path and draws an outline at the same time. - /// - /// This command is a combination of [`FillPath`] and [`DrawLinePath`]. It - /// first performs a [`FillPath`] with the `fill_style`, then performs - /// [`DrawLinePath`] with `line_style` and `line_width`. - OutlineFillPath { - /// The style that is used to fill the path. - fill_style: Style, - /// The style that is used to draw the outline of the path. - line_style: Style, - /// The width of the line. - line_width: f64, - /// The path that should be drawn. - path: Path, - }, -} - -/// The header is different for outline commands, so we use this as a helper -struct OutlineHeader { - count: u32, - fill_style: Style, - line_style: Style, - line_width: f64, -} - -impl OutlineHeader { - fn read( - reader: &mut impl Read, - header: &TvgHeader, - prim_style_kind: StyleKind, - ) -> Result { - // the count and secondary style kind are stores in the same byte - let byte = reader.read_u8()?; - let count = (byte & 0b0011_1111) as u32 + 1; - let sec_style_kind = StyleKind::try_from((byte & 0b1100_0000) >> 6)?; - - let fill_style = Style::read(reader, header, prim_style_kind)?; - let line_style = Style::read(reader, header, sec_style_kind)?; - - let line_width = read_unit(reader, header)?; - - Ok(Self { - count, - fill_style, - line_style, - line_width, - }) - } -} - -impl Command { - pub fn read(reader: &mut impl Read, header: &TvgHeader) -> Result { - // the command name and primary style kind are stores in the same byte - let byte = reader.read_u8()?; - let command = CommandName::try_from(byte & 0b0011_1111)?; - let style_kind = StyleKind::try_from((byte & 0b1100_0000) >> 6)?; - - match command { - CommandName::EndOfDocument => Self::end_of_document(style_kind), - CommandName::FillPolygon => Self::read_fill_polygon(reader, header, style_kind), - CommandName::FillRectangles => Self::read_fill_rectangles(reader, header, style_kind), - CommandName::FillPath => Self::read_fill_path(reader, header, style_kind), - CommandName::DrawLines => Self::read_draw_lines(reader, header, style_kind), - CommandName::DrawLineLoop => Self::read_draw_line_loop(reader, header, style_kind), - CommandName::DrawLineStrip => Self::read_draw_line_strip(reader, header, style_kind), - CommandName::DrawLinePath => Self::read_draw_line_path(reader, header, style_kind), - CommandName::OutlineFillPolygon => { - Self::read_outline_fill_polygon(reader, header, style_kind) - } - CommandName::OutlineFillRectangles => { - Self::read_outline_fill_rectangles(reader, header, style_kind) - } - CommandName::OutlineFillPath => { - Self::read_outline_fill_path(reader, header, style_kind) - } - } - } - - pub fn is_end_of_document(&self) -> bool { - matches!(self, Self::EndOfDocument) - } - - fn read_command_header( - reader: &mut impl Read, - header: &TvgHeader, - style_kind: StyleKind, - ) -> io::Result<(u32, Style)> { - // every command adds one to the count - let count = read_varuint(reader)? + 1; - let style = Style::read(reader, header, style_kind)?; - - Ok((count, style)) - } - - fn end_of_document(style_kind: StyleKind) -> Result { - if style_kind != StyleKind::FlatColored { - Err(TvgError::InvalidEndOfDocument(style_kind as u8)) - } else { - Ok(Self::EndOfDocument) - } - } - - fn read_fill_polygon( - reader: &mut impl Read, - header: &TvgHeader, - style_kind: StyleKind, - ) -> Result { - let (point_count, fill_style) = Self::read_command_header(reader, header, style_kind)?; - if point_count < 3 { - yeet!(TvgError::InvalidPolygon(point_count)); - } - - let polygon = Point::read_multiple(reader, header, point_count)?; - - Ok(Self::FillPolygon { - fill_style, - polygon, - }) - } - - fn read_fill_rectangles( - reader: &mut impl Read, - header: &TvgHeader, - style_kind: StyleKind, - ) -> Result { - let (rectangle_count, fill_style) = Self::read_command_header(reader, header, style_kind)?; - let rectangles = Rectangle::read_multiple(reader, header, rectangle_count)?; - - Ok(Self::FillRectangles { - fill_style, - rectangles, - }) - } - - fn read_fill_path( - reader: &mut impl Read, - header: &TvgHeader, - style_kind: StyleKind, - ) -> Result { - let (segment_count, fill_style) = Self::read_command_header(reader, header, style_kind)?; - let path = Path::read(reader, header, segment_count)?; - - Ok(Self::FillPath { fill_style, path }) - } - - fn read_draw_lines( - reader: &mut impl Read, - header: &TvgHeader, - style_kind: StyleKind, - ) -> Result { - let (line_count, line_style) = Self::read_command_header(reader, header, style_kind)?; - let line_width = read_unit(reader, header)?; - let lines = Line::read_multiple(reader, header, line_count)?; - - Ok(Self::DrawLines { - line_style, - line_width, - lines, - }) - } - - fn read_draw_line_loop( - reader: &mut impl Read, - header: &TvgHeader, - style_kind: StyleKind, - ) -> Result { - let (point_count, line_style) = Self::read_command_header(reader, header, style_kind)?; - let line_width = read_unit(reader, header)?; - let points = Point::read_multiple(reader, header, point_count)?; - - Ok(Self::DrawLineLoop { - line_style, - line_width, - points, - }) - } - - fn read_draw_line_strip( - reader: &mut impl Read, - header: &TvgHeader, - style_kind: StyleKind, - ) -> Result { - let (point_count, line_style) = Self::read_command_header(reader, header, style_kind)?; - let line_width = read_unit(reader, header)?; - let points = Point::read_multiple(reader, header, point_count)?; - - Ok(Self::DrawLineStrip { - line_style, - line_width, - points, - }) - } - - fn read_draw_line_path( - reader: &mut impl Read, - header: &TvgHeader, - style_kind: StyleKind, - ) -> Result { - let (segment_count, line_style) = Self::read_command_header(reader, header, style_kind)?; - let line_width = read_unit(reader, header)?; - let path = Path::read(reader, header, segment_count)?; - - Ok(Self::DrawLinePath { - line_style, - line_width, - path, - }) - } - - fn read_outline_fill_polygon( - reader: &mut impl Read, - header: &TvgHeader, - style_kind: StyleKind, - ) -> Result { - let OutlineHeader { - count: segment_count, - fill_style, - line_style, - line_width, - } = OutlineHeader::read(reader, header, style_kind)?; - - let points = Point::read_multiple(reader, header, segment_count)?; - - Ok(Self::OutlineFillPolygon { - fill_style, - line_style, - line_width, - points, - }) - } - - fn read_outline_fill_rectangles( - reader: &mut impl Read, - header: &TvgHeader, - style_kind: StyleKind, - ) -> Result { - let OutlineHeader { - count: rect_count, - fill_style, - line_style, - line_width, - } = OutlineHeader::read(reader, header, style_kind)?; - - let rectangles = Rectangle::read_multiple(reader, header, rect_count)?; - - Ok(Self::OutlineFillRectangles { - fill_style, - line_style, - line_width, - rectangles, - }) - } - - fn read_outline_fill_path( - reader: &mut impl Read, - header: &TvgHeader, - style_kind: StyleKind, - ) -> Result { - let OutlineHeader { - count: segment_count, - fill_style, - line_style, - line_width, - } = OutlineHeader::read(reader, header, style_kind)?; - - let path = Path::read(reader, header, segment_count)?; - - Ok(Self::OutlineFillPath { - fill_style, - line_style, - line_width, - path, - }) - } -} 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(reader: &mut R) -> Result { - // 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( - coordinate_range: CoordinateRange, - bytes: &mut R, -) -> io::Result { - Ok(match coordinate_range { - CoordinateRange::Reduced => bytes.read_u8()? as u32, - CoordinateRange::Default => bytes.read_u16::()? as u32, - CoordinateRange::Enhanced => bytes.read_u32::()?, - }) -} diff --git a/alligator_tvg/src/lib.rs b/alligator_tvg/src/lib.rs deleted file mode 100644 index 5cbe33c..0000000 --- a/alligator_tvg/src/lib.rs +++ /dev/null @@ -1,151 +0,0 @@ -use std::io::{self, Read}; - -use byteorder::{LittleEndian, ReadBytesExt}; -use colors::{Color, ColorTable}; -use commands::Command; -use header::{CoordinateRange, Scale, TvgHeader}; -use thiserror::Error; - -mod colors; -mod commands; -mod header; -mod path; - -pub use colors::Rgba16; -pub use header::SUPPORTED_VERSION; - -pub struct TvgFile { - header: TvgHeader, - color_table: ColorTable, - commands: Box<[Command]>, -} - -impl TvgFile { - pub fn read_from(reader: &mut impl Read) -> Result { - let header = TvgHeader::read(reader)?; - let color_table = - ColorTable::read_from_encoding(reader, header.color_count(), header.color_encoding())?; - - let mut commands = Vec::new(); - loop { - let command = Command::read(reader, &header)?; - commands.push(command.clone()); - - if command.is_end_of_document() { - break; - } - } - - Ok(Self { - header, - color_table, - commands: commands.into_boxed_slice(), - }) - } -} - -#[derive(Debug, Error)] -pub enum TvgError { - #[error("Not a valid TVG file. The magic number was invalid.")] - InvalidFile, - #[error("Expected version 1, but found version {}", .0)] - UnsupportedVersion(u8), - #[error("Found a coordinate range with an index of 3, which is invalid")] - InvalidCoordinateRange, - #[error("Found a command with an index of {}, which is invalid", .0)] - InvalidCommand(u8), - #[error("Found a style kind with an index of 3, which is invalid")] - InvalidStyleKind, - #[error("Polygons must have at least 3 points, found {}", .0)] - InvalidPolygon(u32), - #[error("The end of the document must have a `prim_style_kind` value of 0. Found {}", .0)] - InvalidEndOfDocument(u8), - #[error("{}", .0)] - IoError(#[from] io::Error), -} - -trait Decode: Sized { - fn read(reader: &mut impl Read, header: &TvgHeader) -> io::Result; - - fn read_multiple( - reader: &mut impl Read, - header: &TvgHeader, - count: u32, - ) -> io::Result> { - let mut vec = Vec::with_capacity(count as usize); - for _ in 0..count { - vec.push(Self::read(reader, header)?); - } - - Ok(vec.into_boxed_slice()) - } -} - -/// The unit is the common type for both positions and sizes in the vector -/// graphic. It is encoded as a signed integer with a configurable amount of -/// bits (see [`CoordinateRange`]) and fractional bits. -fn read_unit(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - let value = match header.coordinate_range() { - CoordinateRange::Reduced => reader.read_i8()? as i32, - CoordinateRange::Default => reader.read_i16::()? as i32, - CoordinateRange::Enhanced => reader.read_i32::()?, - }; - - let fractional = match header.scale() { - Scale::_1 => 1.0, - Scale::_2 => 2.0, - Scale::_4 => 4.0, - Scale::_8 => 8.0, - Scale::_16 => 16.0, - Scale::_32 => 32.0, - Scale::_64 => 64.0, - Scale::_128 => 128.0, - Scale::_256 => 256.0, - Scale::_512 => 512.0, - Scale::_1024 => 1024.0, - Scale::_2048 => 2048.0, - Scale::_4096 => 4096.0, - Scale::_8192 => 8192.0, - Scale::_16384 => 16_384.0, - Scale::_32768 => 32_768.0, - }; - - Ok((value as f64) / fractional) -} - -/// A X and Y coordinate pair. -#[derive(Debug, Clone, Copy)] -pub struct Point { - /// Horizontal distance of the point to the origin. - x: f64, - /// Vertical distance of the point to the origin. - y: f64, -} - -impl Decode for Point { - fn read(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - Ok(Self { - x: read_unit(reader, header)?, - y: read_unit(reader, header)?, - }) - } -} - -fn read_varuint(reader: &mut impl Read) -> io::Result { - let mut count = 0; - let mut result = 0; - - loop { - let byte = reader.read_u8()? as u32; - let value = (byte & 0x7F) << (7 * count); - result |= value; - - if (byte & 0x80) == 0 { - break; - } - - count += 1; - } - - Ok(result) -} diff --git a/alligator_tvg/src/path.rs b/alligator_tvg/src/path.rs deleted file mode 100644 index d2bf4fb..0000000 --- a/alligator_tvg/src/path.rs +++ /dev/null @@ -1,294 +0,0 @@ -use std::io::{self, Read}; - -use byteorder::ReadBytesExt; -use num_enum::TryFromPrimitive; - -use crate::{header::TvgHeader, read_unit, read_varuint, Decode, Point}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)] -#[repr(u8)] -enum Sweep { - Right = 0, - Left = 1, -} - -/// An instruction to move a hypothetical "pen". -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)] -#[repr(u8)] -enum InstructionKind { - /// A straight line is drawn from the current point to a new point. - Line = 0, - /// A straight horizontal line is drawn from the current point to a new x - /// coordinate. - HorizontalLine = 1, - /// A straight vertical line is drawn from the current point to a new y - /// coordiante. - VerticalLine = 2, - /// A cubic Bézier curve is drawn from the current point to a new point. - CubicBezier = 3, - /// A circle segment is drawn from current point to a new point. - ArcCircle = 4, - /// An ellipse segment is drawn from current point to a new point. - ArcEllipse = 5, - /// The path is closed, and a straight line is drawn to the starting point. - ClosePath = 6, - /// A quadratic Bézier curve is drawn from the current point to a new point. - QuadraticBezier = 7, -} - -#[derive(Debug, Clone, Copy)] -enum InstructionData { - /// The line instruction draws a straight line to the position. - Line { - /// The end point of the line. - position: Point, - }, - /// The horizontal line instruction draws a straight horizontal line to a - /// given x coordinate. - HorizontalLine { - /// The new x coordinate. - x: f64, - }, - /// The vertical line instruction draws a straight vertical line to a given - /// y coordinate. - VerticalLine { - /// The new y coordinate. - y: f64, - }, - /// The cubic bezier instruction draws a Bézier curve with two control - /// points. - /// - /// The curve is drawn between the current location and `point_1` with - /// `control_0` being the first control point and `control_1` being the - /// second one. - CubicBezier { - /// The first control point. - control_0: Point, - /// The second control point. - control_1: Point, - /// The end point of the Bézier curve. - point_1: Point, - }, - /// Draws a circle segment between the current and the target point. - /// - /// The `radius` field determines the radius of the circle. If the distance - /// between the current point and `target` is larger than `radius`, the - /// distance is used as the radius. - ArcCircle { - /// If `true`, the large portion of the circle segment is drawn. - large_arc: bool, - /// Determines if the circle segment is left- or right bending. - sweep: Sweep, - /// The radius of the circle. - radius: f64, - /// The end point of the circle segment. - target: Point, - }, - /// Draws an ellipse segment between the current and the target point. - /// - /// The `radius_x` and `radius_y` fields determine the both radii of the - /// ellipse. If the distance between the current point and target is not - /// enough to fit any ellipse segment between the two points, `radius_x` - /// and `radius_y` are scaled uniformly so that it fits exactly. - ArcEllipse { - /// If `true`, the large portion of the ellipse segment is drawn. - large_arc: bool, - /// Determines if the ellipse segment is left- or right bending. - sweep: Sweep, - /// The radius of the ellipse segment in the horizontal direction. - radius_x: f64, - /// The radius of the ellipse segment in the vertical direction. - radius_y: f64, - /// The rotation of the ellipse in mathematical negative direction, in - /// degrees. - rotation: f64, - /// The end point of the ellipse segment. - target: Point, - }, - /// A straight line is drawn to the start location of the current segment. - /// This instruction doesn’t have additional data encoded. - ClosePath, - /// The quadratic bezier instruction draws a Bézier curve with a single - /// control point. - /// - /// The curve is drawn between the current location and `point_1` with - /// control being the control point. - QuadraticBezier { - /// The control point. - control: Point, - /// The end point of the Bézier curve. - target: Point, - }, -} - -impl InstructionData { - fn read(reader: &mut impl Read, header: &TvgHeader, kind: InstructionKind) -> io::Result { - match kind { - InstructionKind::Line => Self::read_line(reader, header), - InstructionKind::HorizontalLine => Self::read_horizontal_line(reader, header), - InstructionKind::VerticalLine => Self::read_vertical_line(reader, header), - InstructionKind::CubicBezier => Self::read_cubic_bezier(reader, header), - InstructionKind::ArcCircle => Self::read_arc_circle(reader, header), - InstructionKind::ArcEllipse => Self::read_arc_ellipse(reader, header), - InstructionKind::ClosePath => Ok(Self::ClosePath), - InstructionKind::QuadraticBezier => Self::read_quadratic_bezier(reader, header), - } - } - - fn read_line(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - Ok(Self::Line { - position: Point::read(reader, header)?, - }) - } - - fn read_horizontal_line(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - Ok(Self::HorizontalLine { - x: read_unit(reader, header)?, - }) - } - - fn read_vertical_line(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - Ok(Self::VerticalLine { - y: read_unit(reader, header)?, - }) - } - - fn read_cubic_bezier(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - Ok(Self::CubicBezier { - control_0: Point::read(reader, header)?, - control_1: Point::read(reader, header)?, - point_1: Point::read(reader, header)?, - }) - } - - fn read_arc_header(reader: &mut impl Read, header: &TvgHeader) -> io::Result<(bool, Sweep)> { - // large_arc and sweep are stored in the same byte - let byte = reader.read_u8()?; - let large_arc = (byte & 1) != 0; - let sweep = match byte & 2 { - 0 => Sweep::Left, - _ => Sweep::Right, - }; - - Ok((large_arc, sweep)) - } - - fn read_arc_circle(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - let (large_arc, sweep) = Self::read_arc_header(reader, header)?; - let radius = read_unit(reader, header)?; - let target = Point::read(reader, header)?; - - Ok(Self::ArcCircle { - large_arc, - sweep, - radius, - target, - }) - } - - fn read_arc_ellipse(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - let (large_arc, sweep) = Self::read_arc_header(reader, header)?; - let radius_x = read_unit(reader, header)?; - let radius_y = read_unit(reader, header)?; - let rotation = read_unit(reader, header)?; - let target = Point::read(reader, header)?; - - Ok(Self::ArcEllipse { - large_arc, - sweep, - radius_x, - radius_y, - rotation, - target, - }) - } - - fn read_quadratic_bezier(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - Ok(Self::QuadraticBezier { - control: Point::read(reader, header)?, - target: Point::read(reader, header)?, - }) - } -} - -#[derive(Debug, Clone)] -struct Instruction { - /// The width of the line the "pen" makes, if it makes one at all. - line_width: Option, - /// The arguments to the instruction. - data: InstructionData, -} - -impl Instruction { - fn read(reader: &mut impl Read, header: &TvgHeader) -> io::Result { - let byte = reader.read_u8()?; - let instruction_kind = - InstructionKind::try_from_primitive(byte & 0b0000_0111).expect("invalid instruction"); - let has_line_width = (byte & 0b0001_0000) != 0; - - let line_width = has_line_width - .then(|| read_unit(reader, header)) - .transpose()?; - let data = InstructionData::read(reader, header, instruction_kind)?; - - Ok(Self { line_width, data }) - } -} - -#[derive(Debug, Clone)] -struct Segment { - /// The starting point of the segment. - start: Point, - /// The list of instructions for tha segment. - instructions: Box<[Instruction]>, -} - -impl Segment { - fn read(reader: &mut impl Read, header: &TvgHeader, segment_length: u32) -> io::Result { - let start = Point::read(reader, header)?; - - let mut instructions = Vec::with_capacity(segment_length as usize); - for _ in 0..segment_length { - instructions.push(Instruction::read(reader, header)?) - } - - Ok(Segment { - start, - instructions: instructions.into_boxed_slice(), - }) - } -} - -/// Paths describe instructions to create complex 2D graphics. -/// -/// Each path segment generates a shape by moving a ”pen” around. The path this -/// ”pen” takes is the outline of our segment. Each segment, the ”pen” starts -/// at a defined position and is moved by instructions. Each instruction will -/// leave the ”pen” at a new position. The line drawn by our ”pen” is the -/// outline of the shape. -#[derive(Debug, Clone)] -pub struct Path { - segments: Box<[Segment]>, -} - -impl Path { - pub(crate) fn read( - reader: &mut impl Read, - header: &TvgHeader, - segment_count: u32, - ) -> io::Result { - let mut segment_lengths = Vec::with_capacity(segment_count as usize); - for _ in 0..segment_count { - segment_lengths.push(read_varuint(reader)? + 1); - } - - let mut segments = Vec::with_capacity(segment_count as usize); - for segment_length in segment_lengths { - segments.push(Segment::read(reader, header, segment_length)?); - } - - Ok(Self { - segments: segments.into_boxed_slice(), - }) - } -} diff --git a/alligator_tvg/tests/examples/tvg/everything-32.tvg b/alligator_tvg/tests/examples/tvg/everything-32.tvg deleted file mode 100644 index 7ea4bdd..0000000 Binary files a/alligator_tvg/tests/examples/tvg/everything-32.tvg and /dev/null differ diff --git a/alligator_tvg/tests/examples/tvg/everything.tvg b/alligator_tvg/tests/examples/tvg/everything.tvg deleted file mode 100644 index b211c53..0000000 Binary files a/alligator_tvg/tests/examples/tvg/everything.tvg and /dev/null differ diff --git a/alligator_tvg/tests/examples/tvg/shield-16.tvg b/alligator_tvg/tests/examples/tvg/shield-16.tvg deleted file mode 100644 index aacd3ea..0000000 Binary files a/alligator_tvg/tests/examples/tvg/shield-16.tvg and /dev/null differ diff --git a/alligator_tvg/tests/examples/tvg/shield-32.tvg b/alligator_tvg/tests/examples/tvg/shield-32.tvg deleted file mode 100644 index a2abc92..0000000 Binary files a/alligator_tvg/tests/examples/tvg/shield-32.tvg and /dev/null differ diff --git a/alligator_tvg/tests/examples/tvg/shield-8.tvg b/alligator_tvg/tests/examples/tvg/shield-8.tvg deleted file mode 100644 index 57033be..0000000 Binary files a/alligator_tvg/tests/examples/tvg/shield-8.tvg and /dev/null differ diff --git a/alligator_tvg/tests/parse.rs b/alligator_tvg/tests/parse.rs deleted file mode 100644 index eb6e801..0000000 --- a/alligator_tvg/tests/parse.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::fs::File; - -use alligator_tvg::{Rgba16, TvgFile}; - -#[test] -fn main() { - for entry in std::fs::read_dir("tests/examples/tvg").unwrap() { - let entry = entry.unwrap().file_name(); - let entry = entry.to_string_lossy(); - let mut file = File::open(format!("./tests/examples/tvg/{}", &entry)).unwrap(); - let _: TvgFile = TvgFile::read_from(&mut file).unwrap(); - println!("{:?} succeeded!", entry); - } -} -- cgit v1.2.3