GUAC-1366: Adjust WebP and JPEG image sizes before compressing to avoid artifacts on the edges of the images

This commit is contained in:
Frode Langelo 2015-10-06 22:31:58 +00:00
parent 6a7b397110
commit 69a7b8c066

View File

@ -98,6 +98,20 @@
*/ */
#define GUAC_SURFACE_WEBP_IMAGE_QUALITY 90 #define GUAC_SURFACE_WEBP_IMAGE_QUALITY 90
/**
* The JPEG compression min block size. This defines the optimal rectangle block
* size factor for JPEG compression. Usually 8x8 would suffice, but use 16 to
* reduce the occurrence of ringing artifacts further.
*/
#define GUAC_SURFACE_JPEG_BLOCK_SIZE 16
/**
* The WebP compression min block size. This defines the optimal rectangle block
* size factor for WebP compression. WebP does utilize variable block size, but
* ensuring a block size factor reduces any noise on the image edges.
*/
#define GUAC_SURFACE_WEBP_BLOCK_SIZE 8
/** /**
* Updates the coordinates of the given rectangle to be within the bounds of * Updates the coordinates of the given rectangle to be within the bounds of
* the given surface. * the given surface.
@ -1290,6 +1304,14 @@ static void __guac_common_surface_flush_to_jpeg(guac_common_surface* surface) {
guac_socket* socket = surface->socket; guac_socket* socket = surface->socket;
const guac_layer* layer = surface->layer; const guac_layer* layer = surface->layer;
guac_common_rect max;
guac_common_rect_init(&max, 0, 0, surface->width, surface->height);
/* Expand the dirty rect size to fit in a grid with cells equal to the
* minimum JPEG block size */
guac_common_rect_expand_to_grid(GUAC_SURFACE_JPEG_BLOCK_SIZE,
&surface->dirty_rect, &max);
/* Get Cairo surface for specified rect */ /* Get Cairo surface for specified rect */
unsigned char* buffer = surface->buffer + surface->dirty_rect.y * surface->stride + surface->dirty_rect.x * 4; unsigned char* buffer = surface->buffer + surface->dirty_rect.y * surface->stride + surface->dirty_rect.x * 4;
cairo_surface_t* rect = cairo_image_surface_create_for_data(buffer, CAIRO_FORMAT_RGB24, cairo_surface_t* rect = cairo_image_surface_create_for_data(buffer, CAIRO_FORMAT_RGB24,
@ -1327,6 +1349,14 @@ static void __guac_common_surface_flush_to_webp(guac_common_surface* surface) {
guac_socket* socket = surface->socket; guac_socket* socket = surface->socket;
const guac_layer* layer = surface->layer; const guac_layer* layer = surface->layer;
guac_common_rect max;
guac_common_rect_init(&max, 0, 0, surface->width, surface->height);
/* Expand the dirty rect size to fit in a grid with cells equal to the
* minimum WebP block size */
guac_common_rect_expand_to_grid(GUAC_SURFACE_WEBP_BLOCK_SIZE,
&surface->dirty_rect, &max);
/* Get Cairo surface for specified rect */ /* Get Cairo surface for specified rect */
unsigned char* buffer = surface->buffer unsigned char* buffer = surface->buffer
+ surface->dirty_rect.y * surface->stride + surface->dirty_rect.y * surface->stride