1 use std::os::raw::*;
2 
3 cfg_if! {
4     if #[cfg(feature = "1_1")] {
5         pub const WEBP_ENCODER_ABI_VERSION: c_int = 0x020F;
6     } else if #[cfg(feature = "0_6")] {
7         pub const WEBP_ENCODER_ABI_VERSION: c_int = 0x020E;
8     } else if #[cfg(feature = "0_5")] {
9         pub const WEBP_ENCODER_ABI_VERSION: c_int = 0x0209;
10     } else {
11         pub const WEBP_ENCODER_ABI_VERSION: c_int = 0x0202;
12     }
13 }
14 
15 #[allow(non_camel_case_types)]
16 pub type WebPImageHint = u32;
17 
18 pub const WEBP_HINT_DEFAULT: WebPImageHint = 0;
19 pub const WEBP_HINT_PICTURE: WebPImageHint = 1;
20 pub const WEBP_HINT_PHOTO: WebPImageHint = 2;
21 pub const WEBP_HINT_GRAPH: WebPImageHint = 3;
22 pub const WEBP_HINT_LAST: WebPImageHint = 4;
23 
24 #[allow(non_snake_case)]
25 #[repr(C)]
26 #[derive(Debug, Clone, Copy)]
27 pub struct WebPConfig {
28     pub lossless: c_int,
29     pub quality: c_float,
30     pub method: c_int,
31     pub image_hint: WebPImageHint,
32     pub target_size: c_int,
33     pub target_PSNR: c_float,
34     pub segments: c_int,
35     pub sns_strength: c_int,
36     pub filter_strength: c_int,
37     pub filter_sharpness: c_int,
38     pub filter_type: c_int,
39     pub autofilter: c_int,
40     pub alpha_compression: c_int,
41     pub alpha_filtering: c_int,
42     pub alpha_quality: c_int,
43     pub pass: c_int,
44     pub show_compressed: c_int,
45     pub preprocessing: c_int,
46     pub partitions: c_int,
47     pub partition_limit: c_int,
48     pub emulate_jpeg_size: c_int,
49     pub thread_level: c_int,
50     pub low_memory: c_int,
51     #[cfg(feature = "0_5")]
52     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "0_5")))]
53     pub near_lossless: c_int,
54     #[cfg(feature = "0_5")]
55     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "0_5")))]
56     pub exact: c_int,
57     #[cfg(feature = "0_6")]
58     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "0_6")))]
59     pub use_delta_palette: c_int,
60     #[cfg(feature = "0_6")]
61     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "0_6")))]
62     pub use_sharp_yuv: c_int,
63     #[cfg(feature = "1_2")]
64     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "1_2")))]
65     pub qmin: c_int,
66     #[cfg(feature = "1_2")]
67     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "1_2")))]
68     pub qmax: c_int,
69     #[cfg(not(feature = "0_5"))]
70     #[doc(hidden)]
71     pub pad: [u32; 5],
72     #[cfg(all(feature = "0_5", not(feature = "0_6")))]
73     #[doc(hidden)]
74     pub pad: [u32; 3],
75     #[cfg(all(feature = "0_6", not(feature = "1_2")))]
76     #[doc(hidden)]
77     pub pad: [u32; 2],
78 }
79 
80 #[allow(non_camel_case_types)]
81 pub type WebPPreset = u32;
82 
83 pub const WEBP_PRESET_DEFAULT: WebPPreset = 0;
84 pub const WEBP_PRESET_PICTURE: WebPPreset = 1;
85 pub const WEBP_PRESET_PHOTO: WebPPreset = 2;
86 pub const WEBP_PRESET_DRAWING: WebPPreset = 3;
87 pub const WEBP_PRESET_ICON: WebPPreset = 4;
88 pub const WEBP_PRESET_TEXT: WebPPreset = 5;
89 
90 #[allow(non_snake_case)]
91 #[repr(C)]
92 #[derive(Debug, Clone, Copy)]
93 pub struct WebPAuxStats {
94     pub coded_size: c_int,
95     pub PSNR: [c_float; 5],
96     pub block_count: [c_int; 3],
97     pub header_bytes: [c_int; 2],
98     pub residual_bytes: [[c_int; 4]; 3],
99     pub segment_size: [c_int; 4],
100     pub segment_quant: [c_int; 4],
101     pub segment_level: [c_int; 4],
102     pub alpha_data_size: c_int,
103     pub layer_data_size: c_int,
104     pub lossless_features: u32,
105     pub histogram_bits: c_int,
106     pub transform_bits: c_int,
107     pub cache_bits: c_int,
108     pub palette_size: c_int,
109     pub lossless_size: c_int,
110     #[cfg(feature = "0_5")]
111     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "0_5")))]
112     pub lossless_hdr_size: c_int,
113     #[cfg(feature = "0_5")]
114     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "0_5")))]
115     pub lossless_data_size: c_int,
116     #[cfg(not(feature = "0_5"))]
117     #[doc(hidden)]
118     pub pad: [u32; 4],
119     #[cfg(feature = "0_5")]
120     #[doc(hidden)]
121     pub pad: [u32; 2],
122 }
123 
124 pub type WebPWriterFunction = Option<extern "C" fn(*const u8, usize, *const WebPPicture) -> c_int>;
125 
126 pub type WebPProgressHook = Option<extern "C" fn(c_int, *const WebPPicture) -> c_int>;
127 
128 #[allow(non_camel_case_types)]
129 pub type WebPEncCSP = u32;
130 
131 pub const WEBP_YUV420: WebPEncCSP = 0;
132 pub const WEBP_YUV420A: WebPEncCSP = 4;
133 
134 pub const WEBP_CSP_UV_MASK: WebPEncCSP = 3;
135 pub const WEBP_CSP_ALPHA_BIT: WebPEncCSP = 4;
136 
137 #[allow(non_camel_case_types)]
138 pub type WebPEncodingError = u32;
139 
140 pub const VP8_ENC_OK: WebPEncodingError = 0;
141 pub const VP8_ENC_ERROR_OUT_OF_MEMORY: WebPEncodingError = 1;
142 pub const VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: WebPEncodingError = 2;
143 pub const VP8_ENC_ERROR_NULL_PARAMETER: WebPEncodingError = 3;
144 pub const VP8_ENC_ERROR_INVALID_CONFIGURATION: WebPEncodingError = 4;
145 pub const VP8_ENC_ERROR_BAD_DIMENSION: WebPEncodingError = 5;
146 pub const VP8_ENC_ERROR_PARTITION0_OVERFLOW: WebPEncodingError = 6;
147 pub const VP8_ENC_ERROR_PARTITION_OVERFLOW: WebPEncodingError = 7;
148 pub const VP8_ENC_ERROR_BAD_WRITE: WebPEncodingError = 8;
149 pub const VP8_ENC_ERROR_FILE_TOO_BIG: WebPEncodingError = 9;
150 pub const VP8_ENC_ERROR_USER_ABORT: WebPEncodingError = 10;
151 pub const VP8_ENC_ERROR_LAST: WebPEncodingError = 11;
152 
153 #[repr(C)]
154 #[derive(Debug, Clone, Copy)]
155 pub struct WebPMemoryWriter {
156     pub mem: *mut u8,
157     pub size: usize,
158     pub max_size: usize,
159     #[doc(hidden)]
160     pub pad: [u32; 1],
161 }
162 
163 pub const WEBP_MAX_DIMENSION: c_int = 16383;
164 
165 #[repr(C)]
166 #[derive(Debug, Clone, Copy)]
167 pub struct WebPPicture {
168     pub use_argb: c_int,
169     pub colorspace: WebPEncCSP,
170     pub width: c_int,
171     pub height: c_int,
172     pub y: *mut u8,
173     pub u: *mut u8,
174     pub v: *mut u8,
175     pub y_stride: c_int,
176     pub uv_stride: c_int,
177     pub a: *mut u8,
178     pub a_stride: c_int,
179     #[doc(hidden)]
180     pub pad1: [u32; 2],
181     pub argb: *mut u32,
182     pub argb_stride: c_int,
183     #[doc(hidden)]
184     pub pad2: [u32; 3],
185     pub writer: WebPWriterFunction,
186     pub custom_ptr: *mut c_void,
187     pub extra_info_type: c_int,
188     pub extra_info: *mut u8,
189     pub stats: *mut WebPAuxStats,
190     pub error_code: WebPEncodingError,
191     pub progress_hook: WebPProgressHook,
192     pub user_data: *mut c_void,
193     #[doc(hidden)]
194     pub pad3: [u32; 3],
195     #[doc(hidden)]
196     pub pad4: *mut u8,
197     #[doc(hidden)]
198     pub pad5: *mut u8,
199     #[doc(hidden)]
200     pub pad6: [u32; 8],
201     // PRIVATE FIELDS
202     #[doc(hidden)]
203     pub memory_: *mut c_void,
204     #[doc(hidden)]
205     pub memory_argb_: *mut c_void,
206     #[doc(hidden)]
207     pub pad7: [*mut c_void; 2],
208 }
209 
210 extern "C" {
WebPGetEncoderVersion() -> c_int211     pub fn WebPGetEncoderVersion() -> c_int;
WebPEncodeRGB( rgb: *const u8, width: c_int, height: c_int, stride: c_int, quality_factor: c_float, output: *mut *mut u8, ) -> usize212     pub fn WebPEncodeRGB(
213         rgb: *const u8,
214         width: c_int,
215         height: c_int,
216         stride: c_int,
217         quality_factor: c_float,
218         output: *mut *mut u8,
219     ) -> usize;
WebPEncodeBGR( bgr: *const u8, width: c_int, height: c_int, stride: c_int, quality_factor: c_float, output: *mut *mut u8, ) -> usize220     pub fn WebPEncodeBGR(
221         bgr: *const u8,
222         width: c_int,
223         height: c_int,
224         stride: c_int,
225         quality_factor: c_float,
226         output: *mut *mut u8,
227     ) -> usize;
WebPEncodeRGBA( rgba: *const u8, width: c_int, height: c_int, stride: c_int, quality_factor: c_float, output: *mut *mut u8, ) -> usize228     pub fn WebPEncodeRGBA(
229         rgba: *const u8,
230         width: c_int,
231         height: c_int,
232         stride: c_int,
233         quality_factor: c_float,
234         output: *mut *mut u8,
235     ) -> usize;
WebPEncodeBGRA( bgra: *const u8, width: c_int, height: c_int, stride: c_int, quality_factor: c_float, output: *mut *mut u8, ) -> usize236     pub fn WebPEncodeBGRA(
237         bgra: *const u8,
238         width: c_int,
239         height: c_int,
240         stride: c_int,
241         quality_factor: c_float,
242         output: *mut *mut u8,
243     ) -> usize;
WebPEncodeLosslessRGB( rgb: *const u8, width: c_int, height: c_int, stride: c_int, output: *mut *mut u8, ) -> usize244     pub fn WebPEncodeLosslessRGB(
245         rgb: *const u8,
246         width: c_int,
247         height: c_int,
248         stride: c_int,
249         output: *mut *mut u8,
250     ) -> usize;
WebPEncodeLosslessBGR( bgr: *const u8, width: c_int, height: c_int, stride: c_int, output: *mut *mut u8, ) -> usize251     pub fn WebPEncodeLosslessBGR(
252         bgr: *const u8,
253         width: c_int,
254         height: c_int,
255         stride: c_int,
256         output: *mut *mut u8,
257     ) -> usize;
WebPEncodeLosslessRGBA( rgba: *const u8, width: c_int, height: c_int, stride: c_int, output: *mut *mut u8, ) -> usize258     pub fn WebPEncodeLosslessRGBA(
259         rgba: *const u8,
260         width: c_int,
261         height: c_int,
262         stride: c_int,
263         output: *mut *mut u8,
264     ) -> usize;
WebPEncodeLosslessBGRA( bgra: *const u8, width: c_int, height: c_int, stride: c_int, output: *mut *mut u8, ) -> usize265     pub fn WebPEncodeLosslessBGRA(
266         bgra: *const u8,
267         width: c_int,
268         height: c_int,
269         stride: c_int,
270         output: *mut *mut u8,
271     ) -> usize;
272     #[doc(hidden)]
WebPConfigInitInternal(_: *mut WebPConfig, _: WebPPreset, _: c_float, _: c_int) -> c_int273     pub fn WebPConfigInitInternal(_: *mut WebPConfig, _: WebPPreset, _: c_float, _: c_int)
274         -> c_int;
275     #[cfg(feature = "0_5")]
276     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "0_5")))]
WebPConfigLosslessPreset(config: *mut WebPConfig, level: c_int) -> c_int277     pub fn WebPConfigLosslessPreset(config: *mut WebPConfig, level: c_int) -> c_int;
WebPValidateConfig(config: *const WebPConfig) -> c_int278     pub fn WebPValidateConfig(config: *const WebPConfig) -> c_int;
WebPMemoryWriterInit(writer: *mut WebPMemoryWriter)279     pub fn WebPMemoryWriterInit(writer: *mut WebPMemoryWriter);
280     #[cfg(feature = "0_5")]
281     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "0_5")))]
WebPMemoryWriterClear(writer: *mut WebPMemoryWriter)282     pub fn WebPMemoryWriterClear(writer: *mut WebPMemoryWriter);
WebPMemoryWrite(data: *const u8, data_size: usize, picture: *const WebPPicture) -> c_int283     pub fn WebPMemoryWrite(data: *const u8, data_size: usize, picture: *const WebPPicture)
284         -> c_int;
285     #[doc(hidden)]
WebPPictureInitInternal(_: *mut WebPPicture, _: c_int) -> c_int286     pub fn WebPPictureInitInternal(_: *mut WebPPicture, _: c_int) -> c_int;
WebPPictureAlloc(picture: *mut WebPPicture) -> c_int287     pub fn WebPPictureAlloc(picture: *mut WebPPicture) -> c_int;
WebPPictureFree(picture: *mut WebPPicture)288     pub fn WebPPictureFree(picture: *mut WebPPicture);
WebPPictureCopy(src: *const WebPPicture, dst: *mut WebPPicture) -> c_int289     pub fn WebPPictureCopy(src: *const WebPPicture, dst: *mut WebPPicture) -> c_int;
290     #[cfg(feature = "0_6")]
291     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "0_6")))]
WebPPlaneDistortion( src: *const u8, src_stride: usize, ref_: *const u8, ref_stride: usize, width: c_int, height: c_int, x_step: usize, type_: c_int, distortion: *mut c_float, result: *mut c_float, ) -> c_int292     pub fn WebPPlaneDistortion(
293         src: *const u8,
294         src_stride: usize,
295         ref_: *const u8,
296         ref_stride: usize,
297         width: c_int,
298         height: c_int,
299         x_step: usize,
300         type_: c_int,
301         distortion: *mut c_float,
302         result: *mut c_float,
303     ) -> c_int;
WebPPictureDistortion( src: *const WebPPicture, ref_: *const WebPPicture, metric_type: c_int, result: *mut c_float, ) -> c_int304     pub fn WebPPictureDistortion(
305         src: *const WebPPicture,
306         ref_: *const WebPPicture,
307         metric_type: c_int,
308         result: *mut c_float,
309     ) -> c_int;
WebPPictureCrop( picture: *mut WebPPicture, left: c_int, top: c_int, width: c_int, height: c_int, ) -> c_int310     pub fn WebPPictureCrop(
311         picture: *mut WebPPicture,
312         left: c_int,
313         top: c_int,
314         width: c_int,
315         height: c_int,
316     ) -> c_int;
WebPPictureView( src: *const WebPPicture, left: c_int, top: c_int, width: c_int, height: c_int, dst: *mut WebPPicture, ) -> c_int317     pub fn WebPPictureView(
318         src: *const WebPPicture,
319         left: c_int,
320         top: c_int,
321         width: c_int,
322         height: c_int,
323         dst: *mut WebPPicture,
324     ) -> c_int;
WebPPictureIsView(picture: *const WebPPicture) -> c_int325     pub fn WebPPictureIsView(picture: *const WebPPicture) -> c_int;
WebPPictureRescale(pic: *mut WebPPicture, width: c_int, height: c_int) -> c_int326     pub fn WebPPictureRescale(pic: *mut WebPPicture, width: c_int, height: c_int) -> c_int;
WebPPictureImportRGB( picture: *mut WebPPicture, rgb: *const u8, rgb_stride: c_int, ) -> c_int327     pub fn WebPPictureImportRGB(
328         picture: *mut WebPPicture,
329         rgb: *const u8,
330         rgb_stride: c_int,
331     ) -> c_int;
WebPPictureImportRGBA( picture: *mut WebPPicture, rgba: *const u8, rgba_stride: c_int, ) -> c_int332     pub fn WebPPictureImportRGBA(
333         picture: *mut WebPPicture,
334         rgba: *const u8,
335         rgba_stride: c_int,
336     ) -> c_int;
WebPPictureImportRGBX( picture: *mut WebPPicture, rgbx: *const u8, rgbx_stride: c_int, ) -> c_int337     pub fn WebPPictureImportRGBX(
338         picture: *mut WebPPicture,
339         rgbx: *const u8,
340         rgbx_stride: c_int,
341     ) -> c_int;
WebPPictureImportBGR( picture: *mut WebPPicture, bgr: *const u8, bgr_stride: c_int, ) -> c_int342     pub fn WebPPictureImportBGR(
343         picture: *mut WebPPicture,
344         bgr: *const u8,
345         bgr_stride: c_int,
346     ) -> c_int;
WebPPictureImportBGRA( picture: *mut WebPPicture, bgra: *const u8, bgra_stride: c_int, ) -> c_int347     pub fn WebPPictureImportBGRA(
348         picture: *mut WebPPicture,
349         bgra: *const u8,
350         bgra_stride: c_int,
351     ) -> c_int;
WebPPictureImportBGRX( picture: *mut WebPPicture, bgrx: *const u8, bgrx_stride: c_int, ) -> c_int352     pub fn WebPPictureImportBGRX(
353         picture: *mut WebPPicture,
354         bgrx: *const u8,
355         bgrx_stride: c_int,
356     ) -> c_int;
WebPPictureARGBToYUVA(picture: *mut WebPPicture, colorspace: WebPEncCSP) -> c_int357     pub fn WebPPictureARGBToYUVA(picture: *mut WebPPicture, colorspace: WebPEncCSP) -> c_int;
WebPPictureARGBToYUVADithered( picture: *mut WebPPicture, colorspace: WebPEncCSP, dithering: c_float, ) -> c_int358     pub fn WebPPictureARGBToYUVADithered(
359         picture: *mut WebPPicture,
360         colorspace: WebPEncCSP,
361         dithering: c_float,
362     ) -> c_int;
363     #[cfg(feature = "0_5")]
364     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "0_5")))]
WebPPictureSmartARGBToYUVA(picture: *mut WebPPicture) -> c_int365     pub fn WebPPictureSmartARGBToYUVA(picture: *mut WebPPicture) -> c_int;
WebPPictureYUVAToARGB(picture: *mut WebPPicture) -> c_int366     pub fn WebPPictureYUVAToARGB(picture: *mut WebPPicture) -> c_int;
WebPCleanupTransparentArea(picture: *mut WebPPicture)367     pub fn WebPCleanupTransparentArea(picture: *mut WebPPicture);
WebPPictureHasTransparency(picture: *const WebPPicture) -> c_int368     pub fn WebPPictureHasTransparency(picture: *const WebPPicture) -> c_int;
WebPBlendAlpha(pic: *mut WebPPicture, background_rgb: u32)369     pub fn WebPBlendAlpha(pic: *mut WebPPicture, background_rgb: u32);
WebPEncode(config: *const WebPConfig, picture: *mut WebPPicture) -> c_int370     pub fn WebPEncode(config: *const WebPConfig, picture: *mut WebPPicture) -> c_int;
371 }
372 
373 #[allow(non_snake_case)]
374 #[inline]
WebPConfigInit(config: *mut WebPConfig) -> c_int375 pub unsafe extern "C" fn WebPConfigInit(config: *mut WebPConfig) -> c_int {
376     WebPConfigInitInternal(
377         config,
378         WEBP_PRESET_DEFAULT,
379         75_f32 as c_float,
380         WEBP_ENCODER_ABI_VERSION,
381     )
382 }
383 
384 #[allow(non_snake_case)]
385 #[inline]
WebPConfigPreset( config: *mut WebPConfig, preset: WebPPreset, quality: c_float, ) -> c_int386 pub unsafe extern "C" fn WebPConfigPreset(
387     config: *mut WebPConfig,
388     preset: WebPPreset,
389     quality: c_float,
390 ) -> c_int {
391     WebPConfigInitInternal(config, preset, quality, WEBP_ENCODER_ABI_VERSION)
392 }
393 
394 #[allow(non_snake_case)]
395 #[inline]
WebPPictureInit(picture: *mut WebPPicture) -> c_int396 pub unsafe extern "C" fn WebPPictureInit(picture: *mut WebPPicture) -> c_int {
397     WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION)
398 }
399 
400 #[cfg(test)]
401 mod tests {
402     use super::*;
403 
404     use std::mem;
405 
406     #[test]
test_new_and_delete()407     fn test_new_and_delete() {
408         unsafe {
409             let mut buf = mem::zeroed();
410             WebPMemoryWriterInit(&mut buf);
411             #[cfg(feature = "0_5")]
412             WebPMemoryWriterClear(&mut buf);
413         }
414     }
415 }
416