go-libwebp

Experimental translation from libwebp to Go source.
Log | Files | Refs | README | LICENSE

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, &timestamp);
    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).