Skip to main content

webp_animation/
webp_data.rs

1use std::{mem, ops::Deref, slice};
2
3use libwebp_sys as webp;
4
5/// A safe wrapper for WebP bytedata. Consider as `&[u8]` (implements [`Deref`])
6#[derive(Debug)]
7pub struct WebPData {
8    data: webp::WebPData,
9}
10
11impl WebPData {
12    pub(crate) fn new() -> Self {
13        let data = unsafe {
14            let mut data = mem::zeroed();
15            webp::WebPDataInit(&mut data);
16            data
17        };
18
19        WebPData { data }
20    }
21
22    pub(crate) fn inner_ref(&mut self) -> &mut webp::WebPData {
23        &mut self.data
24    }
25
26    fn as_slice(&self) -> &[u8] {
27        if self.data.bytes.is_null() {
28            &[]
29        } else {
30            unsafe { slice::from_raw_parts(self.data.bytes, self.data.size) }
31        }
32    }
33}
34
35/// SAFETY: Sending `WebPData` to another thread is safe until there is no way to share internal
36/// pointer without borrowing in safe code
37unsafe impl Send for WebPData {}
38
39/// SAFETY: Sharing `WebPData` via borrowing is safe until there is no way to share internal
40/// pointer without borrowing in safe code
41unsafe impl Sync for WebPData {}
42
43impl Drop for WebPData {
44    fn drop(&mut self) {
45        unsafe { libwebp_sys::WebPDataClear(self.inner_ref()) }
46    }
47}
48
49impl Deref for WebPData {
50    type Target = [u8];
51
52    fn deref(&self) -> &Self::Target {
53        self.as_slice()
54    }
55}
56
57impl AsRef<[u8]> for WebPData {
58    fn as_ref(&self) -> &[u8] {
59        self.as_slice()
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    #[test]
68    fn test_encoder() {
69        let data = WebPData::new();
70        assert_eq!(data.len(), 0);
71    }
72}