diff --git a/src/libguac/client.c b/src/libguac/client.c index f7747ea3..358af87b 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -36,6 +36,10 @@ #include "stream.h" #include "timestamp.h" +#ifdef ENABLE_WEBP +#include "encode-webp.h" +#endif + #ifdef HAVE_OSSP_UUID_H #include #else @@ -419,3 +423,54 @@ void guac_client_stream_jpeg(guac_client* client, guac_socket* socket, } +void guac_client_stream_webp(guac_client* client, guac_socket* socket, + guac_composite_mode mode, const guac_layer* layer, int x, int y, + cairo_surface_t* surface, int quality) { + +#ifdef ENABLE_WEBP + /* Allocate new stream for image */ + guac_stream* stream = guac_client_alloc_stream(client); + + /* Declare stream as containing image data */ + guac_protocol_send_img(socket, stream, mode, layer, "image/webp", x, y); + + /* Write WebP data */ + guac_webp_write(socket, stream, surface, quality); + + /* Terminate stream */ + guac_protocol_send_end(socket, stream); + + /* Free allocated stream */ + guac_client_free_stream(client, stream); +#else + /* Do nothing if WebP support is not built in */ +#endif + +} + +int guac_client_supports_webp(guac_client* client) { + +#ifdef ENABLE_WEBP + const char** mimetype = client->info.image_mimetypes; + + /* Search for WebP mimetype in list of supported image mimetypes */ + while (*mimetype != NULL) { + + /* If WebP mimetype found, no need to search further */ + if (strcmp(*mimetype, "image/webp") == 0) + return 1; + + /* Next mimetype */ + mimetype++; + + } + + /* Client does not support WebP */ + return 0; +#else + /* Support for WebP is completely absent */ + return 0; +#endif + +} + diff --git a/src/libguac/guacamole/client.h b/src/libguac/guacamole/client.h index 27bb7901..1e8c17d2 100644 --- a/src/libguac/guacamole/client.h +++ b/src/libguac/guacamole/client.h @@ -696,11 +696,67 @@ void guac_client_stream_png(guac_client* client, guac_socket* socket, * * @param surface * A Cairo surface containing the image data to be streamed. + * + * @param quality + * The JPEG image quality, which must be an integer value between 0 and + * 100 inclusive. */ void guac_client_stream_jpeg(guac_client* client, guac_socket* socket, guac_composite_mode mode, const guac_layer* layer, int x, int y, cairo_surface_t* surface, int quality); +/** + * Streams the image data of the given surface over an image stream ("img" + * instruction) as WebP-encoded data at the given quality. The image stream + * will be automatically allocated and freed. If the server does not support + * WebP, this function has no effect, so be sure to check the result of + * guac_client_supports_webp() prior to calling this function. + * + * @param client + * The Guacamole client from which the image stream should be allocated. + * + * @param socket + * The socket over which instructions associated with the image stream + * should be sent. + * + * @param mode + * The composite mode to use when rendering the image over the given layer. + * + * @param layer + * The destination layer. + * + * @param x + * The X coordinate of the upper-left corner of the destination rectangle + * within the given layer. + * + * @param y + * The Y coordinate of the upper-left corner of the destination rectangle + * within the given layer. + * + * @param surface + * A Cairo surface containing the image data to be streamed. + * + * @param quality + * The WebP image quality, which must be an integer value between 0 and + * 100 inclusive. + */ +void guac_client_stream_webp(guac_client* client, guac_socket* socket, + guac_composite_mode mode, const guac_layer* layer, int x, int y, + cairo_surface_t* surface, int quality); + +/** + * Returns whether the given client supports WebP. If the client does not + * support WebP, or the server cannot encode WebP images, zero is returned. + * + * @param client + * The Guacamole client to check for WebP support. + * + * @return + * Non-zero if the given client claims to support WebP and the server has + * been built with WebP support, zero otherwise. + */ +int guac_client_supports_webp(guac_client* client); + /** * The default Guacamole client layer, layer 0. */