1 use std::os::raw::*;
2 use std::ptr;
3 
4 // MAJOR(8b) + MINOR(8b)
5 cfg_if! {
6     if #[cfg(feature = "1_1")] {
7         pub const WEBP_DECODER_ABI_VERSION: c_int = 0x0209;
8     } else if #[cfg(feature = "0_5")] {
9         pub const WEBP_DECODER_ABI_VERSION: c_int = 0x0208;
10     } else {
11         pub const WEBP_DECODER_ABI_VERSION: c_int = 0x0203;
12     }
13 }
14 
15 #[cfg(feature = "extern-types")]
16 extern "C" {
17     pub type WebPIDecoder;
18 }
19 
20 #[cfg(not(feature = "extern-types"))]
21 #[repr(C)]
22 pub struct WebPIDecoder(c_void);
23 
24 // Colorspaces
25 // Note: the naming describes the byte-ordering of packed samples in memory.
26 // For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,...
27 // Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels.
28 // RGBA-4444 and RGB-565 colorspaces are represented by following byte-order:
29 // RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ...
30 // RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ...
31 // In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for
32 // these two modes:
33 // RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ...
34 // RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ...
35 
36 #[allow(non_camel_case_types)]
37 pub type WEBP_CSP_MODE = u32;
38 
39 pub const MODE_RGB: WEBP_CSP_MODE = 0;
40 pub const MODE_RGBA: WEBP_CSP_MODE = 1;
41 pub const MODE_BGR: WEBP_CSP_MODE = 2;
42 pub const MODE_BGRA: WEBP_CSP_MODE = 3;
43 pub const MODE_ARGB: WEBP_CSP_MODE = 4;
44 pub const MODE_RGBA_4444: WEBP_CSP_MODE = 5;
45 pub const MODE_RGB_565: WEBP_CSP_MODE = 6;
46 // RGB-premultiplied transparent modes (alpha value is preserved)
47 #[allow(non_upper_case_globals)]
48 pub const MODE_rgbA: WEBP_CSP_MODE = 7;
49 #[allow(non_upper_case_globals)]
50 pub const MODE_bgrA: WEBP_CSP_MODE = 8;
51 #[allow(non_upper_case_globals)]
52 pub const MODE_Argb: WEBP_CSP_MODE = 9;
53 #[allow(non_upper_case_globals)]
54 pub const MODE_rgbA_4444: WEBP_CSP_MODE = 10;
55 // YUV modes must come after RGB ones.
56 pub const MODE_YUV: WEBP_CSP_MODE = 11;
57 pub const MODE_YUVA: WEBP_CSP_MODE = 12;
58 pub const MODE_LAST: WEBP_CSP_MODE = 13;
59 
60 // Some useful macros:
61 
62 #[allow(non_snake_case)]
63 #[inline]
WebPIsPremultipliedMode(mode: WEBP_CSP_MODE) -> c_int64 pub extern "C" fn WebPIsPremultipliedMode(mode: WEBP_CSP_MODE) -> c_int {
65     (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb || mode == MODE_rgbA_4444) as c_int
66 }
67 
68 #[allow(non_snake_case)]
69 #[inline]
WebPIsAlphaMode(mode: WEBP_CSP_MODE) -> c_int70 pub extern "C" fn WebPIsAlphaMode(mode: WEBP_CSP_MODE) -> c_int {
71     (mode == MODE_RGBA
72         || mode == MODE_BGRA
73         || mode == MODE_ARGB
74         || mode == MODE_RGBA_4444
75         || mode == MODE_YUVA
76         || WebPIsPremultipliedMode(mode) != 0) as c_int
77 }
78 
79 #[allow(non_snake_case)]
80 #[inline]
WebPIsRGBMode(mode: WEBP_CSP_MODE) -> c_int81 pub extern "C" fn WebPIsRGBMode(mode: WEBP_CSP_MODE) -> c_int {
82     (mode < MODE_YUV) as c_int
83 }
84 
85 //------------------------------------------------------------------------------
86 // WebPDecBuffer: Generic structure for describing the output sample buffer.
87 
88 /// view as RGBA
89 #[repr(C)]
90 #[derive(Debug, Clone, Copy)]
91 pub struct WebPRGBABuffer {
92     /// pointer to RGBA samples
93     pub rgba: *mut u8,
94     /// stride in bytes from one scanline to the next.
95     pub stride: c_int,
96     /// total size of the *rgba buffer.
97     pub size: usize,
98 }
99 
100 /// view as YUVA
101 #[repr(C)]
102 #[derive(Debug, Clone, Copy)]
103 pub struct WebPYUVABuffer {
104     /// pointer to luma samples
105     pub y: *mut u8,
106     /// pointer to chroma U samples
107     pub u: *mut u8,
108     /// pointer to chroma V samples
109     pub v: *mut u8,
110     /// pointer to alpha samples
111     pub a: *mut u8,
112     /// luma stride
113     pub y_stride: c_int,
114     /// chroma U stride
115     pub u_stride: c_int,
116     /// chroma V stride
117     pub v_stride: c_int,
118     /// alpha stride
119     pub a_stride: c_int,
120     /// luma plane size
121     pub y_size: usize,
122     /// chroma U plane size
123     pub u_size: usize,
124     /// chroma V planes size
125     pub v_size: usize,
126     /// alpha-plane size
127     pub a_size: usize,
128 }
129 
130 /// Output buffer
131 #[repr(C)]
132 #[derive(Debug, Clone, Copy)]
133 pub struct WebPDecBuffer {
134     /// Colorspace.
135     pub colorspace: WEBP_CSP_MODE,
136     /// Dimension (width).
137     pub width: c_int,
138     /// Dimension (height).
139     pub height: c_int,
140     /// If non-zero, 'internal_memory' pointer is not
141     /// used. If value is '2' or more, the external
142     /// memory is considered 'slow' and multiple
143     /// read/write will be avoided.
144     pub is_external_memory: c_int,
145     /// Nameless union of buffer parameters.
146     pub u: __WebPDecBufferUnion,
147     /// padding for later use
148     pub pad: [u32; 4],
149     /// Internally allocated memory (only when
150     /// is_external_memory is 0). Should not be used
151     /// externally, but accessed via the buffer union.
152     #[doc(hidden)]
153     pub private_memory: *mut u8,
154 }
155 
156 #[allow(non_snake_case)]
157 #[repr(C)]
158 #[derive(Clone, Copy)]
159 pub union __WebPDecBufferUnion {
160     pub RGBA: WebPRGBABuffer,
161     pub YUVA: WebPYUVABuffer,
162 }
163 
164 impl std::fmt::Debug for __WebPDecBufferUnion {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result165     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
166         f.write_str("<union>")
167     }
168 }
169 
170 /// Enumeration of the status codes
171 #[allow(non_camel_case_types)]
172 pub type VP8StatusCode = u32;
173 
174 pub const VP8_STATUS_OK: VP8StatusCode = 0;
175 pub const VP8_STATUS_OUT_OF_MEMORY: VP8StatusCode = 1;
176 pub const VP8_STATUS_INVALID_PARAM: VP8StatusCode = 2;
177 pub const VP8_STATUS_BITSTREAM_ERROR: VP8StatusCode = 3;
178 pub const VP8_STATUS_UNSUPPORTED_FEATURE: VP8StatusCode = 4;
179 pub const VP8_STATUS_SUSPENDED: VP8StatusCode = 5;
180 pub const VP8_STATUS_USER_ABORT: VP8StatusCode = 6;
181 pub const VP8_STATUS_NOT_ENOUGH_DATA: VP8StatusCode = 7;
182 
183 /// Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the
184 /// alpha information (if present). Kept for backward compatibility.
185 #[allow(non_snake_case)]
186 #[inline]
WebPIDecGetYUV( idec: *const WebPIDecoder, last_y: *mut c_int, u: *mut *mut u8, v: *mut *mut u8, width: *mut c_int, height: *mut c_int, stride: *mut c_int, uv_stride: *mut c_int, ) -> *mut u8187 pub unsafe extern "C" fn WebPIDecGetYUV(
188     idec: *const WebPIDecoder,
189     last_y: *mut c_int,
190     u: *mut *mut u8,
191     v: *mut *mut u8,
192     width: *mut c_int,
193     height: *mut c_int,
194     stride: *mut c_int,
195     uv_stride: *mut c_int,
196 ) -> *mut u8 {
197     WebPIDecGetYUVA(
198         idec,
199         last_y,
200         u,
201         v,
202         ptr::null_mut(),
203         width,
204         height,
205         stride,
206         uv_stride,
207         ptr::null_mut(),
208     )
209 }
210 
211 /// Features gathered from the bitstream
212 #[repr(C)]
213 #[derive(Debug, Clone, Copy)]
214 pub struct WebPBitstreamFeatures {
215     /// Width in pixels, as read from the bitstream.
216     pub width: c_int,
217     /// Height in pixels, as read from the bitstream.
218     pub height: c_int,
219     /// True if the bitstream contains an alpha channel.
220     pub has_alpha: c_int,
221     /// True if the bitstream is an animation.
222     pub has_animation: c_int,
223     /// 0 = undefined (/mixed), 1 = lossy, 2 = lossless
224     pub format: c_int,
225     /// Unused for now. if true, using incremental decoding is not
226     /// recommended.
227     #[cfg(not(feature = "0_5"))]
228     #[deprecated(note = "Removed as of libwebp 0.5.0")]
229     pub no_incremental_decoding: c_int,
230     /// Unused for now. TODO(later)
231     #[cfg(not(feature = "0_5"))]
232     #[deprecated(note = "Removed as of libwebp 0.5.0")]
233     pub rotate: c_int,
234     /// Unused for now. should be 0 for now. TODO(later)
235     #[cfg(not(feature = "0_5"))]
236     #[deprecated(note = "Removed as of libwebp 0.5.0")]
237     pub uv_sampling: c_int,
238     /// padding for later use
239     #[cfg(not(feature = "0_5"))]
240     #[doc(hidden)]
241     pub pad: [u32; 2],
242     /// padding for later use
243     #[cfg(feature = "0_5")]
244     #[doc(hidden)]
245     pub pad: [u32; 5],
246 }
247 
248 /// Decoding options
249 #[repr(C)]
250 #[derive(Debug, Clone, Copy)]
251 pub struct WebPDecoderOptions {
252     /// if true, skip the in-loop filtering
253     pub bypass_filtering: c_int,
254     /// if true, use faster pointwise upsampler
255     pub no_fancy_upsampling: c_int,
256     /// if true, cropping is applied _first_
257     pub use_cropping: c_int,
258     /// left position for cropping.
259     /// Will be snapped to even value.
260     pub crop_left: c_int,
261     /// top position for cropping.
262     /// Will be snapped to even value.
263     pub crop_top: c_int,
264     /// width of the cropping area
265     pub crop_width: c_int,
266     /// height of the cropping area
267     pub crop_height: c_int,
268     /// if true, scaling is applied _afterward_
269     pub use_scaling: c_int,
270     /// final resolution width
271     pub scaled_width: c_int,
272     /// final resolution height
273     pub scaled_height: c_int,
274     /// if true, use multi-threaded decoding
275     pub use_threads: c_int,
276     /// dithering strength (0=Off, 100=full)
277     pub dithering_strength: c_int,
278     /// if true, flip output vertically
279     #[cfg(feature = "0_5")]
280     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "0_5")))]
281     pub flip: c_int,
282     /// alpha dithering strength in [0..100]
283     #[cfg(feature = "0_5")]
284     #[cfg_attr(feature = "__doc_cfg", doc(cfg(feature = "0_5")))]
285     pub alpha_dithering_strength: c_int,
286     /// Unused for now. forced rotation (to be applied _last_)
287     #[cfg(not(feature = "0_5"))]
288     #[deprecated(note = "Removed as of libwebp 0.5.0")]
289     pub force_rotation: c_int,
290     /// Unused for now. if true, discard enhancement layer
291     #[cfg(not(feature = "0_5"))]
292     #[deprecated(note = "Removed as of libwebp 0.5.0")]
293     pub no_enhancement: c_int,
294     /// padding for later use
295     #[doc(hidden)]
296     pub pad: [u32; 5],
297 }
298 
299 /// Main object storing the configuration for advanced decoding.
300 #[repr(C)]
301 #[derive(Debug, Clone, Copy)]
302 pub struct WebPDecoderConfig {
303     /// Immutable bitstream features (optional)
304     pub input: WebPBitstreamFeatures,
305     /// Output buffer (can point to external mem)
306     pub output: WebPDecBuffer,
307     /// Decoding options
308     pub options: WebPDecoderOptions,
309 }
310 
311 extern "C" {
312     /// Return the decoder's version number, packed in hexadecimal using 8bits for
313     /// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
WebPGetDecoderVersion() -> c_int314     pub fn WebPGetDecoderVersion() -> c_int;
315     /// Retrieve basic header information: width, height.
316     /// This function will also validate the header, returning true on success,
317     /// false otherwise. '*width' and '*height' are only valid on successful return.
318     /// Pointers 'width' and 'height' can be passed NULL if deemed irrelevant.
319     /// Note: The following chunk sequences (before the raw VP8/VP8L data) are
320     /// considered valid by this function:
321     /// RIFF + VP8(L)
322     /// RIFF + VP8X + (optional chunks) + VP8(L)
323     /// ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
324     /// VP8(L)     <-- Not a valid WebP format: only allowed for internal purpose.
WebPGetInfo( data: *const u8, data_size: usize, width: *mut c_int, height: *mut c_int, ) -> c_int325     pub fn WebPGetInfo(
326         data: *const u8,
327         data_size: usize,
328         width: *mut c_int,
329         height: *mut c_int,
330     ) -> c_int;
331     /// Decodes WebP images pointed to by 'data' and returns RGBA samples, along
332     /// with the dimensions in *width and *height. The ordering of samples in
333     /// memory is R, G, B, A, R, G, B, A... in scan order (endian-independent).
334     /// The returned pointer should be deleted calling WebPFree().
335     /// Returns NULL in case of error.
WebPDecodeRGBA( data: *const u8, data_size: usize, width: *mut c_int, height: *mut c_int, ) -> *mut u8336     pub fn WebPDecodeRGBA(
337         data: *const u8,
338         data_size: usize,
339         width: *mut c_int,
340         height: *mut c_int,
341     ) -> *mut u8;
342     /// Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data.
WebPDecodeARGB( data: *const u8, data_size: usize, width: *mut c_int, height: *mut c_int, ) -> *mut u8343     pub fn WebPDecodeARGB(
344         data: *const u8,
345         data_size: usize,
346         width: *mut c_int,
347         height: *mut c_int,
348     ) -> *mut u8;
349     /// Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data.
WebPDecodeBGRA( data: *const u8, data_size: usize, width: *mut c_int, height: *mut c_int, ) -> *mut u8350     pub fn WebPDecodeBGRA(
351         data: *const u8,
352         data_size: usize,
353         width: *mut c_int,
354         height: *mut c_int,
355     ) -> *mut u8;
356     /// Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data.
357     /// If the bitstream contains transparency, it is ignored.
WebPDecodeRGB( data: *const u8, data_size: usize, width: *mut c_int, height: *mut c_int, ) -> *mut u8358     pub fn WebPDecodeRGB(
359         data: *const u8,
360         data_size: usize,
361         width: *mut c_int,
362         height: *mut c_int,
363     ) -> *mut u8;
364     /// Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data.
WebPDecodeBGR( data: *const u8, data_size: usize, width: *mut c_int, height: *mut c_int, ) -> *mut u8365     pub fn WebPDecodeBGR(
366         data: *const u8,
367         data_size: usize,
368         width: *mut c_int,
369         height: *mut c_int,
370     ) -> *mut u8;
371     /// Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer
372     /// returned is the Y samples buffer. Upon return, *u and *v will point to
373     /// the U and V chroma data. These U and V buffers need NOT be passed to
374     /// WebPFree(), unlike the returned Y luma one. The dimension of the U and V
375     /// planes are both (*width + 1) / 2 and (*height + 1)/ 2.
376     /// Upon return, the Y buffer has a stride returned as '*stride', while U and V
377     /// have a common stride returned as '*uv_stride'.
378     /// Return NULL in case of error.
379     /// (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr
WebPDecodeYUV( data: *const u8, data_size: usize, width: *mut c_int, height: *mut c_int, u: *mut *mut u8, v: *mut *mut u8, stride: *mut c_int, uv_stride: *mut c_int, ) -> *mut u8380     pub fn WebPDecodeYUV(
381         data: *const u8,
382         data_size: usize,
383         width: *mut c_int,
384         height: *mut c_int,
385         u: *mut *mut u8,
386         v: *mut *mut u8,
387         stride: *mut c_int,
388         uv_stride: *mut c_int,
389     ) -> *mut u8;
390     // These five functions are variants of the above ones, that decode the image
391     // directly into a pre-allocated buffer 'output_buffer'. The maximum storage
392     // available in this buffer is indicated by 'output_buffer_size'. If this
393     // storage is not sufficient (or an error occurred), NULL is returned.
394     // Otherwise, output_buffer is returned, for convenience.
395     // The parameter 'output_stride' specifies the distance (in bytes)
396     // between scanlines. Hence, output_buffer_size is expected to be at least
397     // output_stride x picture-height.
WebPDecodeRGBAInto( data: *const u8, data_size: usize, output_buffer: *mut u8, output_buffer_size: usize, output_stride: c_int, ) -> *mut u8398     pub fn WebPDecodeRGBAInto(
399         data: *const u8,
400         data_size: usize,
401         output_buffer: *mut u8,
402         output_buffer_size: usize,
403         output_stride: c_int,
404     ) -> *mut u8;
WebPDecodeARGBInto( data: *const u8, data_size: usize, output_buffer: *mut u8, output_buffer_size: usize, output_stride: c_int, ) -> *mut u8405     pub fn WebPDecodeARGBInto(
406         data: *const u8,
407         data_size: usize,
408         output_buffer: *mut u8,
409         output_buffer_size: usize,
410         output_stride: c_int,
411     ) -> *mut u8;
WebPDecodeBGRAInto( data: *const u8, data_size: usize, output_buffer: *mut u8, output_buffer_size: usize, output_stride: c_int, ) -> *mut u8412     pub fn WebPDecodeBGRAInto(
413         data: *const u8,
414         data_size: usize,
415         output_buffer: *mut u8,
416         output_buffer_size: usize,
417         output_stride: c_int,
418     ) -> *mut u8;
419     // RGB and BGR variants. Here too the transparency information, if present,
420     // will be dropped and ignored.
WebPDecodeRGBInto( data: *const u8, data_size: usize, output_buffer: *mut u8, output_buffer_size: usize, output_stride: c_int, ) -> *mut u8421     pub fn WebPDecodeRGBInto(
422         data: *const u8,
423         data_size: usize,
424         output_buffer: *mut u8,
425         output_buffer_size: usize,
426         output_stride: c_int,
427     ) -> *mut u8;
WebPDecodeBGRInto( data: *const u8, data_size: usize, output_buffer: *mut u8, output_buffer_size: usize, output_stride: c_int, ) -> *mut u8428     pub fn WebPDecodeBGRInto(
429         data: *const u8,
430         data_size: usize,
431         output_buffer: *mut u8,
432         output_buffer_size: usize,
433         output_stride: c_int,
434     ) -> *mut u8;
435     /// WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly
436     /// into pre-allocated luma/chroma plane buffers. This function requires the
437     /// strides to be passed: one for the luma plane and one for each of the
438     /// chroma ones. The size of each plane buffer is passed as 'luma_size',
439     /// 'u_size' and 'v_size' respectively.
440     /// Pointer to the luma plane ('*luma') is returned or NULL if an error occurred
441     /// during decoding (or because some buffers were found to be too small).
WebPDecodeYUVInto( data: *const u8, data_size: usize, luma: *mut u8, luma_size: usize, luma_stride: c_int, u: *mut u8, u_size: usize, u_stride: c_int, v: *mut u8, v_size: usize, v_stride: c_int, ) -> *mut u8442     pub fn WebPDecodeYUVInto(
443         data: *const u8,
444         data_size: usize,
445         luma: *mut u8,
446         luma_size: usize,
447         luma_stride: c_int,
448         u: *mut u8,
449         u_size: usize,
450         u_stride: c_int,
451         v: *mut u8,
452         v_size: usize,
453         v_stride: c_int,
454     ) -> *mut u8;
455     /// Internal, version-checked, entry point
456     #[doc(hidden)]
WebPInitDecBufferInternal(_: *mut WebPDecBuffer, _: c_int) -> c_int457     pub fn WebPInitDecBufferInternal(_: *mut WebPDecBuffer, _: c_int) -> c_int;
458     /// Free any memory associated with the buffer. Must always be called last.
459     /// Note: doesn't free the 'buffer' structure itself.
WebPFreeDecBuffer(buffer: *mut WebPDecBuffer)460     pub fn WebPFreeDecBuffer(buffer: *mut WebPDecBuffer);
461     /// Creates a new incremental decoder with the supplied buffer parameter.
462     /// This output_buffer can be passed NULL, in which case a default output buffer
463     /// is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer'
464     /// is kept, which means that the lifespan of 'output_buffer' must be larger than
465     /// that of the returned WebPIDecoder object.
466     /// The supplied 'output_buffer' content MUST NOT be changed between calls to
467     /// WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is
468     /// not set to 0. In such a case, it is allowed to modify the pointers, size and
469     /// stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain
470     /// within valid bounds.
471     /// All other fields of WebPDecBuffer MUST remain constant between calls.
472     /// Returns NULL if the allocation failed.
WebPINewDecoder(output_buffer: *mut WebPDecBuffer) -> *mut WebPIDecoder473     pub fn WebPINewDecoder(output_buffer: *mut WebPDecBuffer) -> *mut WebPIDecoder;
474     /// This function allocates and initializes an incremental-decoder object, which
475     /// will output the RGB/A samples specified by 'csp' into a preallocated
476     /// buffer 'output_buffer'. The size of this buffer is at least
477     /// 'output_buffer_size' and the stride (distance in bytes between two scanlines)
478     /// is specified by 'output_stride'.
479     /// Additionally, output_buffer can be passed NULL in which case the output
480     /// buffer will be allocated automatically when the decoding starts. The
481     /// colorspace 'csp' is taken into account for allocating this buffer. All other
482     /// parameters are ignored.
483     /// Returns NULL if the allocation failed, or if some parameters are invalid.
WebPINewRGB( csp: WEBP_CSP_MODE, output_buffer: *mut u8, output_buffer_size: usize, output_stride: c_int, ) -> *mut WebPIDecoder484     pub fn WebPINewRGB(
485         csp: WEBP_CSP_MODE,
486         output_buffer: *mut u8,
487         output_buffer_size: usize,
488         output_stride: c_int,
489     ) -> *mut WebPIDecoder;
490     /// This function allocates and initializes an incremental-decoder object, which
491     /// will output the raw luma/chroma samples into a preallocated planes if
492     /// supplied. The luma plane is specified by its pointer 'luma', its size
493     /// 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane
494     /// is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v
495     /// plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer
496     /// can be pass NULL in case one is not interested in the transparency plane.
497     /// Conversely, 'luma' can be passed NULL if no preallocated planes are supplied.
498     /// In this case, the output buffer will be automatically allocated (using
499     /// MODE_YUVA) when decoding starts. All parameters are then ignored.
500     /// Returns NULL if the allocation failed or if a parameter is invalid.
WebPINewYUVA( luma: *mut u8, luma_size: usize, luma_stride: c_int, u: *mut u8, u_size: usize, u_stride: c_int, v: *mut u8, v_size: usize, v_stride: c_int, a: *mut u8, a_size: usize, a_stride: c_int, ) -> *mut WebPIDecoder501     pub fn WebPINewYUVA(
502         luma: *mut u8,
503         luma_size: usize,
504         luma_stride: c_int,
505         u: *mut u8,
506         u_size: usize,
507         u_stride: c_int,
508         v: *mut u8,
509         v_size: usize,
510         v_stride: c_int,
511         a: *mut u8,
512         a_size: usize,
513         a_stride: c_int,
514     ) -> *mut WebPIDecoder;
515     /// Deprecated version of the above, without the alpha plane.
516     /// Kept for backward compatibility.
WebPINewYUV( luma: *mut u8, luma_size: usize, luma_stride: c_int, u: *mut u8, u_size: usize, u_stride: c_int, v: *mut u8, v_size: usize, v_stride: c_int, ) -> *mut WebPIDecoder517     pub fn WebPINewYUV(
518         luma: *mut u8,
519         luma_size: usize,
520         luma_stride: c_int,
521         u: *mut u8,
522         u_size: usize,
523         u_stride: c_int,
524         v: *mut u8,
525         v_size: usize,
526         v_stride: c_int,
527     ) -> *mut WebPIDecoder;
528     /// Deletes the WebPIDecoder object and associated memory. Must always be called
529     /// if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded.
WebPIDelete(idec: *mut WebPIDecoder)530     pub fn WebPIDelete(idec: *mut WebPIDecoder);
531     /// Copies and decodes the next available data. Returns VP8_STATUS_OK when
532     /// the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more
533     /// data is expected. Returns error in other cases.
WebPIAppend(idec: *mut WebPIDecoder, data: *const u8, data_size: usize) -> VP8StatusCode534     pub fn WebPIAppend(idec: *mut WebPIDecoder, data: *const u8, data_size: usize)
535         -> VP8StatusCode;
536     /// A variant of the above function to be used when data buffer contains
537     /// partial data from the beginning. In this case data buffer is not copied
538     /// to the internal memory.
539     /// Note that the value of the 'data' pointer can change between calls to
540     /// WebPIUpdate, for instance when the data buffer is resized to fit larger data.
WebPIUpdate(idec: *mut WebPIDecoder, data: *const u8, data_size: usize) -> VP8StatusCode541     pub fn WebPIUpdate(idec: *mut WebPIDecoder, data: *const u8, data_size: usize)
542         -> VP8StatusCode;
543     /// Returns the RGB/A image decoded so far. Returns NULL if output params
544     /// are not initialized yet. The RGB/A output type corresponds to the colorspace
545     /// specified during call to WebPINewDecoder() or WebPINewRGB().
546     /// *last_y is the index of last decoded row in raster scan order. Some pointers
547     /// (*last_y, *width etc.) can be NULL if corresponding information is not
548     /// needed. The values in these pointers are only valid on successful (non-NULL)
549     /// return.
WebPIDecGetRGB( idec: *const WebPIDecoder, last_y: *mut c_int, width: *mut c_int, height: *mut c_int, stride: *mut c_int, ) -> *mut u8550     pub fn WebPIDecGetRGB(
551         idec: *const WebPIDecoder,
552         last_y: *mut c_int,
553         width: *mut c_int,
554         height: *mut c_int,
555         stride: *mut c_int,
556     ) -> *mut u8;
557     /// Same as above function to get a YUVA image. Returns pointer to the luma
558     /// plane or NULL in case of error. If there is no alpha information
559     /// the alpha pointer '*a' will be returned NULL.
WebPIDecGetYUVA( idec: *const WebPIDecoder, last_y: *mut c_int, u: *mut *mut u8, v: *mut *mut u8, a: *mut *mut u8, width: *mut c_int, height: *mut c_int, stride: *mut c_int, uv_stride: *mut c_int, a_stride: *mut c_int, ) -> *mut u8560     pub fn WebPIDecGetYUVA(
561         idec: *const WebPIDecoder,
562         last_y: *mut c_int,
563         u: *mut *mut u8,
564         v: *mut *mut u8,
565         a: *mut *mut u8,
566         width: *mut c_int,
567         height: *mut c_int,
568         stride: *mut c_int,
569         uv_stride: *mut c_int,
570         a_stride: *mut c_int,
571     ) -> *mut u8;
572     /// Generic call to retrieve information about the displayable area.
573     /// If non NULL, the left/right/width/height pointers are filled with the visible
574     /// rectangular area so far.
575     /// Returns NULL in case the incremental decoder object is in an invalid state.
576     /// Otherwise returns the pointer to the internal representation. This structure
577     /// is read-only, tied to WebPIDecoder's lifespan and should not be modified.
WebPIDecodedArea( idec: *const WebPIDecoder, left: *mut c_int, top: *mut c_int, width: *mut c_int, height: *mut c_int, ) -> *const WebPDecBuffer578     pub fn WebPIDecodedArea(
579         idec: *const WebPIDecoder,
580         left: *mut c_int,
581         top: *mut c_int,
582         width: *mut c_int,
583         height: *mut c_int,
584     ) -> *const WebPDecBuffer;
585     /// Internal, version-checked, entry point
586     #[doc(hidden)]
WebPGetFeaturesInternal( _: *const u8, _: usize, _: *mut WebPBitstreamFeatures, _: c_int, ) -> VP8StatusCode587     pub fn WebPGetFeaturesInternal(
588         _: *const u8,
589         _: usize,
590         _: *mut WebPBitstreamFeatures,
591         _: c_int,
592     ) -> VP8StatusCode;
593     /// Internal, version-checked, entry point
594     #[doc(hidden)]
WebPInitDecoderConfigInternal(_: *mut WebPDecoderConfig, _: c_int) -> c_int595     pub fn WebPInitDecoderConfigInternal(_: *mut WebPDecoderConfig, _: c_int) -> c_int;
596     /// Instantiate a new incremental decoder object with the requested
597     /// configuration. The bitstream can be passed using 'data' and 'data_size'
598     /// parameter, in which case the features will be parsed and stored into
599     /// config->input. Otherwise, 'data' can be NULL and no parsing will occur.
600     /// Note that 'config' can be NULL too, in which case a default configuration
601     /// is used. If 'config' is not NULL, it must outlive the WebPIDecoder object
602     /// as some references to its fields will be used. No internal copy of 'config'
603     /// is made.
604     /// The return WebPIDecoder object must always be deleted calling WebPIDelete().
605     /// Returns NULL in case of error (and config->status will then reflect
606     /// the error condition, if available).
WebPIDecode( data: *const u8, data_size: usize, config: *mut WebPDecoderConfig, ) -> *mut WebPIDecoder607     pub fn WebPIDecode(
608         data: *const u8,
609         data_size: usize,
610         config: *mut WebPDecoderConfig,
611     ) -> *mut WebPIDecoder;
612     /// Non-incremental version. This version decodes the full data at once, taking
613     /// 'config' into account. Returns decoding status (which should be VP8_STATUS_OK
614     /// if the decoding was successful). Note that 'config' cannot be NULL.
WebPDecode( data: *const u8, data_size: usize, config: *mut WebPDecoderConfig, ) -> VP8StatusCode615     pub fn WebPDecode(
616         data: *const u8,
617         data_size: usize,
618         config: *mut WebPDecoderConfig,
619     ) -> VP8StatusCode;
620 }
621 
622 /// Initialize the structure as empty. Must be called before any other use.
623 /// Returns false in case of version mismatch
624 #[allow(non_snake_case)]
625 #[inline]
WebPInitDecBuffer(buffer: *mut WebPDecBuffer) -> c_int626 pub unsafe extern "C" fn WebPInitDecBuffer(buffer: *mut WebPDecBuffer) -> c_int {
627     WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION)
628 }
629 
630 /// Retrieve features from the bitstream. The *features structure is filled
631 /// with information gathered from the bitstream.
632 /// Returns VP8_STATUS_OK when the features are successfully retrieved. Returns
633 /// VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the
634 /// features from headers. Returns error in other cases.
635 /// Note: The following chunk sequences (before the raw VP8/VP8L data) are
636 /// considered valid by this function:
637 /// RIFF + VP8(L)
638 /// RIFF + VP8X + (optional chunks) + VP8(L)
639 /// ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
640 /// VP8(L)     <-- Not a valid WebP format: only allowed for internal purpose.
641 #[allow(non_snake_case)]
642 #[inline]
WebPGetFeatures( data: *const u8, data_size: usize, features: *mut WebPBitstreamFeatures, ) -> VP8StatusCode643 pub unsafe extern "C" fn WebPGetFeatures(
644     data: *const u8,
645     data_size: usize,
646     features: *mut WebPBitstreamFeatures,
647 ) -> VP8StatusCode {
648     WebPGetFeaturesInternal(data, data_size, features, WEBP_DECODER_ABI_VERSION)
649 }
650 
651 /// Initialize the configuration as empty. This function must always be
652 /// called first, unless WebPGetFeatures() is to be called.
653 /// Returns false in case of mismatched version.
654 #[allow(non_snake_case)]
655 #[inline]
WebPInitDecoderConfig(config: *mut WebPDecoderConfig) -> c_int656 pub unsafe extern "C" fn WebPInitDecoderConfig(config: *mut WebPDecoderConfig) -> c_int {
657     WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION)
658 }
659 
660 #[cfg(test)]
661 mod tests {
662     use super::*;
663 
664     use std::mem;
665 
666     #[test]
test_new_and_delete()667     fn test_new_and_delete() {
668         unsafe {
669             let mut buf = mem::zeroed();
670             WebPInitDecBuffer(&mut buf);
671             buf.colorspace = MODE_RGB;
672             buf.is_external_memory = 0;
673             let idec = WebPINewDecoder(&mut buf);
674             assert!(!idec.is_null());
675             WebPIDelete(idec);
676         }
677     }
678 }
679