libwebp_sys/
decode.rs

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