skia_safe/encode_/
png_encoder.rs

1use std::io;
2
3use crate::{encode, interop::RustWStream, prelude::*, Pixmap};
4use skia_bindings as sb;
5
6bitflags! {
7    #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
8    pub struct FilterFlag: u32 {
9        const ZERO = sb::SkPngEncoder_FilterFlag::kZero as _;
10        const NONE = sb::SkPngEncoder_FilterFlag::kNone as _;
11        const SUB = sb::SkPngEncoder_FilterFlag::kSub as _;
12        const UP = sb::SkPngEncoder_FilterFlag::kUp as _;
13        const AVG = sb::SkPngEncoder_FilterFlag::kAvg as _;
14        const PAETH = sb::SkPngEncoder_FilterFlag::kPaeth as _;
15        const ALL = Self::NONE.bits() | Self::SUB.bits() | Self::UP.bits() | Self::AVG.bits() | Self::PAETH.bits();
16    }
17}
18native_transmutable!(sb::SkPngEncoder_FilterFlag, FilterFlag);
19
20#[derive(Debug, Clone, PartialEq, Eq)]
21#[non_exhaustive]
22pub struct Options {
23    pub filter_flags: FilterFlag,
24    pub z_lib_level: i32,
25    pub comments: Vec<encode::Comment>,
26    // TODO: fHdrMetadata
27    // TODO: If SkGainmapInfo get out of private/ : fGainmap fGainmapInfo
28}
29
30impl Default for Options {
31    fn default() -> Self {
32        Self {
33            filter_flags: FilterFlag::ALL,
34            z_lib_level: 6,
35            comments: vec![],
36        }
37    }
38}
39
40#[deprecated(since = "0.90.0", note = "use encode::Comment")]
41pub type Comment = encode::Comment;
42
43pub fn encode<W: io::Write>(pixmap: &Pixmap, writer: &mut W, options: &Options) -> bool {
44    let Some(comments) = encode::comments::to_data_table(&options.comments) else {
45        return false;
46    };
47
48    let mut stream = RustWStream::new(writer);
49
50    unsafe {
51        sb::C_SkPngEncoder_Encode(
52            stream.stream_mut(),
53            pixmap.native(),
54            comments.into_ptr(),
55            options.filter_flags.into_native(),
56            options.z_lib_level,
57        )
58    }
59}
60
61pub fn encode_pixmap(src: &Pixmap, options: &Options) -> Option<crate::Data> {
62    crate::Data::from_ptr(unsafe {
63        sb::C_SkPngEncoder_EncodePixmap(
64            src.native(),
65            encode::comments::to_data_table(&options.comments)?.into_ptr(),
66            options.filter_flags.into_native(),
67            options.z_lib_level,
68        )
69    })
70}
71
72pub fn encode_image<'a>(
73    context: impl Into<Option<&'a mut crate::gpu::DirectContext>>,
74    img: &crate::Image,
75    options: &Options,
76) -> Option<crate::Data> {
77    crate::Data::from_ptr(unsafe {
78        sb::C_SkPngEncoder_EncodeImage(
79            context.into().native_ptr_or_null_mut(),
80            img.native(),
81            encode::comments::to_data_table(&options.comments)?.into_ptr(),
82            options.filter_flags.into_native(),
83            options.z_lib_level,
84        )
85    })
86}
87
88// TODO: Make