mirror of
https://github.com/Dangoware/sqp.git
synced 2025-04-18 23:02:58 -05:00
Fixed minor issues
This commit is contained in:
parent
765f7f7789
commit
861baa9999
4 changed files with 97 additions and 20 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,6 +5,7 @@ Cargo.lock
|
|||
# Ignore images
|
||||
*.png
|
||||
*.dpf
|
||||
*.sqp
|
||||
*.raw
|
||||
*.rgba
|
||||
*.jpg
|
||||
|
|
|
@ -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
|
||||
|
|
66
src/lib.rs
66
src/lib.rs
|
@ -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;
|
||||
|
|
|
@ -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)?)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue