From f77e5b475ddae1115343ab98c3e6b3f961408a55 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Tue, 11 Nov 2025 13:16:22 +0000 Subject: [PATCH 1/4] WIP replacement of pixel density unit enum with the struct definition from `image` --- src/writer.rs | 59 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/src/writer.rs b/src/writer.rs index e818b67..e0c6a1e 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -4,17 +4,58 @@ use crate::marker::{Marker, SOFType}; use crate::quantization::QuantizationTable; use crate::EncodingError; -/// Density settings -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum Density { - /// No pixel density is set, which means "1 pixel per pixel" - None, +/// Represents the pixel density of an image +/// +/// For example, a 300 DPI image is represented by: +/// +/// ```rust +/// use image::codecs::jpeg::*; +/// let hdpi = PixelDensity::dpi(300); +/// assert_eq!(hdpi, PixelDensity {density: (300,300), unit: PixelDensityUnit::Inches}) +/// ``` +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct PixelDensity { + /// A couple of values for (Xdensity, Ydensity) + pub density: (u16, u16), + /// The unit in which the density is measured + pub unit: PixelDensityUnit, +} + +impl PixelDensity { + /// Creates the most common pixel density type: + /// the horizontal and the vertical density are equal, + /// and measured in pixels per inch. + #[must_use] + pub fn dpi(density: u16) -> Self { + PixelDensity { + density: (density, density), + unit: PixelDensityUnit::Inches, + } + } +} + +impl Default for PixelDensity { + /// Returns a pixel density with a pixel aspect ratio of 1 + fn default() -> Self { + PixelDensity { + density: (1, 1), + unit: PixelDensityUnit::PixelAspectRatio, + } + } +} + +/// Represents a unit in which the density of an image is measured +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum PixelDensityUnit { + /// Represents the absence of a unit, the values indicate only a + /// [pixel aspect ratio](https://en.wikipedia.org/wiki/Pixel_aspect_ratio) + PixelAspectRatio, - /// Horizontal and vertical dots per inch (dpi) - Inch { x: u16, y: u16 }, + /// Pixels per inch (2.54 cm) + Inches, - /// Horizontal and vertical dots per centimeters - Centimeter { x: u16, y: u16 }, + /// Pixels per centimeter + Centimeters, } /// Zig-zag sequence of quantized DCT coefficients From de0e9d888e5403adbe5175bdb082ad76f86246fa Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Tue, 11 Nov 2025 13:22:55 +0000 Subject: [PATCH 2/4] Adjust the code to use the new struct definition --- src/encoder.rs | 10 +++++----- src/lib.rs | 2 +- src/writer.rs | 19 ++++++++----------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/encoder.rs b/src/encoder.rs index eded305..e88266b 100644 --- a/src/encoder.rs +++ b/src/encoder.rs @@ -4,7 +4,7 @@ use crate::image_buffer::*; use crate::marker::Marker; use crate::quantization::{QuantizationTable, QuantizationTableType}; use crate::writer::{JfifWrite, JfifWriter, ZIGZAG}; -use crate::{Density, EncodingError}; +use crate::{PixelDensity, EncodingError}; use alloc::vec; use alloc::vec::Vec; @@ -194,7 +194,7 @@ macro_rules! add_component { /// # The JPEG encoder pub struct Encoder { writer: JfifWriter, - density: Density, + density: PixelDensity, quality: u8, components: Vec, @@ -243,7 +243,7 @@ impl Encoder { Encoder { writer: JfifWriter::new(w), - density: Density::None, + density: PixelDensity::default(), quality, components: vec![], quantization_tables, @@ -259,12 +259,12 @@ impl Encoder { /// Set pixel density for the image /// /// By default, this value is None which is equal to "1 pixel per pixel". - pub fn set_density(&mut self, density: Density) { + pub fn set_density(&mut self, density: PixelDensity) { self.density = density; } /// Return pixel density - pub fn density(&self) -> Density { + pub fn density(&self) -> PixelDensity { self.density } diff --git a/src/lib.rs b/src/lib.rs index 9fc0a0e..0fb6ff0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,7 +46,7 @@ pub use encoder::{ColorType, Encoder, JpegColorType, SamplingFactor}; pub use error::EncodingError; pub use image_buffer::{cmyk_to_ycck, rgb_to_ycbcr, ImageBuffer}; pub use quantization::QuantizationTableType; -pub use writer::{Density, JfifWrite}; +pub use writer::{PixelDensity, JfifWrite}; #[cfg(feature = "benchmark")] pub use fdct::fdct; diff --git a/src/writer.rs b/src/writer.rs index e0c6a1e..160b97e 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -213,30 +213,27 @@ impl JfifWriter { Ok(()) } - pub fn write_header(&mut self, density: &Density) -> Result<(), EncodingError> { + pub fn write_header(&mut self, density: &PixelDensity) -> Result<(), EncodingError> { self.write_marker(Marker::APP(0))?; self.write_u16(16)?; self.write(b"JFIF\0")?; self.write(&[0x01, 0x02])?; - match *density { - Density::None => { + match density.unit { + PixelDensityUnit::PixelAspectRatio => { self.write_u8(0x00)?; - self.write_u16(1)?; - self.write_u16(1)?; } - Density::Inch { x, y } => { + PixelDensityUnit::Inches => { self.write_u8(0x01)?; - self.write_u16(x)?; - self.write_u16(y)?; } - Density::Centimeter { x, y } => { + PixelDensityUnit::Centimeters => { self.write_u8(0x02)?; - self.write_u16(x)?; - self.write_u16(y)?; } } + let (x, y) = density.density; + self.write_u16(x)?; + self.write_u16(y)?; self.write(&[0x00, 0x00]) } From fc1629a4afc50efe4f5ad8d75cbf3411719aaeb5 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Tue, 11 Nov 2025 13:34:22 +0000 Subject: [PATCH 3/4] Export PixelDensityUnit as a toplevel type --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 0fb6ff0..0ba9ba2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,7 +46,7 @@ pub use encoder::{ColorType, Encoder, JpegColorType, SamplingFactor}; pub use error::EncodingError; pub use image_buffer::{cmyk_to_ycck, rgb_to_ycbcr, ImageBuffer}; pub use quantization::QuantizationTableType; -pub use writer::{PixelDensity, JfifWrite}; +pub use writer::{PixelDensity, PixelDensityUnit, JfifWrite}; #[cfg(feature = "benchmark")] pub use fdct::fdct; From c0c7937b5e1018a2cb54412e8319bc1dca625cfb Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Tue, 11 Nov 2025 13:34:31 +0000 Subject: [PATCH 4/4] Fix doctest --- src/writer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/writer.rs b/src/writer.rs index 160b97e..6490e98 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -9,7 +9,7 @@ use crate::EncodingError; /// For example, a 300 DPI image is represented by: /// /// ```rust -/// use image::codecs::jpeg::*; +/// # use jpeg_encoder::{PixelDensity, PixelDensityUnit}; /// let hdpi = PixelDensity::dpi(300); /// assert_eq!(hdpi, PixelDensity {density: (300,300), unit: PixelDensityUnit::Inches}) /// ```