into_png: Consume a Pixmap to write it to PNG without copying
Pr0methean opened this issue · comments
The TODO note in encode_png to eliminate the clone of the Pixmap can be addressed by adding a variant function that consumes self
. Here's an example I've implemented from the outside:
pub fn into_png(mut image: MaybeFromPool<Pixmap>) -> Result<Vec<u8>, png::EncodingError> {
for pixel in image.pixels_mut() {
unsafe {
// Treat this PremultipliedColorU8 slice as a ColorU8 slice
*pixel = mem::transmute(pixel.demultiply());
}
}
let mut data = Vec::with_capacity(1024 * 1024);
{
let mut encoder = png::Encoder::new(&mut data, image.width(), image.height());
encoder.set_color(png::ColorType::Rgba);
encoder.set_depth(png::BitDepth::Eight);
let mut writer = encoder.write_header()?;
writer.write_image_data(image.data())?;
}
Ok(data)
}
Hm... yes, we can add such function. But then Pixmap
cannot be used anymore.
We could also add mutating encode_png
variant, which would demultiply and multiply back. But I'm not sure if this could be done in a lossless way.
But then
Pixmap
cannot be used anymore.
That's more or less the point: it can be obtained with a method such as Arc::unwrap_or_clone
or Cow::into_owned
so that the question of whether to keep a copy for future use is separate from tiny-skia's responsibilities.