Skip to content

Commit 15004d4

Browse files
lovasoa197g
authored andcommitted
Avoid large allocation in grayscale image decoding
We can work directly on the decoded image buffer instead of allocating a second one
1 parent 91cdd86 commit 15004d4

File tree

1 file changed

+13
-17
lines changed

1 file changed

+13
-17
lines changed

src/decoder.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -785,24 +785,20 @@ fn compute_image(components: &[Component],
785785

786786
// if the image width is a multiple of the block size,
787787
// then we don't have to move bytes in the decoded data
788-
if usize::from(output_size.width) == line_stride {
789-
// If the height of the image is not a multiple of the block size,
790-
// Then we have lines at the end that we don't need
791-
decoded.resize(size, 0); // We are in greyscale, 1 byte per pixel
792-
return Ok(decoded)
793-
}
794-
795-
let mut buffer = vec![0u8; size];
796-
797-
for y in 0..height {
798-
let destination_idx = y * width;
799-
let source_idx = y * line_stride;
800-
let destination = &mut buffer[destination_idx..][..width];
801-
let source = &decoded[source_idx..][..width];
802-
destination.copy_from_slice(source);
788+
if usize::from(output_size.width) != line_stride {
789+
let mut buffer = vec![0u8; width];
790+
// The first line already starts at index 0, so we need to move only lines 1..height
791+
for y in 1..height {
792+
let destination_idx = y * width;
793+
let source_idx = y * line_stride;
794+
// We could use copy_within, but we need to support old rust versions
795+
buffer.copy_from_slice(&decoded[source_idx..][..width]);
796+
let destination = &mut decoded[destination_idx..][..width];
797+
destination.copy_from_slice(&buffer);
798+
}
803799
}
804-
805-
Ok(buffer)
800+
decoded.resize(size, 0);
801+
Ok(decoded)
806802
}
807803
else {
808804
compute_image_parallel(components, data, output_size, is_jfif, color_transform)

0 commit comments

Comments
 (0)