aboutsummaryrefslogtreecommitdiff
path: root/src/layer.rs
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2023-01-18 20:46:26 +0100
committerDaniel Schadt <kingdread@gmx.de>2023-01-18 20:46:26 +0100
commita6e3e58877307d7c9113fb229d46ada5f165eadc (patch)
tree35a1d5d3a8e00369ea958ec02df688430d78a995 /src/layer.rs
parentac3afadba547b4b9a4063da567acd6d2f4f74554 (diff)
downloadhittekaart-a6e3e58877307d7c9113fb229d46ada5f165eadc.tar.gz
hittekaart-a6e3e58877307d7c9113fb229d46ada5f165eadc.tar.bz2
hittekaart-a6e3e58877307d7c9113fb229d46ada5f165eadc.zip
add some more docstrings
Diffstat (limited to 'src/layer.rs')
-rw-r--r--src/layer.rs28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/layer.rs b/src/layer.rs
index 2726c81..dec2419 100644
--- a/src/layer.rs
+++ b/src/layer.rs
@@ -18,12 +18,17 @@ use image::{
use num_traits::Zero;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
+/// Height of a single tile.
pub const TILE_HEIGHT: u64 = 256;
+/// Width of a single tile.
pub const TILE_WIDTH: u64 = 256;
type TileIndex = (u64, u64);
/// Main "lazy image buffer" struct.
+///
+/// This lazily allocates a new tile (of size [`TILE_WIDTH`] × [`TILE_HEIGHT`]) for each mutable
+/// pixel access. Each tile is pre-filled with the given default pixel.
#[derive(Debug, Clone)]
pub struct TileLayer<P: Pixel> {
tiles: FnvHashMap<TileIndex, ImageBuffer<P, Vec<P::Subpixel>>>,
@@ -31,6 +36,9 @@ pub struct TileLayer<P: Pixel> {
}
impl<P: Pixel> TileLayer<P> {
+ /// Construct a new lazy buffer with the given default (background) pixel.
+ ///
+ /// Note that this does not yet allocate any image tiles.
pub fn from_pixel(pixel: P) -> Self {
TileLayer {
tiles: Default::default(),
@@ -38,19 +46,25 @@ impl<P: Pixel> TileLayer<P> {
}
}
+ /// Iterates over all tiles, together with their indices.
pub fn enumerate_tiles(
&self,
) -> impl Iterator<Item = (u64, u64, &ImageBuffer<P, Vec<P::Subpixel>>)> {
self.tiles.iter().map(|((x, y), t)| (*x, *y, t))
}
+ /// Returns a mutable reference to the given tile.
+ ///
+ /// This allocates a new tile if the requested tile does not yet exist.
pub fn tile_mut(&mut self, tile_x: u64, tile_y: u64) -> &mut ImageBuffer<P, Vec<P::Subpixel>> {
self.tiles.entry((tile_x, tile_y)).or_insert_with(|| {
ImageBuffer::from_pixel(TILE_WIDTH as u32, TILE_HEIGHT as u32, self.default_pixel)
})
}
- /// Enumerate all pixels that are explicitely set in this layer.
+ /// Enumerate all pixels that are allocated.
+ ///
+ /// This provides access to the pixel and its coordinates.
pub fn enumerate_pixels(&self) -> impl Iterator<Item = (u64, u64, &P)> {
self.tiles.iter().flat_map(|((tx, ty), tile)| {
tile.enumerate_pixels().map(move |(x, y, p)| {
@@ -63,10 +77,12 @@ impl<P: Pixel> TileLayer<P> {
})
}
+ /// Iterate over all pixels that are allocated.
pub fn pixels(&self) -> impl Iterator<Item = &P> {
self.enumerate_pixels().map(|x| x.2)
}
+ /// Returns the number of allocated tiles.
pub fn tile_count(&self) -> usize {
self.tiles.len()
}
@@ -78,8 +94,8 @@ impl<P: Pixel> TileLayer<P> {
///
/// The top-left pixel of `source` is copied to `(x, y)`.
///
- /// This method is more efficient than repeatedly calling [`get_pixel_mut`], as it groups
- /// pixels by tile and only does one tile lookup.
+ /// This method is more efficient than copying pixels one by one, as it groups them by tile and
+ /// only does one tile lookup then.
pub fn blit_nonzero(&mut self, x: u64, y: u64, source: &ImageBuffer<P, Vec<P::Subpixel>>) {
let zero = zero_pixel::<P>();
let source_width = u64::from(source.width());
@@ -114,6 +130,7 @@ where
P: Pixel + Send,
P::Subpixel: Send,
{
+ /// Turns this lazy tile layer into a parallelized iterator.
pub fn into_parallel_tiles(
self,
) -> impl ParallelIterator<Item = (u64, u64, ImageBuffer<P, Vec<P::Subpixel>>)> {
@@ -121,11 +138,15 @@ where
}
}
+/// Saves the given image buffer to the given path.
pub fn compress_png<P: AsRef<Path>>(image: &RgbaImage, path: P) -> Result<()> {
let outstream = BufWriter::new(File::create(path)?);
compress_png_stream(image, outstream)
}
+/// Saves the given image buffer to the given stream.
+///
+/// Note that this uses the best compression available.
pub fn compress_png_stream<W: Write>(image: &RgbaImage, outstream: W) -> Result<()> {
let encoder =
PngEncoder::new_with_quality(outstream, CompressionType::Best, FilterType::Adaptive);
@@ -135,6 +156,7 @@ pub fn compress_png_stream<W: Write>(image: &RgbaImage, outstream: W) -> Result<
Ok(())
}
+/// Encodes the given image buffer and returns its data as a vector.
pub fn compress_png_as_bytes(image: &RgbaImage) -> Result<Vec<u8>> {
let mut buffer = Vec::new();
compress_png_stream(image, &mut buffer)?;