Documentation sur l'API WebP

Cette section décrit l'API de l'encodeur et du décodeur fournis dans la bibliothèque WebP. Cette description de l'API se rapporte à la version 1.4.0.

En-têtes et bibliothèques

Lorsque vous installez libwebp, un répertoire nommé webp/ sera installé à l'emplacement habituel de votre plate-forme. Par exemple, sur sur les plates-formes Unix, les fichiers d'en-tête suivants seraient copiés sur /usr/local/include/webp/

decode.h
encode.h
types.h

Les bibliothèques se trouvent dans les répertoires habituels des bibliothèques. Les fonctions statiques et Les bibliothèques dynamiques se trouvent dans /usr/local/lib/ sur les plates-formes Unix.

API Simple Decoding

Pour commencer à utiliser l'API de décodage, vous devez vous assurer que vous disposez des de bibliothèque et des fichiers d'en-tête installés ci-dessus.

Incluez l'en-tête de l'API de décodage dans votre code C/C++ comme suit:

#include "webp/decode.h"
int WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height);

Cette fonction validera l'en-tête de l'image WebP et récupérera la largeur de l'image et la hauteur. Les pointeurs *width et *height peuvent être transmis NULL s'ils sont jugés non pertinentes.

Attributs d'entrée

données
Pointeur vers des données d'image WebP
data_size
Il s'agit de la taille du bloc de mémoire vers lequel renvoie data contenant le données d'image.

Renvoie

faux
Code d'erreur affiché en cas (a) d'erreurs de mise en forme.
true
En cas de réussite. *width et *height ne sont valides que si le retour a abouti.
largeur
Valeur entière. La plage est comprise entre 1 et 16 383.
hauteur
Valeur entière. La plage est comprise entre 1 et 16 383.
struct WebPBitstreamFeatures {
  int width;          // Width in pixels.
  int height;         // Height in pixels.
  int has_alpha;      // True if the bitstream contains an alpha channel.
  int has_animation;  // True if the bitstream is an animation.
  int format;         // 0 = undefined (/mixed), 1 = lossy, 2 = lossless
}

VP8StatusCode WebPGetFeatures(const uint8_t* data,
                              size_t data_size,
                              WebPBitstreamFeatures* features);

Cette fonction récupère les caractéristiques du flux de bits. *features est remplie d'informations recueillies à partir du bitstream:

Attributs d'entrée

données
Pointeur vers des données d'image WebP
data_size
Il s'agit de la taille du bloc de mémoire vers lequel renvoie data contenant le données d'image.

Renvoie

VP8_STATUS_OK
Lorsque les caractéristiques ont bien été récupérées.
VP8_STATUS_NOT_ENOUGH_DATA
Lorsque davantage de données sont nécessaires pour extraire les caractéristiques des en-têtes.

Valeurs d'erreur VP8StatusCode supplémentaires dans les autres cas.

fonctionnalités
Pointeur vers la structure WebPBitstreamFeatures.
uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size, int* width, int* height);
uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size, int* width, int* height);
uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size, int* width, int* height);
uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size, int* width, int* height);
uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size, int* width, int* height);

Ces fonctions décodent une image WebP vers laquelle data renvoie.

  • WebPDecodeRGBA renvoie des échantillons d'images RVBA dans l'ordre [r0, g0, b0, a0, r1, g1, b1, a1, ...].
  • WebPDecodeARGB renvoie des exemples d'images ARVB dans l'ordre [a0, r0, g0, b0, a1, r1, g1, b1, ...].
  • WebPDecodeBGRA renvoie des échantillons d'images BGRA dans l'ordre [b0, g0, r0, a0, b1, g1, r1, a1, ...].
  • WebPDecodeRGB renvoie des échantillons d'images RVB dans l'ordre [r0, g0, b0, r1, g1, b1, ...].
  • WebPDecodeBGR renvoie des échantillons d'images BGR dans l'ordre [b0, g0, r0, b1, g1, r1, ...].

Le code qui appelle l'une de ces fonctions doit supprimer le tampon de données (uint8_t*) renvoyé par ces fonctions avec WebPFree().

Attributs d'entrée

données
Pointeur vers des données d'image WebP
data_size
Il s'agit de la taille du bloc de mémoire vers lequel renvoie data contenant le données d'image
largeur
Valeur entière. La plage est actuellement limitée à 1 et 16 383.
hauteur
Valeur entière. La plage est actuellement limitée à 1 et 16 383.

Renvoie

uint8_t*
Pointeur vers des échantillons d'images WebP décodés au format linéaire RVBA/ARVB/BGRA/RVB/BGR respectivement.
uint8_t* WebPDecodeRGBAInto(const uint8_t* data, size_t data_size,
                            uint8_t* output_buffer, int output_buffer_size, int output_stride);
uint8_t* WebPDecodeARGBInto(const uint8_t* data, size_t data_size,
                            uint8_t* output_buffer, int output_buffer_size, int output_stride);
uint8_t* WebPDecodeBGRAInto(const uint8_t* data, size_t data_size,
                            uint8_t* output_buffer, int output_buffer_size, int output_stride);
uint8_t* WebPDecodeRGBInto(const uint8_t* data, size_t data_size,
                           uint8_t* output_buffer, int output_buffer_size, int output_stride);
uint8_t* WebPDecodeBGRInto(const uint8_t* data, size_t data_size,
                           uint8_t* output_buffer, int output_buffer_size, int output_stride);

Ces fonctions sont des variantes des fonctions ci-dessus et décodent l'image directement dans un output_buffer de tampon préalloué. L'espace de stockage maximal disponible dans ce tampon est indiqué par output_buffer_size. Si ce n'est pas le cas, suffisant (ou une erreur s'est produite), NULL est renvoyé. Sinon, Pour plus de commodité, output_buffer est renvoyé.

Le paramètre output_stride spécifie la distance (en octets) entre dans les moindres détails. Par conséquent, output_buffer_size doit être au moins égal à output_stride * picture - height

Attributs d'entrée

données
Pointeur vers des données d'image WebP
data_size
Il s'agit de la taille du bloc de mémoire vers lequel renvoie data contenant le données d'image
output_buffer_size
Valeur entière. Taille du tampon alloué
output_stride
Valeur entière. Spécifie la distance entre les lignes de balayage.

Renvoie

output_buffer
Pointeur vers une image WebP décodée.
uint8_t*
output_buffer si la fonction aboutit ; NULL dans le cas contraire.

API Advanced Decoding

Le décodage WebP est compatible avec une API avancée qui permet d'avoir des le redimensionnement et le redimensionnement, qui sont très utiles pour les modèles environnements tels que les téléphones portables. En gros, l'utilisation de la mémoire évoluera avec à la taille de la sortie, et non à l'entrée lorsqu'un simple aperçu ou zoom avant sur une partie d'une image autrement trop grande. Certains CPU peuvent être enregistrés de façon occasionnelle.

Le décodage WebP se décline en deux variantes : décodage complet de l'image et décodage incrémentiel le décodage sur de petits tampons d'entrée. Les utilisateurs peuvent éventuellement fournir un tampon de mémoire pour décoder l'image. L'exemple de code suivant passe par les étapes d'utilisation de l'API de décodage avancée.

Nous devons d'abord initialiser un objet de configuration:

#include "webp/decode.h"

WebPDecoderConfig config;
CHECK(WebPInitDecoderConfig(&config));

// One can adjust some additional decoding options:
config.options.no_fancy_upsampling = 1;
config.options.use_scaling = 1;
config.options.scaled_width = scaledWidth();
config.options.scaled_height = scaledHeight();
// etc.

Les options de décodage sont regroupées dans le WebPDecoderConfig structure:

struct WebPDecoderOptions {
  int bypass_filtering;             // if true, skip the in-loop filtering
  int no_fancy_upsampling;          // if true, use faster pointwise upsampler
  int use_cropping;                 // if true, cropping is applied first 
  int crop_left, crop_top;          // top-left position for cropping.
                                    // Will be snapped to even values.
  int crop_width, crop_height;      // dimension of the cropping area
  int use_scaling;                  // if true, scaling is applied afterward
  int scaled_width, scaled_height;  // final resolution
  int use_threads;                  // if true, use multi-threaded decoding
  int dithering_strength;           // dithering strength (0=Off, 100=full)
  int flip;                         // if true, flip output vertically
  int alpha_dithering_strength;     // alpha dithering strength in [0..100]
};

Les caractéristiques de flux de bits peuvent éventuellement être lues dans config.input, au cas où nous aurions besoin de les connaître à l'avance. Par exemple, il peut être utile de connaître si l'image présente une certaine transparence. Notez que cette opération analysent également l'en-tête du bitstream, ce qui permet de connaître si le flux de bits ressemble à un flux WebP valide.

CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);

Ensuite, nous devons configurer le tampon de mémoire de décodage, au cas où nous voudrions lui fournir au lieu de s'appuyer sur le décodeur pour son allocation. Nous n'avons besoin fournir le pointeur vers la mémoire, ainsi que la taille totale du tampon et le pas de ligne (distance en octets entre les lignes de balayage).

// Specify the desired output colorspace:
config.output.colorspace = MODE_BGRA;
// Have config.output point to an external buffer:
config.output.u.RGBA.rgba = (uint8_t*)memory_buffer;
config.output.u.RGBA.stride = scanline_stride;
config.output.u.RGBA.size = total_size_of_the_memory_buffer;
config.output.is_external_memory = 1;

L'image est prête à être décodée. Il existe deux variantes possibles pour le décodage l'image. Nous pouvons décoder l'image en une seule fois en utilisant:

CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);

Nous pouvons également utiliser la méthode incrémentielle pour décoder progressivement l'image à mesure que de nouveaux octets sont disponibles:

WebPIDecoder* idec = WebPINewDecoder(&config.output);
CHECK(idec != NULL);
while (additional_data_is_available) {
  // ... (get additional data in some new_data[] buffer)
  VP8StatusCode status = WebPIAppend(idec, new_data, new_data_size);
  if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) {
    break;
  }
  // The above call decodes the current available buffer.
  // Part of the image can now be refreshed by calling
  // WebPIDecGetRGB()/WebPIDecGetYUVA() etc.
}
WebPIDelete(idec);  // the object doesn't own the image memory, so it can
                    // now be deleted. config.output memory is preserved.

L'image décodée se trouve maintenant dans config.output (ou plutôt dans config.output.u.RGBA). dans ce cas, puisque l'espace colorimétrique de sortie demandé était MODE_BGRA). L'image peut être enregistrées, affichées ou traitées d'une autre manière. Ensuite, il nous suffit de récupérer la mémoire allouée dans l'objet de la configuration. Vous pouvez appeler cette fonction sans risque, même si la mémoire est externe et n'était pas alloué par WebPDecode():

WebPFreeDecBuffer(&config.output);

Cette API permet également de décoder l'image aux formats YUV et YUVA, MODE_YUV et MODE_YUVA, respectivement. Ce format est également appelé Y'CbCr.

API Simple Encoding

Certaines fonctions très simples sont fournies pour encoder des tableaux d'échantillons RVBA dans la plupart des mises en page courantes. Elles sont déclarées dans le webp/encode.h. en-tête comme:

size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output);
size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride, float quality_factor, uint8_t** output);
size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride, float quality_factor, uint8_t** output);
size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride, float quality_factor, uint8_t** output);

Le facteur de qualité quality_factor est compris entre 0 et 100. contrôle la perte et la qualité lors de la compression. La valeur 0 correspond à la plus faible avec une qualité de sortie réduite, alors que 100 correspond à la qualité la plus élevée taille de sortie. En cas de réussite, les octets compressés sont placés dans *output. et la taille en octets est renvoyée (sinon, 0 est renvoyé, d'échec). L'appelant doit appeler WebPFree() sur le *output. pointeur pour récupérer de la mémoire.

Le tableau d'entrée doit être un tableau d'octets empaquetés (un pour chaque canal, car attendue par le nom de la fonction). stride correspond aux le nombre d'octets nécessaires pour passer d'une ligne à la suivante. Par exemple, La mise en page BGRA est:

Il existe des fonctions équivalentes pour l'encodage sans perte, avec des signatures:

size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height, int stride, uint8_t** output);
size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height, int stride, uint8_t** output);
size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height, int stride, uint8_t** output);
size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height, int stride, uint8_t** output);

Notez que ces fonctions, comme les versions avec perte, utilisent la valeur par défaut de la bibliothèque paramètres. Dans le cas d'une utilisation sans perte, c'est-à-dire "exact" est désactivé. Les valeurs RVB dans les zones transparentes seront modifiées pour améliorer la compression. Pour éviter cela, utilisez WebPEncode() et définissez WebPConfig::exact sur 1.

API Advanced Encoding

L'encodeur est doté de nombreux paramètres d'encodage avancés. Elles peuvent être utiles pour mieux équilibrer le compromis entre compression l'efficacité et le temps de traitement. Ces paramètres sont rassemblés dans la structure WebPConfig. Les champs les plus utilisés de cette structure sont les suivants:

struct WebPConfig {
  int lossless;           // Lossless encoding (0=lossy(default), 1=lossless).
  float quality;          // between 0 and 100. For lossy, 0 gives the smallest
                          // size and 100 the largest. For lossless, this
                          // parameter is the amount of effort put into the
                          // compression: 0 is the fastest but gives larger
                          // files compared to the slowest, but best, 100.
  int method;             // quality/speed trade-off (0=fast, 6=slower-better)

  WebPImageHint image_hint;  // Hint for image type (lossless only for now).

  // Parameters related to lossy compression only:
  int target_size;        // if non-zero, set the desired target size in bytes.
                          // Takes precedence over the 'compression' parameter.
  float target_PSNR;      // if non-zero, specifies the minimal distortion to
                          // try to achieve. Takes precedence over target_size.
  int segments;           // maximum number of segments to use, in [1..4]
  int sns_strength;       // Spatial Noise Shaping. 0=off, 100=maximum.
  int filter_strength;    // range: [0 = off .. 100 = strongest]
  int filter_sharpness;   // range: [0 = off .. 7 = least sharp]
  int filter_type;        // filtering type: 0 = simple, 1 = strong (only used
                          // if filter_strength > 0 or autofilter > 0)
  int autofilter;         // Auto adjust filter's strength [0 = off, 1 = on]
  int alpha_compression;  // Algorithm for encoding the alpha plane (0 = none,
                          // 1 = compressed with WebP lossless). Default is 1.
  int alpha_filtering;    // Predictive filtering method for alpha plane.
                          //  0: none, 1: fast, 2: best. Default if 1.
  int alpha_quality;      // Between 0 (smallest size) and 100 (lossless).
                          // Default is 100.
  int pass;               // number of entropy-analysis passes (in [1..10]).

  int show_compressed;    // if true, export the compressed picture back.
                          // In-loop filtering is not applied.
  int preprocessing;      // preprocessing filter (0=none, 1=segment-smooth)
  int partitions;         // log2(number of token partitions) in [0..3]
                          // Default is set to 0 for easier progressive decoding.
  int partition_limit;    // quality degradation allowed to fit the 512k limit on
                          // prediction modes coding (0: no degradation,
                          // 100: maximum possible degradation).
  int use_sharp_yuv;      // if needed, use sharp (and slow) RGB->YUV conversion
};

Notez que la plupart de ces paramètres peuvent être testés à l'aide de l'outil de ligne de commande cwebp.

Les échantillons d'entrée doivent être encapsulés dans une structure WebPPicture. Cette structure peut stocker des échantillons d'entrée au format RVBA ou YUVA, selon sur la valeur de l'option use_argb.

La structure est organisée comme suit:

struct WebPPicture {
  int use_argb;              // To select between ARGB and YUVA input.

  // YUV input, recommended for lossy compression.
  // Used if use_argb = 0.
  WebPEncCSP colorspace;     // colorspace: should be YUVA420 or YUV420 for now (=Y'CbCr).
  int width, height;         // dimensions (less or equal to WEBP_MAX_DIMENSION)
  uint8_t *y, *u, *v;        // pointers to luma/chroma planes.
  int y_stride, uv_stride;   // luma/chroma strides.
  uint8_t* a;                // pointer to the alpha plane
  int a_stride;              // stride of the alpha plane

  // Alternate ARGB input, recommended for lossless compression.
  // Used if use_argb = 1.
  uint32_t* argb;            // Pointer to argb (32 bit) plane.
  int argb_stride;           // This is stride in pixels units, not bytes.

  // Byte-emission hook, to store compressed bytes as they are ready.
  WebPWriterFunction writer;  // can be NULL
  void* custom_ptr;           // can be used by the writer.

  // Error code for the latest error encountered during encoding
  WebPEncodingError error_code;
};

Cette structure a également une fonction pour émettre les octets compressés lorsqu'ils sont mis à disposition. Vous trouverez ci-dessous un exemple avec un rédacteur en mémoire. D'autres rédacteurs peuvent stocker directement des données dans un fichier (voir examples/cwebp.c pour cet exemple).

Le flux général d'encodage à l'aide de l'API avancée se présente comme suit : suivantes:

Nous devons tout d'abord définir une configuration d'encodage contenant le paramètres de compression. Notez que vous pouvez utiliser la même configuration permettant de compresser plusieurs images différentes par la suite.

#include "webp/encode.h"

WebPConfig config;
if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) return 0;   // version error

// Add additional tuning:
config.sns_strength = 90;
config.filter_sharpness = 6;
config.alpha_quality = 90;
config_error = WebPValidateConfig(&config);  // will verify parameter ranges (always a good habit)

Ensuite, les échantillons d'entrée doivent être référencés dans un WebPPicture par référence ou par copie. Voici un exemple d'allocation du tampon pour la conservation les échantillons. Mais il est facile de configurer une "vue" à un budget déjà alloué exemple de tableau. Consultez la fonction WebPPictureView().

// Setup the input data, allocating a picture of width x height dimension
WebPPicture pic;
if (!WebPPictureInit(&pic)) return 0;  // version error
pic.width = width;
pic.height = height;
if (!WebPPictureAlloc(&pic)) return 0;   // memory error

// At this point, 'pic' has been initialized as a container, and can receive the YUVA or RGBA samples.
// Alternatively, one could use ready-made import functions like WebPPictureImportRGBA(), which will take
// care of memory allocation. In any case, past this point, one will have to call WebPPictureFree(&pic)
// to reclaim allocated memory.

Pour émettre les octets compressés, un hook est appelé chaque fois que de nouveaux octets sont disponibles. Voici un exemple simple avec le paramètre Memory-writer déclaré dans webp/encode.h Cette initialisation sera probablement nécessaire chaque image à compresser:

// Set up a byte-writing method (write-to-memory, in this case):
WebPMemoryWriter writer;
WebPMemoryWriterInit(&writer);
pic.writer = WebPMemoryWrite;
pic.custom_ptr = &writer;

Nous sommes maintenant prêts à compresser les échantillons d'entrée (et à libérer leur mémoire par la suite):

int ok = WebPEncode(&config, &pic);
WebPPictureFree(&pic);   // Always free the memory associated with the input.
if (!ok) {
  printf("Encoding error: %d\n", pic.error_code);
} else {
  printf("Output size: %d\n", writer.size);
}

Pour une utilisation plus avancée de l'API et de la structure, nous vous recommandons de consulter consultez la documentation disponible dans l'en-tête webp/encode.h. Lire l'exemple de code examples/cwebp.c peut s'avérer utile pour identifier les paramètres les moins utilisés.