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