
Preuve de concept d'exploit pour CVE-2023-1999 ciblant la bibliothèque de codec WebP sur Android 10 (r33). Démontre une vulnérabilité de heap buffer overflow dans la bibliothèque libwebp, permettant l'exécution de code à distance via une image WebP spécialement conçue.
/ \\/ \/ _ \/ _ )/ _ \
\ / __/ _ \ __/
\__\__/\____/\_____/__/ ____ ___
/ _/ / \ \ / _ \/ _/
/ \_/ / / \ \ __/ \__
\____/____/\_____/_____/____/v1.0.2
Codec WebP : bibliothèque pour encoder et décoder des images au format WebP. Ce paquet contient la bibliothèque qui peut être utilisée dans d'autres programmes pour ajouter le support WebP, ainsi que les outils en ligne de commande 'cwebp' et 'dwebp'.
Voir http://developers.google.com/speed/webp
L'arborescence source la plus récente est disponible à l'adresse https://chromium.googlesource.com/webm/libwebp
Elle est distribuée sous la même licence que le projet WebM. Voir http://www.webmproject.org/license/software/ ou le fichier "COPYING" pour plus de détails. Une concession supplémentaire de droits de propriété intellectuelle se trouve dans le fichier PATENTS.
En exécutant :
nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
le répertoire output\release-static(x64|x86)\bin contiendra les outils cwebp.exe et dwebp.exe. Le répertoire output\release-static(x64|x86)\lib contiendra la bibliothèque statique libwebp. L'architecture cible (x86/x64) est détectée par Makefile.vc depuis le compilateur Visual Studio (cl.exe) disponible dans le chemin système.
Sur les plateformes avec les outils GNU installés (gcc et make), exécuter
make -f makefile.unix
construira les binaires examples/cwebp et examples/dwebp, ainsi que la bibliothèque statique src/libwebp.a. Aucune installation système n'est fournie, car il s'agit d'une alternative simple au système d'installation complet basé sur les outils autoconf (voir ci-dessous). Veuillez vous référer à makefile.unix pour plus de détails et de personnalisations.
Prérequis : Un compilateur (par ex. gcc), make, autoconf, automake, libtool. Sur un système de type Debian, ce qui suit devrait installer tout ce dont vous avez besoin pour une construction minimale : $ sudo apt-get install gcc make autoconf automake libtool
Lors de la construction à partir des sources git, vous devrez exécuter autogen.sh pour générer le script configure.
./configure make make install
devrait être tout ce dont vous avez besoin pour obtenir les fichiers suivants
/usr/local/include/webp/decode.h /usr/local/include/webp/encode.h /usr/local/include/webp/types.h /usr/local/lib/libwebp.* /usr/local/bin/cwebp /usr/local/bin/dwebp
installés.
Remarque : Une bibliothèque de décodage uniquement, libwebpdecoder, est disponible en utilisant le drapeau '--enable-libwebpdecoder'. La bibliothèque d'encodage est construite séparément et peut être installée indépendamment en utilisant une modification mineure dans les fichiers configure Makefile.am correspondants (voir les commentaires ici). Voir './configure --help' pour plus d'options.
Les versions stables disponibles de la chaîne d'outils MIPS Linux peuvent être trouvées à : https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/available-releases/
export PATH=$PATH:/path/to/toolchain/bin
HOST=mips-mti-linux-gnu
MIPS_CFLAGS="-O3 -mips32r5 -mabi=32 -mtune=p5600 -mmsa -mfp64
-msched-weight -mload-store-pairs -fPIE"
MIPS_LDFLAGS="-mips32r5 -mabi=32 -mmsa -mfp64 -pie"
HOST=mips-img-linux-gnu
MIPS_CFLAGS="-O3 -mips64r6 -mabi=64 -mtune=i6400 -mmsa -mfp64
-msched-weight -mload-store-pairs -fPIE"
MIPS_LDFLAGS="-mips64r6 -mabi=64 -mmsa -mfp64 -pie"
./configure --host=${HOST} --build=config.guess
CC="${HOST}-gcc -EL"
CFLAGS="$MIPS_CFLAGS"
LDFLAGS="$MIPS_LDFLAGS"
make
make install
Avec CMake, vous pouvez compiler libwebp, cwebp, dwebp, gif2web, img2webp, webpinfo et les liaisons JS.
Prérequis : Un compilateur (par ex. gcc avec autotools) et CMake. Sur un système de type Debian, ce qui suit devrait installer tout ce dont vous avez besoin pour une construction minimale : $ sudo apt-get install build-essential cmake
Lors de la construction à partir des sources git, vous devrez exécuter cmake pour générer les makefiles.
mkdir build && cd build && cmake ../ make make install
Si vous souhaitez également l'un des exécutables, vous devrez les activer via CMake, par exemple :
cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../
ou via votre interface préférée (comme ccmake ou cmake-qt-gui).
Utilisez l'option -DWEBP_UNICODE=ON pour le support Unicode sous Windows (avec chcp 65001).
Enfin, une fois installé, vous pouvez également utiliser WebP dans votre projet CMake en faisant :
find_package(WebP)
ce qui définira les variables CMake WebP_INCLUDE_DIRS et WebP_LIBRARIES.
Le support pour Gradle est minimal : il vous aide seulement à compiler libwebp, cwebp et dwebp et webpmux_example.
Prérequis : Un compilateur (par ex. gcc avec autotools) et gradle. Sur un système de type Debian, ce qui suit devrait installer tout ce dont vous avez besoin pour une construction minimale : $ sudo apt-get install build-essential gradle
Lors de la construction à partir des sources git, vous devrez exécuter le wrapper Gradle avec la cible appropriée, par exemple :
./gradlew buildAllExecutables
Pour générer des liaisons linguistiques à partir de swig/libwebp.swig, au moins swig-1.3 (http://www.swig.org) est requis.
Actuellement, les fonctions suivantes sont mappées : Decode : WebPGetDecoderVersion WebPGetInfo WebPDecodeRGBA WebPDecodeARGB WebPDecodeBGRA WebPDecodeBGR WebPDecodeRGB
Encode : WebPGetEncoderVersion WebPEncodeRGBA WebPEncodeBGRA WebPEncodeRGB WebPEncodeBGR WebPEncodeLosslessRGBA WebPEncodeLosslessBGRA WebPEncodeLosslessRGB WebPEncodeLosslessBGR
Voir swig/README pour des instructions de construction plus détaillées.
Liaisons Java :
Pour construire le code wrapper JNI généré par swig, au moins JDK-1.5 (ou équivalent) est nécessaire pour le support des énumérations. La sortie est destinée à être un objet partagé / DLL qui peut être chargé via System.loadLibrary("webp_jni").
Liaisons Python :
Pour construire le code d'extension Python généré par swig, au moins Python 2.6 est requis. Python < 2.6 pourrait être construit avec quelques modifications mineures de libwebp.swig ou du code généré, mais n'a pas été testé.
Le répertoire examples/ contient des outils pour encoder (cwebp) et décoder (dwebp) des images.
L'utilisation la plus simple devrait ressembler à : cwebp input.png -q 80 -o output.webp ce qui convertira le fichier d'entrée en un fichier WebP en utilisant un facteur de qualité de 80 sur une échelle de 0 à 100 (0 étant la qualité la plus basse, 100 la meilleure. La valeur par défaut est 75). Vous voudrez peut-être aussi essayer le drapeau -lossless, qui comprimera la source (en format RGBA) sans aucune perte. Le paramètre de qualité -q contrôlera dans ce cas la quantité de temps de traitement consacré à essayer de rendre le fichier de sortie aussi petit que possible.
Une liste plus longue d'options est disponible en utilisant le drapeau de ligne de commande -longhelp :
cwebp -longhelp Usage : cwebp [-preset <...>] [options] in_file [-o out_file]
Si la taille d'entrée (-s) pour une image n'est pas spécifiée, il est supposé qu'il s'agit d'un fichier PNG, JPEG, TIFF ou WebP.
Options : -h / -help ............. aide courte -H / -longhelp ......... aide longue -q ............. facteur de qualité (0:petit..100:grand), défaut=75 -alpha_q ......... qualité de compression de la transparence (0..100), défaut=100 -preset ....... réglage prédéfini, l'un de : default, photo, picture, drawing, icon, text -preset doit venir en premier, car il écrase les autres paramètres -z ............... active le préréglage sans perte avec le niveau donné dans [0:rapide, ..., 9:le plus lent]
-m ............... méthode de compression (0=rapide, 6=le plus lent), défaut=4 -segments ........ nombre de segments à utiliser (1..4), défaut=4 -size ............ taille cible (en octets) -psnr .......... PSNR cible (en dB. typiquement : 42)
-s ......... taille d'entrée (largeur x hauteur) pour YUV -sns ............. mise en forme du bruit spatial (0:désactivé, 100:max), défaut=50 -f ............... force du filtre (0=désactivé..100), défaut=60 -sharpness ....... netteté du filtre (0:la plus .. 7:la moins nette), défaut=0 -strong ................ utiliser un filtre fort au lieu du simple (défaut) -nostrong .............. utiliser un filtre simple au lieu du fort -sharp_yuv ............. utiliser une conversion RVB->YUV plus nette (et plus lente) -partition_limit . limiter la qualité pour respecter la limite de 512k sur la première partition (0=pas de dégradation ... 100=complète) -pass ............ numéro de passe d'analyse (1..10) -crop .. recadrer l'image avec le rectangle donné -resize ........ redimensionner l'image (après tout recadrage) -mt .................... utiliser le multi-threading si disponible -low_memory ............ réduire l'utilisation de la mémoire (encodage plus lent) -map ............. imprimer une carte des informations supplémentaires -print_psnr ............ imprime la distorsion PSNR moyenne -print_ssim ............ imprime la distorsion SSIM moyenne -print_lsim ............ imprime la distorsion de similarité locale -d <file.pgm> .......... déverser la sortie compressée (fichier PGM) -alpha_method .... méthode de compression de la transparence (0..1), défaut=1 -alpha_filter . filtrage prédictif pour le plan alpha, l'un de : none, fast (défaut) ou best -exact ................. préserver les valeurs RVB dans la zone transparente, défaut=désactivé -blend_alpha ..... mélanger les couleurs sur la couleur de fond exprimée sous forme de valeurs RVB écrites en hexadécimal, par ex. 0xc0e0d0 pour rouge=0xc0 vert=0xe0 et bleu=0xd0 -noalpha ............... supprimer toute information de transparence -lossless .............. encoder l'image sans perte, défaut=désactivé -near_lossless ... utiliser le prétraitement d'image quasi sans perte (0..100=désactivé), défaut=100 -hint ......... spécifier une indication sur les caractéristiques de l'image, l'un de : photo, picture ou graph
-metadata ..... liste de métadonnées séparées par des virgules à copier de l'entrée vers la sortie si présente. Valeurs valides : all, none (défaut), exif, icc, xmp
-short ................. condenser le message imprimé -quiet ................. n'imprimer rien -version ............... imprimer le numéro de version et quitter -noasm ................. désactiver toutes les optimisations d'assembly -v ..................... verbeux, par ex. imprimer les temps d'encodage/décodage -progress .............. signaler la progression de l'encodage
Options expérimentales : -jpeg_like ............. correspondre approximativement à la taille JPEG attendue -af .................... ajuster automatiquement la force du filtre -pre ............. filtre de prétraitement
Les principales options que vous voudrez peut-être essayer pour affiner davantage la qualité visuelle sont : -preset -sns -f -m
À savoir :
Il y a un exemple de décodage dans examples/dwebp.c qui prendra un fichier .webp et le décodera en un fichier image PNG (entre autres formats). Ceci est simplement pour démontrer l'utilisation de l'API. Vous pouvez vérifier que le fichier test.webp se décode exactement comme test_ref.ppm en utilisant :
cd examples ./dwebp test.webp -ppm -o test.ppm diff test.ppm test_ref.ppm
La liste complète des options est disponible en utilisant -h :
dwebp -h Usage : dwebp in_file [options] [-o out_file]
Décode le fichier image WebP au format PNG [Par défaut] Utilisez les options suivantes pour convertir dans des formats d'image alternatifs : -pam ......... sauvegarder les échantillons RGBA bruts en tant que PAM couleur -ppm ......... sauvegarder les échantillons RVB bruts en tant que PPM couleur -bmp ......... sauvegarder au format BMP non compressé -tiff ........ sauvegarder au format TIFF non compressé -pgm ......... sauvegarder les échantillons YUV bruts en tant que PGM en niveaux de gris avec disposition IMC4 -yuv ......... sauvegarder les échantillons YUV bruts en disposition plane
Autres options sont : -version ..... imprimer le numéro de version et quitter -nofancy ..... ne pas utiliser le sur-échantillonneur YUV420 sophistiqué -nofilter .... désactiver le filtrage en boucle -nodither .... désactiver le tramage -dither .. force du tramage (dans 0..100) -alpha_dither utiliser le tramage du plan alpha si nécessaire -mt .......... utiliser le multi-threading -crop ... recadrer la sortie avec le rectangle donné -resize ......... redimensionner la sortie (après tout recadrage) -flip ........ retourner la sortie verticalement -alpha ....... sauvegarder uniquement le plan alpha -incremental . utiliser le décodage incrémental (utile pour les tests) -h ........... ce message d'aide -v ........... verbeux (par ex. imprimer les temps d'encodage/décodage) -quiet ....... mode silencieux, n'imprimer rien -noasm ....... désactiver toutes les optimisations d'assembly
'webpinfo' peut être utilisé pour imprimer la structure au niveau des chunks et les informations d'en-tête de flux binaire des fichiers WebP. Il peut également vérifier si les fichiers sont au format WebP valide.
Usage : webpinfo [options] in_files Remarque : il peut y avoir plusieurs fichiers d'entrée ; les options doivent précéder les fichiers d'entrée. Options : -version ........... Imprimer le numéro de version et quitter. -quiet ............. Ne pas afficher les informations d'analyse des chunks. -diag .............. Afficher le diagnostic des erreurs d'analyse. -summary ........... Afficher le résumé des statistiques des chunks. -bitstream_info .... Analyser l'en-tête du flux binaire.
Il y a un petit outil de visualisation libre-service appelé 'vwebp' dans le répertoire examples/. Il utilise OpenGL pour ouvrir une simple fenêtre de dessin et afficher un fichier WebP décodé. Il n'est pas encore intégré dans le système de compilation automake, mais vous pouvez essayer de le compiler manuellement en utilisant les recommandations ci-dessous.
Usage : vwebp in_file [options]
Décode le fichier image WebP et le visualise en utilisant OpenGL Les options sont : -version ..... imprimer le numéro de version et quitter -noicc ....... ne pas utiliser le profil icc s'il est présent -nofancy ..... ne pas utiliser le sur-échantillonneur YUV420 sophistiqué -nofilter .... désactiver le filtrage en boucle -dither force du tramage (0..100), défaut=50 -noalphadither désactiver le tramage du plan alpha -usebgcolor .. afficher la couleur de fond -mt .......... utiliser le multi-threading -info ........ imprimer les informations -h ........... ce message d'aide
Raccourcis clavier : 'c' ................ basculer l'utilisation du profil colorimétrique 'b' ................ basculer l'affichage de la couleur de fond 'i' ................ superposer les informations du fichier 'd' ................ désactiver le mélange et l'élimination (débogage) 'q' / 'Q' / ESC .... quitter
Prérequis :
OpenGL & OpenGL Utility Toolkit (GLUT) Linux : $ sudo apt-get install freeglut3-dev mesa-common-dev Mac + XCode :
(Optionnel) qcms (Quick Color Management System) i. Téléchargez qcms depuis Mozilla / Chromium : http://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms http://src.chromium.org/viewvc/chrome/trunk/src/third_party/qcms ii. Compilez et archivez les fichiers sources en tant que libqcms.a / qcms.lib iii. Mettez à jour makefile.unix / Makefile.vc a) Définissez WEBP_HAVE_QCMS b) Mettez à jour les chemins d'inclusion / de bibliothèque pour référencer le répertoire qcms.
Construction en utilisant makefile.unix / Makefile.vc : $ make -f makefile.unix examples/vwebp
nmake /f Makefile.vc CFG=release-static
../obj/x64/release-static/bin/vwebp.exe
L'utilitaire 'img2webp' peut transformer une séquence d'images d'entrée (PNG, JPEG, ...) en un fichier WebP animé. Il offre un contrôle fin sur la durée, les modes d'encodage, etc.
Usage :
img2webp [options au niveau du fichier] [fichiers image...] [options par trame...]
Options au niveau du fichier (utilisées uniquement au début de la compression) : -min_size ............ minimiser la taille -loop .......... nombre de boucles (défaut : 0, = boucle infinie) -kmax .......... nombre maximal de trames entre les trames clés (0=trames clés uniquement) -kmin .......... nombre minimal de trames entre les trames clés (0=désactiver complètement les trames clés) -mixed ............... utiliser le mode automatique mixte avec/sans perte -v ................... mode verbeux -h ................... cette aide -version ............. imprimer le numéro de version et quitter
Options par trame (utilisées uniquement pour les images d'entrée suivantes) : -d ............. durée de la trame en ms (défaut : 100) -lossless ........... utiliser le mode sans perte (défaut) -lossy ... ........... utiliser le mode avec perte -q ........... qualité -m ............. méthode à utiliser
exemple : img2webp -loop 2 in0.png -lossy in1.jpg -d 80 in2.tiff -o out.webp
Remarque : si un seul nom de fichier est passé en argument, les arguments seront tokenisés à partir de ce fichier. Le nom du fichier ne doit pas commencer par le caractère '-'.
Les fichiers GIF animés peuvent être convertis en fichiers WebP avec animation en utilisant l'utilitaire gif2webp disponible dans examples/. Les fichiers peuvent ensuite être visualisés en utilisant vwebp.
Usage : gif2webp [options] gif_file -o webp_file Options : -h / -help ............. cette aide -lossy ................. encoder l'image en utilisant la compression avec perte -mixed ................. pour chaque trame de l'image, choisir heuristiquement la compression avec ou sans perte -q ............. facteur de qualité (0:petit..100:grand) -m ............... méthode de compression (0=rapide, 6=le plus lent) -min_size .............. minimiser la taille de sortie (défaut : désactivé) compression sans perte par défaut ; peut être combiné avec les options -q, -m, -lossy ou -mixed -kmin ............ distance minimale entre les trames clés -kmax ............ distance maximale entre les trames clés -f ............... force du filtre (0=désactivé..100) -metadata ..... liste de métadonnées séparées par des virgules à copier de l'entrée vers la sortie si présente Valeurs valides : all, none, icc, xmp (défaut) -loop_compatibility .... utiliser le mode de compatibilité pour les versions de Chrome antérieures à M62 (inclus) -mt .................... utiliser le multi-threading si disponible
-version ............... imprimer le numéro de version et quitter -v ..................... verbeux -quiet ................. n'imprimer rien
Avec les fichiers de développement libgif installés, gif2webp peut être construit en utilisant makefile.unix : $ make -f makefile.unix examples/gif2webp
ou en utilisant autoconf : $ ./configure --enable-everything $ make
L'utilitaire de test anim_diff sous examples/ peut être utilisé pour comparer deux images animées (chacune peut être GIF ou WebP).Usage: anim_diff [options]
Options: -dump_frames dump decoded frames in PAM format -min_psnr ... minimum per-frame PSNR -raw_comparison ..... if this flag is not used, RGB is premultiplied before comparison -max_diff ..... maximum allowed difference per channel between corresponding pixels in subsequent frames -h .................. this help -version ............ print version number and exit
With the libgif development files and a C++ compiler installed, anim_diff can be built using makefile.unix: $ make -f makefile.unix examples/anim_diff
or using autoconf: $ ./configure --enable-everything $ make
The main encoding functions are available in the header src/webp/encode.h The ready-to-use ones are: 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);
They will convert raw RGB samples to a WebP data. The only control supplied is the quality factor.
There are some variants for using the lossless format:
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);
Of course in this case, no quality factor is needed since the compression occurs without loss of the input values, at the expense of larger output sizes.
A more advanced API is based on the WebPConfig and WebPPicture structures.
WebPConfig contains the encoding settings and is not tied to a particular picture. WebPPicture contains input data, on which some WebPConfig will be used for compression. The encoding flow looks like:
-------------------------------------- BEGIN PSEUDO EXAMPLE
#include <webp/encode.h>
// Setup a config, starting form a preset and tuning some additional // parameters WebPConfig config; if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) return 0; // version error } // ... additional tuning config.sns_strength = 90; config.filter_sharpness = 6; config_error = WebPValidateConfig(&config); // not mandatory, but useful
// Setup the input data WebPPicture pic; if (!WebPPictureInit(&pic)) { return 0; // version error } pic.width = width; pic.height = height; // allocated picture of dimension width x height if (!WebPPictureAllocate(&pic)) { return 0; // memory error } // at this point, 'pic' has been initialized as a container, // and can receive the Y/U/V samples. // Alternatively, one could use ready-made import functions like // WebPPictureImportRGB(), which will take care of memory allocation. // In any case, past this point, one will have to call // WebPPictureFree(&pic) to reclaim memory.
// Set up a byte-output write method. WebPMemoryWriter, for instance. WebPMemoryWriter wrt; WebPMemoryWriterInit(&wrt); // initialize 'wrt'
pic.writer = MyFileWriter; pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
// Compress! int ok = WebPEncode(&config, &pic); // ok = 0 => error occurred! WebPPictureFree(&pic); // must be called independently of the 'ok' result.
// output data should have been handled by the writer at that point. // -> compressed data is the memory buffer described by wrt.mem / wrt.size
// deallocate the memory used by compressed data WebPMemoryWriterClear(&wrt);
-------------------------------------- END PSEUDO EXAMPLE
This is mainly just one function to call:
#include "webp/decode.h" uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size, int* width, int* height);
Please have a look at the file src/webp/decode.h for the details. There are variants for decoding in BGR/RGBA/ARGB/BGRA order, along with decoding to raw Y'CbCr samples. One can also decode the image directly into a pre-allocated buffer.
To detect a WebP file and gather the picture's dimensions, the function: int WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height); is supplied. No decoding is involved when using it.
In the case when data is being progressively transmitted, pictures can still be incrementally decoded using a slightly more complicated API. Decoder state is stored into an instance of the WebPIDecoder object. This object can be created with the purpose of decoding either RGB or Y'CbCr samples. For instance:
WebPDecBuffer buffer; WebPInitDecBuffer(&buffer); buffer.colorspace = MODE_BGR; ... WebPIDecoder* idec = WebPINewDecoder(&buffer);
As data is made progressively available, this incremental-decoder object can be used to decode the picture further. There are two (mutually exclusive) ways to pass freshly arrived data:
either by appending the fresh bytes:
WebPIAppend(idec, fresh_data, size_of_fresh_data);
or by just mentioning the new size of the transmitted data:
WebPIUpdate(idec, buffer, size_of_transmitted_buffer);
Note that 'buffer' can be modified between each call to WebPIUpdate, in particular when the buffer is resized to accommodate larger data.
These functions will return the decoding status: either VP8_STATUS_SUSPENDED if decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other status is an error condition.
The 'idec' object must always be released (even upon an error condition) by calling: WebPDelete(idec).
To retrieve partially decoded picture samples, one must use the corresponding method: WebPIDecGetRGB or WebPIDecGetYUVA. It will return the last displayable pixel row.
Lastly, note that decoding can also be performed into a pre-allocated pixel buffer. This buffer must be passed when creating a WebPIDecoder, calling WebPINewRGB() or WebPINewYUVA().
Please have a look at the src/webp/decode.h header for further details.
WebP decoding supports an advanced API which provides on-the-fly cropping and rescaling, something of great usefulness on memory-constrained environments like mobile phones. Basically, the memory usage will scale with the output's size, not the input's, when one only needs a quick preview or a zoomed in portion of an otherwise too-large picture. Some CPU can be saved too, incidentally.
-------------------------------------- BEGIN PSEUDO EXAMPLE // A) Init a configuration object WebPDecoderConfig config; CHECK(WebPInitDecoderConfig(&config));
// B) optional: retrieve the bitstream's features.
CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
// C) Adjust 'config' options, if needed
config.options.no_fancy_upsampling = 1;
config.options.use_scaling = 1;
config.options.scaled_width = scaledWidth();
config.options.scaled_height = scaledHeight();
// etc.
// D) Specify 'config' output options for specifying output colorspace.
// Optionally the external image decode buffer can also be specified.
config.output.colorspace = MODE_BGRA;
// Optionally, the config.output can be pointed to an external buffer as
// well for decoding the image. This externally supplied memory buffer
// should be big enough to store the decoded picture.
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;
// E) Decode the WebP image. There are two variants w.r.t decoding image.
// The first one (E.1) decodes the full image and the second one (E.2) is
// used to incrementally decode the image using small input buffers.
// Any one of these steps can be used to decode the WebP image.
// E.1) Decode full image.
CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
// E.2) Decode image incrementally.
WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
CHECK(idec != NULL);
while (bytes_remaining > 0) {
VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
bytes_remaining -= bytes_read;
} else {
break;
}
}
WebPIDelete(idec);
// F) Decoded image is now in config.output (and config.output.u.RGBA).
// It can be saved, displayed or otherwise processed.
// G) Reclaim memory allocated in config's object. It's safe to call
// this function even if the memory is external and wasn't allocated
// by WebPDecode().
WebPFreeDecBuffer(&config.output);
-------------------------------------- END PSEUDO EXAMPLE
Please report all bugs to the issue tracker: https://bugs.chromium.org/p/webp Patches welcome! See this page to get started: http://www.webmproject.org/code/contribute/submitting-patches/
Email: [email protected] Web: http://groups.google.com/a/webmproject.org/group/webp-discuss