Fixed minor issues

This commit is contained in:
G2-Games 2024-07-28 23:58:52 -05:00
parent 765f7f7789
commit 861baa9999
4 changed files with 97 additions and 20 deletions

1
.gitignore vendored
View file

@ -5,6 +5,7 @@ Cargo.lock
# Ignore images
*.png
*.dpf
*.sqp
*.raw
*.rgba
*.jpg

View file

@ -98,7 +98,7 @@ pub fn idct(input: &[f32], width: usize, height: usize) -> Vec<u8> {
/// JPEG 8x8 Base Quantization Matrix for a quality level of 50.
///
/// Instead of using this, utilize the [`quantization_matrix`] function to
/// Instead of using this, use the [`quantization_matrix`] function to
/// get a quantization matrix corresponding to the image quality value.
const BASE_QUANTIZATION_MATRIX: [u16; 64] = [
16, 11, 10, 16, 24, 40, 51, 61,
@ -221,7 +221,7 @@ pub fn dct_decompress(input: &[i16], parameters: DctParameters) -> Vec<u8> {
let row_offset = row_num * parameters.width;
let offset = if start_x + 8 >= parameters.width {
let offset = if start_x + 8 > parameters.width {
parameters.width % 8
} else {
8

View file

@ -1,5 +1,52 @@
//! SQP (SQuishy Picture Format) is an image format. It can be used to store
//! image data in lossless or lossy compressed form.
//! SQP (**SQ**uishy **P**icture Format) is an image format. It can be used to store
//! image data in lossless or lossy compressed form. It is designed to be
//! relatively simple compared to other more standard formats.
//!
//! This image format is mainly for experimentation and learning about
//! compression. While it can be used, there are no guarantees about stability,
//! breaking changes, or features.
//!
//! If you're looking for an image format to use, you might want to consider
//! using a more standard one such as those supported by the
//! [image crate](https://docs.rs/image/latest/image/).
//!
//! # Example
//! ## Creating and writing an SQP
//! ```no_run
//! use sqp::{SquishyPicture, ColorFormat};
//!
//! let width = 2;
//! let height = 2;
//! let bitmap = vec![
//! 255, 255, 255, 255, 0, 255, 0, 128,
//! 255, 255, 255, 255, 0, 255, 0, 128
//! ];
//!
//! // Create a 2×2 image in memory. Nothing is compressed or encoded
//! // at this point.
//! let sqp_image = SquishyPicture::from_raw_lossless(
//! width,
//! height,
//! ColorFormat::Rgba8,
//! bitmap
//! );
//!
//! // Write it out to a file. This performs compression and encoding.
//! sqp_image.save("my_image.sqp").expect("Could not save the image");
//! ```
//!
//! ## Reading an SQP from a file.
//! ```no_run
//! use std::fs::File;
//! use sqp::SquishyPicture;
//!
//! // Load it directly with the `open` function...
//! let image = sqp::open("my_image.sqp").expect("Could not open file");
//!
//! // ...or from something implementing Read.
//! let input_file = File::open("my_image.sqp").expect("Could not open image file");
//! let image2 = SquishyPicture::decode(&input_file);
//! ```
mod compression {
pub mod dct;
@ -10,3 +57,18 @@ mod operations;
pub mod picture;
pub mod header;
// ----------------------- //
// INLINED USEFUL FEATURES //
// ----------------------- //
#[doc(inline)]
pub use picture::SquishyPicture;
#[doc(inline)]
pub use header::ColorFormat;
#[doc(inline)]
pub use header::CompressionType;
#[doc(inline)]
pub use picture::open;

View file

@ -1,4 +1,6 @@
use std::{fs::File, io::{self, BufWriter, Read, Write}};
//! Functions and other utilities surrounding the [`SquishyPicture`] type.
use std::{fs::File, io::{self, BufWriter, Read, Write}, path::Path};
use byteorder::{ReadBytesExt, WriteBytesExt};
use integer_encoding::VarInt;
@ -11,11 +13,6 @@ use crate::{
operations::{diff_line, line_diff},
};
pub struct DangoPicture {
pub header: Header,
pub bitmap: Vec<u8>,
}
#[derive(Error, Debug)]
pub enum Error {
#[error("incorrect identifier, got {0:02X?}")]
@ -28,7 +25,13 @@ pub enum Error {
CompressionError(#[from] CompressionError),
}
impl DangoPicture {
/// The basic Squishy Picture type for manipulation in-memory.
pub struct SquishyPicture {
pub header: Header,
pub bitmap: Vec<u8>,
}
impl SquishyPicture {
/// Create a DPF from raw bytes in a particular [`ColorFormat`].
///
/// The quality parameter does nothing if the compression type is not
@ -36,7 +39,7 @@ impl DangoPicture {
///
/// # Example
/// ```ignore
/// let dpf_lossy = DangoPicture::from_raw(
/// let dpf_lossy = SquishyPicture::from_raw(
/// input.width(),
/// input.height(),
/// ColorFormat::Rgba32,
@ -72,13 +75,13 @@ impl DangoPicture {
color_format,
};
DangoPicture {
Self {
header,
bitmap,
}
}
/// Convenience method over [`DangoPicture::from_raw`] which creates a
/// Convenience method over [`SquishyPicture::from_raw`] which creates a
/// lossy image with a given quality.
pub fn from_raw_lossy(
width: u32,
@ -97,7 +100,8 @@ impl DangoPicture {
)
}
/// Convenience method over [`SquishyPicture::from_raw`] which creates a
/// lossless image.
pub fn from_raw_lossless(
width: u32,
height: u32,
@ -114,8 +118,9 @@ impl DangoPicture {
)
}
/// Encode the image into anything that implements [Write]. Returns the
/// number of bytes written.
/// Encode the image into anything that implements [`Write`].
///
/// Returns the number of bytes written.
pub fn encode<O: Write + WriteBytesExt>(&self, mut output: O) -> Result<usize, Error> {
let mut count = 0;
@ -146,6 +151,9 @@ impl DangoPicture {
},
};
let mut inspection_file = File::create("raw_data").unwrap();
inspection_file.write_all(&modified_data).unwrap();
// Compress the final image data using the basic LZW scheme
let (compressed_data, compression_info) = compress(modified_data)?;
@ -168,8 +176,8 @@ impl DangoPicture {
Ok(())
}
/// Decode the image from anything that implements [Read]
pub fn decode<I: Read + ReadBytesExt>(mut input: I) -> Result<DangoPicture, Error> {
/// Decode the image from anything that implements [`Read`]
pub fn decode<I: Read + ReadBytesExt>(mut input: I) -> Result<Self, Error> {
let header = Header::read_from(&mut input)?;
let compression_info = CompressionInfo::read_from(&mut input);
@ -194,7 +202,7 @@ impl DangoPicture {
},
};
Ok(DangoPicture { header, bitmap })
Ok(Self { header, bitmap })
}
}
@ -209,3 +217,9 @@ fn decode_varint_stream(stream: &[u8]) -> Vec<i16> {
output
}
pub fn open<P: AsRef<Path>>(path: P) -> Result<SquishyPicture, Error> {
let input = File::open(path)?;
Ok(SquishyPicture::decode(input)?)
}