Skip to content

Commit 8b28f75

Browse files
authored
Merge pull request #2765 from okaneco/convert_to_as_chunks
Refactor: Convert `chunks_exact[_mut]` iterators to `as_chunks[_mut]` iterators
2 parents 49acf15 + e6dad12 commit 8b28f75

File tree

14 files changed

+128
-170
lines changed

14 files changed

+128
-170
lines changed

src/codecs/avif/decoder.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ fn reshape_plane(source: &[u8], stride: usize, width: usize, height: usize) -> V
170170
.chunks_exact_mut(width)
171171
.zip(source.chunks_exact(stride))
172172
{
173-
for (dst, src) in shaped_row.iter_mut().zip(src_row.chunks_exact(2)) {
174-
*dst = u16::from_ne_bytes([src[0], src[1]]);
173+
for (dst, src) in shaped_row.iter_mut().zip(src_row.as_chunks::<2>().0) {
174+
*dst = u16::from_ne_bytes(*src);
175175
}
176176
}
177177
target_plane
@@ -500,7 +500,7 @@ impl<R: Read> ImageDecoder for AvifDecoder<R> {
500500
buf.chunks_exact_mut(width as usize * 4),
501501
plane.as_ref().chunks_exact(stride),
502502
) {
503-
for (rgba, a_src) in buf.chunks_exact_mut(4).zip(slice) {
503+
for (rgba, a_src) in buf.as_chunks_mut::<4>().0.iter_mut().zip(slice) {
504504
rgba[3] = *a_src;
505505
}
506506
}
@@ -514,10 +514,9 @@ impl<R: Read> ImageDecoder for AvifDecoder<R> {
514514
// If buffer from Decoder is unaligned
515515
let mut aligned_store = vec![0u16; buf.len() / 2];
516516
self.process_16bit_picture(&mut aligned_store, yuv_range, matrix_strategy)?;
517-
for (dst, src) in buf.chunks_exact_mut(2).zip(aligned_store.iter()) {
518-
let bytes = src.to_ne_bytes();
519-
dst[0] = bytes[0];
520-
dst[1] = bytes[1];
517+
let buf_chunks = buf.as_chunks_mut::<2>().0.iter_mut();
518+
for (dst, src) in buf_chunks.zip(aligned_store.iter()) {
519+
*dst = src.to_ne_bytes();
521520
}
522521
}
523522
}
@@ -686,7 +685,7 @@ impl<R: Read> AvifDecoder<R> {
686685
target.chunks_exact_mut(width as usize * 4),
687686
a_plane_view.data.as_ref().chunks_exact(a_plane_view.stride),
688687
) {
689-
for (rgba, a_src) in buf.chunks_exact_mut(4).zip(slice) {
688+
for (rgba, a_src) in buf.as_chunks_mut::<4>().0.iter_mut().zip(slice) {
690689
rgba[3] = *a_src;
691690
}
692691
}

src/codecs/avif/ycgco.rs

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,14 @@ fn process_halved_chroma_row_cgco<
119119

120120
let bias_y = range.bias_y as i32;
121121
let bias_uv = range.bias_uv as i32;
122-
let y_iter = y_plane.chunks_exact(2);
123-
let rgb_chunks = rgba.chunks_exact_mut(CHANNELS * 2);
122+
let (y_iter, y_left) = y_plane.as_chunks::<2>();
123+
let mut rgb_chunks = rgba.chunks_exact_mut(CHANNELS * 2);
124124

125125
let scale_coef = ((max_value as f32 / range.range_y as f32) * (1 << PRECISION) as f32) as i32;
126126

127-
for (((y_src, &u_src), &v_src), rgb_dst) in y_iter.zip(u_plane).zip(v_plane).zip(rgb_chunks) {
127+
for (((y_src, &u_src), &v_src), rgb_dst) in
128+
y_iter.iter().zip(u_plane).zip(v_plane).zip(&mut rgb_chunks)
129+
{
128130
let y_value0: i32 = y_src[0].as_() - bias_y;
129131
let cg_value: i32 = u_src.as_() - bias_uv;
130132
let co_value: i32 = v_src.as_() - bias_uv;
@@ -154,11 +156,11 @@ fn process_halved_chroma_row_cgco<
154156

155157
// Process remainder if width is odd.
156158
if image.width & 1 != 0 {
157-
let y_left = y_plane.chunks_exact(2).remainder();
158-
let rgb_chunks = rgba
159-
.chunks_exact_mut(CHANNELS * 2)
159+
let rgb_chunks = rgb_chunks
160160
.into_remainder()
161-
.chunks_exact_mut(CHANNELS);
161+
.as_chunks_mut::<CHANNELS>()
162+
.0
163+
.iter_mut();
162164
let u_iter = u_plane.iter().rev();
163165
let v_iter = v_plane.iter().rev();
164166

@@ -170,11 +172,7 @@ fn process_halved_chroma_row_cgco<
170172
let co_value = v_src.as_() - bias_uv;
171173

172174
ycgco_execute_limited::<V, PRECISION, CHANNELS, BIT_DEPTH>(
173-
rgb_dst.try_into().unwrap(),
174-
y_value,
175-
cg_value,
176-
co_value,
177-
scale_coef,
175+
rgb_dst, y_value, cg_value, co_value, scale_coef,
178176
);
179177
}
180178
}
@@ -249,7 +247,7 @@ where
249247

250248
// All branches on generic const will be optimized out.
251249
for (((y_src, u_src), v_src), rgb) in y_iter.zip(u_iter).zip(v_iter).zip(rgb_iter) {
252-
let rgb_chunks = rgb.chunks_exact_mut(CHANNELS);
250+
let rgb_chunks = rgb.as_chunks_mut::<CHANNELS>().0.iter_mut();
253251
match yuv_range {
254252
YuvIntensityRange::Tv => {
255253
let y_coef =
@@ -262,11 +260,7 @@ where
262260
let co_value = v_src.as_() - bias_uv;
263261

264262
ycgco_execute_limited::<V, PRECISION, CHANNELS, BIT_DEPTH>(
265-
rgb_dst.try_into().unwrap(),
266-
y_value,
267-
cg_value,
268-
co_value,
269-
y_coef,
263+
rgb_dst, y_value, cg_value, co_value, y_coef,
270264
);
271265
}
272266
}
@@ -279,10 +273,7 @@ where
279273
let co_value = v_src.as_() - bias_uv;
280274

281275
ycgco_execute_full::<V, PRECISION, CHANNELS, BIT_DEPTH>(
282-
rgb_dst.try_into().unwrap(),
283-
y_value,
284-
cg_value,
285-
co_value,
276+
rgb_dst, y_value, cg_value, co_value,
286277
);
287278
}
288279
}

src/codecs/avif/yuv.rs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ where
367367

368368
// All branches on generic const will be optimized out.
369369
for (y_src, rgb) in y_iter.zip(rgb_iter) {
370-
let rgb_chunks = rgb.chunks_exact_mut(CHANNELS);
370+
let rgb_chunks = rgb.as_chunks_mut::<CHANNELS>().0.iter_mut();
371371

372372
for (y_src, rgb_dst) in y_src.iter().zip(rgb_chunks) {
373373
let r = *y_src;
@@ -403,7 +403,7 @@ where
403403

404404
// All branches on generic const will be optimized out.
405405
for (y_src, rgb) in y_iter.zip(rgb_iter) {
406-
let rgb_chunks = rgb.chunks_exact_mut(CHANNELS);
406+
let rgb_chunks = rgb.as_chunks_mut::<CHANNELS>().0.iter_mut();
407407

408408
for (y_src, rgb_dst) in y_src.iter().zip(rgb_chunks) {
409409
let y_value = (y_src.as_() - bias_y) * y_coef;
@@ -567,9 +567,11 @@ fn process_halved_chroma_row_cbcr<
567567

568568
let bias_y = range.bias_y as i32;
569569
let bias_uv = range.bias_uv as i32;
570-
let y_iter = y_plane.chunks_exact(2);
571-
let rgb_chunks = rgba.chunks_exact_mut(CHANNELS * 2);
572-
for (((y_src, &u_src), &v_src), rgb_dst) in y_iter.zip(u_plane).zip(v_plane).zip(rgb_chunks) {
570+
let (y_iter, y_left) = y_plane.as_chunks::<2>();
571+
let mut rgb_chunks = rgba.chunks_exact_mut(CHANNELS * 2);
572+
for (((y_src, &u_src), &v_src), rgb_dst) in
573+
y_iter.iter().zip(u_plane).zip(v_plane).zip(&mut rgb_chunks)
574+
{
573575
let y_value0: i32 = y_src[0].as_() - bias_y;
574576
let cb_value: i32 = u_src.as_() - bias_uv;
575577
let cr_value: i32 = v_src.as_() - bias_uv;
@@ -599,11 +601,11 @@ fn process_halved_chroma_row_cbcr<
599601

600602
// Process remainder if width is odd.
601603
if image.width & 1 != 0 {
602-
let y_left = y_plane.chunks_exact(2).remainder();
603-
let rgb_chunks = rgba
604-
.chunks_exact_mut(CHANNELS * 2)
604+
let rgb_chunks = rgb_chunks
605605
.into_remainder()
606-
.chunks_exact_mut(CHANNELS);
606+
.as_chunks_mut::<CHANNELS>()
607+
.0
608+
.iter_mut();
607609
let u_iter = u_plane.iter().rev();
608610
let v_iter = v_plane.iter().rev();
609611

@@ -615,11 +617,7 @@ fn process_halved_chroma_row_cbcr<
615617
let cr_value = v_src.as_() - bias_uv;
616618

617619
ycbcr_execute::<V, PRECISION, CHANNELS, BIT_DEPTH>(
618-
rgb_dst.try_into().unwrap(),
619-
y_value,
620-
cb_value,
621-
cr_value,
622-
transform,
620+
rgb_dst, y_value, cb_value, cr_value, transform,
623621
);
624622
}
625623
}
@@ -1098,7 +1096,7 @@ where
10981096

10991097
// All branches on generic const will be optimized out.
11001098
for (((y_src, u_src), v_src), rgb) in y_iter.zip(u_iter).zip(v_iter).zip(rgb_iter) {
1101-
let rgb_chunks = rgb.chunks_exact_mut(CHANNELS);
1099+
let rgb_chunks = rgb.as_chunks_mut::<CHANNELS>().0.iter_mut();
11021100

11031101
for (((y_src, u_src), v_src), rgb_dst) in y_src.iter().zip(u_src).zip(v_src).zip(rgb_chunks)
11041102
{
@@ -1107,7 +1105,7 @@ where
11071105
let cr_value = v_src.as_() - bias_uv;
11081106

11091107
ycbcr_execute::<V, PRECISION, CHANNELS, BIT_DEPTH>(
1110-
rgb_dst.try_into().unwrap(),
1108+
rgb_dst,
11111109
y_value,
11121110
cb_value,
11131111
cr_value,
@@ -1240,7 +1238,7 @@ where
12401238
let y_bias = range.bias_y as i32;
12411239

12421240
for (((y_src, u_src), v_src), rgb) in y_iter.zip(u_iter).zip(v_iter).zip(rgb_iter) {
1243-
let rgb_chunks = rgb.chunks_exact_mut(CHANNELS);
1241+
let rgb_chunks = rgb.as_chunks_mut::<CHANNELS>().0.iter_mut();
12441242

12451243
for (((&y_src, &u_src), &v_src), rgb_dst) in
12461244
y_src.iter().zip(u_src).zip(v_src).zip(rgb_chunks)
@@ -1259,7 +1257,7 @@ where
12591257
}
12601258
YuvIntensityRange::Pc => {
12611259
for (((y_src, u_src), v_src), rgb) in y_iter.zip(u_iter).zip(v_iter).zip(rgb_iter) {
1262-
let rgb_chunks = rgb.chunks_exact_mut(CHANNELS);
1260+
let rgb_chunks = rgb.as_chunks_mut::<CHANNELS>().0.iter_mut();
12631261

12641262
for (((&y_src, &u_src), &v_src), rgb_dst) in
12651263
y_src.iter().zip(u_src).zip(v_src).zip(rgb_chunks)

src/codecs/bmp/decoder.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,7 +1567,10 @@ impl<R: BufRead + Seek> BmpDecoder<R> {
15671567

15681568
// Set alpha to opaque for all pixels if needed (only on first call)
15691569
if start_row == 0 && num_channels == 4 {
1570-
buf.chunks_exact_mut(4).for_each(|c| c[3] = ALPHA_OPAQUE);
1570+
buf.as_chunks_mut::<4>()
1571+
.0
1572+
.iter_mut()
1573+
.for_each(|c| c[3] = ALPHA_OPAQUE);
15711574
}
15721575

15731576
let reader = &mut self.reader;
@@ -1643,11 +1646,10 @@ impl<R: BufRead + Seek> BmpDecoder<R> {
16431646
start_row,
16441647
|row| {
16451648
reader.read_exact(&mut row_buffer)?;
1646-
for (row_data, pixel) in row_buffer
1647-
.chunks_exact(2)
1648-
.zip(row.chunks_exact_mut(num_channels))
1649+
let row_buffer_chunks = row_buffer.as_chunks::<2>().0.iter();
1650+
for (&row_data, pixel) in row_buffer_chunks.zip(row.chunks_exact_mut(num_channels))
16491651
{
1650-
let data = u32::from(u16::from_le_bytes(row_data.try_into().unwrap()));
1652+
let data = u32::from(u16::from_le_bytes(row_data));
16511653
pixel[0] = bitfields.r.read(data);
16521654
pixel[1] = bitfields.g.read(data);
16531655
pixel[2] = bitfields.b.read(data);
@@ -1694,11 +1696,10 @@ impl<R: BufRead + Seek> BmpDecoder<R> {
16941696
start_row,
16951697
|row| {
16961698
reader.read_exact(&mut row_buffer)?;
1697-
for (row_data, pixel) in row_buffer
1698-
.chunks_exact(4)
1699-
.zip(row.chunks_exact_mut(num_channels))
1699+
let row_buffer_chunks = row_buffer.as_chunks::<4>().0.iter();
1700+
for (&row_data, pixel) in row_buffer_chunks.zip(row.chunks_exact_mut(num_channels))
17001701
{
1701-
let data = u32::from_le_bytes(row_data.try_into().unwrap());
1702+
let data = u32::from_le_bytes(row_data);
17021703
pixel[0] = bitfields.r.read(data);
17031704
pixel[1] = bitfields.g.read(data);
17041705
pixel[2] = bitfields.b.read(data);

src/codecs/farbfeld.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl<R: Read> Read for FarbfeldReader<R> {
9999
bytes_written += 1;
100100
self.current_offset += 1;
101101
} else {
102-
for channel_out in buf.chunks_exact_mut(2) {
102+
for channel_out in buf.as_chunks_mut::<2>().0 {
103103
consume_channel(&mut self.inner, channel_out)?;
104104
bytes_written += 2;
105105
self.current_offset += 2;
@@ -165,10 +165,10 @@ impl<R: Read + Seek> Seek for FarbfeldReader<R> {
165165
}
166166
}
167167

168-
fn consume_channel<R: Read>(from: &mut R, mut to: &mut [u8]) -> io::Result<()> {
168+
fn consume_channel<R: Read>(from: &mut R, to: &mut [u8; 2]) -> io::Result<()> {
169169
let mut ibuf = [0u8; 2];
170170
from.read_exact(&mut ibuf)?;
171-
to.write_all(&u16::from_be_bytes(ibuf).to_ne_bytes())?;
171+
to.copy_from_slice(&u16::from_be_bytes(ibuf).to_ne_bytes());
172172

173173
Ok(())
174174
}
@@ -249,9 +249,9 @@ impl<W: Write> FarbfeldEncoder<W> {
249249
self.w.write_all(&width.to_be_bytes())?;
250250
self.w.write_all(&height.to_be_bytes())?;
251251

252-
for channel in data.chunks_exact(2) {
252+
for &channel in data.as_chunks::<2>().0 {
253253
self.w
254-
.write_all(&u16::from_ne_bytes(channel.try_into().unwrap()).to_be_bytes())?;
254+
.write_all(&u16::from_ne_bytes(channel).to_be_bytes())?;
255255
}
256256

257257
Ok(())

src/codecs/hdr/decoder.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,8 @@ impl<R: Read> ImageDecoder for HdrDecoder<R> {
295295
// read_scanline overwrites the entire buffer or returns an Err,
296296
// so not resetting the buffer here is ok.
297297
read_scanline(&mut self.r, &mut scanline[..])?;
298-
for (dst, &pix) in chunk.chunks_exact_mut(PIXEL_SIZE).zip(scanline.iter()) {
298+
let dst_chunks = chunk.as_chunks_mut::<PIXEL_SIZE>().0.iter_mut();
299+
for (dst, &pix) in dst_chunks.zip(scanline.iter()) {
299300
dst.copy_from_slice(bytemuck::cast_slice(&pix.to_hdr().0));
300301
}
301302
}

src/codecs/png.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,6 @@ impl<R: BufRead + Seek> ImageDecoder for PngDecoder<R> {
270270
}
271271

272272
fn read_image(mut self, buf: &mut [u8]) -> ImageResult<()> {
273-
use byteorder_lite::{BigEndian, ByteOrder, NativeEndian};
274-
275273
assert_eq!(u64::try_from(buf.len()), Ok(self.total_bytes()));
276274
self.reader.next_frame(buf).map_err(ImageError::from_png)?;
277275
// PNG images are big endian. For 16 bit per channel and larger types,
@@ -282,9 +280,8 @@ impl<R: BufRead + Seek> ImageDecoder for PngDecoder<R> {
282280

283281
match bpc {
284282
1 => (), // No reodering necessary for u8
285-
2 => buf.chunks_exact_mut(2).for_each(|c| {
286-
let v = BigEndian::read_u16(c);
287-
NativeEndian::write_u16(c, v);
283+
2 => buf.as_chunks_mut::<2>().0.iter_mut().for_each(|c| {
284+
*c = u16::from_be_bytes(*c).to_ne_bytes();
288285
}),
289286
_ => unreachable!(),
290287
}
@@ -800,7 +797,7 @@ impl<W: Write> ImageEncoder for PngEncoder<W> {
800797
let mut reordered;
801798
let buf = if cfg!(target_endian = "little") {
802799
reordered = vec_try_with_capacity(buf.len())?;
803-
reordered.extend(buf.chunks_exact(2).flat_map(|le| [le[1], le[0]]));
800+
reordered.extend(buf.as_chunks::<2>().0.iter().flat_map(|le| [le[1], le[0]]));
804801
&reordered
805802
} else {
806803
buf

src/codecs/pnm/decoder.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ use crate::error::{
1414
use crate::io::ReadExt;
1515
use crate::{utils, ImageDecoder, ImageFormat};
1616

17-
use byteorder_lite::{BigEndian, ByteOrder, NativeEndian};
18-
1917
/// All errors that can occur when attempting to parse a PNM
2018
#[derive(Debug, Clone)]
2119
enum DecoderError {
@@ -689,9 +687,9 @@ impl<R: Read> PnmDecoder<R> {
689687
*v = (f32::from(*v) * factor).round() as u8;
690688
}
691689
} else if S::sample_size() == 2 {
692-
for chunk in buf.chunks_exact_mut(2) {
693-
let v = NativeEndian::read_u16(chunk);
694-
NativeEndian::write_u16(chunk, (f32::from(v) * factor).round() as u16);
690+
for chunk in buf.as_chunks_mut::<2>().0.iter_mut() {
691+
let v = (f32::from(u16::from_ne_bytes(*chunk)) * factor).round() as u16;
692+
chunk.copy_from_slice(&v.to_ne_bytes());
695693
}
696694
}
697695
}
@@ -762,17 +760,17 @@ impl Sample for U16 {
762760

763761
fn from_bytes(bytes: &[u8], _row_size: usize, output_buf: &mut [u8]) -> ImageResult<()> {
764762
output_buf.copy_from_slice(bytes);
765-
for chunk in output_buf.chunks_exact_mut(2) {
766-
let v = BigEndian::read_u16(chunk);
767-
NativeEndian::write_u16(chunk, v);
763+
for chunk in output_buf.as_chunks_mut::<2>().0.iter_mut() {
764+
let v = u16::from_be_bytes(*chunk);
765+
chunk.copy_from_slice(&v.to_ne_bytes());
768766
}
769767
Ok(())
770768
}
771769

772770
fn from_ascii(reader: &mut dyn Read, output_buf: &mut [u8]) -> ImageResult<()> {
773-
for chunk in output_buf.chunks_exact_mut(2) {
771+
for chunk in output_buf.as_chunks_mut::<2>().0.iter_mut() {
774772
let v = read_separated_ascii::<u16>(reader)?;
775-
NativeEndian::write_u16(chunk, v);
773+
chunk.copy_from_slice(&v.to_ne_bytes());
776774
}
777775
Ok(())
778776
}

0 commit comments

Comments
 (0)