/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "config.h"
#include "common/rect.h"
#include "common/surface.h"

#include <cairo/cairo.h>
#include <guacamole/client.h>
#include <guacamole/layer.h>
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/timestamp.h>
#include <guacamole/user.h>

#include <pthread.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

/**
 * The width of an update which should be considered negible and thus
 * trivial overhead compared ot the cost of two updates.
 */
#define GUAC_SURFACE_NEGLIGIBLE_WIDTH 64

/**
 * The height of an update which should be considered negible and thus
 * trivial overhead compared ot the cost of two updates.
 */
#define GUAC_SURFACE_NEGLIGIBLE_HEIGHT 64

/**
 * The proportional increase in cost contributed by transfer and processing of
 * image data, compared to processing an equivalent amount of client-side
 * data.
 */
#define GUAC_SURFACE_DATA_FACTOR 16

/**
 * The base cost of every update. Each update should be considered to have
 * this starting cost, plus any additional cost estimated from its
 * content.
 */
#define GUAC_SURFACE_BASE_COST 4096

/**
 * An increase in cost is negligible if it is less than
 * 1/GUAC_SURFACE_NEGLIGIBLE_INCREASE of the old cost.
 */
#define GUAC_SURFACE_NEGLIGIBLE_INCREASE 4

/**
 * If combining an update because it appears to be follow a fill pattern,
 * the combined cost must not exceed
 * GUAC_SURFACE_FILL_PATTERN_FACTOR * (total uncombined cost).
 */
#define GUAC_SURFACE_FILL_PATTERN_FACTOR 3

/* Define cairo_format_stride_for_width() if missing */
#ifndef HAVE_CAIRO_FORMAT_STRIDE_FOR_WIDTH
#define cairo_format_stride_for_width(format, width) (width*4)
#endif

/**
 * The framerate which, if exceeded, indicates that JPEG is preferred.
 */
#define GUAC_COMMON_SURFACE_JPEG_FRAMERATE 3

/**
 * Minimum JPEG bitmap size (area). If the bitmap is smaller than this threshold,
 * it should be compressed as a PNG image to avoid the JPEG compression tax.
 */
#define GUAC_SURFACE_JPEG_MIN_BITMAP_SIZE 4096

/**
 * 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

void guac_common_surface_move(guac_common_surface* surface, int x, int y) {

    pthread_mutex_lock(&surface->_lock);

    surface->x = x;
    surface->y = y;
    surface->location_dirty = 1;

    pthread_mutex_unlock(&surface->_lock);

}

void guac_common_surface_stack(guac_common_surface* surface, int z) {

    pthread_mutex_lock(&surface->_lock);

    surface->z = z;
    surface->location_dirty = 1;

    pthread_mutex_unlock(&surface->_lock);

}

void guac_common_surface_set_parent(guac_common_surface* surface,
        const guac_layer* parent) {

    pthread_mutex_lock(&surface->_lock);

    surface->parent = parent;
    surface->location_dirty = 1;

    pthread_mutex_unlock(&surface->_lock);

}

void guac_common_surface_set_opacity(guac_common_surface* surface,
        int opacity) {

    pthread_mutex_lock(&surface->_lock);

    surface->opacity = opacity;
    surface->opacity_dirty = 1;

    pthread_mutex_unlock(&surface->_lock);

}

/**
 * Updates the coordinates of the given rectangle to be within the bounds of
 * the given surface.
 *
 * @param surface The surface to use for clipping.
 * @param rect The rectangle to clip.
 * @param sx The X coordinate of the source rectangle, if any.
 * @param sy The Y coordinate of the source rectangle, if any.
 */
static void __guac_common_bound_rect(guac_common_surface* surface,
        guac_common_rect* rect, int* sx, int* sy) {

    guac_common_rect bounds_rect = {
        .x = 0,
        .y = 0,
        .width  = surface->width,
        .height = surface->height
    };

    int orig_x = rect->x;
    int orig_y = rect->y;

    guac_common_rect_constrain(rect, &bounds_rect);

    /* Update source X/Y if given */
    if (sx != NULL) *sx += rect->x - orig_x;
    if (sy != NULL) *sy += rect->y - orig_y;

}

/**
 * Updates the coordinates of the given rectangle to be within the clipping
 * rectangle of the given surface, which must always be within the bounding
 * rectangle of the given surface.
 *
 * @param surface The surface to use for clipping.
 * @param rect The rectangle to clip.
 * @param sx The X coordinate of the source rectangle, if any.
 * @param sy The Y coordinate of the source rectangle, if any.
 */
static void __guac_common_clip_rect(guac_common_surface* surface,
        guac_common_rect* rect, int* sx, int* sy) {

    int orig_x = rect->x;
    int orig_y = rect->y;

    /* Just bound within surface if no clipping rectangle applied */
    if (!surface->clipped) {
        __guac_common_bound_rect(surface, rect, sx, sy);
        return;
    }

    guac_common_rect_constrain(rect, &surface->clip_rect);

    /* Update source X/Y if given */
    if (sx != NULL) *sx += rect->x - orig_x;
    if (sy != NULL) *sy += rect->y - orig_y;

}

/**
 * Returns whether a rectangle within the given surface contains only fully
 * opaque pixels.
 *
 * @param surface
 *     The surface to check.
 *
 * @param rect
 *     The rectangle to check.
 *
 * @return
 *     Non-zero if the rectangle contains only fully opaque pixels, zero
 *     otherwise.
 */
static int __guac_common_surface_is_opaque(guac_common_surface* surface,
        guac_common_rect* rect) {

    int x, y;

    int stride = surface ->stride;
    unsigned char* buffer =
        surface->buffer + (stride * rect->y) + (4 * rect->x);

    /* For each row */
    for (y = 0; y < rect->height; y++) {

        /* Search for a non-opaque pixel */
        uint32_t* current = (uint32_t*) buffer;
        for (x=0; x < rect->width; x++) {

            /* Rectangle is non-opaque if a single non-opaque pixel is found */
            uint32_t color = *(current++);
            if ((color & 0xFF000000) != 0xFF000000)
                return 0;

        }

        /* Next row */
        buffer += stride;

    }

    /* Rectangle is opaque */
    return 1;

}


/**
 * Returns whether the given rectangle should be combined into the existing
 * dirty rectangle, to be eventually flushed as image data, or would be best
 * kept independent of the current rectangle.
 *
 * @param surface
 *     The surface being updated.
 *
 * @param rect
 *     The bounding rectangle of the update being made to the surface.
 *
 * @param rect_only
 *     Non-zero if this update, by its nature, contains only metainformation
 *     about the update's bounding rectangle, zero if the update also contains
 *     image data.
 *
 * @return
 *     Non-zero if the update should be combined with any existing update, zero
 *     otherwise.
 */
static int __guac_common_should_combine(guac_common_surface* surface, const guac_common_rect* rect, int rect_only) {

    /* Always favor combining updates if surface is currently a purely
     * server-side scratch area */
    if (!surface->realized)
        return 1;

    if (surface->dirty) {

        int combined_cost, dirty_cost, update_cost;

        /* Simulate combination */
        guac_common_rect combined = surface->dirty_rect;
        guac_common_rect_extend(&combined, rect);

        /* Combine if result is still small */
        if (combined.width <= GUAC_SURFACE_NEGLIGIBLE_WIDTH && combined.height <= GUAC_SURFACE_NEGLIGIBLE_HEIGHT)
            return 1;

        /* Estimate costs of the existing update, new update, and both combined */
        combined_cost = GUAC_SURFACE_BASE_COST + combined.width * combined.height;
        dirty_cost    = GUAC_SURFACE_BASE_COST + surface->dirty_rect.width * surface->dirty_rect.height;
        update_cost   = GUAC_SURFACE_BASE_COST + rect->width * rect->height;

        /* Reduce cost if no image data */
        if (rect_only)
            update_cost /= GUAC_SURFACE_DATA_FACTOR;

        /* Combine if cost estimate shows benefit */
        if (combined_cost <= update_cost + dirty_cost)
            return 1;

        /* Combine if increase in cost is negligible */
        if (combined_cost - dirty_cost <= dirty_cost / GUAC_SURFACE_NEGLIGIBLE_INCREASE)
            return 1;

        if (combined_cost - update_cost <= update_cost / GUAC_SURFACE_NEGLIGIBLE_INCREASE)
            return 1;

        /* Combine if we anticipate further updates, as this update follows a common fill pattern */
        if (rect->x == surface->dirty_rect.x && rect->y == surface->dirty_rect.y + surface->dirty_rect.height) {
            if (combined_cost <= (dirty_cost + update_cost) * GUAC_SURFACE_FILL_PATTERN_FACTOR)
                return 1;
        }

    }
    
    /* Otherwise, do not combine */
    return 0;

}

/**
 * Expands the dirty rect of the given surface to contain the rect described by the given
 * coordinates.
 *
 * @param surface The surface to mark as dirty.
 * @param rect The rectangle of the update which is dirtying the surface.
 */
static void __guac_common_mark_dirty(guac_common_surface* surface, const guac_common_rect* rect) {

    /* Ignore empty rects */
    if (rect->width <= 0 || rect->height <= 0)
        return;

    /* If already dirty, update existing rect */
    if (surface->dirty)
        guac_common_rect_extend(&surface->dirty_rect, rect);

    /* Otherwise init dirty rect */
    else {
        surface->dirty_rect = *rect;
        surface->dirty = 1;
    }

}

/**
 * Calculate the current average framerate for a given area on the surface.
 *
 * @param surface
 *     The surface on which the framerate will be calculated.
 *
 * @param rect
 *     The rect containing the area for which the average framerate will be
 *     calculated.
 *
 * @return
 *     The average framerate of the given area, in frames per second.
 */
static unsigned int __guac_common_surface_calculate_framerate(
        guac_common_surface* surface, const guac_common_rect* rect) {

    int x, y;

    /* Calculate heat map dimensions */
    int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(surface->width);

    /* Calculate minimum X/Y coordinates intersecting given rect */
    int min_x = rect->x / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
    int min_y = rect->y / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;

    /* Calculate maximum X/Y coordinates intersecting given rect */
    int max_x = min_x + (rect->width  - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
    int max_y = min_y + (rect->height - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;

    unsigned int sum_framerate = 0;
    unsigned int count = 0;

    /* Get start of buffer at given coordinates */
    const guac_common_surface_heat_cell* heat_row =
        surface->heat_map + min_y * heat_width + min_x;

    /* Iterate over all the heat map cells for the area
     * and calculate the average framerate */
    for (y = min_y; y < max_y; y++) {

        /* Get current row of heat map */
        const guac_common_surface_heat_cell* heat_cell = heat_row;

        /* For each cell in subset of row */
        for (x = min_x; x < max_x; x++) {

            /* Calculate indicies for latest and oldest history entries */
            int oldest_entry = heat_cell->oldest_entry;
            int latest_entry = oldest_entry - 1;
            if (latest_entry < 0)
                latest_entry = GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE - 1;

            /* Calculate elapsed time covering entire history for this cell */
            int elapsed_time = heat_cell->history[latest_entry]
                             - heat_cell->history[oldest_entry];

            /* Calculate and add framerate */
            if (elapsed_time)
                sum_framerate += GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE
                    * 1000 / elapsed_time;

            /* Next heat map cell */
            heat_cell++;
            count++;

        }

        /* Next heat map row */
        heat_row += heat_width;

    }

    /* Calculate the average framerate over entire rect */
    if (count)
        return sum_framerate / count;

    return 0;

}

 /**
 * Guesses whether a rectangle within a particular surface would be better
 * compressed as PNG or using a lossy format like JPEG. Positive values
 * indicate PNG is likely to be superior, while negative values indicate the
 * opposite.
 *
 * @param surface
 *     The surface containing the image data to check.
 *
 * @param rect
 *     The rect to check within the given surface.
 *
 * @return
 *     Positive values if PNG compression is likely to perform better than
 *     lossy alternatives, or negative values if PNG is likely to perform
 *     worse.
 */
static int __guac_common_surface_png_optimality(guac_common_surface* surface,
        const guac_common_rect* rect) {

    int x, y;

    int num_same = 0;
    int num_different = 1;

    /* Get image/buffer metrics */
    int width = rect->width;
    int height = rect->height;
    int stride = surface->stride;

    /* Get buffer from surface */
    unsigned char* buffer = surface->buffer + rect->y * stride + rect->x * 4;

    /* Image must be at least 1x1 */
    if (width < 1 || height < 1)
        return 0;

    /* For each row */
    for (y = 0; y < height; y++) {

        uint32_t* row = (uint32_t*) buffer;
        uint32_t last_pixel = *(row++) | 0xFF000000;

        /* For each pixel in current row */
        for (x = 1; x < width; x++) {

            /* Get next pixel */
            uint32_t current_pixel = *(row++) | 0xFF000000;

            /* Update same/different counts according to pixel value */
            if (current_pixel == last_pixel)
                num_same++;
            else
                num_different++;

            last_pixel = current_pixel;

        }

        /* Advance to next row */
        buffer += stride;

    }

    /* Return rough approximation of optimality for PNG compression */
    return 0x100 * num_same / num_different - 0x400;

}

/**
 * Returns whether the given rectangle would be optimally encoded as JPEG
 * rather than PNG.
 *
 * @param surface
 *     The surface to be queried.
 *
 * @param rect
 *     The rectangle to check.
 *
 * @return
 *     Non-zero if the rectangle would be optimally encoded as JPEG, zero
 *     otherwise.
 */
static int __guac_common_surface_should_use_jpeg(guac_common_surface* surface,
        const guac_common_rect* rect) {

    /* Calculate the average framerate for the given rect */
    int framerate = __guac_common_surface_calculate_framerate(surface, rect);

    int rect_size = rect->width * rect->height;

    /* JPEG is preferred if:
     * - frame rate is high enough
     * - image size is large enough
     * - PNG is not more optimal based on image contents */
    return framerate >= GUAC_COMMON_SURFACE_JPEG_FRAMERATE
        && rect_size > GUAC_SURFACE_JPEG_MIN_BITMAP_SIZE
        && __guac_common_surface_png_optimality(surface, rect) < 0;

}

/**
 * Returns whether the given rectangle would be optimally encoded as WebP
 * rather than PNG.
 *
 * @param surface
 *     The surface to be queried.
 *
 * @param rect
 *     The rectangle to check.
 *
 * @return
 *     Non-zero if the rectangle would be optimally encoded as WebP, zero
 *     otherwise.
 */
static int __guac_common_surface_should_use_webp(guac_common_surface* surface,
        const guac_common_rect* rect) {

    /* Do not use WebP if not supported */
    if (!guac_client_supports_webp(surface->client))
        return 0;

    /* Calculate the average framerate for the given rect */
    int framerate = __guac_common_surface_calculate_framerate(surface, rect);

    /* WebP is preferred if:
     * - frame rate is high enough
     * - PNG is not more optimal based on image contents */
    return framerate >= GUAC_COMMON_SURFACE_JPEG_FRAMERATE
        && __guac_common_surface_png_optimality(surface, rect) < 0;

}

/**
 * Updates the heat map cells which intersect the given rectangle using the
 * given timestamp. This timestamp, along with timestamps from past updates,
 * is used to calculate the framerate of each heat cell.
 *
 * @param surface
 *     The surface containing the heat map cells to be updated.
 *
 * @param rect
 *     The rectangle containing the heat map cells to be updated.
 *
 * @param time
 *     The timestamp to use when updating the heat map cells which intersect
 *     the given rectangle.
 */
static void __guac_common_surface_touch_rect(guac_common_surface* surface,
        guac_common_rect* rect, guac_timestamp time) {

    int x, y;

    /* Calculate heat map dimensions */
    int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(surface->width);

    /* Calculate minimum X/Y coordinates intersecting given rect */
    int min_x = rect->x / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
    int min_y = rect->y / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;

    /* Calculate maximum X/Y coordinates intersecting given rect */
    int max_x = min_x + (rect->width  - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
    int max_y = min_y + (rect->height - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;

    /* Get start of buffer at given coordinates */
    guac_common_surface_heat_cell* heat_row =
        surface->heat_map + min_y * heat_width + min_x;

    /* Update all heat map cells which intersect with rectangle */
    for (y = min_y; y <= max_y; y++) {

        /* Get current row of heat map */
        guac_common_surface_heat_cell* heat_cell = heat_row;

        /* For each cell in subset of row */
        for (x = min_x; x <= max_x; x++) {

            /* Replace oldest entry with new timestamp */
            heat_cell->history[heat_cell->oldest_entry] = time;

            /* Update to next oldest entry */
            heat_cell->oldest_entry++;
            if (heat_cell->oldest_entry >=
                    GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE)
                heat_cell->oldest_entry = 0;

            /* Advance to next heat map cell */
            heat_cell++;

        }

        /* Next heat map row */
        heat_row += heat_width;

    }

}

/**
 * Flushes the bitmap update currently described by the dirty rectangle within the
 * given surface to that surface's bitmap queue. There MUST be space within the
 * queue.
 *
 * @param surface The surface to flush.
 */
static void __guac_common_surface_flush_to_queue(guac_common_surface* surface) {

    guac_common_surface_bitmap_rect* rect;

    /* Do not flush if not dirty */
    if (!surface->dirty)
        return;

    /* Add new rect to queue */
    rect = &(surface->bitmap_queue[surface->bitmap_queue_length++]);
    rect->rect = surface->dirty_rect;
    rect->flushed = 0;

    /* Surface now flushed */
    surface->dirty = 0;

}

/**
 * Flushes the given surface, drawing any pending operations on the remote
 * display. Surface properties are not flushed.
 *
 * @param surface
 *     The surface to flush.
 */
static void __guac_common_surface_flush(guac_common_surface* surface);

/**
 * Schedules a deferred flush of the given surface. This will not immediately
 * flush the surface to the client. Instead, the result of the flush is
 * added to a queue which is reinspected and combined (if possible) with other
 * deferred flushes during the call to guac_common_surface_flush().
 *
 * @param surface The surface to flush.
 */
static void __guac_common_surface_flush_deferred(guac_common_surface* surface) {

    /* Do not flush if not dirty */
    if (!surface->dirty)
        return;

    /* Flush if queue size has reached maximum (space is reserved for the final
     * dirty rect, as __guac_common_surface_flush() MAY add an additional rect
     * to the queue */
    if (surface->bitmap_queue_length == GUAC_COMMON_SURFACE_QUEUE_SIZE-1)
        __guac_common_surface_flush(surface);

    /* Append dirty rect to queue */
    __guac_common_surface_flush_to_queue(surface);

}

/**
 * Transfers a single uint32_t using the given transfer function.
 *
 * @param op The transfer function to use.
 * @param src The source of the uint32_t value.
 * @param dst THe destination which will hold the result of the transfer.
 * @return Non-zero if the destination value was changed, zero otherwise.
 */
static int __guac_common_surface_transfer_int(guac_transfer_function op, uint32_t* src, uint32_t* dst) {

    uint32_t orig = *dst;

    switch (op) {

        case GUAC_TRANSFER_BINARY_BLACK:
            *dst = 0xFF000000;
            break;

        case GUAC_TRANSFER_BINARY_WHITE:
            *dst = 0xFFFFFFFF;
            break;

        case GUAC_TRANSFER_BINARY_SRC:
            *dst = *src;
            break;

        case GUAC_TRANSFER_BINARY_DEST:
            /* NOP */
            break;

        case GUAC_TRANSFER_BINARY_NSRC:
            *dst = *src ^ 0x00FFFFFF;
            break;

        case GUAC_TRANSFER_BINARY_NDEST:
            *dst = *dst ^ 0x00FFFFFF;
            break;

        case GUAC_TRANSFER_BINARY_AND:
            *dst = ((*dst) & (0xFF000000 | *src));
            break;

        case GUAC_TRANSFER_BINARY_NAND:
            *dst = ((*dst) & (0xFF000000 | *src)) ^ 0x00FFFFFF;
            break;

        case GUAC_TRANSFER_BINARY_OR:
            *dst = ((*dst) | (0x00FFFFFF & *src));
            break;

        case GUAC_TRANSFER_BINARY_NOR:
            *dst = ((*dst) | (0x00FFFFFF & *src)) ^ 0x00FFFFFF;
            break;

        case GUAC_TRANSFER_BINARY_XOR:
            *dst = ((*dst) ^ (0x00FFFFFF & *src));
            break;

        case GUAC_TRANSFER_BINARY_XNOR:
            *dst = ((*dst) ^ (0x00FFFFFF & *src)) ^ 0x00FFFFFF;
            break;

        case GUAC_TRANSFER_BINARY_NSRC_AND:
            *dst = ((*dst) & (0xFF000000 | (*src ^ 0x00FFFFFF)));
            break;

        case GUAC_TRANSFER_BINARY_NSRC_NAND:
            *dst = ((*dst) & (0xFF000000 | (*src ^ 0x00FFFFFF))) ^ 0x00FFFFFF;
            break;

        case GUAC_TRANSFER_BINARY_NSRC_OR:
            *dst = ((*dst) | (0x00FFFFFF & (*src ^ 0x00FFFFFF)));
            break;

        case GUAC_TRANSFER_BINARY_NSRC_NOR:
            *dst = ((*dst) | (0x00FFFFFF & (*src ^ 0x00FFFFFF))) ^ 0x00FFFFFF;
            break;

    }

    return *dst != orig;

}

/**
 * Assigns the given value to all pixels within a rectangle of the backing
 * surface of the given destination surface. The color of all pixels within the
 * rectangle, including the alpha component, is entirely replaced.
 *
 * @param dst
 *     The destination surface.
 *
 * @param rect
 *     The rectangle to draw.
 *
 * @param red
 *     The red component of the color value to assign to all pixels within the
 *     rectangle.
 *
 * @param green
 *     The green component of the color value to assign to all pixels within
 *     the rectangle.
 *
 * @param blue 
 *     The blue component of the color value to assign to all pixels within the
 *     rectangle.
 *
 * @param alpha 
 *     The alpha component of the color value to assign to all pixels within
 *     the rectangle.
 */
static void __guac_common_surface_set(guac_common_surface* dst,
        guac_common_rect* rect, int red, int green, int blue, int alpha) {

    int x, y;

    int dst_stride;
    unsigned char* dst_buffer;

    uint32_t color = (alpha << 24) | (red << 16) | (green << 8) | blue;

    int min_x = rect->width - 1;
    int min_y = rect->height - 1;
    int max_x = 0;
    int max_y = 0;

    dst_stride = dst->stride;
    dst_buffer = dst->buffer + (dst_stride * rect->y) + (4 * rect->x);

    /* For each row */
    for (y=0; y < rect->height; y++) {

        uint32_t* dst_current = (uint32_t*) dst_buffer;

        /* Set row */
        for (x=0; x < rect->width; x++) {

            uint32_t old_color = *dst_current;

            if (old_color != color) {
                if (x < min_x) min_x = x;
                if (y < min_y) min_y = y;
                if (x > max_x) max_x = x;
                if (y > max_y) max_y = y;
                *dst_current = color;
            }

            dst_current++;
        }

        /* Next row */
        dst_buffer += dst_stride;

    }

    /* Restrict destination rect to only updated pixels */
    if (max_x >= min_x && max_y >= min_y) {
        rect->x += min_x;
        rect->y += min_y;
        rect->width = max_x - min_x + 1;
        rect->height = max_y - min_y + 1;
    }
    else {
        rect->width = 0;
        rect->height = 0;
    }

}

/**
 * Applies the Porter-Duff "over" composite operator, blending the two given
 * color components using the given alpha value.
 *
 * @param dst
 *     The destination color component.
 *
 * @param src
 *     The source color component.
 *
 * @param alpha
 *     The alpha value which applies to the blending operation.
 *
 * @return
 *     The result of applying the Porter-Duff "over" composite operator to the
 *     given source and destination components.
 */
static int guac_common_surface_blend_component(int dst, int src, int alpha) {

    int blended = src + dst * (0xFF - alpha);

    /* Do not exceed maximum component value */
    if (blended > 0xFF)
        return 0xFF;

    return blended;

}

/**
 * Applies the Porter-Duff "over" composite operator, blending each component
 * of the two given ARGB colors.
 *
 * @param dst
 *     The destination ARGB color.
 *
 * @param src
 *     The source ARGB color.
 *
 * @return
 *     The result of applying the Porter-Duff "over" composite operator to the
 *     given source and destination colors.
 */
static uint32_t guac_common_surface_argb_blend(uint32_t dst, uint32_t src) {

    /* Separate destination ARGB color into its components */
    int dst_a = (dst >> 24) & 0xFF;
    int dst_r = (dst >> 16) & 0xFF;
    int dst_g = (dst >>  8) & 0xFF;
    int dst_b =  dst        & 0xFF;

    /* Separate source ARGB color into its components */
    int src_a = (src >> 24) & 0xFF;
    int src_r = (src >> 16) & 0xFF;
    int src_g = (src >>  8) & 0xFF;
    int src_b =  src        & 0xFF;

    /* If source is fully opaque (or destination is fully transparent), the
     * blended result is the source */
    if (src_a == 0xFF || dst_a == 0x00)
        return src;

    /* If source is fully transparent, the blended result is the destination */
    if (src_a == 0x00)
        return dst;

    /* Otherwise, blend each ARGB component, assuming pre-multiplied alpha */
    int r = guac_common_surface_blend_component(dst_r, src_r, src_a);
    int g = guac_common_surface_blend_component(dst_g, src_g, src_a);
    int b = guac_common_surface_blend_component(dst_b, src_b, src_a);
    int a = guac_common_surface_blend_component(dst_a, src_a, src_a);

    /* Recombine blended components */
    return (a << 24) | (r << 16) | (g << 8) | b;

}

/**
 * Copies data from the given buffer to the surface at the given coordinates.
 * The dimensions and location of the destination rectangle will be altered
 * to remove as many unchanged pixels as possible.
 *
 * @param src_buffer The buffer to copy.
 * @param src_stride The number of bytes in each row of the source buffer.
 * @param sx The X coordinate of the source rectangle.
 * @param sy The Y coordinate of the source rectangle.
 * @param dst The destination surface.
 * @param rect The destination rectangle.
 * @param opaque Non-zero if the source surface is opaque (its alpha channel
 *               should be ignored), zero otherwise.
 */
static void __guac_common_surface_put(unsigned char* src_buffer, int src_stride,
                                      int* sx, int* sy,
                                      guac_common_surface* dst, guac_common_rect* rect,
                                      int opaque) {

    unsigned char* dst_buffer = dst->buffer;
    int dst_stride = dst->stride;

    int x, y;

    int min_x = rect->width;
    int min_y = rect->height;
    int max_x = 0;
    int max_y = 0;

    int orig_x = rect->x;
    int orig_y = rect->y;

    src_buffer += src_stride * (*sy) + 4 * (*sx);
    dst_buffer += (dst_stride * rect->y) + (4 * rect->x);

    /* For each row */
    for (y=0; y < rect->height; y++) {

        uint32_t* src_current = (uint32_t*) src_buffer;
        uint32_t* dst_current = (uint32_t*) dst_buffer;

        /* Copy row */
        for (x=0; x < rect->width; x++) {

            uint32_t color;

            /* Get source and destination color values */
            uint32_t src_color = *src_current;
            uint32_t dst_color = *dst_current;

            /* Ignore alpha channel if opaque */
            if (opaque)
                color = src_color | 0xFF000000;

            /* Otherwise, perform alpha blending operation */
            else
                color = guac_common_surface_argb_blend(dst_color, src_color);

            /* If the destination color is changing, update rectangle bounds
             * and store the new color */
            if (dst_color != color) {
                if (x < min_x) min_x = x;
                if (y < min_y) min_y = y;
                if (x > max_x) max_x = x;
                if (y > max_y) max_y = y;
                *dst_current = color;
            }

            /* Advance to next pixel */
            src_current++;
            dst_current++;

        }

        /* Next row */
        src_buffer += src_stride;
        dst_buffer += dst_stride;

    }

    /* Restrict destination rect to only updated pixels */
    if (max_x >= min_x && max_y >= min_y) {
        rect->x += min_x;
        rect->y += min_y;
        rect->width = max_x - min_x + 1;
        rect->height = max_y - min_y + 1;
    }
    else {
        rect->width = 0;
        rect->height = 0;
    }

    /* Update source X/Y */
    *sx += rect->x - orig_x;
    *sy += rect->y - orig_y;

}

/**
 * Fills the given surface with color, using the given buffer as a mask. Color
 * will be added to the given surface iff the corresponding pixel within the
 * buffer is opaque.
 *
 * @param src_buffer The buffer to use as a mask.
 * @param src_stride The number of bytes in each row of the source buffer.
 * @param sx The X coordinate of the source rectangle.
 * @param sy The Y coordinate of the source rectangle.
 * @param dst The destination surface.
 * @param rect The destination rectangle.
 * @param red The red component of the color of the fill.
 * @param green The green component of the color of the fill.
 * @param blue The blue component of the color of the fill.
 */
static void __guac_common_surface_fill_mask(unsigned char* src_buffer, int src_stride,
                                            int sx, int sy,
                                            guac_common_surface* dst, guac_common_rect* rect,
                                            int red, int green, int blue) {

    unsigned char* dst_buffer = dst->buffer;
    int dst_stride = dst->stride;

    uint32_t color = 0xFF000000 | (red << 16) | (green << 8) | blue;
    int x, y;

    src_buffer += src_stride*sy + 4*sx;
    dst_buffer += (dst_stride * rect->y) + (4 * rect->x);

    /* For each row */
    for (y=0; y < rect->height; y++) {

        uint32_t* src_current = (uint32_t*) src_buffer;
        uint32_t* dst_current = (uint32_t*) dst_buffer;

        /* Stencil row */
        for (x=0; x < rect->width; x++) {

            /* Fill with color if opaque */
            if (*src_current & 0xFF000000)
                *dst_current = color;

            src_current++;
            dst_current++;
        }

        /* Next row */
        src_buffer += src_stride;
        dst_buffer += dst_stride;

    }

}

/**
 * Copies data from the given surface to the given destination surface using
 * the specified transfer function.
 *
 * @param src_buffer The buffer to copy.
 * @param src_stride The number of bytes in each row of the source buffer.
 * @param sx The X coordinate of the source rectangle.
 * @param sy The Y coordinate of the source rectangle.
 * @param op The transfer function to use.
 * @param dst The destination surface.
 * @param rect The destination rectangle.
 */
static void __guac_common_surface_transfer(guac_common_surface* src, int* sx, int* sy,
                                           guac_transfer_function op,
                                           guac_common_surface* dst, guac_common_rect* rect) {

    unsigned char* src_buffer = src->buffer;
    unsigned char* dst_buffer = dst->buffer;

    int x, y;
    int src_stride, dst_stride;
    int step = 1;

    int min_x = rect->width - 1;
    int min_y = rect->height - 1;
    int max_x = 0;
    int max_y = 0;

    int orig_x = rect->x;
    int orig_y = rect->y;

    /* Copy forwards only if destination is in a different surface or is before source */
    if (src != dst || rect->y < *sy || (rect->y == *sy && rect->x < *sx)) {
        src_buffer += src->stride * (*sy) + 4 * (*sx);
        dst_buffer += (dst->stride * rect->y) + (4 * rect->x);
        src_stride = src->stride;
        dst_stride = dst->stride;
        step = 1;
    }

    /* Otherwise, copy backwards */
    else {
        src_buffer += src->stride * (*sy + rect->height - 1) + 4 * (*sx + rect->width - 1);
        dst_buffer += dst->stride * (rect->y + rect->height - 1) + 4 * (rect->x + rect->width - 1);
        src_stride = -src->stride;
        dst_stride = -dst->stride;
        step = -1;
    }

    /* For each row */
    for (y=0; y < rect->height; y++) {

        uint32_t* src_current = (uint32_t*) src_buffer;
        uint32_t* dst_current = (uint32_t*) dst_buffer;

        /* Transfer each pixel in row */
        for (x=0; x < rect->width; x++) {

            if (__guac_common_surface_transfer_int(op, src_current, dst_current)) {
                if (x < min_x) min_x = x;
                if (y < min_y) min_y = y;
                if (x > max_x) max_x = x;
                if (y > max_y) max_y = y;
            }

            src_current += step;
            dst_current += step;
        }

        /* Next row */
        src_buffer += src_stride;
        dst_buffer += dst_stride;

    }

    /* Translate X coordinate space of moving backwards */
    if (step < 0) {
        int old_max_x = max_x;
        max_x = rect->width - 1 - min_x;
        min_x = rect->width - 1 - old_max_x;
    }

    /* Translate Y coordinate space of moving backwards */
    if (dst_stride < 0) {
        int old_max_y = max_y;
        max_y = rect->height - 1 - min_y;
        min_y = rect->height - 1 - old_max_y;
    }

    /* Restrict destination rect to only updated pixels */
    if (max_x >= min_x && max_y >= min_y) {
        rect->x += min_x;
        rect->y += min_y;
        rect->width = max_x - min_x + 1;
        rect->height = max_y - min_y + 1;
    }
    else {
        rect->width = 0;
        rect->height = 0;
    }

    /* Update source X/Y */
    *sx += rect->x - orig_x;
    *sy += rect->y - orig_y;

}

guac_common_surface* guac_common_surface_alloc(guac_client* client,
        guac_socket* socket, const guac_layer* layer, int w, int h) {

    /* Calculate heat map dimensions */
    int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(w);
    int heat_height = GUAC_COMMON_SURFACE_HEAT_DIMENSION(h);

    /* Init surface */
    guac_common_surface* surface = calloc(1, sizeof(guac_common_surface));
    surface->client = client;
    surface->socket = socket;
    surface->layer = layer;
    surface->parent = GUAC_DEFAULT_LAYER;
    surface->opacity = 0xFF;
    surface->width = w;
    surface->height = h;

    pthread_mutex_init(&surface->_lock, NULL);

    /* Create corresponding Cairo surface */
    surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, w);
    surface->buffer = calloc(h, surface->stride);

    /* Create corresponding heat map */
    surface->heat_map = calloc(heat_width * heat_height,
            sizeof(guac_common_surface_heat_cell));

    /* Reset clipping rect */
    guac_common_surface_reset_clip(surface);

    /* Layers must initially exist */
    if (layer->index >= 0) {
        guac_protocol_send_size(socket, layer, w, h);
        surface->realized = 1;
    }

    /* Defer creation of buffers */
    else
        surface->realized = 0;

    return surface;
}

void guac_common_surface_free(guac_common_surface* surface) {

    /* Only dispose of surface if it exists */
    if (surface->realized)
        guac_protocol_send_dispose(surface->socket, surface->layer);

    pthread_mutex_destroy(&surface->_lock);

    free(surface->heat_map);
    free(surface->buffer);
    free(surface);

}

void guac_common_surface_resize(guac_common_surface* surface, int w, int h) {

    pthread_mutex_lock(&surface->_lock);

    /* Ignore if resize will have no effect */
    if (w == surface->width && h == surface->height)
        goto complete;

    guac_socket* socket = surface->socket;
    const guac_layer* layer = surface->layer;

    unsigned char* old_buffer;
    int old_stride;
    guac_common_rect old_rect;

    int sx = 0;
    int sy = 0;

    /* Calculate heat map dimensions */
    int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(w);
    int heat_height = GUAC_COMMON_SURFACE_HEAT_DIMENSION(h);

    /* Copy old surface data */
    old_buffer = surface->buffer;
    old_stride = surface->stride;
    guac_common_rect_init(&old_rect, 0, 0, surface->width, surface->height);

    /* Re-initialize at new size */
    surface->width  = w;
    surface->height = h;
    surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, w);
    surface->buffer = calloc(h, surface->stride);
    __guac_common_bound_rect(surface, &surface->clip_rect, NULL, NULL);

    /* Copy relevant old data */
    __guac_common_bound_rect(surface, &old_rect, NULL, NULL);
    __guac_common_surface_put(old_buffer, old_stride, &sx, &sy, surface, &old_rect, 1);

    /* Free old data */
    free(old_buffer);

    /* Allocate completely new heat map (can safely discard old stats) */
    free(surface->heat_map);
    surface->heat_map = calloc(heat_width * heat_height,
            sizeof(guac_common_surface_heat_cell));

    /* Resize dirty rect to fit new surface dimensions */
    if (surface->dirty) {
        __guac_common_bound_rect(surface, &surface->dirty_rect, NULL, NULL);
        if (surface->dirty_rect.width <= 0 || surface->dirty_rect.height <= 0)
            surface->dirty = 0;
    }

    /* Update Guacamole layer */
    if (surface->realized)
        guac_protocol_send_size(socket, layer, w, h);

complete:
    pthread_mutex_unlock(&surface->_lock);

}

void guac_common_surface_draw(guac_common_surface* surface, int x, int y, cairo_surface_t* src) {

    pthread_mutex_lock(&surface->_lock);

    unsigned char* buffer = cairo_image_surface_get_data(src);
    cairo_format_t format = cairo_image_surface_get_format(src);
    int stride = cairo_image_surface_get_stride(src);
    int w = cairo_image_surface_get_width(src);
    int h = cairo_image_surface_get_height(src);

    int sx = 0;
    int sy = 0;

    guac_common_rect rect;
    guac_common_rect_init(&rect, x, y, w, h);

    /* Clip operation */
    __guac_common_clip_rect(surface, &rect, &sx, &sy);
    if (rect.width <= 0 || rect.height <= 0)
        goto complete;

    /* Update backing surface */
    __guac_common_surface_put(buffer, stride, &sx, &sy, surface, &rect, format != CAIRO_FORMAT_ARGB32);
    if (rect.width <= 0 || rect.height <= 0)
        goto complete;

    /* Update the heat map for the update rectangle. */
    guac_timestamp time = guac_timestamp_current();
    __guac_common_surface_touch_rect(surface, &rect, time);

    /* Flush if not combining */
    if (!__guac_common_should_combine(surface, &rect, 0))
        __guac_common_surface_flush_deferred(surface);

    /* Always defer draws */
    __guac_common_mark_dirty(surface, &rect);

complete:
    pthread_mutex_unlock(&surface->_lock);

}

void guac_common_surface_paint(guac_common_surface* surface, int x, int y,
        cairo_surface_t* src, int red, int green, int blue) {

    pthread_mutex_lock(&surface->_lock);

    unsigned char* buffer = cairo_image_surface_get_data(src);
    int stride = cairo_image_surface_get_stride(src);
    int w = cairo_image_surface_get_width(src);
    int h = cairo_image_surface_get_height(src);

    int sx = 0;
    int sy = 0;

    guac_common_rect rect;
    guac_common_rect_init(&rect, x, y, w, h);

    /* Clip operation */
    __guac_common_clip_rect(surface, &rect, &sx, &sy);
    if (rect.width <= 0 || rect.height <= 0)
        goto complete;

    /* Update backing surface */
    __guac_common_surface_fill_mask(buffer, stride, sx, sy, surface, &rect, red, green, blue);

    /* Flush if not combining */
    if (!__guac_common_should_combine(surface, &rect, 0))
        __guac_common_surface_flush_deferred(surface);

    /* Always defer draws */
    __guac_common_mark_dirty(surface, &rect);

complete:
    pthread_mutex_unlock(&surface->_lock);

}

void guac_common_surface_copy(guac_common_surface* src, int sx, int sy,
        int w, int h, guac_common_surface* dst, int dx, int dy) {

    /* Lock both surfaces */
    pthread_mutex_lock(&dst->_lock);
    if (src != dst)
        pthread_mutex_lock(&src->_lock);

    guac_socket* socket = dst->socket;
    const guac_layer* src_layer = src->layer;
    const guac_layer* dst_layer = dst->layer;

    guac_common_rect srect;
    guac_common_rect_init(&srect, sx, sy, w, h);

    /* Clip operation source rect to bounds */
    __guac_common_bound_rect(src, &srect, &dx, &dy);
    if (srect.width <= 0 || srect.height <= 0)
        goto complete;

    guac_common_rect drect;
    guac_common_rect_init(&drect, dx, dy,
            srect.width, srect.height);

    /* Clip operation destination rect */
    __guac_common_clip_rect(dst, &drect, &srect.x, &srect.y);
    if (drect.width <= 0 || drect.height <= 0)
        goto complete;

    /* NOTE: Being the last rectangle to be adjusted, only the width/height of
     * drect is now correct! */

    /* Update backing surface first only if drect cannot intersect srect */
    if (src != dst) {
        __guac_common_surface_transfer(src, &srect.x, &srect.y,
                GUAC_TRANSFER_BINARY_SRC, dst, &drect);
        if (drect.width <= 0 || drect.height <= 0)
            goto complete;
    }

    /* Defer if combining */
    if (__guac_common_should_combine(dst, &drect, 1))
        __guac_common_mark_dirty(dst, &drect);

    /* Otherwise, flush and draw immediately */
    else {
        __guac_common_surface_flush(dst);
        __guac_common_surface_flush(src);
        guac_protocol_send_copy(socket, src_layer, srect.x, srect.y,
                drect.width, drect.height, GUAC_COMP_OVER, dst_layer,
                drect.x, drect.y);
        dst->realized = 1;
    }

    /* Update backing surface last if drect can intersect srect */
    if (src == dst)
        __guac_common_surface_transfer(src, &srect.x, &srect.y,
                GUAC_TRANSFER_BINARY_SRC, dst, &drect);

complete:

    /* Unlock both surfaces */
    pthread_mutex_unlock(&dst->_lock);
    if (src != dst)
        pthread_mutex_unlock(&src->_lock);

}

void guac_common_surface_transfer(guac_common_surface* src, int sx, int sy, int w, int h,
                                  guac_transfer_function op, guac_common_surface* dst, int dx, int dy) {

    /* Lock both surfaces */
    pthread_mutex_lock(&dst->_lock);
    if (src != dst)
        pthread_mutex_lock(&src->_lock);

    guac_socket* socket = dst->socket;
    const guac_layer* src_layer = src->layer;
    const guac_layer* dst_layer = dst->layer;

    guac_common_rect srect;
    guac_common_rect_init(&srect, sx, sy, w, h);

    /* Clip operation source rect to bounds */
    __guac_common_bound_rect(src, &srect, &dx, &dy);
    if (srect.width <= 0 || srect.height <= 0)
        goto complete;

    guac_common_rect drect;
    guac_common_rect_init(&drect, dx, dy,
            srect.width, srect.height);

    /* Clip operation destination rect */
    __guac_common_clip_rect(dst, &drect, &srect.x, &srect.y);
    if (drect.width <= 0 || drect.height <= 0)
        goto complete;

    /* NOTE: Being the last rectangle to be adjusted, only the width/height of
     * drect is now correct! */

    /* Update backing surface first only if drect cannot intersect srect */
    if (src != dst) {
        __guac_common_surface_transfer(src, &srect.x, &srect.y, op, dst, &drect);
        if (drect.width <= 0 || drect.height <= 0)
            goto complete;
    }

    /* Defer if combining */
    if (__guac_common_should_combine(dst, &drect, 1))
        __guac_common_mark_dirty(dst, &drect);

    /* Otherwise, flush and draw immediately */
    else {
        __guac_common_surface_flush(dst);
        __guac_common_surface_flush(src);
        guac_protocol_send_transfer(socket, src_layer, srect.x, srect.y,
                drect.width, drect.height, op, dst_layer, drect.x, drect.y);
        dst->realized = 1;
    }

    /* Update backing surface last if drect can intersect srect */
    if (src == dst)
        __guac_common_surface_transfer(src, &srect.x, &srect.y, op, dst, &drect);

complete:

    /* Unlock both surfaces */
    pthread_mutex_unlock(&dst->_lock);
    if (src != dst)
        pthread_mutex_unlock(&src->_lock);

}

void guac_common_surface_set(guac_common_surface* surface,
        int x, int y, int w, int h, int red, int green, int blue, int alpha) {

    pthread_mutex_lock(&surface->_lock);

    guac_socket* socket = surface->socket;
    const guac_layer* layer = surface->layer;

    guac_common_rect rect;
    guac_common_rect_init(&rect, x, y, w, h);

    /* Clip operation */
    __guac_common_clip_rect(surface, &rect, NULL, NULL);
    if (rect.width <= 0 || rect.height <= 0)
        goto complete;

    /* Update backing surface */
    __guac_common_surface_set(surface, &rect, red, green, blue, alpha);
    if (rect.width <= 0 || rect.height <= 0)
        goto complete;

    /* Handle as normal draw if non-opaque */
    if (alpha != 0xFF) {

        /* Flush if not combining */
        if (!__guac_common_should_combine(surface, &rect, 0))
            __guac_common_surface_flush_deferred(surface);

        /* Always defer draws */
        __guac_common_mark_dirty(surface, &rect);

    }

    /* Defer if combining */
    else if (__guac_common_should_combine(surface, &rect, 1))
        __guac_common_mark_dirty(surface, &rect);

    /* Otherwise, flush and draw immediately */
    else {
        __guac_common_surface_flush(surface);
        guac_protocol_send_rect(socket, layer, rect.x, rect.y, rect.width, rect.height);
        guac_protocol_send_cfill(socket, GUAC_COMP_OVER, layer, red, green, blue, alpha);
        surface->realized = 1;
    }

complete:
    pthread_mutex_unlock(&surface->_lock);

}

void guac_common_surface_clip(guac_common_surface* surface, int x, int y, int w, int h) {

    pthread_mutex_lock(&surface->_lock);

    guac_common_rect clip;

    /* Init clipping rectangle if clipping not already applied */
    if (!surface->clipped) {
        guac_common_rect_init(&surface->clip_rect, 0, 0, surface->width, surface->height);
        surface->clipped = 1;
    }

    guac_common_rect_init(&clip, x, y, w, h);
    guac_common_rect_constrain(&surface->clip_rect, &clip);

    pthread_mutex_unlock(&surface->_lock);

}

void guac_common_surface_reset_clip(guac_common_surface* surface) {
    pthread_mutex_lock(&surface->_lock);
    surface->clipped = 0;
    pthread_mutex_unlock(&surface->_lock);
}

/**
 * Flushes the bitmap update currently described by the dirty rectangle within
 * the given surface directly via an "img" instruction as PNG data. The
 * resulting instructions will be sent over the socket associated with the
 * given surface.
 *
 * @param surface
 *     The surface to flush.
 *
 * @param opaque
 *     Whether the rectangle being flushed contains only fully-opaque pixels.
 */
static void __guac_common_surface_flush_to_png(guac_common_surface* surface,
        int opaque) {

    if (surface->dirty) {

        guac_socket* socket = surface->socket;
        const guac_layer* layer = surface->layer;

        /* Get Cairo surface for specified rect */
        unsigned char* buffer = surface->buffer
                              + surface->dirty_rect.y * surface->stride
                              + surface->dirty_rect.x * 4;

        cairo_surface_t* rect;

        /* Use RGB24 if the image is fully opaque */
        if (opaque)
            rect = cairo_image_surface_create_for_data(buffer,
                    CAIRO_FORMAT_RGB24, surface->dirty_rect.width,
                    surface->dirty_rect.height, surface->stride);

        /* Otherwise ARGB32 is needed */
        else {

            rect = cairo_image_surface_create_for_data(buffer,
                    CAIRO_FORMAT_ARGB32, surface->dirty_rect.width,
                    surface->dirty_rect.height, surface->stride);

            /* Clear destination rect first */
            guac_protocol_send_rect(socket, layer,
                    surface->dirty_rect.x, surface->dirty_rect.y,
                    surface->dirty_rect.width, surface->dirty_rect.height);
            guac_protocol_send_cfill(socket, GUAC_COMP_ROUT, layer,
                    0x00, 0x00, 0x00, 0xFF);

        }

        /* Send PNG for rect */
        guac_client_stream_png(surface->client, socket, GUAC_COMP_OVER,
                layer, surface->dirty_rect.x, surface->dirty_rect.y, rect);

        cairo_surface_destroy(rect);
        surface->realized = 1;

        /* Surface is no longer dirty */
        surface->dirty = 0;

    }

}

/**
 * Returns an appropriate quality between 0 and 100 for lossy encoding
 * depending on the current processing lag calculated for the given client.
 *
 * @param client
 *     The client for which the lossy quality is being calculated.
 *
 * @return
 *     A value between 0 and 100 inclusive which seems appropriate for the
 *     client based on lag measurements.
 */
static int guac_common_surface_suggest_quality(guac_client* client) {

    int lag = guac_client_get_processing_lag(client);

    /* Scale quality linearly from 90 to 30 as lag varies from 20ms to 80ms */
    int quality = 90 - (lag - 20);

    /* Do not exceed 90 for quality */
    if (quality > 90)
        return 90;

    /* Do not go below 30 for quality */
    if (quality < 30)
        return 30;

    return quality;

}

/**
 * Flushes the bitmap update currently described by the dirty rectangle within
 * the given surface directly via an "img" instruction as JPEG data. The
 * resulting instructions will be sent over the socket associated with the
 * given surface.
 *
 * @param surface
 *     The surface to flush.
 */
static void __guac_common_surface_flush_to_jpeg(guac_common_surface* surface) {

    if (surface->dirty) {

        guac_socket* socket = surface->socket;
        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 */
        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, surface->dirty_rect.width,
                surface->dirty_rect.height, surface->stride);

        /* Send JPEG for rect */
        guac_client_stream_jpeg(surface->client, socket, GUAC_COMP_OVER, layer,
                surface->dirty_rect.x, surface->dirty_rect.y, rect,
                guac_common_surface_suggest_quality(surface->client));

        cairo_surface_destroy(rect);
        surface->realized = 1;

        /* Surface is no longer dirty */
        surface->dirty = 0;

    }

}

/**
 * Flushes the bitmap update currently described by the dirty rectangle within
 * the given surface directly via an "img" instruction as WebP data. The
 * resulting instructions will be sent over the socket associated with the
 * given surface.
 *
 * @param surface
 *     The surface to flush.
 *
 * @param opaque
 *     Whether the rectangle being flushed contains only fully-opaque pixels.
 */
static void __guac_common_surface_flush_to_webp(guac_common_surface* surface,
        int opaque) {

    if (surface->dirty) {

        guac_socket* socket = surface->socket;
        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 */
        unsigned char* buffer = surface->buffer
                              + surface->dirty_rect.y * surface->stride
                              + surface->dirty_rect.x * 4;

        cairo_surface_t* rect;

        /* Use RGB24 if the image is fully opaque */
        if (opaque)
            rect = cairo_image_surface_create_for_data(buffer,
                    CAIRO_FORMAT_RGB24, surface->dirty_rect.width,
                    surface->dirty_rect.height, surface->stride);

        /* Otherwise ARGB32 is needed */
        else
            rect = cairo_image_surface_create_for_data(buffer,
                    CAIRO_FORMAT_ARGB32, surface->dirty_rect.width,
                    surface->dirty_rect.height, surface->stride);

        /* Send WebP for rect */
        guac_client_stream_webp(surface->client, socket, GUAC_COMP_OVER, layer,
                surface->dirty_rect.x, surface->dirty_rect.y, rect,
                guac_common_surface_suggest_quality(surface->client), 0);

        cairo_surface_destroy(rect);
        surface->realized = 1;

        /* Surface is no longer dirty */
        surface->dirty = 0;

    }

}

/**
 * Comparator for instances of guac_common_surface_bitmap_rect, the elements
 * which make up a surface's bitmap buffer.
 *
 * @see qsort
 */
static int __guac_common_surface_bitmap_rect_compare(const void* a, const void* b) {

    guac_common_surface_bitmap_rect* ra = (guac_common_surface_bitmap_rect*) a;
    guac_common_surface_bitmap_rect* rb = (guac_common_surface_bitmap_rect*) b;

    /* Order roughly top to bottom, left to right */
    if (ra->rect.y != rb->rect.y) return ra->rect.y - rb->rect.y;
    if (ra->rect.x != rb->rect.x) return ra->rect.x - rb->rect.x;

    /* Wider updates should come first (more likely to intersect later) */
    if (ra->rect.width != rb->rect.width) return rb->rect.width - ra->rect.width;

    /* Shorter updates should come first (less likely to increase cost) */
    return ra->rect.height - rb->rect.height;

}

/**
 * Flushes only the properties of the given surface, such as layer location or
 * opacity. Image state is not flushed. If the surface represents a buffer or
 * the default layer, this function has no effect.
 *
 * @param surface
 *     The surface to flush.
 */
static void __guac_common_surface_flush_properties(
        guac_common_surface* surface) {

    guac_socket* socket = surface->socket;

    /* Only applicable to non-default visible layers */
    if (surface->layer->index <= 0)
        return;

    /* Flush opacity */
    if (surface->opacity_dirty) {
        guac_protocol_send_shade(socket, surface->layer, surface->opacity);
        surface->opacity_dirty = 0;
    }

    /* Flush location and hierarchy */
    if (surface->location_dirty) {
        guac_protocol_send_move(socket, surface->layer,
                surface->parent, surface->x, surface->y, surface->z);
        surface->location_dirty = 0;
    }

}

static void __guac_common_surface_flush(guac_common_surface* surface) {

    /* Flush final dirty rectangle to queue. */
    __guac_common_surface_flush_to_queue(surface);

    guac_common_surface_bitmap_rect* current = surface->bitmap_queue;
    int i, j;
    int original_queue_length;
    int flushed = 0;

    original_queue_length = surface->bitmap_queue_length;

    /* Sort updates to make combination less costly */
    qsort(surface->bitmap_queue, surface->bitmap_queue_length, sizeof(guac_common_surface_bitmap_rect),
          __guac_common_surface_bitmap_rect_compare);

    /* Flush all rects in queue */
    for (i=0; i < surface->bitmap_queue_length; i++) {

        /* Get next unflushed candidate */
        guac_common_surface_bitmap_rect* candidate = current;
        if (!candidate->flushed) {

            int combined = 0;

            /* Build up rect as much as possible */
            for (j=i; j < surface->bitmap_queue_length; j++) {

                if (!candidate->flushed) {

                    /* Clip candidate within current bounds */
                    __guac_common_bound_rect(surface, &candidate->rect, NULL, NULL);
                    if (candidate->rect.width <= 0 || candidate->rect.height <= 0)
                        candidate->flushed = 1;

                    /* Combine if reasonable */
                    else if (__guac_common_should_combine(surface, &candidate->rect, 0) || !surface->dirty) {
                        __guac_common_mark_dirty(surface, &candidate->rect);
                        candidate->flushed = 1;
                        combined++;
                    }

                }

                candidate++;

            }

            /* Re-add to queue if there's room and this update was modified or we expect others might be */
            if ((combined > 1 || i < original_queue_length)
                    && surface->bitmap_queue_length < GUAC_COMMON_SURFACE_QUEUE_SIZE)
                __guac_common_surface_flush_to_queue(surface);

            /* Flush as bitmap otherwise */
            else if (surface->dirty) {

                flushed++;

                int opaque = __guac_common_surface_is_opaque(surface,
                            &surface->dirty_rect);

                /* Prefer WebP when reasonable */
                if (__guac_common_surface_should_use_webp(surface,
                            &surface->dirty_rect))
                    __guac_common_surface_flush_to_webp(surface, opaque);

                /* If not WebP, JPEG is the next best (lossy) choice */
                else if (opaque && __guac_common_surface_should_use_jpeg(
                            surface, &surface->dirty_rect))
                    __guac_common_surface_flush_to_jpeg(surface);

                /* Use PNG if no lossy formats are appropriate */
                else
                    __guac_common_surface_flush_to_png(surface, opaque);

            }

        }

        current++;

    }

    /* Flush complete */
    surface->bitmap_queue_length = 0;

}

void guac_common_surface_flush(guac_common_surface* surface) {

    pthread_mutex_lock(&surface->_lock);

    /* Flush any applicable layer properties */
    __guac_common_surface_flush_properties(surface);

    /* Flush surface contents */
    __guac_common_surface_flush(surface);

    pthread_mutex_unlock(&surface->_lock);

}

void guac_common_surface_dup(guac_common_surface* surface, guac_user* user,
        guac_socket* socket) {

    pthread_mutex_lock(&surface->_lock);

    /* Do nothing if not realized */
    if (!surface->realized)
        goto complete;

    /* Synchronize layer-specific properties if applicable */
    if (surface->layer->index > 0) {

        /* Synchronize opacity */
        guac_protocol_send_shade(socket, surface->layer, surface->opacity);

        /* Synchronize location and hierarchy */
        guac_protocol_send_move(socket, surface->layer,
                surface->parent, surface->x, surface->y, surface->z);

    }

    /* Sync size to new socket */
    guac_protocol_send_size(socket, surface->layer,
            surface->width, surface->height);

    /* Send contents of layer, if non-empty */
    if (surface->width > 0 && surface->height > 0) {

        /* Get entire surface */
        cairo_surface_t* rect = cairo_image_surface_create_for_data(
                surface->buffer, CAIRO_FORMAT_ARGB32,
                surface->width, surface->height, surface->stride);

        /* Send PNG for rect */
        guac_user_stream_png(user, socket, GUAC_COMP_OVER, surface->layer,
                0, 0, rect);
        cairo_surface_destroy(rect);

    }

complete:
    pthread_mutex_unlock(&surface->_lock);

}

