From 3cae4f016f8274269076c307dd744f2e358f1c6e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 1 Apr 2012 20:19:12 -0700 Subject: [PATCH] Use libpng for writing of PNGs (currently only works with RGB/RGBA surfaces, and only writes RGB) --- libguac/src/protocol.c | 113 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 10 deletions(-) diff --git a/libguac/src/protocol.c b/libguac/src/protocol.c index 9176c491..3f99fb68 100644 --- a/libguac/src/protocol.c +++ b/libguac/src/protocol.c @@ -54,6 +54,8 @@ #include #endif +#include + #include #include @@ -108,12 +110,18 @@ typedef struct __guac_socket_write_png_data { int buffer_size; int data_size; -} - __guac_socket_write_png_data; +} __guac_socket_write_png_data; -cairo_status_t __guac_socket_write_png(void* closure, const unsigned char* data, unsigned int length) { +void __guac_socket_write_png(png_structp png, + png_bytep data, png_size_t length) { - __guac_socket_write_png_data* png_data = (__guac_socket_write_png_data*) closure; + /* Get png buffer structure */ + __guac_socket_write_png_data* png_data; +#ifdef HAVE_PNG_GET_IO_PTR + png_data = (__guac_socket_write_png_data*) png_get_io_ptr(png); +#else + png_data = (__guac_socket_write_png_data*) png->io_ptr; +#endif /* Calculate next buffer size */ int next_size = png_data->data_size + length; @@ -137,26 +145,111 @@ cairo_status_t __guac_socket_write_png(void* closure, const unsigned char* data, memcpy(png_data->buffer + png_data->data_size, data, length); png_data->data_size += length; - return CAIRO_STATUS_SUCCESS; - } +void __guac_socket_flush_png(png_structp png) { + /* Dummy function */ +} int __guac_socket_write_length_png(guac_socket* socket, cairo_surface_t* surface) { + png_structp png; + png_infop png_info; + png_byte** png_rows; + + int x, y; + __guac_socket_write_png_data png_data; int base64_length; - /* Write surface */ + /* Get image surface properties and data */ + /*cairo_format_t format = cairo_image_surface_get_format(surface);*/ + int width = cairo_image_surface_get_width(surface); + int height = cairo_image_surface_get_height(surface); + int stride = cairo_image_surface_get_stride(surface); + unsigned char* data = cairo_image_surface_get_data(surface); + /* Flush pending operations to surface */ + cairo_surface_flush(surface); + + /* If not an image surface, fail */ + if (data == NULL) { + return -1; /* FIXME: Set guac_error, etc? */ + } + + /* Copy data from surface into PNG data */ + png_rows = (png_byte**) malloc(sizeof(png_byte*) * height); + for (y=0; y