diff --git a/src/guacenc/webp.c b/src/guacenc/webp.c index 63024373..191d0451 100644 --- a/src/guacenc/webp.c +++ b/src/guacenc/webp.c @@ -21,14 +21,57 @@ */ #include "config.h" +#include "log.h" #include "webp.h" #include +#include +#include +#include #include cairo_surface_t* guacenc_webp_decoder(unsigned char* data, int length) { - /* STUB */ - return NULL; + + int width, height; + + /* Validate WebP and pull dimensions */ + if (!WebPGetInfo((uint8_t*) data, length, &width, &height)) { + guacenc_log(GUAC_LOG_WARNING, "Invalid WebP data"); + return NULL; + } + + /* Create blank Cairo surface */ + cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + width, height); + + /* Fill surface with opaque black */ + cairo_t* cairo = cairo_create(surface); + cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); + cairo_set_source_rgba(cairo, 0.0, 0.0, 0.0, 1.0); + cairo_paint(cairo); + cairo_destroy(cairo); + + /* Finish any pending draws */ + cairo_surface_flush(surface); + + /* Pull underlying buffer and its stride */ + int stride = cairo_image_surface_get_stride(surface); + unsigned char* image = cairo_image_surface_get_data(surface); + + /* Read WebP into surface */ + uint8_t* result = WebPDecodeBGRAInto((uint8_t*) data, length, + (uint8_t*) image, stride * height, stride); + + /* Verify WebP was successfully decoded */ + if (result == NULL) { + guacenc_log(GUAC_LOG_WARNING, "Invalid WebP data"); + cairo_surface_destroy(surface); + return NULL; + } + + /* WebP was read successfully */ + return surface; + }