Skip to content

Commit be74506

Browse files
committed
Ensure no copies when endianness matches system endianness
1 parent 2ac868a commit be74506

File tree

1 file changed

+44
-34
lines changed

1 file changed

+44
-34
lines changed

src/predictor.rs

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,11 @@ impl Unpredict for NoPredictor {
144144
_: u32,
145145
_: u32,
146146
) -> AsyncTiffResult<Bytes> {
147-
let mut res = BytesMut::from(buffer);
148-
fix_endianness(
149-
&mut res[..],
147+
Ok(fix_endianness(
148+
buffer,
150149
predictor_info.endianness,
151150
predictor_info.bits_per_sample,
152-
);
153-
Ok(res.into())
151+
))
154152
}
155153
}
156154

@@ -170,8 +168,8 @@ impl Unpredict for HorizontalPredictor {
170168
let samples = predictor_info.samples_per_pixel as usize;
171169
let bit_depth = predictor_info.bits_per_sample;
172170

171+
let buffer = fix_endianness(buffer, predictor_info.endianness, bit_depth);
173172
let mut res = BytesMut::from(buffer);
174-
fix_endianness(&mut res[..], predictor_info.endianness, bit_depth);
175173
for buf in res.chunks_mut(output_row_stride) {
176174
rev_hpredict_nsamp(buf, bit_depth, samples);
177175
}
@@ -221,33 +219,47 @@ pub fn rev_hpredict_nsamp(buf: &mut [u8], bit_depth: u16, samples: usize) {
221219
/// Fix endianness. If `byte_order` matches the host, then conversion is a no-op.
222220
///
223221
/// from image-tiff
224-
pub fn fix_endianness(buf: &mut [u8], byte_order: Endianness, bit_depth: u16) {
222+
pub fn fix_endianness(buffer: Bytes, byte_order: Endianness, bit_depth: u16) -> Bytes {
225223
match byte_order {
226-
Endianness::LittleEndian => match bit_depth {
227-
0..=8 => {}
228-
9..=16 => buf.chunks_exact_mut(2).for_each(|v| {
229-
v.copy_from_slice(&u16::from_le_bytes((*v).try_into().unwrap()).to_ne_bytes())
230-
}),
231-
17..=32 => buf.chunks_exact_mut(4).for_each(|v| {
232-
v.copy_from_slice(&u32::from_le_bytes((*v).try_into().unwrap()).to_ne_bytes())
233-
}),
234-
_ => buf.chunks_exact_mut(8).for_each(|v| {
235-
v.copy_from_slice(&u64::from_le_bytes((*v).try_into().unwrap()).to_ne_bytes())
236-
}),
237-
},
238-
Endianness::BigEndian => match bit_depth {
239-
0..=8 => {}
240-
9..=16 => buf.chunks_exact_mut(2).for_each(|v| {
241-
v.copy_from_slice(&u16::from_be_bytes((*v).try_into().unwrap()).to_ne_bytes())
242-
}),
243-
17..=32 => buf.chunks_exact_mut(4).for_each(|v| {
244-
v.copy_from_slice(&u32::from_be_bytes((*v).try_into().unwrap()).to_ne_bytes())
245-
}),
246-
_ => buf.chunks_exact_mut(8).for_each(|v| {
247-
v.copy_from_slice(&u64::from_be_bytes((*v).try_into().unwrap()).to_ne_bytes())
248-
}),
249-
},
250-
};
224+
#[cfg(target_endian = "little")]
225+
Endianness::LittleEndian => buffer,
226+
#[cfg(target_endian = "big")]
227+
Endianness::LittleEndian => {
228+
let mut buf = BytesMut::from(buffer);
229+
match bit_depth {
230+
0..=8 => {}
231+
9..=16 => buf.chunks_exact_mut(2).for_each(|v| {
232+
v.copy_from_slice(&u16::from_le_bytes((*v).try_into().unwrap()).to_ne_bytes())
233+
}),
234+
17..=32 => buf.chunks_exact_mut(4).for_each(|v| {
235+
v.copy_from_slice(&u32::from_le_bytes((*v).try_into().unwrap()).to_ne_bytes())
236+
}),
237+
_ => buf.chunks_exact_mut(8).for_each(|v| {
238+
v.copy_from_slice(&u64::from_le_bytes((*v).try_into().unwrap()).to_ne_bytes())
239+
}),
240+
}
241+
buf.freeze()
242+
}
243+
#[cfg(target_endian = "little")]
244+
Endianness::BigEndian => {
245+
let mut buf = BytesMut::from(buffer);
246+
match bit_depth {
247+
0..=8 => {}
248+
9..=16 => buf.chunks_exact_mut(2).for_each(|v| {
249+
v.copy_from_slice(&u16::from_be_bytes((*v).try_into().unwrap()).to_ne_bytes())
250+
}),
251+
17..=32 => buf.chunks_exact_mut(4).for_each(|v| {
252+
v.copy_from_slice(&u32::from_be_bytes((*v).try_into().unwrap()).to_ne_bytes())
253+
}),
254+
_ => buf.chunks_exact_mut(8).for_each(|v| {
255+
v.copy_from_slice(&u64::from_be_bytes((*v).try_into().unwrap()).to_ne_bytes())
256+
}),
257+
};
258+
buf.freeze()
259+
}
260+
#[cfg(target_endian = "big")]
261+
Endianness::BigEndian => buffer,
262+
}
251263
}
252264

253265
/// Floating point predictor
@@ -318,7 +330,6 @@ impl Unpredict for FloatingPointPredictor {
318330
/// floating point prediction first shuffles the bytes and then uses horizontal
319331
/// differencing
320332
/// also performs byte-order conversion if needed.
321-
///
322333
pub fn rev_predict_f16(input: &mut [u8], output: &mut [u8], samples: usize) {
323334
// reverse horizontal differencing
324335
for i in samples..input.len() {
@@ -339,7 +350,6 @@ pub fn rev_predict_f16(input: &mut [u8], output: &mut [u8], samples: usize) {
339350
/// floating point prediction first shuffles the bytes and then uses horizontal
340351
/// differencing
341352
/// also performs byte-order conversion if needed.
342-
///
343353
pub fn rev_predict_f32(input: &mut [u8], output: &mut [u8], samples: usize) {
344354
// reverse horizontal differencing
345355
for i in samples..input.len() {

0 commit comments

Comments
 (0)