Skip to content

Commit 8f372be

Browse files
authored
Merge pull request #2736 from Shnatsel/jpeg-encoder-0.7
Upgrade to jpeg-encoder 0.7
2 parents 04cb373 + 7232995 commit 8f372be

File tree

10 files changed

+32
-43
lines changed

10 files changed

+32
-43
lines changed

.github/workflows/rust.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ jobs:
3939
strategy:
4040
fail-fast: false
4141
matrix:
42-
rust: ["1.85.0", nightly, beta]
42+
rust: ["1.87.0", nightly, beta]
4343
steps:
4444
- uses: actions/checkout@v4
4545

4646
- uses: dtolnay/rust-toolchain@nightly
47-
if: ${{ matrix.rust == '1.85.0' }}
47+
if: ${{ matrix.rust == '1.87.0' }}
4848
- name: Generate Cargo.lock with minimal-version dependencies
49-
if: ${{ matrix.rust == '1.85.0' }}
49+
if: ${{ matrix.rust == '1.87.0' }}
5050
run: |
5151
cargo -Zminimal-versions generate-lockfile
5252
cargo update --offline num-bigint --precise 0.4.2
@@ -61,7 +61,7 @@ jobs:
6161
- name: build
6262
run: cargo build -v
6363
- name: test
64-
if: ${{ matrix.rust != '1.85.0' }}
64+
if: ${{ matrix.rust != '1.87.0' }}
6565
run: cargo test -v && cargo doc -v
6666

6767
test_other_archs:

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ resolver = "2"
1010
publish = false
1111

1212
# note: when changed, also update test runner in `.github/workflows/rust.yml`
13-
rust-version = "1.85.0"
13+
rust-version = "1.87.0"
1414

1515
license = "MIT OR Apache-2.0"
1616
description = "Imaging library. Provides basic image processing and encoders/decoders for common image formats."
@@ -60,7 +60,7 @@ rgb = { version = "0.8.48", default-features = false, optional = true }
6060
tiff = { version = "0.10.3", optional = true }
6161
zune-core = { version = "0.5.0", default-features = false, optional = true }
6262
zune-jpeg = { version = "0.5.5", optional = true }
63-
jpeg-encoder = { version = "0.6.1", optional = true, features = ["simd"] }
63+
jpeg-encoder = { version = "0.7.0", optional = true, features = ["simd"] }
6464
serde = { version = "1.0.214", optional = true, features = ["derive"] }
6565
pic-scale-safe = "0.1.5"
6666

src/codecs/avif/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ impl<W: Write> AvifEncoder<W> {
196196
Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned) => {
197197
// Sad, but let's allocate.
198198
// bytemuck checks alignment _before_ slop but size mismatch before this..
199-
if buf.len() % size_of::<Channel>() != 0 {
199+
if !buf.len().is_multiple_of(size_of::<Channel>()) {
200200
Err(ImageError::Parameter(ParameterError::from_kind(
201201
ParameterErrorKind::DimensionMismatch,
202202
)))

src/codecs/dxt.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl<R: Read> DxtDecoder<R> {
8080
height: u32,
8181
variant: DxtVariant,
8282
) -> Result<DxtDecoder<R>, ImageError> {
83-
if width % 4 != 0 || height % 4 != 0 {
83+
if !width.is_multiple_of(4) || !height.is_multiple_of(4) {
8484
// TODO: this is actually a bit of a weird case. We could return `DecodingError` but
8585
// it's not really the format that is wrong However, the encoder should surely return
8686
// `EncodingError` so it would be the logical choice for symmetry.
@@ -289,7 +289,7 @@ fn decode_dxt1_block(source: &[u8], dest: &mut [u8]) {
289289
/// Decode a row of DXT1 data to four rows of RGB data.
290290
/// `source.len()` should be a multiple of 8, otherwise this panics.
291291
fn decode_dxt1_row(source: &[u8], dest: &mut [u8]) {
292-
assert!(source.len() % 8 == 0);
292+
assert!(source.len().is_multiple_of(8));
293293
let block_count = source.len() / 8;
294294
assert!(dest.len() >= block_count * 48);
295295

@@ -310,7 +310,7 @@ fn decode_dxt1_row(source: &[u8], dest: &mut [u8]) {
310310
/// Decode a row of DXT3 data to four rows of RGBA data.
311311
/// `source.len()` should be a multiple of 16, otherwise this panics.
312312
fn decode_dxt3_row(source: &[u8], dest: &mut [u8]) {
313-
assert!(source.len() % 16 == 0);
313+
assert!(source.len().is_multiple_of(16));
314314
let block_count = source.len() / 16;
315315
assert!(dest.len() >= block_count * 64);
316316

@@ -331,7 +331,7 @@ fn decode_dxt3_row(source: &[u8], dest: &mut [u8]) {
331331
/// Decode a row of DXT5 data to four rows of RGBA data.
332332
/// `source.len()` should be a multiple of 16, otherwise this panics.
333333
fn decode_dxt5_row(source: &[u8], dest: &mut [u8]) {
334-
assert!(source.len() % 16 == 0);
334+
assert!(source.len().is_multiple_of(16));
335335
let block_count = source.len() / 16;
336336
assert!(dest.len() >= block_count * 64);
337337

src/codecs/jpeg/encoder.rs

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,15 @@ impl PixelDensity {
8585
}
8686

8787
/// Converts pixel density to the representation used by jpeg-encoder crate
88-
fn to_encoder_repr(self) -> jpeg_encoder::Density {
89-
match self.unit {
90-
PixelDensityUnit::PixelAspectRatio => jpeg_encoder::Density::None, // TODO: https://github.com/vstroebel/jpeg-encoder/issues/21
91-
PixelDensityUnit::Inches => jpeg_encoder::Density::Inch {
92-
x: self.density.0,
93-
y: self.density.1,
94-
},
95-
PixelDensityUnit::Centimeters => jpeg_encoder::Density::Centimeter {
96-
x: self.density.0,
97-
y: self.density.1,
98-
},
88+
fn to_encoder_repr(self) -> jpeg_encoder::PixelDensity {
89+
let unit = match self.unit {
90+
PixelDensityUnit::PixelAspectRatio => jpeg_encoder::PixelDensityUnit::PixelAspectRatio,
91+
PixelDensityUnit::Inches => jpeg_encoder::PixelDensityUnit::Inches,
92+
PixelDensityUnit::Centimeters => jpeg_encoder::PixelDensityUnit::Centimeters,
93+
};
94+
jpeg_encoder::PixelDensity {
95+
density: self.density,
96+
unit,
9997
}
10098
}
10199
}
@@ -238,11 +236,6 @@ impl<W: Write> JpegEncoder<W> {
238236
}
239237
}
240238

241-
// E x i f \0 \0
242-
/// The header for an EXIF APP1 segment
243-
const EXIF_HEADER: [u8; 6] = [0x45, 0x78, 0x69, 0x66, 0x00, 0x00];
244-
const APP1: u8 = 1;
245-
246239
impl<W: Write> ImageEncoder for JpegEncoder<W> {
247240
#[track_caller]
248241
fn write_image(
@@ -265,16 +258,12 @@ impl<W: Write> ImageEncoder for JpegEncoder<W> {
265258
}
266259

267260
fn set_exif_metadata(&mut self, exif: Vec<u8>) -> Result<(), UnsupportedError> {
268-
let mut formatted = EXIF_HEADER.to_vec();
269-
formatted.extend_from_slice(&exif);
270-
self.encoder
271-
.add_app_segment(APP1, &formatted)
272-
.map_err(|_| {
273-
UnsupportedError::from_format_and_kind(
274-
ImageFormat::Jpeg.into(),
275-
UnsupportedErrorKind::GenericFeature("Exif chunk too large".to_string()),
276-
)
277-
})?;
261+
self.encoder.add_exif_metadata(&exif).map_err(|_| {
262+
UnsupportedError::from_format_and_kind(
263+
ImageFormat::Jpeg.into(),
264+
UnsupportedErrorKind::GenericFeature("Exif chunk too large".to_string()),
265+
)
266+
})?;
278267
Ok(())
279268
}
280269

src/codecs/pnm/decoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ impl Sample for PbmBit {
786786

787787
fn bytelen(width: u32, height: u32, samples: u32) -> ImageResult<usize> {
788788
let count = width * samples;
789-
let linelen = (count / 8) + u32::from((count % 8) != 0);
789+
let linelen = (count / 8) + u32::from(!count.is_multiple_of(8));
790790
Ok((linelen * height) as usize)
791791
}
792792

src/imageops/fast_blur.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ fn boxes_for_gauss(sigma: f32, n: usize) -> Vec<usize> {
128128

129129
#[inline]
130130
fn ceil_to_odd(x: usize) -> usize {
131-
if x % 2 == 0 {
131+
if x.is_multiple_of(2) {
132132
x + 1
133133
} else {
134134
x

src/imageops/sample.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,7 @@ impl GaussianBlurParameters {
12011201
#[inline]
12021202
fn round_to_nearest_odd(x: f32) -> u32 {
12031203
let n = x.round() as u32;
1204-
if n % 2 != 0 {
1204+
if !n.is_multiple_of(2) {
12051205
n
12061206
} else {
12071207
let lower = n - 1;
@@ -1225,7 +1225,7 @@ impl GaussianBlurParameters {
12251225

12261226
fn kernel_size_from_sigma(sigma: f32) -> u32 {
12271227
let possible_size = (((((sigma - 0.8) / 0.3) + 1.) * 2.) + 1.).max(3.) as u32;
1228-
if possible_size % 2 == 0 {
1228+
if possible_size.is_multiple_of(2) {
12291229
return possible_size + 1;
12301230
}
12311231
possible_size

src/metadata/cicp.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,7 @@ impl CicpRgb {
11551155
{
11561156
use crate::traits::private::LayoutWithColor as Layout;
11571157

1158-
assert!(buffer.len() % from_layout.channels() == 0);
1158+
assert!(buffer.len().is_multiple_of(from_layout.channels()));
11591159
let pixels = buffer.len() / from_layout.channels();
11601160

11611161
let mut output: Vec<IntoSubpixel> = vec_try_with_capacity(pixels * into_layout.channels())

src/utils/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub(crate) fn expand_bits(bit_depth: u8, row_size: u32, buf: &[u8]) -> Vec<u8> {
4040
let mask = (1u8 << bit_depth as usize) - 1;
4141
let scaling_factor = 255 / ((1 << bit_depth as usize) - 1);
4242
let bit_width = row_size * u32::from(bit_depth);
43-
let skip = if bit_width % 8 == 0 {
43+
let skip = if bit_width.is_multiple_of(8) {
4444
0
4545
} else {
4646
(8 - bit_width % 8) / u32::from(bit_depth)

0 commit comments

Comments
 (0)