/*
 * 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 a "png" instruction.
 *
 * @param surface The surface to be queried.
 * @param rect The update rectangle.
 * @param rect_only Non-zero if this update, by its nature, contains only
 *                  metainformation about the update's 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) {

    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);

}

