1use crate::{interop::RustWStream, prelude::*, Data, Pixmap};
2use skia_bindings::{SkJpegEncoder_AlphaOption, SkJpegEncoder_Downsample};
3use std::io;
4
5pub type AlphaOption = SkJpegEncoder_AlphaOption;
6variant_name!(AlphaOption::BlendOnBlack);
7
8#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
9pub enum Downsample {
10 BothDirections,
11 Horizontal,
12 No,
13}
14
15impl Downsample {
16 fn native(&self) -> SkJpegEncoder_Downsample {
17 match self {
18 Downsample::BothDirections => SkJpegEncoder_Downsample::k420,
19 Downsample::Horizontal => SkJpegEncoder_Downsample::k422,
20 Downsample::No => SkJpegEncoder_Downsample::k444,
21 }
22 }
23}
24
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub struct Options {
27 pub quality: u32,
28 pub downsample: Downsample,
29 pub alpha_option: AlphaOption,
30 pub xmp_metadata: Option<String>,
31 // TODO: ICCProfile
32 // TODO: ICCProfileDescription
33}
34
35impl Default for Options {
36 fn default() -> Self {
37 Self {
38 quality: 100,
39 downsample: Downsample::BothDirections,
40 alpha_option: AlphaOption::Ignore,
41 xmp_metadata: None,
42 }
43 }
44}
45
46pub fn encode<W: io::Write>(pixmap: &Pixmap, writer: &mut W, options: &Options) -> bool {
47 let xml_metadata: Option> = options.xmp_metadata.as_ref().map(Data::new_str);
48 let mut stream: RustWStream<'_> = RustWStream::new(writer);
49
50 unsafe {
51 skia_bindings::C_SkJpegEncoder_Encode(
52 stream.stream_mut(),
53 pixmap:pixmap.native(),
54 options.quality as _,
55 downsample:options.downsample.native(),
56 alphaOption:options.alpha_option,
57 xmpMetadata:xml_metadata.as_ref().native_ptr_or_null(),
58 )
59 }
60}
61
62// TODO: encode YUVAPixmaps
63
64pub fn encode_image<'a>(
65 context: impl Into<Option<&'a mut crate::gpu::DirectContext>>,
66 img: &crate::Image,
67 options: &Options,
68) -> Option<crate::Data> {
69 let xml_metadata: Option> = options.xmp_metadata.as_ref().map(Data::new_str);
70
71 Data::from_ptr(unsafe {
72 skia_bindings::C_SkJpegEncoder_EncodeImage(
73 ctx:context.into().native_ptr_or_null_mut(),
74 img:img.native(),
75 options.quality as _,
76 downsample:options.downsample.native(),
77 alphaOption:options.alpha_option,
78 xmpMetadata:xml_metadata.as_ref().native_ptr_or_null(),
79 )
80 })
81}
82
83// TODO: Make (Pixmap + SkYUVAPixmaps)
84