xref: /aosp_15_r20/external/webp/doc/api.md (revision b2055c353e87c8814eb2b6b1b11112a1562253bd)
1*b2055c35SXin Li# WebP APIs
2*b2055c35SXin Li
3*b2055c35SXin Li## Encoding API
4*b2055c35SXin Li
5*b2055c35SXin LiThe main encoding functions are available in the header src/webp/encode.h
6*b2055c35SXin Li
7*b2055c35SXin LiThe ready-to-use ones are:
8*b2055c35SXin Li
9*b2055c35SXin Li```c
10*b2055c35SXin Lisize_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride,
11*b2055c35SXin Li                     float quality_factor, uint8_t** output);
12*b2055c35SXin Lisize_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride,
13*b2055c35SXin Li                     float quality_factor, uint8_t** output);
14*b2055c35SXin Lisize_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride,
15*b2055c35SXin Li                      float quality_factor, uint8_t** output);
16*b2055c35SXin Lisize_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride,
17*b2055c35SXin Li                      float quality_factor, uint8_t** output);
18*b2055c35SXin Li```
19*b2055c35SXin Li
20*b2055c35SXin LiThey will convert raw RGB samples to a WebP data. The only control supplied is
21*b2055c35SXin Lithe quality factor.
22*b2055c35SXin Li
23*b2055c35SXin LiThere are some variants for using the lossless format:
24*b2055c35SXin Li
25*b2055c35SXin Li```c
26*b2055c35SXin Lisize_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height,
27*b2055c35SXin Li                             int stride, uint8_t** output);
28*b2055c35SXin Lisize_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height,
29*b2055c35SXin Li                             int stride, uint8_t** output);
30*b2055c35SXin Lisize_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height,
31*b2055c35SXin Li                              int stride, uint8_t** output);
32*b2055c35SXin Lisize_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height,
33*b2055c35SXin Li                              int stride, uint8_t** output);
34*b2055c35SXin Li```
35*b2055c35SXin Li
36*b2055c35SXin LiOf course in this case, no quality factor is needed since the compression occurs
37*b2055c35SXin Liwithout loss of the input values, at the expense of larger output sizes.
38*b2055c35SXin Li
39*b2055c35SXin Li### Advanced encoding API
40*b2055c35SXin Li
41*b2055c35SXin LiA more advanced API is based on the WebPConfig and WebPPicture structures.
42*b2055c35SXin Li
43*b2055c35SXin LiWebPConfig contains the encoding settings and is not tied to a particular
44*b2055c35SXin Lipicture. WebPPicture contains input data, on which some WebPConfig will be used
45*b2055c35SXin Lifor compression. The encoding flow looks like:
46*b2055c35SXin Li
47*b2055c35SXin Li```c
48*b2055c35SXin Li#include <webp/encode.h>
49*b2055c35SXin Li
50*b2055c35SXin Li// Setup a config, starting form a preset and tuning some additional
51*b2055c35SXin Li// parameters
52*b2055c35SXin LiWebPConfig config;
53*b2055c35SXin Liif (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) {
54*b2055c35SXin Li  return 0;   // version error
55*b2055c35SXin Li}
56*b2055c35SXin Li// ... additional tuning
57*b2055c35SXin Liconfig.sns_strength = 90;
58*b2055c35SXin Liconfig.filter_sharpness = 6;
59*b2055c35SXin Liconfig_error = WebPValidateConfig(&config);  // not mandatory, but useful
60*b2055c35SXin Li
61*b2055c35SXin Li// Setup the input data
62*b2055c35SXin LiWebPPicture pic;
63*b2055c35SXin Liif (!WebPPictureInit(&pic)) {
64*b2055c35SXin Li  return 0;  // version error
65*b2055c35SXin Li}
66*b2055c35SXin Lipic.width = width;
67*b2055c35SXin Lipic.height = height;
68*b2055c35SXin Li// allocated picture of dimension width x height
69*b2055c35SXin Liif (!WebPPictureAlloc(&pic)) {
70*b2055c35SXin Li  return 0;   // memory error
71*b2055c35SXin Li}
72*b2055c35SXin Li// at this point, 'pic' has been initialized as a container,
73*b2055c35SXin Li// and can receive the Y/U/V samples.
74*b2055c35SXin Li// Alternatively, one could use ready-made import functions like
75*b2055c35SXin Li// WebPPictureImportRGB(), which will take care of memory allocation.
76*b2055c35SXin Li// In any case, past this point, one will have to call
77*b2055c35SXin Li// WebPPictureFree(&pic) to reclaim memory.
78*b2055c35SXin Li
79*b2055c35SXin Li// Set up a byte-output write method. WebPMemoryWriter, for instance.
80*b2055c35SXin LiWebPMemoryWriter wrt;
81*b2055c35SXin LiWebPMemoryWriterInit(&wrt);     // initialize 'wrt'
82*b2055c35SXin Li
83*b2055c35SXin Lipic.writer = MyFileWriter;
84*b2055c35SXin Lipic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
85*b2055c35SXin Li
86*b2055c35SXin Li// Compress!
87*b2055c35SXin Liint ok = WebPEncode(&config, &pic);   // ok = 0 => error occurred!
88*b2055c35SXin LiWebPPictureFree(&pic);  // must be called independently of the 'ok' result.
89*b2055c35SXin Li
90*b2055c35SXin Li// output data should have been handled by the writer at that point.
91*b2055c35SXin Li// -> compressed data is the memory buffer described by wrt.mem / wrt.size
92*b2055c35SXin Li
93*b2055c35SXin Li// deallocate the memory used by compressed data
94*b2055c35SXin LiWebPMemoryWriterClear(&wrt);
95*b2055c35SXin Li```
96*b2055c35SXin Li
97*b2055c35SXin Li## Decoding API
98*b2055c35SXin Li
99*b2055c35SXin LiThis is mainly just one function to call:
100*b2055c35SXin Li
101*b2055c35SXin Li```c
102*b2055c35SXin Li#include "webp/decode.h"
103*b2055c35SXin Liuint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
104*b2055c35SXin Li                       int* width, int* height);
105*b2055c35SXin Li```
106*b2055c35SXin Li
107*b2055c35SXin LiPlease have a look at the file src/webp/decode.h for the details. There are
108*b2055c35SXin Livariants for decoding in BGR/RGBA/ARGB/BGRA order, along with decoding to raw
109*b2055c35SXin LiY'CbCr samples. One can also decode the image directly into a pre-allocated
110*b2055c35SXin Libuffer.
111*b2055c35SXin Li
112*b2055c35SXin LiTo detect a WebP file and gather the picture's dimensions, the function:
113*b2055c35SXin Li
114*b2055c35SXin Li```c
115*b2055c35SXin Liint WebPGetInfo(const uint8_t* data, size_t data_size,
116*b2055c35SXin Li                int* width, int* height);
117*b2055c35SXin Li```
118*b2055c35SXin Li
119*b2055c35SXin Liis supplied. No decoding is involved when using it.
120*b2055c35SXin Li
121*b2055c35SXin Li### Incremental decoding API
122*b2055c35SXin Li
123*b2055c35SXin LiIn the case when data is being progressively transmitted, pictures can still be
124*b2055c35SXin Liincrementally decoded using a slightly more complicated API. Decoder state is
125*b2055c35SXin Listored into an instance of the WebPIDecoder object. This object can be created
126*b2055c35SXin Liwith the purpose of decoding either RGB or Y'CbCr samples. For instance:
127*b2055c35SXin Li
128*b2055c35SXin Li```c
129*b2055c35SXin LiWebPDecBuffer buffer;
130*b2055c35SXin LiWebPInitDecBuffer(&buffer);
131*b2055c35SXin Libuffer.colorspace = MODE_BGR;
132*b2055c35SXin Li...
133*b2055c35SXin LiWebPIDecoder* idec = WebPINewDecoder(&buffer);
134*b2055c35SXin Li```
135*b2055c35SXin Li
136*b2055c35SXin LiAs data is made progressively available, this incremental-decoder object can be
137*b2055c35SXin Liused to decode the picture further. There are two (mutually exclusive) ways to
138*b2055c35SXin Lipass freshly arrived data:
139*b2055c35SXin Li
140*b2055c35SXin Lieither by appending the fresh bytes:
141*b2055c35SXin Li
142*b2055c35SXin Li```c
143*b2055c35SXin LiWebPIAppend(idec, fresh_data, size_of_fresh_data);
144*b2055c35SXin Li```
145*b2055c35SXin Li
146*b2055c35SXin Lior by just mentioning the new size of the transmitted data:
147*b2055c35SXin Li
148*b2055c35SXin Li```c
149*b2055c35SXin LiWebPIUpdate(idec, buffer, size_of_transmitted_buffer);
150*b2055c35SXin Li```
151*b2055c35SXin Li
152*b2055c35SXin LiNote that 'buffer' can be modified between each call to WebPIUpdate, in
153*b2055c35SXin Liparticular when the buffer is resized to accommodate larger data.
154*b2055c35SXin Li
155*b2055c35SXin LiThese functions will return the decoding status: either VP8_STATUS_SUSPENDED if
156*b2055c35SXin Lidecoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other
157*b2055c35SXin Listatus is an error condition.
158*b2055c35SXin Li
159*b2055c35SXin LiThe 'idec' object must always be released (even upon an error condition) by
160*b2055c35SXin Licalling: WebPIDelete(idec).
161*b2055c35SXin Li
162*b2055c35SXin LiTo retrieve partially decoded picture samples, one must use the corresponding
163*b2055c35SXin Limethod: WebPIDecGetRGB or WebPIDecGetYUVA. It will return the last displayable
164*b2055c35SXin Lipixel row.
165*b2055c35SXin Li
166*b2055c35SXin LiLastly, note that decoding can also be performed into a pre-allocated pixel
167*b2055c35SXin Libuffer. This buffer must be passed when creating a WebPIDecoder, calling
168*b2055c35SXin LiWebPINewRGB() or WebPINewYUVA().
169*b2055c35SXin Li
170*b2055c35SXin LiPlease have a look at the src/webp/decode.h header for further details.
171*b2055c35SXin Li
172*b2055c35SXin Li### Advanced Decoding API
173*b2055c35SXin Li
174*b2055c35SXin LiWebP decoding supports an advanced API which provides on-the-fly cropping and
175*b2055c35SXin Lirescaling, something of great usefulness on memory-constrained environments like
176*b2055c35SXin Limobile phones. Basically, the memory usage will scale with the output's size,
177*b2055c35SXin Linot the input's, when one only needs a quick preview or a zoomed in portion of
178*b2055c35SXin Lian otherwise too-large picture. Some CPU can be saved too, incidentally.
179*b2055c35SXin Li
180*b2055c35SXin Li```c
181*b2055c35SXin Li// A) Init a configuration object
182*b2055c35SXin LiWebPDecoderConfig config;
183*b2055c35SXin LiCHECK(WebPInitDecoderConfig(&config));
184*b2055c35SXin Li
185*b2055c35SXin Li// B) optional: retrieve the bitstream's features.
186*b2055c35SXin LiCHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
187*b2055c35SXin Li
188*b2055c35SXin Li// C) Adjust 'config' options, if needed
189*b2055c35SXin Liconfig.options.no_fancy_upsampling = 1;
190*b2055c35SXin Liconfig.options.use_scaling = 1;
191*b2055c35SXin Liconfig.options.scaled_width = scaledWidth();
192*b2055c35SXin Liconfig.options.scaled_height = scaledHeight();
193*b2055c35SXin Li// etc.
194*b2055c35SXin Li
195*b2055c35SXin Li// D) Specify 'config' output options for specifying output colorspace.
196*b2055c35SXin Li// Optionally the external image decode buffer can also be specified.
197*b2055c35SXin Liconfig.output.colorspace = MODE_BGRA;
198*b2055c35SXin Li// Optionally, the config.output can be pointed to an external buffer as
199*b2055c35SXin Li// well for decoding the image. This externally supplied memory buffer
200*b2055c35SXin Li// should be big enough to store the decoded picture.
201*b2055c35SXin Liconfig.output.u.RGBA.rgba = (uint8_t*) memory_buffer;
202*b2055c35SXin Liconfig.output.u.RGBA.stride = scanline_stride;
203*b2055c35SXin Liconfig.output.u.RGBA.size = total_size_of_the_memory_buffer;
204*b2055c35SXin Liconfig.output.is_external_memory = 1;
205*b2055c35SXin Li
206*b2055c35SXin Li// E) Decode the WebP image. There are two variants w.r.t decoding image.
207*b2055c35SXin Li// The first one (E.1) decodes the full image and the second one (E.2) is
208*b2055c35SXin Li// used to incrementally decode the image using small input buffers.
209*b2055c35SXin Li// Any one of these steps can be used to decode the WebP image.
210*b2055c35SXin Li
211*b2055c35SXin Li// E.1) Decode full image.
212*b2055c35SXin LiCHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
213*b2055c35SXin Li
214*b2055c35SXin Li// E.2) Decode image incrementally.
215*b2055c35SXin LiWebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
216*b2055c35SXin LiCHECK(idec != NULL);
217*b2055c35SXin Liwhile (bytes_remaining > 0) {
218*b2055c35SXin Li  VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
219*b2055c35SXin Li  if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
220*b2055c35SXin Li    bytes_remaining -= bytes_read;
221*b2055c35SXin Li  } else {
222*b2055c35SXin Li    break;
223*b2055c35SXin Li  }
224*b2055c35SXin Li}
225*b2055c35SXin LiWebPIDelete(idec);
226*b2055c35SXin Li
227*b2055c35SXin Li// F) Decoded image is now in config.output (and config.output.u.RGBA).
228*b2055c35SXin Li// It can be saved, displayed or otherwise processed.
229*b2055c35SXin Li
230*b2055c35SXin Li// G) Reclaim memory allocated in config's object. It's safe to call
231*b2055c35SXin Li// this function even if the memory is external and wasn't allocated
232*b2055c35SXin Li// by WebPDecode().
233*b2055c35SXin LiWebPFreeDecBuffer(&config.output);
234*b2055c35SXin Li```
235*b2055c35SXin Li
236*b2055c35SXin Li## WebP Mux
237*b2055c35SXin Li
238*b2055c35SXin LiWebPMux is a set of two libraries 'Mux' and 'Demux' for creation, extraction and
239*b2055c35SXin Limanipulation of an extended format WebP file, which can have features like color
240*b2055c35SXin Liprofile, metadata and animation. Reference command-line tools `webpmux` and
241*b2055c35SXin Li`vwebp` as well as the WebP container specification
242*b2055c35SXin Li'doc/webp-container-spec.txt' are also provided in this package, see the
243*b2055c35SXin Li[tools documentation](tools.md).
244*b2055c35SXin Li
245*b2055c35SXin Li### Mux API
246*b2055c35SXin Li
247*b2055c35SXin LiThe Mux API contains methods for adding data to and reading data from WebP
248*b2055c35SXin Lifiles. This API currently supports XMP/EXIF metadata, ICC profile and animation.
249*b2055c35SXin LiOther features may be added in subsequent releases.
250*b2055c35SXin Li
251*b2055c35SXin LiExample#1 (pseudo code): Creating a WebPMux object with image data, color
252*b2055c35SXin Liprofile and XMP metadata.
253*b2055c35SXin Li
254*b2055c35SXin Li```c
255*b2055c35SXin Liint copy_data = 0;
256*b2055c35SXin LiWebPMux* mux = WebPMuxNew();
257*b2055c35SXin Li// ... (Prepare image data).
258*b2055c35SXin LiWebPMuxSetImage(mux, &image, copy_data);
259*b2055c35SXin Li// ... (Prepare ICC profile data).
260*b2055c35SXin LiWebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
261*b2055c35SXin Li// ... (Prepare XMP metadata).
262*b2055c35SXin LiWebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
263*b2055c35SXin Li// Get data from mux in WebP RIFF format.
264*b2055c35SXin LiWebPMuxAssemble(mux, &output_data);
265*b2055c35SXin LiWebPMuxDelete(mux);
266*b2055c35SXin Li// ... (Consume output_data; e.g. write output_data.bytes to file).
267*b2055c35SXin LiWebPDataClear(&output_data);
268*b2055c35SXin Li```
269*b2055c35SXin Li
270*b2055c35SXin LiExample#2 (pseudo code): Get image and color profile data from a WebP file.
271*b2055c35SXin Li
272*b2055c35SXin Li```c
273*b2055c35SXin Liint copy_data = 0;
274*b2055c35SXin Li// ... (Read data from file).
275*b2055c35SXin LiWebPMux* mux = WebPMuxCreate(&data, copy_data);
276*b2055c35SXin LiWebPMuxGetFrame(mux, 1, &image);
277*b2055c35SXin Li// ... (Consume image; e.g. call WebPDecode() to decode the data).
278*b2055c35SXin LiWebPMuxGetChunk(mux, "ICCP", &icc_profile);
279*b2055c35SXin Li// ... (Consume icc_profile).
280*b2055c35SXin LiWebPMuxDelete(mux);
281*b2055c35SXin Lifree(data);
282*b2055c35SXin Li```
283*b2055c35SXin Li
284*b2055c35SXin LiFor a detailed Mux API reference, please refer to the header file
285*b2055c35SXin Li(src/webp/mux.h).
286*b2055c35SXin Li
287*b2055c35SXin Li### Demux API
288*b2055c35SXin Li
289*b2055c35SXin LiThe Demux API enables extraction of images and extended format data from WebP
290*b2055c35SXin Lifiles. This API currently supports reading of XMP/EXIF metadata, ICC profile and
291*b2055c35SXin Lianimated images. Other features may be added in subsequent releases.
292*b2055c35SXin Li
293*b2055c35SXin LiCode example: Demuxing WebP data to extract all the frames, ICC profile and
294*b2055c35SXin LiEXIF/XMP metadata.
295*b2055c35SXin Li
296*b2055c35SXin Li```c
297*b2055c35SXin LiWebPDemuxer* demux = WebPDemux(&webp_data);
298*b2055c35SXin Liuint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
299*b2055c35SXin Liuint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
300*b2055c35SXin Li// ... (Get information about the features present in the WebP file).
301*b2055c35SXin Liuint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
302*b2055c35SXin Li
303*b2055c35SXin Li// ... (Iterate over all frames).
304*b2055c35SXin LiWebPIterator iter;
305*b2055c35SXin Liif (WebPDemuxGetFrame(demux, 1, &iter)) {
306*b2055c35SXin Li  do {
307*b2055c35SXin Li    // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
308*b2055c35SXin Li    // ... and get other frame properties like width, height, offsets etc.
309*b2055c35SXin Li    // ... see 'struct WebPIterator' below for more info).
310*b2055c35SXin Li  } while (WebPDemuxNextFrame(&iter));
311*b2055c35SXin Li  WebPDemuxReleaseIterator(&iter);
312*b2055c35SXin Li}
313*b2055c35SXin Li
314*b2055c35SXin Li// ... (Extract metadata).
315*b2055c35SXin LiWebPChunkIterator chunk_iter;
316*b2055c35SXin Liif (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
317*b2055c35SXin Li// ... (Consume the ICC profile in 'chunk_iter.chunk').
318*b2055c35SXin LiWebPDemuxReleaseChunkIterator(&chunk_iter);
319*b2055c35SXin Liif (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
320*b2055c35SXin Li// ... (Consume the EXIF metadata in 'chunk_iter.chunk').
321*b2055c35SXin LiWebPDemuxReleaseChunkIterator(&chunk_iter);
322*b2055c35SXin Liif (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
323*b2055c35SXin Li// ... (Consume the XMP metadata in 'chunk_iter.chunk').
324*b2055c35SXin LiWebPDemuxReleaseChunkIterator(&chunk_iter);
325*b2055c35SXin LiWebPDemuxDelete(demux);
326*b2055c35SXin Li```
327*b2055c35SXin Li
328*b2055c35SXin LiFor a detailed Demux API reference, please refer to the header file
329*b2055c35SXin Li(src/webp/demux.h).
330*b2055c35SXin Li
331*b2055c35SXin Li## AnimEncoder API
332*b2055c35SXin Li
333*b2055c35SXin LiThe AnimEncoder API can be used to create animated WebP images.
334*b2055c35SXin Li
335*b2055c35SXin LiCode example:
336*b2055c35SXin Li
337*b2055c35SXin Li```c
338*b2055c35SXin LiWebPAnimEncoderOptions enc_options;
339*b2055c35SXin LiWebPAnimEncoderOptionsInit(&enc_options);
340*b2055c35SXin Li// ... (Tune 'enc_options' as needed).
341*b2055c35SXin LiWebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
342*b2055c35SXin Liwhile(<there are more frames>) {
343*b2055c35SXin Li  WebPConfig config;
344*b2055c35SXin Li  WebPConfigInit(&config);
345*b2055c35SXin Li  // ... (Tune 'config' as needed).
346*b2055c35SXin Li  WebPAnimEncoderAdd(enc, frame, duration, &config);
347*b2055c35SXin Li}
348*b2055c35SXin LiWebPAnimEncoderAssemble(enc, webp_data);
349*b2055c35SXin LiWebPAnimEncoderDelete(enc);
350*b2055c35SXin Li// ... (Write the 'webp_data' to a file, or re-mux it further).
351*b2055c35SXin Li```
352*b2055c35SXin Li
353*b2055c35SXin LiFor a detailed AnimEncoder API reference, please refer to the header file
354*b2055c35SXin Li(src/webp/mux.h).
355*b2055c35SXin Li
356*b2055c35SXin Li## AnimDecoder API
357*b2055c35SXin Li
358*b2055c35SXin LiThis AnimDecoder API allows decoding (possibly) animated WebP images.
359*b2055c35SXin Li
360*b2055c35SXin LiCode Example:
361*b2055c35SXin Li
362*b2055c35SXin Li```c
363*b2055c35SXin LiWebPAnimDecoderOptions dec_options;
364*b2055c35SXin LiWebPAnimDecoderOptionsInit(&dec_options);
365*b2055c35SXin Li// Tune 'dec_options' as needed.
366*b2055c35SXin LiWebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options);
367*b2055c35SXin LiWebPAnimInfo anim_info;
368*b2055c35SXin LiWebPAnimDecoderGetInfo(dec, &anim_info);
369*b2055c35SXin Lifor (uint32_t i = 0; i < anim_info.loop_count; ++i) {
370*b2055c35SXin Li  while (WebPAnimDecoderHasMoreFrames(dec)) {
371*b2055c35SXin Li    uint8_t* buf;
372*b2055c35SXin Li    int timestamp;
373*b2055c35SXin Li    WebPAnimDecoderGetNext(dec, &buf, &timestamp);
374*b2055c35SXin Li    // ... (Render 'buf' based on 'timestamp').
375*b2055c35SXin Li    // ... (Do NOT free 'buf', as it is owned by 'dec').
376*b2055c35SXin Li  }
377*b2055c35SXin Li  WebPAnimDecoderReset(dec);
378*b2055c35SXin Li}
379*b2055c35SXin Liconst WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec);
380*b2055c35SXin Li// ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data).
381*b2055c35SXin LiWebPAnimDecoderDelete(dec);
382*b2055c35SXin Li```
383*b2055c35SXin Li
384*b2055c35SXin LiFor a detailed AnimDecoder API reference, please refer to the header file
385*b2055c35SXin Li(src/webp/demux.h).
386