Skip to content

Commit 3dfb5f3

Browse files
authored
Optimize several predictor transforms (#95)
1 parent d61cc56 commit 3dfb5f3

File tree

1 file changed

+44
-13
lines changed

1 file changed

+44
-13
lines changed

src/lossless_transform.rs

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,12 @@ pub fn apply_predictor_transform_0(image_data: &mut [u8], range: Range<usize>, _
8282
}
8383
}
8484
pub fn apply_predictor_transform_1(image_data: &mut [u8], range: Range<usize>, _width: usize) {
85-
for i in range {
86-
image_data[i] = image_data[i].wrapping_add(image_data[i - 4]);
85+
let mut prev: [u8; 4] = image_data[range.start - 4..][..4].try_into().unwrap();
86+
for chunk in image_data[range].chunks_exact_mut(4) {
87+
for i in 0..4 {
88+
chunk[i] = chunk[i].wrapping_add(prev[i]);
89+
}
90+
prev.copy_from_slice(chunk);
8791
}
8892
}
8993
pub fn apply_predictor_transform_2(image_data: &mut [u8], range: Range<usize>, width: usize) {
@@ -102,23 +106,50 @@ pub fn apply_predictor_transform_4(image_data: &mut [u8], range: Range<usize>, w
102106
}
103107
}
104108
pub fn apply_predictor_transform_5(image_data: &mut [u8], range: Range<usize>, width: usize) {
105-
for i in range {
106-
image_data[i] = image_data[i].wrapping_add(average2(
107-
average2(image_data[i - 4], image_data[i - width * 4 + 4]),
108-
image_data[i - width * 4],
109-
));
109+
let (old, current) = image_data[..range.end].split_at_mut(range.start);
110+
111+
let mut prev: [u8; 4] = old[range.start - 4..][..4].try_into().unwrap();
112+
let top_right = &old[range.start - width * 4 + 4..];
113+
let top = &old[range.start - width * 4..];
114+
115+
for ((chunk, tr), t) in current
116+
.chunks_exact_mut(4)
117+
.zip(top_right.chunks_exact(4))
118+
.zip(top.chunks_exact(4))
119+
{
120+
prev = [
121+
chunk[0].wrapping_add(average2(average2(prev[0], tr[0]), t[0])),
122+
chunk[1].wrapping_add(average2(average2(prev[1], tr[1]), t[1])),
123+
chunk[2].wrapping_add(average2(average2(prev[2], tr[2]), t[2])),
124+
chunk[3].wrapping_add(average2(average2(prev[3], tr[3]), t[3])),
125+
];
126+
chunk.copy_from_slice(&prev);
110127
}
111128
}
112129
pub fn apply_predictor_transform_6(image_data: &mut [u8], range: Range<usize>, width: usize) {
113-
for i in range {
114-
image_data[i] =
115-
image_data[i].wrapping_add(average2(image_data[i - 4], image_data[i - width * 4 - 4]));
130+
let (old, current) = image_data[..range.end].split_at_mut(range.start);
131+
132+
let mut prev: [u8; 4] = old[range.start - 4..][..4].try_into().unwrap();
133+
let top_left = &old[range.start - width * 4 - 4..];
134+
135+
for (chunk, tl) in current.chunks_exact_mut(4).zip(top_left.chunks_exact(4)) {
136+
for i in 0..4 {
137+
chunk[i] = chunk[i].wrapping_add(average2(prev[i], tl[i]));
138+
}
139+
prev.copy_from_slice(chunk);
116140
}
117141
}
118142
pub fn apply_predictor_transform_7(image_data: &mut [u8], range: Range<usize>, width: usize) {
119-
for i in range {
120-
image_data[i] =
121-
image_data[i].wrapping_add(average2(image_data[i - 4], image_data[i - width * 4]));
143+
let (old, current) = image_data[..range.end].split_at_mut(range.start);
144+
145+
let mut prev: [u8; 4] = old[range.start - 4..][..4].try_into().unwrap();
146+
let top = &old[range.start - width * 4..];
147+
148+
for (chunk, t) in current.chunks_exact_mut(4).zip(top.chunks_exact(4)) {
149+
for i in 0..4 {
150+
chunk[i] = chunk[i].wrapping_add(average2(prev[i], t[i]));
151+
}
152+
prev.copy_from_slice(chunk);
122153
}
123154
}
124155
pub fn apply_predictor_transform_8(image_data: &mut [u8], range: Range<usize>, width: usize) {

0 commit comments

Comments
 (0)