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