RazrFalcon / tiny-skia

A tiny Skia subset ported to Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.