summaryrefslogtreecommitdiff
path: root/packer
diff options
context:
space:
mode:
Diffstat (limited to 'packer')
-rw-r--r--packer/Cargo.toml13
-rw-r--r--packer/packed.pngbin1268654 -> 0 bytes
-rw-r--r--packer/src/bin/benchmark.rs28
-rw-r--r--packer/src/bin/res/bunny.ffbin8208 -> 0 bytes
-rw-r--r--packer/src/bin/res/bunny.pngbin438 -> 0 bytes
-rw-r--r--packer/src/bin/res/gator.bmpbin750054 -> 0 bytes
-rw-r--r--packer/src/bin/res/gator.ffbin2000016 -> 0 bytes
-rw-r--r--packer/src/bin/res/ghost.icobin67646 -> 0 bytes
-rw-r--r--packer/src/lib.rs175
9 files changed, 0 insertions, 216 deletions
diff --git a/packer/Cargo.toml b/packer/Cargo.toml
deleted file mode 100644
index 0b1beb8..0000000
--- a/packer/Cargo.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-[package]
-name = "packer"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-image = "0.24"
-exun = "0.2"
-
-[[bin]]
-name = "benchmark"
diff --git a/packer/packed.png b/packer/packed.png
deleted file mode 100644
index 9602cdb..0000000
--- a/packer/packed.png
+++ /dev/null
Binary files differ
diff --git a/packer/src/bin/benchmark.rs b/packer/src/bin/benchmark.rs
deleted file mode 100644
index 4d898d5..0000000
--- a/packer/src/bin/benchmark.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-use std::{fs::File, sync::Arc, time::Instant};
-
-use image::{io::Reader as ImageReader, ImageOutputFormat};
-use packer::RectanglePacker;
-
-fn main() -> Result<(), exun::RawUnexpected> {
- let img1 = ImageReader::open("src/bin/res/gator.bmp")?.decode()?;
- let img2 = ImageReader::open("src/bin/res/bunny.ff")?.decode()?;
- let img3 = ImageReader::open("src/bin/res/ghost.ico")?.decode()?;
-
- let start = Instant::now();
- let mut packer = RectanglePacker::new();
- packer.add_texture("gator".into(), Arc::new(img1.to_rgba8()));
- packer.add_texture("bunny".into(), Arc::new(img2.to_rgba8()));
- packer.add_texture("ghost".into(), Arc::new(img3.to_rgba8()));
- println!("{} milliseconds", start.elapsed().as_secs_f32() * 1000.0);
-
- let start = Instant::now();
- let packed = packer.output(1, 1);
- println!("{} milliseconds", start.elapsed().as_secs_f32() * 1000.0);
-
- let mut file = File::create("packed.png")?;
- packed?
- .get_full_atlas()
- .write_to(&mut file, ImageOutputFormat::Bmp)?;
-
- Ok(())
-}
diff --git a/packer/src/bin/res/bunny.ff b/packer/src/bin/res/bunny.ff
deleted file mode 100644
index 64c5a69..0000000
--- a/packer/src/bin/res/bunny.ff
+++ /dev/null
Binary files differ
diff --git a/packer/src/bin/res/bunny.png b/packer/src/bin/res/bunny.png
deleted file mode 100644
index 87ba72d..0000000
--- a/packer/src/bin/res/bunny.png
+++ /dev/null
Binary files differ
diff --git a/packer/src/bin/res/gator.bmp b/packer/src/bin/res/gator.bmp
deleted file mode 100644
index e752b56..0000000
--- a/packer/src/bin/res/gator.bmp
+++ /dev/null
Binary files differ
diff --git a/packer/src/bin/res/gator.ff b/packer/src/bin/res/gator.ff
deleted file mode 100644
index aac1bcb..0000000
--- a/packer/src/bin/res/gator.ff
+++ /dev/null
Binary files differ
diff --git a/packer/src/bin/res/ghost.ico b/packer/src/bin/res/ghost.ico
deleted file mode 100644
index 102de00..0000000
--- a/packer/src/bin/res/ghost.ico
+++ /dev/null
Binary files differ
diff --git a/packer/src/lib.rs b/packer/src/lib.rs
deleted file mode 100644
index 6715a9e..0000000
--- a/packer/src/lib.rs
+++ /dev/null
@@ -1,175 +0,0 @@
-use std::collections::HashMap;
-use std::ops::Deref;
-use std::sync::Arc;
-
-use exun::RawUnexpected;
-use image::{GenericImage, RgbaImage};
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct Rectangle {
- pub x: u32,
- pub y: u32,
- pub width: u32,
- pub height: u32,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-struct Texture {
- id: Arc<str>,
- x: u32,
- y: u32,
- texture: Arc<RgbaImage>,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-struct ImageRect(Arc<RgbaImage>, Arc<str>);
-
-#[derive(Debug, Default, Clone)]
-pub struct RectanglePacker {
- min_width: u32,
- textures: Vec<ImageRect>,
-}
-
-#[derive(Debug, Clone)]
-pub struct TextureAtlas {
- atlas: RgbaImage,
- ids: HashMap<Arc<str>, Rectangle>,
-}
-
-impl PartialOrd for ImageRect {
- fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl Ord for ImageRect {
- fn cmp(&self, other: &Self) -> std::cmp::Ordering {
- self.0.height().cmp(&other.0.height())
- }
-}
-
-impl RectanglePacker {
- pub fn new() -> Self {
- Self {
- min_width: 1,
- textures: Vec::new(),
- }
- }
-
- pub fn with_capacity(capacity: usize) -> Self {
- Self {
- min_width: 1,
- textures: Vec::with_capacity(capacity),
- }
- }
-
- pub fn capacity(&self) -> usize {
- self.textures.capacity()
- }
-
- pub fn len(&self) -> usize {
- self.textures.len()
- }
-
- pub fn is_empty(&self) -> bool {
- self.textures.is_empty()
- }
-
- pub fn reserve(&mut self, additional: usize) {
- self.textures.reserve(additional)
- }
-
- pub fn shrink_to_fit(&mut self) {
- self.textures.shrink_to_fit()
- }
-
- pub fn add_texture(&mut self, name: Arc<str>, texture: Arc<RgbaImage>) {
- if texture.width() > self.min_width {
- self.min_width = texture.width() + 1;
- }
- self.textures.push(ImageRect(texture, name));
- }
-
- fn pack(&mut self, min_width: u32) -> (Vec<Texture>, u32, u32) {
- let image_width = self.min_width.max(min_width);
-
- // to make sure padding is rounded up and not down, 64 is added
- // to make sure some padding is always present, minimum is 1 pixel
- let horizontal_padding = ((image_width + 64) / 128).max(1);
-
- let mut x_position = 0;
- let mut y_position = 0;
- let mut largest_row_height = 0;
- let mut rectangles = Vec::with_capacity(self.textures.len());
-
- self.textures.sort();
- self.textures.reverse();
- for texture in &self.textures {
- // loop to the next row if we've gone off the edge
- if (x_position + texture.0.width()) > image_width {
- let vertical_padding = ((largest_row_height + 64) / 128).max(1);
-
- y_position += largest_row_height + vertical_padding;
- x_position = 0;
- largest_row_height = 0;
- }
-
- // set the rectangle position
- let x = x_position;
- let y = y_position;
-
- x_position += texture.0.width() + horizontal_padding;
-
- if texture.0.height() > largest_row_height {
- largest_row_height = texture.0.height();
- }
-
- rectangles.push(Texture {
- id: texture.1.clone(),
- x,
- y,
- texture: texture.0.clone(),
- });
- }
-
- let vertical_padding = ((largest_row_height + 64) / 128).max(1);
- let total_height = y_position + largest_row_height + vertical_padding;
-
- (rectangles, image_width, total_height)
- }
-
- pub fn output(
- &mut self,
- min_width: u32,
- min_height: u32,
- ) -> Result<TextureAtlas, RawUnexpected> {
- let (rectangles, image_width, image_height) = self.pack(min_width);
- let image_height = image_height.max(min_height);
- let mut atlas = RgbaImage::new(image_width, image_height);
- let mut ids = HashMap::with_capacity(rectangles.len());
- for rectangle in rectangles {
- atlas.copy_from(rectangle.texture.deref(), rectangle.x, rectangle.y)?;
- ids.insert(
- rectangle.id,
- Rectangle {
- x: rectangle.x,
- y: rectangle.y,
- width: rectangle.texture.width(),
- height: rectangle.texture.height(),
- },
- );
- }
-
- Ok(TextureAtlas { atlas, ids })
- }
-}
-
-impl TextureAtlas {
- pub fn get_full_atlas(&self) -> &RgbaImage {
- &self.atlas
- }
-
- pub fn get_texture_rect(&self, id: &str) -> Option<Rectangle> {
- self.ids.get(id).cloned()
- }
-}