[Spice-devel] [PATCH spice-gtk] use common submodule
Hans de Goede
hdegoede at redhat.com
Thu Mar 15 02:54:48 PDT 2012
Looks good, ack.
On 03/15/2012 02:20 AM, Marc-André Lureau wrote:
> ---
> .gitmodules | 3 +
> common | 1 +
> common/.gitignore | 8 -
> common/Makefile.am | 55 -
> common/canvas_base.c | 3426 ----------------------------------------
> common/canvas_base.h | 316 ----
> common/canvas_utils.c | 307 ----
> common/canvas_utils.h | 72 -
> common/demarshallers.h | 28 -
> common/draw.h | 274 ----
> common/gdi_canvas.c | 1870 ----------------------
> common/gdi_canvas.h | 39 -
> common/gl_canvas.c | 909 -----------
> common/gl_canvas.h | 37 -
> common/gl_utils.h | 105 --
> common/glc.c | 1521 ------------------
> common/glc.c.save | 1413 -----------------
> common/glc.h | 159 --
> common/lines.c | 3618 -------------------------------------------
> common/lines.h | 130 --
> common/lz.c | 738 ---------
> common/lz.h | 76 -
> common/lz_common.h | 62 -
> common/lz_compress_tmpl.c | 526 -------
> common/lz_config.h | 48 -
> common/lz_decompress_tmpl.c | 323 ----
> common/macros.h | 30 -
> common/marshaller.c | 614 --------
> common/marshaller.h | 66 -
> common/marshallers.h | 74 -
> common/mem.c | 243 ---
> common/mem.h | 129 --
> common/messages.h | 550 -------
> common/mutex.h | 35 -
> common/ogl_ctx.c | 254 ---
> common/ogl_ctx.h | 31 -
> common/pixman_utils.c | 1614 -------------------
> common/pixman_utils.h | 128 --
> common/quic.c | 1706 --------------------
> common/quic.h | 66 -
> common/quic_config.h | 51 -
> common/quic_family_tmpl.c | 115 --
> common/quic_rgb_tmpl.c | 763 ---------
> common/quic_tmpl.c | 633 --------
> common/rect.h | 115 --
> common/region.c | 893 -----------
> common/region.h | 63 -
> common/ring.h | 153 --
> common/rop3.c | 657 --------
> common/rop3.h | 34 -
> common/ssl_verify.c | 477 ------
> common/ssl_verify.h | 59 -
> common/sw_canvas.c | 1321 ----------------
> common/sw_canvas.h | 58 -
> configure.ac | 2 +
> gtk/Makefile.am | 8 +-
> gtk/decode.h | 1 +
> gtk/spice-channel-priv.h | 5 +-
> 58 files changed, 15 insertions(+), 26997 deletions(-)
> create mode 160000 common
> delete mode 100644 common/.gitignore
> delete mode 100644 common/Makefile.am
> delete mode 100644 common/canvas_base.c
> delete mode 100644 common/canvas_base.h
> delete mode 100644 common/canvas_utils.c
> delete mode 100644 common/canvas_utils.h
> delete mode 100644 common/demarshallers.h
> delete mode 100644 common/draw.h
> delete mode 100644 common/gdi_canvas.c
> delete mode 100644 common/gdi_canvas.h
> delete mode 100644 common/gl_canvas.c
> delete mode 100644 common/gl_canvas.h
> delete mode 100644 common/gl_utils.h
> delete mode 100644 common/glc.c
> delete mode 100644 common/glc.c.save
> delete mode 100644 common/glc.h
> delete mode 100644 common/lines.c
> delete mode 100644 common/lines.h
> delete mode 100644 common/lz.c
> delete mode 100644 common/lz.h
> delete mode 100644 common/lz_common.h
> delete mode 100644 common/lz_compress_tmpl.c
> delete mode 100644 common/lz_config.h
> delete mode 100644 common/lz_decompress_tmpl.c
> delete mode 100644 common/macros.h
> delete mode 100644 common/marshaller.c
> delete mode 100644 common/marshaller.h
> delete mode 100644 common/marshallers.h
> delete mode 100644 common/mem.c
> delete mode 100644 common/mem.h
> delete mode 100644 common/messages.h
> delete mode 100644 common/mutex.h
> delete mode 100644 common/ogl_ctx.c
> delete mode 100644 common/ogl_ctx.h
> delete mode 100644 common/pixman_utils.c
> delete mode 100644 common/pixman_utils.h
> delete mode 100644 common/quic.c
> delete mode 100644 common/quic.h
> delete mode 100644 common/quic_config.h
> delete mode 100644 common/quic_family_tmpl.c
> delete mode 100644 common/quic_rgb_tmpl.c
> delete mode 100644 common/quic_tmpl.c
> delete mode 100644 common/rect.h
> delete mode 100644 common/region.c
> delete mode 100644 common/region.h
> delete mode 100644 common/ring.h
> delete mode 100644 common/rop3.c
> delete mode 100644 common/rop3.h
> delete mode 100644 common/ssl_verify.c
> delete mode 100644 common/ssl_verify.h
> delete mode 100644 common/sw_canvas.c
> delete mode 100644 common/sw_canvas.h
>
> diff --git a/.gitmodules b/.gitmodules
> index f7de75d..6981ae4 100644
> --- a/.gitmodules
> +++ b/.gitmodules
> @@ -1,3 +1,6 @@
> [submodule "spice-protocol"]
> path = spice-protocol
> url = ../spice-protocol
> +[submodule "common"]
> + path = common
> + url = ../spice-common
> diff --git a/common b/common
> new file mode 160000
> index 0000000..0da9c0d
> --- /dev/null
> +++ b/common
> @@ -0,0 +1 @@
> +Subproject commit 0da9c0d6ac4d709e00dd92b744cdd9f1bd1ca7de
> diff --git a/common/.gitignore b/common/.gitignore
> deleted file mode 100644
> index 07491dd..0000000
> --- a/common/.gitignore
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -*.la
> -*.lo
> -*.loT
> -*.o
> -.deps
> -.libs
> -Makefile
> -Makefile.in
> diff --git a/common/Makefile.am b/common/Makefile.am
> deleted file mode 100644
> index 17e36a3..0000000
> --- a/common/Makefile.am
> +++ /dev/null
> @@ -1,55 +0,0 @@
> -NULL =
> -
> -COMMON_SRCS = \
> - sw_canvas.h \
> - sw_canvas.c \
> - pixman_utils.h \
> - pixman_utils.c \
> - canvas_base.h \
> - canvas_base.c \
> - canvas_utils.h \
> - canvas_utils.c \
> - demarshallers.h \
> - draw.h \
> - gdi_canvas.h \
> - gdi_canvas.c \
> - gl_canvas.h \
> - gl_canvas.c \
> - glc.h \
> - glc.c \
> - gl_utils.h \
> - lz_common.h \
> - mutex.h \
> - ogl_ctx.h \
> - ogl_ctx.c \
> - quic.h \
> - quic.c \
> - quic_config.h \
> - rect.h \
> - region.h \
> - region.c \
> - ring.h \
> - rop3.h \
> - rop3.c \
> - lines.h \
> - lines.c \
> - lz.c \
> - lz_compress_tmpl.c \
> - lz_config.h \
> - lz_decompress_tmpl.c \
> - lz.h \
> - marshaller.h \
> - marshaller.c \
> - marshallers.h \
> - messages.h \
> - mem.h \
> - mem.c \
> - quic_family_tmpl.c \
> - quic_rgb_tmpl.c \
> - quic_tmpl.c \
> - ssl_verify.h \
> - ssl_verify.c \
> - $(NULL)
> -
> -EXTRA_DIST = $(COMMON_SRCS)
> -
> diff --git a/common/canvas_base.c b/common/canvas_base.c
> deleted file mode 100644
> index 46a0cdd..0000000
> --- a/common/canvas_base.c
> +++ /dev/null
> @@ -1,3426 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include<stdarg.h>
> -#include<stdlib.h>
> -#include<setjmp.h>
> -#include<stdio.h>
> -#include<math.h>
> -
> -#include<spice/macros.h>
> -#include "quic.h"
> -#include "lz.h"
> -#include "canvas_base.h"
> -#include "pixman_utils.h"
> -#include "canvas_utils.h"
> -#include "rect.h"
> -#include "lines.h"
> -#include "rop3.h"
> -#include "mem.h"
> -
> -#include "mutex.h"
> -
> -#ifndef spice_return_if_fail
> -#define spice_return_if_fail(x) if (!(x)) { \
> - fprintf(stderr, "(%s:%d) %s: condition %s failed\n", __FILE__, __LINE__, __FUNCTION__, #x); \
> - return; \
> -}
> -#endif
> -
> -#ifndef spice_return_val_if_fail
> -#define spice_return_val_if_fail(x, val) if (!(x)) { \
> - fprintf(stderr, "(%s:%d) %s: condition %s failed\n", __FILE__, __LINE__, __FUNCTION__, #x); \
> - return (val); \
> -}
> -#endif
> -
> -#ifndef spice_warn_if_reached
> -#define spice_warn_if_reached() do { \
> - fprintf(stderr, "(%s:%d) %s: should not be reached", __FILE__, __LINE__, __FUNCTION__); \
> -}while(0)
> -#endif
> -
> -#ifndef spice_warning
> -#define spice_warning(x) do { \
> - fprintf(stderr, "(%s:%d) %s: warning %s", __FILE__, __LINE__, __FUNCTION__, (x)); \
> -} while(0)
> -#endif
> -
> -#ifndef spice_critical
> -#define spice_critical(x) do { \
> - fprintf(stderr, "(%s:%d) %s: CRITICAL %s", __FILE__, __LINE__, __FUNCTION__, (x)); \
> -} while(0)
> -#endif
> -
> -#define ROUND(_x) ((int)floor((_x) + 0.5))
> -
> -#define IS_IMAGE_LOSSY(descriptor) \
> - (((descriptor)->type == SPICE_IMAGE_TYPE_JPEG) || \
> - ((descriptor)->type == SPICE_IMAGE_TYPE_JPEG_ALPHA))
> -
> - static inline int fix_to_int(SPICE_FIXED28_4 fixed)
> -{
> - int val, rem;
> -
> - rem = fixed& 0x0f;
> - val = fixed>> 4;
> - if (rem> 8) {
> - val++;
> - }
> - return val;
> -}
> -
> - static inline SPICE_FIXED28_4 int_to_fix(int v)
> -{
> - return v<< 4;
> -}
> -
> -static inline double fix_to_double(SPICE_FIXED28_4 fixed)
> -{
> - return (double)(fixed& 0x0f) / 0x0f + (fixed>> 4);
> -}
> -
> -static inline uint16_t rgb_32_to_16_555(uint32_t color)
> -{
> - return
> - (((color)>> 3)& 0x001f) |
> - (((color)>> 6)& 0x03e0) |
> - (((color)>> 9)& 0x7c00);
> -}
> -static inline uint16_t rgb_32_to_16_565(uint32_t color)
> -{
> - return
> - (((color)>> 3)& 0x001f) |
> - (((color)>> 5)& 0x07e0) |
> - (((color)>> 8)& 0xf800);
> -}
> -
> -static inline uint32_t canvas_16bpp_to_32bpp(uint32_t color)
> -{
> - uint32_t ret;
> -
> - ret = ((color& 0x001f)<< 3) | ((color& 0x001c)>> 2);
> - ret |= ((color& 0x03e0)<< 6) | ((color& 0x0380)<< 1);
> - ret |= ((color& 0x7c00)<< 9) | ((color& 0x7000)<< 4);
> -
> - return ret;
> -}
> -#if defined(WIN32)&& defined(GDI_CANVAS)
> -static HDC create_compatible_dc()
> -{
> - HDC dc = CreateCompatibleDC(NULL);
> -
> - spice_return_val_if_fail(dc != NULL, NULL);
> -
> - return dc;
> -}
> -
> -#endif
> -
> -typedef struct LzData {
> - LzUsrContext usr;
> - LzContext *lz;
> - LzDecodeUsrData decode_data;
> - jmp_buf jmp_env;
> - char message_buf[512];
> -} LzData;
> -
> -typedef struct GlzData {
> - SpiceGlzDecoder *decoder;
> - LzDecodeUsrData decode_data;
> -} GlzData;
> -
> -typedef struct QuicData {
> - QuicUsrContext usr;
> - QuicContext *quic;
> - jmp_buf jmp_env;
> - char message_buf[512];
> - SpiceChunks *chunks;
> - uint32_t current_chunk;
> -} QuicData;
> -
> -typedef struct CanvasBase {
> - SpiceCanvas parent;
> - uint32_t color_shift;
> - uint32_t color_mask;
> - QuicData quic_data;
> -
> - uint32_t format;
> - int width;
> - int height;
> - pixman_region32_t canvas_region;
> -
> -#if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
> - SpiceImageCache *bits_cache;
> -#endif
> -#ifdef SW_CANVAS_CACHE
> - SpicePaletteCache *palette_cache;
> -#endif
> -#ifdef WIN32
> - HDC dc;
> -#endif
> -
> - SpiceImageSurfaces *surfaces;
> -
> - LzData lz_data;
> - GlzData glz_data;
> - SpiceJpegDecoder* jpeg;
> - SpiceZlibDecoder* zlib;
> -
> - void *usr_data;
> - spice_destroy_fn_t usr_data_destroy;
> -} CanvasBase;
> -
> -typedef enum {
> - ROP_INPUT_SRC,
> - ROP_INPUT_BRUSH,
> - ROP_INPUT_DEST
> -} ROPInput;
> -
> -static SpiceROP ropd_descriptor_to_rop(int desc,
> - ROPInput src_input,
> - ROPInput dest_input)
> -{
> - int old;
> - int invert_masks[] = {
> - SPICE_ROPD_INVERS_SRC,
> - SPICE_ROPD_INVERS_BRUSH,
> - SPICE_ROPD_INVERS_DEST
> - };
> -
> - old = desc;
> -
> - desc&= ~(SPICE_ROPD_INVERS_SRC | SPICE_ROPD_INVERS_DEST);
> - if (old& invert_masks[src_input]) {
> - desc |= SPICE_ROPD_INVERS_SRC;
> - }
> -
> - if (old& invert_masks[dest_input]) {
> - desc |= SPICE_ROPD_INVERS_DEST;
> - }
> -
> - if (desc& SPICE_ROPD_OP_PUT) {
> - if (desc& SPICE_ROPD_INVERS_SRC) {
> - if (desc& SPICE_ROPD_INVERS_RES) {
> - return SPICE_ROP_COPY;
> - }
> - return SPICE_ROP_COPY_INVERTED;
> - } else {
> - if (desc& SPICE_ROPD_INVERS_RES) {
> - return SPICE_ROP_COPY_INVERTED;
> - }
> - return SPICE_ROP_COPY;
> - }
> - } else if (desc& SPICE_ROPD_OP_OR) {
> -
> - if (desc& SPICE_ROPD_INVERS_RES) {
> - if (desc& SPICE_ROPD_INVERS_SRC) {
> - if (desc& SPICE_ROPD_INVERS_DEST) {
> - /* !(!src or !dest) == src and dest*/
> - return SPICE_ROP_AND;
> - } else {
> - /* ! (!src or dest) = src and !dest*/
> - return SPICE_ROP_AND_REVERSE;
> - }
> - } else {
> - if (desc& SPICE_ROPD_INVERS_DEST) {
> - /* !(src or !dest) == !src and dest */
> - return SPICE_ROP_AND_INVERTED;
> - } else {
> - /* !(src or dest) */
> - return SPICE_ROP_NOR;
> - }
> - }
> - } else {
> - if (desc& SPICE_ROPD_INVERS_SRC) {
> - if (desc& SPICE_ROPD_INVERS_DEST) {
> - /* !src or !dest == !(src and dest)*/
> - return SPICE_ROP_NAND;
> - } else {
> - /* !src or dest */
> - return SPICE_ROP_OR_INVERTED;
> - }
> - } else {
> - if (desc& SPICE_ROPD_INVERS_DEST) {
> - /* src or !dest */
> - return SPICE_ROP_OR_REVERSE;
> - } else {
> - /* src or dest */
> - return SPICE_ROP_OR;
> - }
> - }
> - }
> -
> - } else if (desc& SPICE_ROPD_OP_AND) {
> -
> - if (desc& SPICE_ROPD_INVERS_RES) {
> - if (desc& SPICE_ROPD_INVERS_SRC) {
> - if (desc& SPICE_ROPD_INVERS_DEST) {
> - /* !(!src and !dest) == src or dest*/
> - return SPICE_ROP_OR;
> - } else {
> - /* ! (!src and dest) = src or !dest*/
> - return SPICE_ROP_OR_REVERSE;
> - }
> - } else {
> - if (desc& SPICE_ROPD_INVERS_DEST) {
> - /* !(src and !dest) == !src or dest */
> - return SPICE_ROP_OR_INVERTED;
> - } else {
> - /* !(src and dest) */
> - return SPICE_ROP_NAND;
> - }
> - }
> - } else {
> - if (desc& SPICE_ROPD_INVERS_SRC) {
> - if (desc& SPICE_ROPD_INVERS_DEST) {
> - /* !src and !dest == !(src or dest)*/
> - return SPICE_ROP_NOR;
> - } else {
> - /* !src and dest */
> - return SPICE_ROP_AND_INVERTED;
> - }
> - } else {
> - if (desc& SPICE_ROPD_INVERS_DEST) {
> - /* src and !dest */
> - return SPICE_ROP_AND_REVERSE;
> - } else {
> - /* src and dest */
> - return SPICE_ROP_AND;
> - }
> - }
> - }
> -
> - } else if (desc& SPICE_ROPD_OP_XOR) {
> -
> - if (desc& SPICE_ROPD_INVERS_RES) {
> - if (desc& SPICE_ROPD_INVERS_SRC) {
> - if (desc& SPICE_ROPD_INVERS_DEST) {
> - /* !(!src xor !dest) == !src xor dest */
> - return SPICE_ROP_EQUIV;
> - } else {
> - /* ! (!src xor dest) = src xor dest*/
> - return SPICE_ROP_XOR;
> - }
> - } else {
> - if (desc& SPICE_ROPD_INVERS_DEST) {
> - /* !(src xor !dest) == src xor dest */
> - return SPICE_ROP_XOR;
> - } else {
> - /* !(src xor dest) */
> - return SPICE_ROP_EQUIV;
> - }
> - }
> - } else {
> - if (desc& SPICE_ROPD_INVERS_SRC) {
> - if (desc& SPICE_ROPD_INVERS_DEST) {
> - /* !src xor !dest == src xor dest */
> - return SPICE_ROP_XOR;
> - } else {
> - /* !src xor dest */
> - return SPICE_ROP_EQUIV;
> - }
> - } else {
> - if (desc& SPICE_ROPD_INVERS_DEST) {
> - /* src xor !dest */
> - return SPICE_ROP_EQUIV;
> - } else {
> - /* src xor dest */
> - return SPICE_ROP_XOR;
> - }
> - }
> - }
> -
> - } else if (desc& SPICE_ROPD_OP_BLACKNESS) {
> - return SPICE_ROP_CLEAR;
> - } else if (desc& SPICE_ROPD_OP_WHITENESS) {
> - return SPICE_ROP_SET;
> - } else if (desc& SPICE_ROPD_OP_INVERS) {
> - return SPICE_ROP_INVERT;
> - }
> - return SPICE_ROP_COPY;
> -}
> -
> -//#define DEBUG_DUMP_COMPRESS
> -#ifdef DEBUG_DUMP_COMPRESS
> -static void dump_surface(pixman_image_t *surface, int cache);
> -#endif
> -
> -
> -static pixman_format_code_t canvas_get_target_format(CanvasBase *canvas,
> - int source_has_alpha)
> -{
> - pixman_format_code_t format;
> -
> - /* Convert to target surface format */
> - format = spice_surface_format_to_pixman (canvas->format);
> -
> - if (source_has_alpha) {
> - /* Even though the destination has no alpha, we make the source
> - * remember there are alpha bits instead of throwing away this
> - * information. The results are the same if alpha is not
> - * interpreted, and if need to interpret alpha, don't use
> - * conversion to target format.
> - * This is needed for instance when doing the final
> - * canvas_get_target_format() in canvas_get_image_internal
> - * as otherwise we wouldn't know if the bitmap source
> - * really had alpha.
> - */
> - if (format == PIXMAN_x8r8g8b8) {
> - format = PIXMAN_a8r8g8b8;
> - }
> - } else { /* !source_has_alpha */
> - /* If the source doesn't have alpha, but the destination has,
> - don't convert to alpha, since that would just do an unnecessary
> - copy to fill the alpha bytes with 0xff which is not expected if
> - we just use the raw bits, (and handled implicitly by pixman if
> - we're interpreting data) */
> - if (format == PIXMAN_a8r8g8b8) {
> - format = PIXMAN_x8r8g8b8;
> - }
> - }
> -
> - return format;
> -}
> -
> -static pixman_image_t *canvas_get_quic(CanvasBase *canvas, SpiceImage *image,
> - int invers, int want_original)
> -{
> - pixman_image_t *surface = NULL;
> - QuicData *quic_data =&canvas->quic_data;
> - QuicImageType type, as_type;
> - pixman_format_code_t pixman_format;
> - uint8_t *dest;
> - int stride;
> - int width;
> - int height;
> -
> - if (setjmp(quic_data->jmp_env)) {
> - pixman_image_unref(surface);
> - spice_warning(quic_data->message_buf);
> - return NULL;
> - }
> -
> - quic_data->chunks = image->u.quic.data;
> - quic_data->current_chunk = 0;
> -
> - if (quic_decode_begin(quic_data->quic,
> - (uint32_t *)image->u.quic.data->chunk[0].data,
> - image->u.quic.data->chunk[0].len>> 2,
> -&type,&width,&height) == QUIC_ERROR) {
> - spice_warning("quic decode begin failed");
> - return NULL;
> - }
> -
> - switch (type) {
> - case QUIC_IMAGE_TYPE_RGBA:
> - as_type = QUIC_IMAGE_TYPE_RGBA;
> - pixman_format = PIXMAN_a8r8g8b8;
> - break;
> - case QUIC_IMAGE_TYPE_RGB32:
> - case QUIC_IMAGE_TYPE_RGB24:
> - as_type = QUIC_IMAGE_TYPE_RGB32;
> - pixman_format = PIXMAN_x8r8g8b8;
> - break;
> - case QUIC_IMAGE_TYPE_RGB16:
> - if (!want_original&&
> - (canvas->format == SPICE_SURFACE_FMT_32_xRGB ||
> - canvas->format == SPICE_SURFACE_FMT_32_ARGB)) {
> - as_type = QUIC_IMAGE_TYPE_RGB32;
> - pixman_format = PIXMAN_x8r8g8b8;
> - } else {
> - as_type = QUIC_IMAGE_TYPE_RGB16;
> - pixman_format = PIXMAN_x1r5g5b5;
> - }
> - break;
> - case QUIC_IMAGE_TYPE_INVALID:
> - case QUIC_IMAGE_TYPE_GRAY:
> - default:
> - spice_warn_if_reached();
> - return NULL;
> - }
> -
> - spice_return_val_if_fail((uint32_t)width == image->descriptor.width, NULL);
> - spice_return_val_if_fail((uint32_t)height == image->descriptor.height, NULL);
> -
> - surface = surface_create(
> -#ifdef WIN32
> - canvas->dc,
> -#endif
> - pixman_format,
> - width, height, FALSE);
> -
> - spice_return_val_if_fail(surface != NULL, NULL);
> -
> - dest = (uint8_t *)pixman_image_get_data(surface);
> - stride = pixman_image_get_stride(surface);
> - if (quic_decode(quic_data->quic, as_type,
> - dest, stride) == QUIC_ERROR) {
> - pixman_image_unref(surface);
> - spice_warning("quic decode failed");
> - return NULL;
> - }
> -
> - if (invers) {
> - uint8_t *end = dest + height * stride;
> - for (; dest != end; dest += stride) {
> - uint32_t *pix;
> - uint32_t *end_pix;
> -
> - pix = (uint32_t *)dest;
> - end_pix = pix + width;
> - for (; pix< end_pix; pix++) {
> - *pix ^= 0xffffffff;
> - }
> - }
> - }
> -
> -#ifdef DEBUG_DUMP_COMPRESS
> - dump_surface(surface, 0);
> -#endif
> - return surface;
> -}
> -
> -
> -//#define DUMP_JPEG
> -#ifdef DUMP_JPEG
> -static int jpeg_id = 0;
> -static void dump_jpeg(uint8_t* data, int data_size)
> -{
> - char file_str[200];
> - uint32_t id = ++jpeg_id;
> -
> -#ifdef WIN32
> - sprintf(file_str, "c:\\tmp\\spice_dump\\%u.jpg", id);
> -#else
> - sprintf(file_str, "/tmp/spice_dump/%u.jpg", id);
> -#endif
> -
> - FILE *f = fopen(file_str, "wb");
> - if (!f) {
> - return;
> - }
> -
> - fwrite(data, 1, data_size, f);
> - fclose(f);
> -}
> -#endif
> -
> -static pixman_image_t *canvas_get_jpeg(CanvasBase *canvas, SpiceImage *image, int invers)
> -{
> - pixman_image_t *surface = NULL;
> - int stride;
> - int width;
> - int height;
> - uint8_t *dest;
> -
> - spice_return_val_if_fail(image->u.jpeg.data->num_chunks == 1, NULL);
> - canvas->jpeg->ops->begin_decode(canvas->jpeg, image->u.jpeg.data->chunk[0].data, image->u.jpeg.data->chunk[0].len,
> -&width,&height);
> - spice_return_val_if_fail((uint32_t)width == image->descriptor.width, NULL);
> - spice_return_val_if_fail((uint32_t)height == image->descriptor.height, NULL);
> -
> - surface = surface_create(
> -#ifdef WIN32
> - canvas->dc,
> -#endif
> - PIXMAN_x8r8g8b8,
> - width, height, FALSE);
> - if (surface == NULL) {
> - spice_warning("create surface failed");
> - return NULL;
> - }
> -
> - dest = (uint8_t *)pixman_image_get_data(surface);
> - stride = pixman_image_get_stride(surface);
> -
> - canvas->jpeg->ops->decode(canvas->jpeg, dest, stride, SPICE_BITMAP_FMT_32BIT);
> -
> - if (invers) {
> - uint8_t *end = dest + height * stride;
> - for (; dest != end; dest += stride) {
> - uint32_t *pix;
> - uint32_t *end_pix;
> -
> - pix = (uint32_t *)dest;
> - end_pix = pix + width;
> - for (; pix< end_pix; pix++) {
> - *pix ^= 0x00ffffff;
> - }
> - }
> - }
> -#ifdef DUMP_JPEG
> - dump_jpeg(image->u.jpeg.data, image->u.jpeg.data_size);
> -#endif
> - return surface;
> -}
> -
> -static pixman_image_t *canvas_get_jpeg_alpha(CanvasBase *canvas,
> - SpiceImage *image, int invers)
> -{
> - pixman_image_t *surface = NULL;
> - int stride;
> - int width;
> - int height;
> - uint8_t *dest;
> - int alpha_top_down = FALSE;
> - LzData *lz_data =&canvas->lz_data;
> - LzImageType lz_alpha_type;
> - uint8_t *comp_alpha_buf = NULL;
> - uint8_t *decomp_alpha_buf = NULL;
> - int alpha_size;
> - int lz_alpha_width, lz_alpha_height, n_comp_pixels, lz_alpha_top_down;
> -
> - spice_return_val_if_fail(image->u.jpeg_alpha.data->num_chunks == 1, NULL);
> - canvas->jpeg->ops->begin_decode(canvas->jpeg,
> - image->u.jpeg_alpha.data->chunk[0].data,
> - image->u.jpeg_alpha.jpeg_size,
> -&width,&height);
> - spice_return_val_if_fail((uint32_t)width == image->descriptor.width, NULL);
> - spice_return_val_if_fail((uint32_t)height == image->descriptor.height, NULL);
> -
> - if (image->u.jpeg_alpha.flags& SPICE_JPEG_ALPHA_FLAGS_TOP_DOWN) {
> - alpha_top_down = TRUE;
> - }
> -
> -#ifdef WIN32
> - lz_data->decode_data.dc = canvas->dc;
> -#endif
> - surface = alloc_lz_image_surface(&lz_data->decode_data, PIXMAN_a8r8g8b8,
> - width, height, width*height, alpha_top_down);
> -
> - if (surface == NULL) {
> - spice_warning("create surface failed");
> - return NULL;
> - }
> -
> - dest = (uint8_t *)pixman_image_get_data(surface);
> - stride = pixman_image_get_stride(surface);
> -
> - canvas->jpeg->ops->decode(canvas->jpeg, dest, stride, SPICE_BITMAP_FMT_32BIT);
> -
> - comp_alpha_buf = image->u.jpeg_alpha.data->chunk[0].data + image->u.jpeg_alpha.jpeg_size;
> - alpha_size = image->u.jpeg_alpha.data_size - image->u.jpeg_alpha.jpeg_size;
> -
> - lz_decode_begin(lz_data->lz, comp_alpha_buf, alpha_size,&lz_alpha_type,
> -&lz_alpha_width,&lz_alpha_height,&n_comp_pixels,
> -&lz_alpha_top_down, NULL);
> - spice_return_val_if_fail(lz_alpha_type == LZ_IMAGE_TYPE_XXXA, NULL);
> - spice_return_val_if_fail(!!lz_alpha_top_down == !!alpha_top_down, NULL);
> - spice_return_val_if_fail(lz_alpha_width == width, NULL);
> - spice_return_val_if_fail(lz_alpha_height == height, NULL);
> - spice_return_val_if_fail(n_comp_pixels == width * height, NULL);
> -
> - if (!alpha_top_down) {
> - decomp_alpha_buf = dest + stride * (height - 1);
> - } else {
> - decomp_alpha_buf = dest;
> - }
> - lz_decode(lz_data->lz, LZ_IMAGE_TYPE_XXXA, decomp_alpha_buf);
> -
> - if (invers) {
> - uint8_t *end = dest + height * stride;
> - for (; dest != end; dest += stride) {
> - uint32_t *pix;
> - uint32_t *end_pix;
> -
> - pix = (uint32_t *)dest;
> - end_pix = pix + width;
> - for (; pix< end_pix; pix++) {
> - *pix ^= 0x00ffffff;
> - }
> - }
> - }
> -#ifdef DUMP_JPEG
> - dump_jpeg(image->u.jpeg_alpha.data, image->u.jpeg_alpha.jpeg_size);
> -#endif
> - return surface;
> -}
> -
> -static pixman_image_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap* bitmap,
> - SpicePalette *palette, int want_original)
> -{
> - uint8_t* src;
> - pixman_image_t *image;
> - pixman_format_code_t format;
> -
> - spice_chunks_linearize(bitmap->data);
> -
> - src = bitmap->data->chunk[0].data;
> -
> - if (want_original) {
> - format = spice_bitmap_format_to_pixman(bitmap->format, canvas->format);
> - } else {
> - format = canvas_get_target_format(canvas,
> - bitmap->format == SPICE_BITMAP_FMT_RGBA);
> - }
> -
> - image = surface_create(
> -#ifdef WIN32
> - canvas->dc,
> -#endif
> - format,
> - bitmap->x, bitmap->y, FALSE);
> - if (image == NULL) {
> - spice_warning("create surface failed");
> - return NULL;
> - }
> -
> - spice_bitmap_convert_to_pixman(format, image,
> - bitmap->format,
> - bitmap->flags,
> - bitmap->x, bitmap->y,
> - src, bitmap->stride,
> - canvas->format, palette);
> - return image;
> -}
> -
> -
> -#ifdef SW_CANVAS_CACHE
> -
> -static inline SpicePalette *canvas_get_palette(CanvasBase *canvas, SpicePalette *base_palette, uint64_t palette_id, uint8_t flags)
> -{
> - SpicePalette *palette;
> -
> - if (flags& SPICE_BITMAP_FLAGS_PAL_FROM_CACHE) {
> - palette = canvas->palette_cache->ops->get(canvas->palette_cache, palette_id);
> - } else {
> - palette = base_palette;
> - if (palette != NULL&& flags& SPICE_BITMAP_FLAGS_PAL_CACHE_ME) {
> - canvas->palette_cache->ops->put(canvas->palette_cache, palette);
> - }
> - }
> - return palette;
> -}
> -
> -static inline SpicePalette *canvas_get_localized_palette(CanvasBase *canvas, SpicePalette *base_palette, uint64_t palette_id, uint8_t flags, int *free_palette)
> -{
> - SpicePalette *palette = canvas_get_palette(canvas, base_palette, palette_id, flags);
> - SpicePalette *copy;
> - uint32_t *now, *end;
> - size_t size;
> -
> - if (canvas->format == SPICE_SURFACE_FMT_32_xRGB ||
> - canvas->format == SPICE_SURFACE_FMT_32_ARGB) {
> - return palette;
> - }
> -
> - size = sizeof(SpicePalette) + palette->num_ents * 4;
> - copy = (SpicePalette *)spice_malloc(size);
> - memcpy(copy, palette, size);
> -
> - switch (canvas->format) {
> - case SPICE_SURFACE_FMT_32_xRGB:
> - case SPICE_SURFACE_FMT_32_ARGB:
> - /* Won't happen */
> - break;
> - case SPICE_SURFACE_FMT_16_555:
> - now = copy->ents;
> - end = now + copy->num_ents;
> - for (; now< end; now++) {
> - *now = canvas_16bpp_to_32bpp(*now);
> - }
> - break;
> - case SPICE_SURFACE_FMT_16_565:
> - default:
> - spice_warn_if_reached();
> - return NULL;
> - }
> - *free_palette = TRUE;
> - return copy;
> -}
> -
> -static pixman_image_t *canvas_get_lz(CanvasBase *canvas, SpiceImage *image, int invers,
> - int want_original)
> -{
> - LzData *lz_data =&canvas->lz_data;
> - uint8_t *comp_buf = NULL;
> - int comp_size;
> - uint8_t *decomp_buf = NULL;
> - uint8_t *src;
> - pixman_format_code_t pixman_format;
> - LzImageType type, as_type;
> - SpicePalette *palette;
> - int n_comp_pixels;
> - int width;
> - int height;
> - int top_down;
> - int stride;
> - int free_palette;
> -
> - if (setjmp(lz_data->jmp_env)) {
> - if (decomp_buf) {
> - free(decomp_buf);
> - }
> - spice_warning(lz_data->message_buf);
> - return NULL;
> - }
> -
> - free_palette = FALSE;
> - if (image->descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB) {
> - spice_return_val_if_fail(image->u.lz_rgb.data->num_chunks == 1, NULL); /* TODO: Handle chunks */
> - comp_buf = image->u.lz_rgb.data->chunk[0].data;
> - comp_size = image->u.lz_rgb.data->chunk[0].len;
> - palette = NULL;
> - } else if (image->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) {
> - spice_return_val_if_fail(image->u.lz_plt.data->num_chunks == 1, NULL); /* TODO: Handle chunks */
> - comp_buf = image->u.lz_plt.data->chunk[0].data;
> - comp_size = image->u.lz_plt.data->chunk[0].len;
> - palette = canvas_get_localized_palette(canvas, image->u.lz_plt.palette, image->u.lz_plt.palette_id, image->u.lz_plt.flags,&free_palette);
> - } else {
> - spice_warn_if_reached();
> - return NULL;
> - }
> -
> - lz_decode_begin(lz_data->lz, comp_buf, comp_size,&type,
> -&width,&height,&n_comp_pixels,&top_down, palette);
> -
> - switch (type) {
> - case LZ_IMAGE_TYPE_RGBA:
> - as_type = LZ_IMAGE_TYPE_RGBA;
> - pixman_format = PIXMAN_a8r8g8b8;
> - break;
> - case LZ_IMAGE_TYPE_RGB32:
> - case LZ_IMAGE_TYPE_RGB24:
> - case LZ_IMAGE_TYPE_PLT1_LE:
> - case LZ_IMAGE_TYPE_PLT1_BE:
> - case LZ_IMAGE_TYPE_PLT4_LE:
> - case LZ_IMAGE_TYPE_PLT4_BE:
> - case LZ_IMAGE_TYPE_PLT8:
> - as_type = LZ_IMAGE_TYPE_RGB32;
> - pixman_format = PIXMAN_x8r8g8b8;
> - break;
> - case LZ_IMAGE_TYPE_RGB16:
> - if (!want_original&&
> - (canvas->format == SPICE_SURFACE_FMT_32_xRGB ||
> - canvas->format == SPICE_SURFACE_FMT_32_ARGB)) {
> - as_type = LZ_IMAGE_TYPE_RGB32;
> - pixman_format = PIXMAN_x8r8g8b8;
> - } else {
> - as_type = LZ_IMAGE_TYPE_RGB16;
> - pixman_format = PIXMAN_x1r5g5b5;
> - }
> - break;
> - default:
> - spice_warn_if_reached();
> - return NULL;
> - }
> -
> - spice_return_val_if_fail((unsigned)width == image->descriptor.width, NULL);
> - spice_return_val_if_fail((unsigned)height == image->descriptor.height, NULL);
> -
> - spice_return_val_if_fail((image->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) || (n_comp_pixels == width * height), NULL);
> -#ifdef WIN32
> - lz_data->decode_data.dc = canvas->dc;
> -#endif
> -
> -
> - alloc_lz_image_surface(&lz_data->decode_data, pixman_format,
> - width, height, n_comp_pixels, top_down);
> -
> - src = (uint8_t *)pixman_image_get_data(lz_data->decode_data.out_surface);
> -
> - stride = (n_comp_pixels / height) * 4;
> - if (!top_down) {
> - stride = -stride;
> - decomp_buf = src + stride * (height - 1);
> - } else {
> - decomp_buf = src;
> - }
> -
> - lz_decode(lz_data->lz, as_type, decomp_buf);
> -
> - if (invers) {
> - uint8_t *line = src;
> - uint8_t *end = src + height * stride;
> - for (; line != end; line += stride) {
> - uint32_t *pix;
> - uint32_t *end_pix;
> -
> - pix = (uint32_t *)line;
> - end_pix = pix + width;
> - for (; pix< end_pix; pix++) {
> - *pix ^= 0xffffffff;
> - }
> - }
> - }
> -
> - if (free_palette) {
> - free(palette);
> - }
> -
> - return lz_data->decode_data.out_surface;
> -}
> -
> -static pixman_image_t *canvas_get_glz_rgb_common(CanvasBase *canvas, uint8_t *data,
> - int want_original)
> -{
> - spice_return_val_if_fail(canvas->glz_data.decoder != NULL, NULL);
> -
> - canvas->glz_data.decoder->ops->decode(canvas->glz_data.decoder,
> - data, NULL,
> -&canvas->glz_data.decode_data);
> -
> - /* global_decode calls alloc_lz_image, which sets canvas->glz_data.surface */
> - return (canvas->glz_data.decode_data.out_surface);
> -}
> -
> -// don't handle plts since bitmaps with plt can be decoded globally to RGB32 (because
> -// same byte sequence can be transformed to different RGB pixels by different plts)
> -static pixman_image_t *canvas_get_glz(CanvasBase *canvas, SpiceImage *image,
> - int want_original)
> -{
> - spice_return_val_if_fail(image->descriptor.type == SPICE_IMAGE_TYPE_GLZ_RGB, NULL);
> -#ifdef WIN32
> - canvas->glz_data.decode_data.dc = canvas->dc;
> -#endif
> -
> - spice_return_val_if_fail(image->u.lz_rgb.data->num_chunks == 1, NULL); /* TODO: Handle chunks */
> - return canvas_get_glz_rgb_common(canvas, image->u.lz_rgb.data->chunk[0].data, want_original);
> -}
> -
> -static pixman_image_t *canvas_get_zlib_glz_rgb(CanvasBase *canvas, SpiceImage *image,
> - int want_original)
> -{
> - uint8_t *glz_data;
> - pixman_image_t *surface;
> -
> - spice_return_val_if_fail(canvas->zlib != NULL, NULL);
> -
> - spice_return_val_if_fail(image->u.zlib_glz.data->num_chunks == 1, NULL); /* TODO: Handle chunks */
> - glz_data = (uint8_t*)spice_malloc(image->u.zlib_glz.glz_data_size);
> - canvas->zlib->ops->decode(canvas->zlib, image->u.zlib_glz.data->chunk[0].data,
> - image->u.zlib_glz.data->chunk[0].len,
> - glz_data, image->u.zlib_glz.glz_data_size);
> - surface = canvas_get_glz_rgb_common(canvas, glz_data, want_original);
> - free(glz_data);
> - return surface;
> -}
> -
> -//#define DEBUG_DUMP_BITMAP
> -
> -#ifdef DEBUG_DUMP_BITMAP
> -static void dump_bitmap(SpiceBitmap *bitmap, SpicePalette *palette)
> -{
> - uint8_t* data = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
> - static uint32_t file_id = 0;
> - uint32_t i, j;
> - char file_str[200];
> - uint32_t id = ++file_id;
> -
> -#ifdef WIN32
> - sprintf(file_str, "c:\\tmp\\spice_dump\\%u.%ubpp", id, bitmap->format);
> -#else
> - sprintf(file_str, "/tmp/spice_dump/%u.%ubpp", id, bitmap->format);
> -#endif
> - FILE *f = fopen(file_str, "wb");
> - if (!f) {
> - return;
> - }
> -
> - fprintf(f, "%d\n", bitmap->format); // 1_LE,1_BE,....
> - fprintf(f, "%d %d\n", bitmap->x, bitmap->y); // width and height
> - fprintf(f, "%d\n", palette->num_ents); // #plt entries
> - for (i = 0; i< palette->num_ents; i++) {
> - fwrite(&(palette->ents[i]), 4, 1, f);
> - }
> - fprintf(f, "\n");
> -
> - for (i = 0; i< bitmap->y; i++, data += bitmap->stride) {
> - uint8_t *now = data;
> - for (j = 0; j< bitmap->x; j++) {
> - fwrite(now, 1, 1, f);
> - now++;
> - }
> - }
> -}
> -
> -#endif
> -
> -static pixman_image_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap,
> - int want_original)
> -{
> - pixman_image_t* surface;
> - SpicePalette *palette;
> -
> - palette = canvas_get_palette(canvas, bitmap->palette, bitmap->palette_id, bitmap->flags);
> -#ifdef DEBUG_DUMP_BITMAP
> - if (palette) {
> - dump_bitmap(bitmap, palette);
> - }
> -#endif
> -
> - surface = canvas_bitmap_to_surface(canvas, bitmap, palette, want_original);
> -
> - if (palette&& (bitmap->flags& SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
> - canvas->palette_cache->ops->release(canvas->palette_cache, palette);
> - }
> -
> - return surface;
> -}
> -
> -#else
> -
> -
> -static pixman_image_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap,
> - int want_original)
> -{
> - SpicePalette *palette;
> -
> - if (!bitmap->palette) {
> - return canvas_bitmap_to_surface(canvas, bitmap, NULL, want_original);
> - }
> - palette = (SpicePalette *)SPICE_GET_ADDRESS(bitmap->palette);
> - return canvas_bitmap_to_surface(canvas, bitmap, palette, want_original);
> -}
> -
> -#endif
> -
> -
> -
> -// caution: defining DEBUG_DUMP_SURFACE will dump both cached& non-cached
> -// images to disk. it will reduce performance dramatically& eat
> -// disk space rapidly. use it only for debugging.
> -//#define DEBUG_DUMP_SURFACE
> -
> -#if defined(DEBUG_DUMP_SURFACE) || defined(DEBUG_DUMP_COMPRESS)
> -
> -static void dump_surface(pixman_image_t *surface, int cache)
> -{
> - static uint32_t file_id = 0;
> - int i, j;
> - char file_str[200];
> - int depth = pixman_image_get_depth(surface);
> -
> - if (depth != 24&& depth != 32) {
> - return;
> - }
> -
> - uint8_t *data = (uint8_t *)pixman_image_get_data(surface);
> - int width = pixman_image_get_width(surface);
> - int height = pixman_image_get_height(surface);
> - int stride = pixman_image_surface_get_stride(surface);
> -
> - uint32_t id = ++file_id;
> -#ifdef WIN32
> - sprintf(file_str, "c:\\tmp\\spice_dump\\%d\\%u.ppm", cache, id);
> -#else
> - sprintf(file_str, "/tmp/spice_dump/%u.ppm", id);
> -#endif
> - FILE *f = fopen(file_str, "wb");
> - if (!f) {
> - return;
> - }
> - fprintf(f, "P6\n");
> - fprintf(f, "%d %d\n", width, height);
> - fprintf(f, "#spicec dump\n");
> - fprintf(f, "255\n");
> - for (i = 0; i< height; i++, data += stride) {
> - uint8_t *now = data;
> - for (j = 0; j< width; j++) {
> - fwrite(&now[2], 1, 1, f);
> - fwrite(&now[1], 1, 1, f);
> - fwrite(&now[0], 1, 1, f);
> - now += 4;
> - }
> - }
> - fclose(f);
> -}
> -
> -#endif
> -
> -static SpiceCanvas *canvas_get_surface_internal(CanvasBase *canvas, SpiceImage *image)
> -{
> - if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) {
> - SpiceSurface *surface =&image->u.surface;
> - return canvas->surfaces->ops->get(canvas->surfaces, surface->surface_id);
> - }
> - return NULL;
> -}
> -
> -static SpiceCanvas *canvas_get_surface_mask_internal(CanvasBase *canvas, SpiceImage *image)
> -{
> - if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) {
> - SpiceSurface *surface =&image->u.surface;
> - return canvas->surfaces->ops->get(canvas->surfaces, surface->surface_id);
> - }
> - return NULL;
> -}
> -
> -#if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
> -
> -//#define DEBUG_LZ
> -
> -/* If real get is FALSE, then only do whatever is needed but don't return an image. For instance,
> - * if we need to read it to cache it we do.
> - *
> - * This generally converts the image to the right type for the canvas.
> - * However, if want_original is set the real source format is returned, and
> - * you have to be able to handle any image format. This is useful to avoid
> - * e.g. losing alpha when blending a argb32 image on a rgb16 surface.
> - */
> -static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SpiceImage *image,
> - int want_original, int real_get)
> -{
> - SpiceImageDescriptor *descriptor =&image->descriptor;
> - pixman_image_t *surface, *converted;
> - pixman_format_code_t wanted_format, surface_format;
> - int saved_want_original;
> -
> - /* When touching, only really allocate if we need to cache, or
> - * if we're loading a GLZ stream (since those need inter-thread communication
> - * to happen which breaks if we don't. */
> - if (!real_get&&
> - !(descriptor->flags& SPICE_IMAGE_FLAGS_CACHE_ME)&&
> -#ifdef SW_CANVAS_CACHE
> - !(descriptor->flags& SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME)&&
> -#endif
> - (descriptor->type != SPICE_IMAGE_TYPE_GLZ_RGB)&&
> - (descriptor->type != SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB)) {
> - return NULL;
> - }
> -
> - saved_want_original = want_original;
> - if (descriptor->flags& SPICE_IMAGE_FLAGS_CACHE_ME
> -#ifdef SW_CANVAS_CACHE
> - || descriptor->flags& SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME
> -#endif
> - ) {
> - want_original = TRUE;
> - }
> -
> - switch (descriptor->type) {
> - case SPICE_IMAGE_TYPE_QUIC: {
> - surface = canvas_get_quic(canvas, image, 0, want_original);
> - break;
> - }
> -#if defined(SW_CANVAS_CACHE)
> - case SPICE_IMAGE_TYPE_LZ_PLT: {
> - surface = canvas_get_lz(canvas, image, 0, want_original);
> - break;
> - }
> - case SPICE_IMAGE_TYPE_LZ_RGB: {
> - surface = canvas_get_lz(canvas, image, 0, want_original);
> - break;
> - }
> -#endif
> - case SPICE_IMAGE_TYPE_JPEG: {
> - surface = canvas_get_jpeg(canvas, image, 0);
> - break;
> - }
> - case SPICE_IMAGE_TYPE_JPEG_ALPHA: {
> - surface = canvas_get_jpeg_alpha(canvas, image, 0);
> - break;
> - }
> -#if defined(SW_CANVAS_CACHE)
> - case SPICE_IMAGE_TYPE_GLZ_RGB: {
> - surface = canvas_get_glz(canvas, image, want_original);
> - break;
> - }
> - case SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB: {
> - surface = canvas_get_zlib_glz_rgb(canvas, image, want_original);
> - break;
> - }
> -#endif
> - case SPICE_IMAGE_TYPE_FROM_CACHE:
> - surface = canvas->bits_cache->ops->get(canvas->bits_cache, descriptor->id);
> - break;
> -#ifdef SW_CANVAS_CACHE
> - case SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS:
> - surface = canvas->bits_cache->ops->get_lossless(canvas->bits_cache, descriptor->id);
> - break;
> -#endif
> - case SPICE_IMAGE_TYPE_BITMAP: {
> - surface = canvas_get_bits(canvas,&image->u.bitmap, want_original);
> - break;
> - }
> - default:
> - spice_warn_if_reached();
> - return NULL;
> - }
> -
> - spice_return_val_if_fail(surface != NULL, NULL);
> - surface_format = spice_pixman_image_get_format(surface);
> -
> - if (descriptor->flags& SPICE_IMAGE_FLAGS_HIGH_BITS_SET&&
> - descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE&&
> -#ifdef SW_CANVAS_CACHE
> - descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS&&
> -#endif
> - surface_format == PIXMAN_x8r8g8b8) {
> - spice_pixman_fill_rect_rop(surface,
> - 0, 0,
> - pixman_image_get_width(surface),
> - pixman_image_get_height(surface),
> - 0xff000000U, SPICE_ROP_OR);
> - }
> -
> - if (descriptor->flags& SPICE_IMAGE_FLAGS_CACHE_ME&&
> -#ifdef SW_CANVAS_CACHE
> - descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS&&
> -#endif
> - descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE ) {
> -#ifdef SW_CANVAS_CACHE
> - if (!IS_IMAGE_LOSSY(descriptor)) {
> - canvas->bits_cache->ops->put(canvas->bits_cache, descriptor->id, surface);
> - } else {
> - canvas->bits_cache->ops->put_lossy(canvas->bits_cache, descriptor->id, surface);
> - }
> -#else
> - canvas->bits_cache->ops->put(canvas->bits_cache, descriptor->id, surface);
> -#endif
> -#ifdef DEBUG_DUMP_SURFACE
> - dump_surface(surface, 1);
> -#endif
> -#ifdef SW_CANVAS_CACHE
> - } else if (descriptor->flags& SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME) {
> - if (IS_IMAGE_LOSSY(descriptor)) {
> - spice_warning("invalid cache replace request: the image is lossy");
> - return NULL;
> - }
> - canvas->bits_cache->ops->replace_lossy(canvas->bits_cache, descriptor->id, surface);
> -#ifdef DEBUG_DUMP_SURFACE
> - dump_surface(surface, 1);
> -#endif
> -#endif
> -#ifdef DEBUG_DUMP_SURFACE
> - } else if (descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE
> -#ifdef SW_CANVAS_CACHE
> -&& descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS
> -#endif
> - ) {
> -
> - dump_surface(surface, 0);
> -#endif
> - }
> -
> - if (!real_get) {
> - pixman_image_unref(surface);
> - return NULL;
> - }
> -
> - if (!saved_want_original) {
> - /* Conversion to canvas format was requested, but maybe it didn't
> - happen above (due to save/load to cache for instance, or
> - maybe the reader didn't support conversion).
> - If so we convert here. */
> -
> - wanted_format = canvas_get_target_format(canvas,
> - surface_format == PIXMAN_a8r8g8b8);
> -
> - if (surface_format != wanted_format) {
> - converted = surface_create(
> -#ifdef WIN32
> - canvas->dc,
> -#endif
> - wanted_format,
> - pixman_image_get_width(surface),
> - pixman_image_get_height(surface),
> - TRUE);
> - pixman_image_composite32 (PIXMAN_OP_SRC,
> - surface, NULL, converted,
> - 0, 0,
> - 0, 0,
> - 0, 0,
> - pixman_image_get_width(surface),
> - pixman_image_get_height(surface));
> - pixman_image_unref (surface);
> - surface = converted;
> - }
> - }
> -
> - return surface;
> -}
> -
> -#else
> -
> -static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SpiceImage *image,
> - int want_original, int real_get)
> -{
> - SpiceImageDescriptor *descriptor =&image->descriptor;
> - pixman_format_code_t format;
> -
> - /* When touching, never load image. */
> - if (!real_get) {
> - return NULL;
> - }
> -
> - switch (descriptor->type) {
> - case SPICE_IMAGE_TYPE_QUIC: {
> - return canvas_get_quic(canvas, image, 0);
> - }
> - case SPICE_IMAGE_TYPE_BITMAP: {
> - return canvas_get_bits(canvas,&image->u.bitmap, want_original,&format);
> - }
> - default:
> - spice_warn_if_reached();
> - return NULL;
> - }
> -
> - return NULL;
> -}
> -
> -#endif
> -
> -static SpiceCanvas *canvas_get_surface_mask(CanvasBase *canvas, SpiceImage *image)
> -{
> - return canvas_get_surface_mask_internal(canvas, image);
> -}
> -
> -static SpiceCanvas *canvas_get_surface(CanvasBase *canvas, SpiceImage *image)
> -{
> - return canvas_get_surface_internal(canvas, image);
> -}
> -
> -static pixman_image_t *canvas_get_image(CanvasBase *canvas, SpiceImage *image,
> - int want_original)
> -{
> - return canvas_get_image_internal(canvas, image, want_original, TRUE);
> -}
> -
> -static void canvas_touch_image(CanvasBase *canvas, SpiceImage *image)
> -{
> - canvas_get_image_internal(canvas, image, TRUE, FALSE);
> -}
> -
> -static pixman_image_t* canvas_get_image_from_self(SpiceCanvas *canvas,
> - int x, int y,
> - int32_t width, int32_t height)
> -{
> - CanvasBase *canvas_base = (CanvasBase *)canvas;
> - pixman_image_t *surface;
> - uint8_t *dest;
> - int dest_stride;
> - SpiceRect area;
> -
> - surface = pixman_image_create_bits(spice_surface_format_to_pixman (canvas_base->format),
> - width, height, NULL, 0);
> - spice_return_val_if_fail(surface != NULL, NULL);
> -
> - dest = (uint8_t *)pixman_image_get_data(surface);
> - dest_stride = pixman_image_get_stride(surface);
> -
> - area.left = x;
> - area.top = y;
> - area.right = x + width;
> - area.bottom = y + height;
> -
> - canvas->ops->read_bits(canvas, dest, dest_stride,&area);
> -
> - return surface;
> -}
> -
> -static inline uint8_t revers_bits(uint8_t byte)
> -{
> - uint8_t ret = 0;
> - int i;
> -
> - for (i = 0; i< 4; i++) {
> - int shift = 7 - i * 2;
> - ret |= (byte& (1<< i))<< shift;
> - ret |= (byte& (0x80>> i))>> shift;
> - }
> - return ret;
> -}
> -
> -static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* bitmap, int invers)
> -{
> - pixman_image_t *surface;
> - uint8_t *src_line;
> - uint8_t *end_line;
> - uint8_t *dest_line;
> - int src_stride;
> - int line_size;
> - int dest_stride;
> -
> - surface = surface_create(
> -#ifdef WIN32
> - canvas->dc,
> -#endif
> - PIXMAN_a1, bitmap->x, bitmap->y, TRUE);
> - spice_return_val_if_fail(surface != NULL, NULL);
> -
> - spice_chunks_linearize(bitmap->data);
> - src_line = bitmap->data->chunk[0].data;
> - src_stride = bitmap->stride;
> - end_line = src_line + (bitmap->y * src_stride);
> - line_size = SPICE_ALIGN(bitmap->x, 8)>> 3;
> -
> - dest_stride = pixman_image_get_stride(surface);
> - dest_line = (uint8_t *)pixman_image_get_data(surface);
> -#if defined(GL_CANVAS)
> - if ((bitmap->flags& SPICE_BITMAP_FLAGS_TOP_DOWN)) {
> -#else
> - if (!(bitmap->flags& SPICE_BITMAP_FLAGS_TOP_DOWN)) {
> -#endif
> - spice_return_val_if_fail(bitmap->y> 0, NULL);
> - dest_line += dest_stride * ((int)bitmap->y - 1);
> - dest_stride = -dest_stride;
> - }
> -
> - if (invers) {
> - switch (bitmap->format) {
> -#if defined(GL_CANVAS) || defined(GDI_CANVAS)
> - case SPICE_BITMAP_FMT_1BIT_BE:
> -#else
> - case SPICE_BITMAP_FMT_1BIT_LE:
> -#endif
> - for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
> - uint8_t *dest = dest_line;
> - uint8_t *now = src_line;
> - uint8_t *end = now + line_size;
> - while (now< end) {
> - *(dest++) = ~*(now++);
> - }
> - }
> - break;
> -#if defined(GL_CANVAS) || defined(GDI_CANVAS)
> - case SPICE_BITMAP_FMT_1BIT_LE:
> -#else
> - case SPICE_BITMAP_FMT_1BIT_BE:
> -#endif
> - for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
> - uint8_t *dest = dest_line;
> - uint8_t *now = src_line;
> - uint8_t *end = now + line_size;
> -
> - while (now< end) {
> - *(dest++) = ~revers_bits(*(now++));
> - }
> - }
> - break;
> - default:
> - pixman_image_unref(surface);
> - surface = NULL;
> - spice_warn_if_reached();
> - return NULL;
> - }
> - } else {
> - switch (bitmap->format) {
> -#if defined(GL_CANVAS) || defined(GDI_CANVAS)
> - case SPICE_BITMAP_FMT_1BIT_BE:
> -#else
> - case SPICE_BITMAP_FMT_1BIT_LE:
> -#endif
> - for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
> - memcpy(dest_line, src_line, line_size);
> - }
> - break;
> -#if defined(GL_CANVAS) || defined(GDI_CANVAS)
> - case SPICE_BITMAP_FMT_1BIT_LE:
> -#else
> - case SPICE_BITMAP_FMT_1BIT_BE:
> -#endif
> - for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
> - uint8_t *dest = dest_line;
> - uint8_t *now = src_line;
> - uint8_t *end = now + line_size;
> -
> - while (now< end) {
> - *(dest++) = revers_bits(*(now++));
> - }
> - }
> - break;
> - default:
> - pixman_image_unref(surface);
> - surface = NULL;
> - spice_warn_if_reached();
> - return NULL;
> - }
> - }
> - return surface;
> -}
> -
> -static inline pixman_image_t *canvas_A1_invers(pixman_image_t *src_surf)
> -{
> - int width = pixman_image_get_width(src_surf);
> - int height = pixman_image_get_height(src_surf);
> - pixman_image_t * invers;
> - uint8_t *src_line, *end_line, *dest_line;
> - int src_stride, line_size, dest_stride;
> -
> - spice_return_val_if_fail(pixman_image_get_depth(src_surf) == 1, NULL);
> -
> - invers = pixman_image_create_bits(PIXMAN_a1, width, height, NULL, 0);
> - spice_return_val_if_fail(invers != NULL, NULL);
> -
> - src_line = (uint8_t *)pixman_image_get_data(src_surf);
> - src_stride = pixman_image_get_stride(src_surf);
> - end_line = src_line + (height * src_stride);
> - line_size = SPICE_ALIGN(width, 8)>> 3;
> - dest_line = (uint8_t *)pixman_image_get_data(invers);
> - dest_stride = pixman_image_get_stride(invers);
> -
> - for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
> - uint8_t *dest = dest_line;
> - uint8_t *now = src_line;
> - uint8_t *end = now + line_size;
> - while (now< end) {
> - *(dest++) = ~*(now++);
> - }
> - }
> - return invers;
> -}
> -
> -static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask, int *needs_invert_out)
> -{
> - SpiceImage *image;
> - pixman_image_t *surface;
> - int need_invers;
> - int is_invers;
> - int cache_me;
> -
> - if (needs_invert_out) {
> - *needs_invert_out = 0;
> - }
> -
> - image = mask->bitmap;
> - need_invers = mask->flags& SPICE_MASK_FLAGS_INVERS;
> -
> -#ifdef SW_CANVAS_CACHE
> - cache_me = image->descriptor.flags& SPICE_IMAGE_FLAGS_CACHE_ME;
> -#else
> - cache_me = 0;
> -#endif
> -
> - switch (image->descriptor.type) {
> - case SPICE_IMAGE_TYPE_BITMAP: {
> - is_invers = need_invers&& !cache_me;
> - surface = canvas_get_bitmap_mask(canvas,&image->u.bitmap, is_invers);
> - break;
> - }
> -#if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
> - case SPICE_IMAGE_TYPE_FROM_CACHE:
> - surface = canvas->bits_cache->ops->get(canvas->bits_cache, image->descriptor.id);
> - is_invers = 0;
> - break;
> -#endif
> -#ifdef SW_CANVAS_CACHE
> - case SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS:
> - surface = canvas->bits_cache->ops->get_lossless(canvas->bits_cache, image->descriptor.id);
> - is_invers = 0;
> - break;
> -#endif
> - default:
> - spice_warn_if_reached();
> - return NULL;
> - }
> -
> -#if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
> - if (cache_me) {
> - canvas->bits_cache->ops->put(canvas->bits_cache, image->descriptor.id, surface);
> - }
> -
> - if (need_invers&& !is_invers) { // surface is in cache
> - if (needs_invert_out != NULL) {
> - *needs_invert_out = TRUE;
> - } else {
> - pixman_image_t *inv_surf;
> - inv_surf = canvas_A1_invers(surface);
> - pixman_image_unref(surface);
> - surface = inv_surf;
> - }
> - }
> -#endif
> - return surface;
> -}
> -
> -static inline void canvas_raster_glyph_box(const SpiceRasterGlyph *glyph, SpiceRect *r)
> -{
> - spice_return_if_fail(r != NULL);
> -
> - r->top = glyph->render_pos.y + glyph->glyph_origin.y;
> - r->bottom = r->top + glyph->height;
> - r->left = glyph->render_pos.x + glyph->glyph_origin.x;
> - r->right = r->left + glyph->width;
> -}
> -
> -#ifdef GL_CANVAS
> -static inline void __canvas_put_bits(uint8_t *dest, int offset, uint8_t val, int n)
> -{
> - uint8_t mask;
> - int now;
> -
> - dest = dest + (offset>> 3);
> - offset&= 0x07;
> - now = MIN(8 - offset, n);
> -
> - mask = ~((1<< (8 - now)) - 1);
> - mask>>= offset;
> - *dest = ((val>> offset)& mask) | *dest;
> -
> - if ((n = n - now)) {
> - mask = ~((1<< (8 - n)) - 1);
> - dest++;
> - *dest = ((val<< now)& mask) | *dest;
> - }
> -}
> -
> -#else
> -static inline void __canvas_put_bits(uint8_t *dest, int offset, uint8_t val, int n)
> -{
> - uint8_t mask;
> - int now;
> -
> - dest = dest + (offset>> 3);
> - offset&= 0x07;
> -
> - now = MIN(8 - offset, n);
> -
> - mask = (1<< now) - 1;
> - mask<<= offset;
> - val = revers_bits(val);
> - *dest = ((val<< offset)& mask) | *dest;
> -
> - if ((n = n - now)) {
> - mask = (1<< n) - 1;
> - dest++;
> - *dest = ((val>> now)& mask) | *dest;
> - }
> -}
> -
> -#endif
> -
> -static inline void canvas_put_bits(uint8_t *dest, int dest_offset, uint8_t *src, int n)
> -{
> - while (n) {
> - int now = MIN(n, 8);
> -
> - n -= now;
> - __canvas_put_bits(dest, dest_offset, *src, now);
> - dest_offset += now;
> - src++;
> - }
> -}
> -
> -static void canvas_put_glyph_bits(SpiceRasterGlyph *glyph, int bpp, uint8_t *dest, int dest_stride,
> - SpiceRect *bounds)
> -{
> - SpiceRect glyph_box;
> - uint8_t *src;
> - int lines;
> - int width;
> -
> - //todo: support SPICE_STRING_FLAGS_RASTER_TOP_DOWN
> - canvas_raster_glyph_box(glyph,&glyph_box);
> - spice_return_if_fail(glyph_box.top>= bounds->top&& glyph_box.bottom<= bounds->bottom);
> - spice_return_if_fail(glyph_box.left>= bounds->left&& glyph_box.right<= bounds->right);
> - rect_offset(&glyph_box, -bounds->left, -bounds->top);
> -
> - dest += glyph_box.top * dest_stride;
> - src = glyph->data;
> - lines = glyph_box.bottom - glyph_box.top;
> - width = glyph_box.right - glyph_box.left;
> - switch (bpp) {
> - case 1: {
> - int src_stride = SPICE_ALIGN(width, 8)>> 3;
> - int i;
> -
> - src += src_stride * (lines);
> - for (i = 0; i< lines; i++) {
> - src -= src_stride;
> - canvas_put_bits(dest, glyph_box.left, src, width);
> - dest += dest_stride;
> - }
> - break;
> - }
> - case 4: {
> - uint8_t *end;
> - int src_stride = SPICE_ALIGN(width * 4, 8)>> 3;
> -
> - src += src_stride * lines;
> - dest += glyph_box.left;
> - end = dest + dest_stride * lines;
> - for (; dest != end; dest += dest_stride) {
> - int i = 0;
> - uint8_t *now;
> -
> - src -= src_stride;
> - now = src;
> - while (i< (width& ~1)) {
> - dest[i] = MAX(dest[i], *now& 0xf0);
> - dest[i + 1] = MAX(dest[i + 1], *now<< 4);
> - i += 2;
> - now++;
> - }
> - if (i< width) {
> - dest[i] = MAX(dest[i], *now& 0xf0);
> - now++;
> - }
> - }
> - break;
> - }
> - case 8: {
> - uint8_t *end;
> - src += width * lines;
> - dest += glyph_box.left;
> - end = dest + dest_stride * lines;
> - for (; dest != end; dest += dest_stride, src -= width) {
> - int i;
> -
> - for (i = 0; i< width; i++) {
> - dest[i] = MAX(dest[i], src[i]);
> - }
> - }
> - break;
> - }
> - default:
> - spice_warn_if_reached();
> - return;
> - }
> -}
> -
> -static pixman_image_t *canvas_get_str_mask(CanvasBase *canvas, SpiceString *str, int bpp, SpicePoint *pos)
> -{
> - SpiceRasterGlyph *glyph;
> - SpiceRect bounds;
> - pixman_image_t *str_mask;
> - uint8_t *dest;
> - int dest_stride;
> - int i;
> -
> - spice_return_val_if_fail(str->length> 0, NULL);
> -
> - glyph = str->glyphs[0];
> - canvas_raster_glyph_box(glyph,&bounds);
> -
> - for (i = 1; i< str->length; i++) {
> - SpiceRect glyph_box;
> -
> - canvas_raster_glyph_box(str->glyphs[i],&glyph_box);
> - rect_union(&bounds,&glyph_box);
> - }
> -
> - str_mask = pixman_image_create_bits((bpp == 1) ? PIXMAN_a1 : PIXMAN_a8,
> - bounds.right - bounds.left,
> - bounds.bottom - bounds.top, NULL, 0);
> - spice_return_val_if_fail(str_mask != NULL, NULL);
> -
> - dest = (uint8_t *)pixman_image_get_data(str_mask);
> - dest_stride = pixman_image_get_stride(str_mask);
> - for (i = 0; i< str->length; i++) {
> - glyph = str->glyphs[i];
> -#if defined(GL_CANVAS)
> - canvas_put_glyph_bits(glyph, bpp, dest + (bounds.bottom - bounds.top - 1) * dest_stride,
> - -dest_stride,&bounds);
> -#else
> - canvas_put_glyph_bits(glyph, bpp, dest, dest_stride,&bounds);
> -#endif
> - }
> -
> - pos->x = bounds.left;
> - pos->y = bounds.top;
> - return str_mask;
> -}
> -
> -static pixman_image_t *canvas_scale_surface(pixman_image_t *src, const SpiceRect *src_area, int width,
> - int height, int scale_mode)
> -{
> - pixman_image_t *surface;
> - pixman_transform_t transform;
> - double sx, sy;
> -
> - surface = pixman_image_create_bits(spice_pixman_image_get_format (src),
> - width, height, NULL, 0);
> - spice_return_val_if_fail(surface != NULL, NULL);
> -
> - sx = (double)(src_area->right - src_area->left) / width;
> - sy = (double)(src_area->bottom - src_area->top) / height;
> -
> - pixman_transform_init_scale(&transform, pixman_double_to_fixed(sx), pixman_double_to_fixed(sy));
> -
> - pixman_image_set_transform (src,&transform);
> - pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
> - spice_return_val_if_fail(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE || scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST, NULL);
> - pixman_image_set_filter(src,
> - (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
> - NULL, 0);
> -
> - pixman_image_composite32(PIXMAN_OP_SRC,
> - src, NULL, surface,
> - ROUND(src_area->left / sx), ROUND (src_area->top / sy),
> - 0, 0, /* mask */
> - 0, 0, /* dst */
> - width, height);
> -
> - pixman_transform_init_identity(&transform);
> - pixman_image_set_transform(src,&transform);
> -
> - return surface;
> -}
> -
> -ATTR_PRINTF(2, 3) static void quic_usr_error(QuicUsrContext *usr, const char *fmt, ...)
> -{
> - QuicData *usr_data = (QuicData *)usr;
> - va_list ap;
> -
> - va_start(ap, fmt);
> - vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
> - va_end(ap);
> -
> - longjmp(usr_data->jmp_env, 1);
> -}
> -
> -ATTR_PRINTF(2, 3) static void quic_usr_warn(QuicUsrContext *usr, const char *fmt, ...)
> -{
> - QuicData *usr_data = (QuicData *)usr;
> - va_list ap;
> -
> - va_start(ap, fmt);
> - vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
> - va_end(ap);
> -}
> -
> -static void *quic_usr_malloc(QuicUsrContext *usr, int size)
> -{
> - return spice_malloc(size);
> -}
> -
> -static void quic_usr_free(QuicUsrContext *usr, void *ptr)
> -{
> - free(ptr);
> -}
> -
> -ATTR_PRINTF(2, 3) static void lz_usr_warn(LzUsrContext *usr, const char *fmt, ...)
> -{
> - LzData *usr_data = (LzData *)usr;
> - va_list ap;
> -
> - va_start(ap, fmt);
> - vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
> - va_end(ap);
> -}
> -
> -ATTR_PRINTF(2, 3) static void lz_usr_error(LzUsrContext *usr, const char *fmt, ...)
> -{
> - LzData *usr_data = (LzData *)usr;
> - va_list ap;
> -
> - va_start(ap, fmt);
> - vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
> - va_end(ap);
> -
> - longjmp(usr_data->jmp_env, 1);
> -}
> -
> -static void *lz_usr_malloc(LzUsrContext *usr, int size)
> -{
> - return spice_malloc(size);
> -}
> -
> -static void lz_usr_free(LzUsrContext *usr, void *ptr)
> -{
> - free(ptr);
> -}
> -
> -static int lz_usr_more_space(LzUsrContext *usr, uint8_t **io_ptr)
> -{
> - return 0;
> -}
> -
> -static int lz_usr_more_lines(LzUsrContext *usr, uint8_t **lines)
> -{
> - return 0;
> -}
> -
> -static int quic_usr_more_space(QuicUsrContext *usr, uint32_t **io_ptr, int rows_completed)
> -{
> - QuicData *quic_data = (QuicData *)usr;
> -
> - if (quic_data->current_chunk == quic_data->chunks->num_chunks -1) {
> - return 0;
> - }
> - quic_data->current_chunk++;
> -
> - *io_ptr = (uint32_t *)quic_data->chunks->chunk[quic_data->current_chunk].data;
> - return quic_data->chunks->chunk[quic_data->current_chunk].len>> 2;
> -}
> -
> -
> -static int quic_usr_more_lines(QuicUsrContext *usr, uint8_t **lines)
> -{
> - return 0;
> -}
> -
> -static void canvas_base_destroy(CanvasBase *canvas)
> -{
> - quic_destroy(canvas->quic_data.quic);
> - lz_destroy(canvas->lz_data.lz);
> -#ifdef GDI_CANVAS
> - DeleteDC(canvas->dc);
> -#endif
> -
> - if (canvas->usr_data&& canvas->usr_data_destroy) {
> - canvas->usr_data_destroy (canvas->usr_data);
> - canvas->usr_data = NULL;
> - }
> -}
> -
> -/* This is kind of lame, but it protects against multiple
> - instances of these functions. We really should stop including
> - canvas_base.c and build it separately instead */
> -#ifdef CANVAS_SINGLE_INSTANCE
> -
> -void spice_canvas_set_usr_data(SpiceCanvas *spice_canvas,
> - void *data,
> - spice_destroy_fn_t destroy_fn)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - if (canvas->usr_data&& canvas->usr_data_destroy) {
> - canvas->usr_data_destroy (canvas->usr_data);
> - }
> - canvas->usr_data = data;
> - canvas->usr_data_destroy = destroy_fn;
> -}
> -
> -void *spice_canvas_get_usr_data(SpiceCanvas *spice_canvas)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - return canvas->usr_data;
> -}
> -#endif
> -
> -
> -static void canvas_clip_pixman(CanvasBase *canvas,
> - pixman_region32_t *dest_region,
> - SpiceClip *clip)
> -{
> - pixman_region32_intersect(dest_region, dest_region,&canvas->canvas_region);
> -
> - switch (clip->type) {
> - case SPICE_CLIP_TYPE_NONE:
> - break;
> - case SPICE_CLIP_TYPE_RECTS: {
> - uint32_t n = clip->rects->num_rects;
> - SpiceRect *now = clip->rects->rects;
> -
> - pixman_region32_t clip;
> -
> - if (spice_pixman_region32_init_rects(&clip, now, n)) {
> - pixman_region32_intersect(dest_region, dest_region,&clip);
> - pixman_region32_fini(&clip);
> - }
> -
> - break;
> - }
> - default:
> - spice_warn_if_reached();
> - return;
> - }
> -}
> -
> -static void canvas_mask_pixman(CanvasBase *canvas,
> - pixman_region32_t *dest_region,
> - SpiceQMask *mask, int x, int y)
> -{
> - SpiceCanvas *surface_canvas;
> - pixman_image_t *image, *subimage;
> - int needs_invert;
> - pixman_region32_t mask_region;
> - uint32_t *mask_data;
> - int mask_x, mask_y;
> - int mask_width, mask_height, mask_stride;
> - pixman_box32_t extents;
> -
> - if (!mask->bitmap) {
> - return;
> - }
> -
> - surface_canvas = canvas_get_surface_mask(canvas, mask->bitmap);
> - if (surface_canvas) {
> - needs_invert = mask->flags& SPICE_MASK_FLAGS_INVERS;
> - image = surface_canvas->ops->get_image(surface_canvas);
> - } else {
> - needs_invert = FALSE;
> - image = canvas_get_mask(canvas,
> - mask,
> -&needs_invert);
> - }
> -
> - mask_data = pixman_image_get_data(image);
> - mask_width = pixman_image_get_width(image);
> - mask_height = pixman_image_get_height(image);
> - mask_stride = pixman_image_get_stride(image);
> -
> - mask_x = mask->pos.x;
> - mask_y = mask->pos.y;
> -
> - /* We need to subset the area of the mask that we turn into a region,
> - because a cached mask may be much larger than what is used for
> - the clip operation. */
> - extents = *pixman_region32_extents(dest_region);
> -
> - /* convert from destination pixels to mask pixels */
> - extents.x1 -= x - mask_x;
> - extents.y1 -= y - mask_y;
> - extents.x2 -= x - mask_x;
> - extents.y2 -= y - mask_y;
> -
> - /* clip to mask size */
> - if (extents.x1< 0) {
> - extents.x1 = 0;
> - }
> - if (extents.x2>= mask_width) {
> - extents.x2 = mask_width;
> - }
> - if (extents.x2< extents.x1) {
> - extents.x2 = extents.x1;
> - }
> - if (extents.y1< 0) {
> - extents.y1 = 0;
> - }
> - if (extents.y2>= mask_height) {
> - extents.y2 = mask_height;
> - }
> - if (extents.y2< extents.y1) {
> - extents.y2 = extents.y1;
> - }
> -
> - /* round down X to even 32 pixels (i.e. uint32_t) */
> - extents.x1 = extents.x1& ~(0x1f);
> -
> - mask_data = (uint32_t *)((uint8_t *)mask_data + mask_stride * extents.y1 + extents.x1 / 32);
> - mask_x -= extents.x1;
> - mask_y -= extents.y1;
> - mask_width = extents.x2 - extents.x1;
> - mask_height = extents.y2 - extents.y1;
> -
> - subimage = pixman_image_create_bits(PIXMAN_a1, mask_width, mask_height,
> - mask_data, mask_stride);
> - pixman_region32_init_from_image(&mask_region,
> - subimage);
> - pixman_image_unref(subimage);
> -
> - if (needs_invert) {
> - pixman_box32_t rect;
> -
> - rect.x1 = rect.y1 = 0;
> - rect.x2 = mask_width;
> - rect.y2 = mask_height;
> -
> - pixman_region32_inverse(&mask_region,&mask_region,&rect);
> - }
> -
> - pixman_region32_translate(&mask_region,
> - -mask_x + x, -mask_y + y);
> -
> - pixman_region32_intersect(dest_region, dest_region,&mask_region);
> - pixman_region32_fini(&mask_region);
> -
> - pixman_image_unref(image);
> -}
> -
> -static void draw_brush(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - SpiceBrush *brush,
> - SpiceROP rop)
> -{
> - CanvasBase *canvas_base = (CanvasBase *)canvas;
> - uint32_t color;
> - SpicePattern *pattern;
> - pixman_image_t *tile;
> - int offset_x, offset_y;
> - pixman_box32_t *rects;
> - int n_rects;
> -
> - rects = pixman_region32_rectangles(region,&n_rects);
> -
> - switch (brush->type) {
> - case SPICE_BRUSH_TYPE_SOLID:
> - color = brush->u.color;
> - if (rop == SPICE_ROP_COPY) {
> - canvas->ops->fill_solid_rects(canvas, rects, n_rects, color);
> - } else {
> - canvas->ops->fill_solid_rects_rop(canvas, rects, n_rects, color, rop);
> - }
> - break;
> - case SPICE_BRUSH_TYPE_PATTERN: {
> - SpiceCanvas *surface_canvas;
> -
> - pattern =&brush->u.pattern;
> - offset_x = pattern->pos.x;
> - offset_y = pattern->pos.y;
> -
> - surface_canvas = canvas_get_surface(canvas_base, pattern->pat);
> - if (surface_canvas) {
> - if (rop == SPICE_ROP_COPY) {
> - canvas->ops->fill_tiled_rects_from_surface(canvas, rects, n_rects, surface_canvas,
> - offset_x, offset_y);
> - } else {
> - canvas->ops->fill_tiled_rects_rop_from_surface(canvas, rects, n_rects,
> - surface_canvas, offset_x, offset_y,
> - rop);
> - }
> - } else {
> - tile = canvas_get_image(canvas_base, pattern->pat, FALSE);
> - spice_return_if_fail(tile != NULL);
> -
> - if (rop == SPICE_ROP_COPY) {
> - canvas->ops->fill_tiled_rects(canvas, rects, n_rects, tile, offset_x, offset_y);
> - } else {
> - canvas->ops->fill_tiled_rects_rop(canvas, rects, n_rects,
> - tile, offset_x, offset_y, rop);
> - }
> - pixman_image_unref(tile);
> - }
> - break;
> - }
> - case SPICE_BRUSH_TYPE_NONE:
> - /* Still need to do *something* here, because rop could be e.g invert dest */
> - canvas->ops->fill_solid_rects_rop(canvas, rects, n_rects, 0, rop);
> - break;
> - default:
> - spice_warn_if_reached();
> - return;
> - }
> -}
> -
> -/* If we're exiting early we may still have to load an image in case
> - it has to be cached or something */
> -static void touch_brush(CanvasBase *canvas, SpiceBrush *brush)
> -{
> - SpicePattern *pattern;
> -
> - if (brush->type == SPICE_BRUSH_TYPE_PATTERN) {
> - pattern =&brush->u.pattern;
> - canvas_touch_image(canvas, pattern->pat);
> - }
> -}
> -
> -static void canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - pixman_region32_t dest_region;
> - SpiceROP rop;
> -
> - pixman_region32_init_rect(&dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> -
> - canvas_clip_pixman(canvas,&dest_region, clip);
> - canvas_mask_pixman(canvas,&dest_region,&fill->mask,
> - bbox->left, bbox->top);
> -
> - rop = ropd_descriptor_to_rop(fill->rop_descriptor,
> - ROP_INPUT_BRUSH,
> - ROP_INPUT_DEST);
> -
> - if (rop == SPICE_ROP_NOOP || !pixman_region32_not_empty(&dest_region)) {
> - touch_brush(canvas,&fill->brush);
> - pixman_region32_fini(&dest_region);
> - return;
> - }
> -
> - draw_brush(spice_canvas,&dest_region,&fill->brush, rop);
> -
> - pixman_region32_fini(&dest_region);
> -}
> -
> -static void canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - pixman_region32_t dest_region;
> - SpiceCanvas *surface_canvas;
> - pixman_image_t *src_image;
> - SpiceROP rop;
> -
> - pixman_region32_init_rect(&dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> - canvas_clip_pixman(canvas,&dest_region, clip);
> - canvas_mask_pixman(canvas,&dest_region,©->mask,
> - bbox->left, bbox->top);
> -
> - rop = ropd_descriptor_to_rop(copy->rop_descriptor,
> - ROP_INPUT_SRC,
> - ROP_INPUT_DEST);
> -
> - if (rop == SPICE_ROP_NOOP || !pixman_region32_not_empty(&dest_region)) {
> - canvas_touch_image(canvas, copy->src_bitmap);
> - pixman_region32_fini(&dest_region);
> - return;
> - }
> -
> - surface_canvas = canvas_get_surface(canvas, copy->src_bitmap);
> - if (surface_canvas) {
> - if (rect_is_same_size(bbox,©->src_area)) {
> - if (rop == SPICE_ROP_COPY) {
> - spice_canvas->ops->blit_image_from_surface(spice_canvas,&dest_region,
> - surface_canvas,
> - bbox->left - copy->src_area.left,
> - bbox->top - copy->src_area.top);
> - } else {
> - spice_canvas->ops->blit_image_rop_from_surface(spice_canvas,&dest_region,
> - surface_canvas,
> - bbox->left - copy->src_area.left,
> - bbox->top - copy->src_area.top,
> - rop);
> - }
> - } else {
> - if (rop == SPICE_ROP_COPY) {
> - spice_canvas->ops->scale_image_from_surface(spice_canvas,&dest_region,
> - surface_canvas,
> - copy->src_area.left,
> - copy->src_area.top,
> - copy->src_area.right - copy->src_area.left,
> - copy->src_area.bottom - copy->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - copy->scale_mode);
> - } else {
> - spice_canvas->ops->scale_image_rop_from_surface(spice_canvas,&dest_region,
> - surface_canvas,
> - copy->src_area.left,
> - copy->src_area.top,
> - copy->src_area.right - copy->src_area.left,
> - copy->src_area.bottom - copy->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - copy->scale_mode,
> - rop);
> - }
> - }
> - } else {
> - src_image = canvas_get_image(canvas, copy->src_bitmap, FALSE);
> - spice_return_if_fail(src_image != NULL);
> -
> - if (rect_is_same_size(bbox,©->src_area)) {
> - if (rop == SPICE_ROP_COPY) {
> - spice_canvas->ops->blit_image(spice_canvas,&dest_region,
> - src_image,
> - bbox->left - copy->src_area.left,
> - bbox->top - copy->src_area.top);
> - } else {
> - spice_canvas->ops->blit_image_rop(spice_canvas,&dest_region,
> - src_image,
> - bbox->left - copy->src_area.left,
> - bbox->top - copy->src_area.top,
> - rop);
> - }
> - } else {
> - if (rop == SPICE_ROP_COPY) {
> - spice_canvas->ops->scale_image(spice_canvas,&dest_region,
> - src_image,
> - copy->src_area.left,
> - copy->src_area.top,
> - copy->src_area.right - copy->src_area.left,
> - copy->src_area.bottom - copy->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - copy->scale_mode);
> - } else {
> - spice_canvas->ops->scale_image_rop(spice_canvas,&dest_region,
> - src_image,
> - copy->src_area.left,
> - copy->src_area.top,
> - copy->src_area.right - copy->src_area.left,
> - copy->src_area.bottom - copy->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - copy->scale_mode,
> - rop);
> - }
> - }
> - pixman_image_unref(src_image);
> - }
> - pixman_region32_fini(&dest_region);
> -}
> -
> -static void canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - SpiceCanvas *surface_canvas;
> - pixman_image_t *src_image;
> - pixman_region32_t dest_region;
> - uint32_t transparent_color;
> -
> - pixman_region32_init_rect(&dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> - canvas_clip_pixman(canvas,&dest_region, clip);
> -
> - if (pixman_region32_n_rects (&dest_region) == 0) {
> - canvas_touch_image(canvas, transparent->src_bitmap);
> - pixman_region32_fini(&dest_region);
> - return;
> - }
> -
> - switch (canvas->format) {
> - case SPICE_SURFACE_FMT_32_xRGB:
> - case SPICE_SURFACE_FMT_32_ARGB:
> - transparent_color = transparent->true_color;
> - break;
> - case SPICE_SURFACE_FMT_16_555:
> - transparent_color = rgb_32_to_16_555(transparent->true_color);
> - break;
> - case SPICE_SURFACE_FMT_16_565:
> - transparent_color = rgb_32_to_16_565(transparent->true_color);
> - break;
> - default:
> - transparent_color = 0;
> - }
> -
> - surface_canvas = canvas_get_surface(canvas, transparent->src_bitmap);
> - if (surface_canvas) {
> - if (rect_is_same_size(bbox,&transparent->src_area)) {
> - spice_canvas->ops->colorkey_image_from_surface(spice_canvas,&dest_region,
> - surface_canvas,
> - bbox->left - transparent->src_area.left,
> - bbox->top - transparent->src_area.top,
> - transparent_color);
> - } else {
> - spice_canvas->ops->colorkey_scale_image_from_surface(spice_canvas,&dest_region,
> - surface_canvas,
> - transparent->src_area.left,
> - transparent->src_area.top,
> - transparent->src_area.right - transparent->src_area.left,
> - transparent->src_area.bottom - transparent->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - transparent_color);
> - }
> - } else {
> - src_image = canvas_get_image(canvas, transparent->src_bitmap, FALSE);
> - spice_return_if_fail(src_image != NULL);
> -
> - if (rect_is_same_size(bbox,&transparent->src_area)) {
> - spice_canvas->ops->colorkey_image(spice_canvas,&dest_region,
> - src_image,
> - bbox->left - transparent->src_area.left,
> - bbox->top - transparent->src_area.top,
> - transparent_color);
> - } else {
> - spice_canvas->ops->colorkey_scale_image(spice_canvas,&dest_region,
> - src_image,
> - transparent->src_area.left,
> - transparent->src_area.top,
> - transparent->src_area.right - transparent->src_area.left,
> - transparent->src_area.bottom - transparent->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - transparent_color);
> - }
> - pixman_image_unref(src_image);
> - }
> - pixman_region32_fini(&dest_region);
> -}
> -
> -static void canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend* alpha_blend)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - pixman_region32_t dest_region;
> - SpiceCanvas *surface_canvas;
> - pixman_image_t *src_image;
> -
> - pixman_region32_init_rect(&dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> - canvas_clip_pixman(canvas,&dest_region, clip);
> -
> - if (alpha_blend->alpha == 0 ||
> - !pixman_region32_not_empty(&dest_region)) {
> - canvas_touch_image(canvas, alpha_blend->src_bitmap);
> - pixman_region32_fini(&dest_region);
> - return;
> - }
> -
> - surface_canvas = canvas_get_surface(canvas, alpha_blend->src_bitmap);
> - if (surface_canvas) {
> - if (rect_is_same_size(bbox,&alpha_blend->src_area)) {
> - spice_canvas->ops->blend_image_from_surface(spice_canvas,&dest_region,
> - alpha_blend->alpha_flags& SPICE_ALPHA_FLAGS_DEST_HAS_ALPHA,
> - surface_canvas,
> - alpha_blend->alpha_flags& SPICE_ALPHA_FLAGS_SRC_SURFACE_HAS_ALPHA,
> - alpha_blend->src_area.left,
> - alpha_blend->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - alpha_blend->alpha);
> - } else {
> - spice_canvas->ops->blend_scale_image_from_surface(spice_canvas,&dest_region,
> - alpha_blend->alpha_flags& SPICE_ALPHA_FLAGS_DEST_HAS_ALPHA,
> - surface_canvas,
> - alpha_blend->alpha_flags& SPICE_ALPHA_FLAGS_SRC_SURFACE_HAS_ALPHA,
> - alpha_blend->src_area.left,
> - alpha_blend->src_area.top,
> - alpha_blend->src_area.right - alpha_blend->src_area.left,
> - alpha_blend->src_area.bottom - alpha_blend->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - SPICE_IMAGE_SCALE_MODE_NEAREST,
> - alpha_blend->alpha);
> - }
> - } else {
> - src_image = canvas_get_image(canvas, alpha_blend->src_bitmap, TRUE);
> - spice_return_if_fail(src_image != NULL);
> -
> - if (rect_is_same_size(bbox,&alpha_blend->src_area)) {
> - spice_canvas->ops->blend_image(spice_canvas,&dest_region,
> - alpha_blend->alpha_flags& SPICE_ALPHA_FLAGS_DEST_HAS_ALPHA,
> - src_image,
> - alpha_blend->src_area.left,
> - alpha_blend->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - alpha_blend->alpha);
> - } else {
> - spice_canvas->ops->blend_scale_image(spice_canvas,&dest_region,
> - alpha_blend->alpha_flags& SPICE_ALPHA_FLAGS_DEST_HAS_ALPHA,
> - src_image,
> - alpha_blend->src_area.left,
> - alpha_blend->src_area.top,
> - alpha_blend->src_area.right - alpha_blend->src_area.left,
> - alpha_blend->src_area.bottom - alpha_blend->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - SPICE_IMAGE_SCALE_MODE_NEAREST,
> - alpha_blend->alpha);
> - }
> -
> - pixman_image_unref(src_image);
> - }
> -
> - pixman_region32_fini(&dest_region);
> -}
> -
> -static void canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - pixman_image_t *src_image;
> - pixman_region32_t dest_region;
> - SpiceCanvas *surface_canvas;
> - SpiceROP rop;
> -
> - pixman_region32_init_rect(&dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> - canvas_clip_pixman(canvas,&dest_region, clip);
> - canvas_mask_pixman(canvas,&dest_region,&opaque->mask,
> - bbox->left, bbox->top);
> -
> - rop = ropd_descriptor_to_rop(opaque->rop_descriptor,
> - ROP_INPUT_BRUSH,
> - ROP_INPUT_SRC);
> -
> - if (rop == SPICE_ROP_NOOP || !pixman_region32_not_empty(&dest_region)) {
> - canvas_touch_image(canvas, opaque->src_bitmap);
> - touch_brush(canvas,&opaque->brush);
> - pixman_region32_fini(&dest_region);
> - return;
> - }
> -
> - surface_canvas = canvas_get_surface(canvas, opaque->src_bitmap);
> - if (surface_canvas) {
> - if (rect_is_same_size(bbox,&opaque->src_area)) {
> - spice_canvas->ops->blit_image_from_surface(spice_canvas,&dest_region,
> - surface_canvas,
> - bbox->left - opaque->src_area.left,
> - bbox->top - opaque->src_area.top);
> - } else {
> - spice_canvas->ops->scale_image_from_surface(spice_canvas,&dest_region,
> - surface_canvas,
> - opaque->src_area.left,
> - opaque->src_area.top,
> - opaque->src_area.right - opaque->src_area.left,
> - opaque->src_area.bottom - opaque->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - opaque->scale_mode);
> - }
> - } else {
> - src_image = canvas_get_image(canvas, opaque->src_bitmap, FALSE);
> - spice_return_if_fail(src_image != NULL);
> -
> - if (rect_is_same_size(bbox,&opaque->src_area)) {
> - spice_canvas->ops->blit_image(spice_canvas,&dest_region,
> - src_image,
> - bbox->left - opaque->src_area.left,
> - bbox->top - opaque->src_area.top);
> - } else {
> - spice_canvas->ops->scale_image(spice_canvas,&dest_region,
> - src_image,
> - opaque->src_area.left,
> - opaque->src_area.top,
> - opaque->src_area.right - opaque->src_area.left,
> - opaque->src_area.bottom - opaque->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - opaque->scale_mode);
> - }
> - pixman_image_unref(src_image);
> - }
> -
> - draw_brush(spice_canvas,&dest_region,&opaque->brush, rop);
> -
> - pixman_region32_fini(&dest_region);
> -}
> -
> -static void canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - SpiceCanvas *surface_canvas;
> - pixman_image_t *src_image;
> - pixman_region32_t dest_region;
> - SpiceROP rop;
> -
> - pixman_region32_init_rect(&dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> - canvas_clip_pixman(canvas,&dest_region, clip);
> - canvas_mask_pixman(canvas,&dest_region,&blend->mask,
> - bbox->left, bbox->top);
> -
> - rop = ropd_descriptor_to_rop(blend->rop_descriptor,
> - ROP_INPUT_SRC,
> - ROP_INPUT_DEST);
> -
> - if (rop == SPICE_ROP_NOOP || !pixman_region32_not_empty(&dest_region)) {
> - canvas_touch_image(canvas, blend->src_bitmap);
> - pixman_region32_fini(&dest_region);
> - return;
> - }
> -
> - surface_canvas = canvas_get_surface(canvas, blend->src_bitmap);
> - if (surface_canvas) {
> - if (rect_is_same_size(bbox,&blend->src_area)) {
> - if (rop == SPICE_ROP_COPY)
> - spice_canvas->ops->blit_image_from_surface(spice_canvas,&dest_region,
> - surface_canvas,
> - bbox->left - blend->src_area.left,
> - bbox->top - blend->src_area.top);
> - else
> - spice_canvas->ops->blit_image_rop_from_surface(spice_canvas,&dest_region,
> - surface_canvas,
> - bbox->left - blend->src_area.left,
> - bbox->top - blend->src_area.top,
> - rop);
> - } else {
> - if (rop == SPICE_ROP_COPY) {
> - spice_canvas->ops->scale_image_from_surface(spice_canvas,&dest_region,
> - surface_canvas,
> - blend->src_area.left,
> - blend->src_area.top,
> - blend->src_area.right - blend->src_area.left,
> - blend->src_area.bottom - blend->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - blend->scale_mode);
> - } else {
> - spice_canvas->ops->scale_image_rop_from_surface(spice_canvas,&dest_region,
> - surface_canvas,
> - blend->src_area.left,
> - blend->src_area.top,
> - blend->src_area.right - blend->src_area.left,
> - blend->src_area.bottom - blend->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - blend->scale_mode, rop);
> - }
> - }
> - } else {
> - src_image = canvas_get_image(canvas, blend->src_bitmap, FALSE);
> - spice_return_if_fail(src_image != NULL);
> -
> - if (rect_is_same_size(bbox,&blend->src_area)) {
> - if (rop == SPICE_ROP_COPY)
> - spice_canvas->ops->blit_image(spice_canvas,&dest_region,
> - src_image,
> - bbox->left - blend->src_area.left,
> - bbox->top - blend->src_area.top);
> - else
> - spice_canvas->ops->blit_image_rop(spice_canvas,&dest_region,
> - src_image,
> - bbox->left - blend->src_area.left,
> - bbox->top - blend->src_area.top,
> - rop);
> - } else {
> - if (rop == SPICE_ROP_COPY) {
> - spice_canvas->ops->scale_image(spice_canvas,&dest_region,
> - src_image,
> - blend->src_area.left,
> - blend->src_area.top,
> - blend->src_area.right - blend->src_area.left,
> - blend->src_area.bottom - blend->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - blend->scale_mode);
> - } else {
> - spice_canvas->ops->scale_image_rop(spice_canvas,&dest_region,
> - src_image,
> - blend->src_area.left,
> - blend->src_area.top,
> - blend->src_area.right - blend->src_area.left,
> - blend->src_area.bottom - blend->src_area.top,
> - bbox->left,
> - bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top,
> - blend->scale_mode, rop);
> - }
> - }
> - pixman_image_unref(src_image);
> - }
> - pixman_region32_fini(&dest_region);
> -}
> -
> -static void canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - pixman_region32_t dest_region;
> - pixman_box32_t *rects;
> - int n_rects;
> -
> - pixman_region32_init_rect(&dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> -
> - canvas_clip_pixman(canvas,&dest_region, clip);
> - canvas_mask_pixman(canvas,&dest_region,&blackness->mask,
> - bbox->left, bbox->top);
> -
> - if (!pixman_region32_not_empty(&dest_region)) {
> - pixman_region32_fini (&dest_region);
> - return;
> - }
> -
> - rects = pixman_region32_rectangles(&dest_region,&n_rects);
> -
> - spice_canvas->ops->fill_solid_rects(spice_canvas, rects, n_rects, 0x000000);
> -
> - pixman_region32_fini(&dest_region);
> -}
> -
> -static void canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - pixman_region32_t dest_region;
> - pixman_box32_t *rects;
> - int n_rects;
> -
> - pixman_region32_init_rect(&dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> -
> - canvas_clip_pixman(canvas,&dest_region, clip);
> - canvas_mask_pixman(canvas,&dest_region,&whiteness->mask,
> - bbox->left, bbox->top);
> -
> - if (!pixman_region32_not_empty(&dest_region)) {
> - pixman_region32_fini(&dest_region);
> - return;
> - }
> -
> - rects = pixman_region32_rectangles(&dest_region,&n_rects);
> - spice_canvas->ops->fill_solid_rects(spice_canvas, rects, n_rects, 0xffffffff);
> -
> - pixman_region32_fini(&dest_region);
> -}
> -
> -static void canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - pixman_region32_t dest_region;
> - pixman_box32_t *rects;
> - int n_rects;
> -
> - pixman_region32_init_rect(&dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> -
> - canvas_clip_pixman(canvas,&dest_region, clip);
> - canvas_mask_pixman(canvas,&dest_region,&invers->mask,
> - bbox->left, bbox->top);
> -
> - if (!pixman_region32_not_empty(&dest_region)) {
> - pixman_region32_fini(&dest_region);
> - return;
> - }
> -
> - rects = pixman_region32_rectangles(&dest_region,&n_rects);
> - spice_canvas->ops->fill_solid_rects_rop(spice_canvas, rects, n_rects, 0x00000000,
> - SPICE_ROP_INVERT);
> -
> - pixman_region32_fini(&dest_region);
> -}
> -
> -typedef struct {
> - lineGC base;
> - SpiceCanvas *canvas;
> - pixman_region32_t dest_region;
> - SpiceROP fore_rop;
> - SpiceROP back_rop;
> - int solid;
> - uint32_t color;
> - int use_surface_canvas;
> - union {
> - SpiceCanvas *surface_canvas;
> - pixman_image_t *tile;
> - };
> - int tile_offset_x;
> - int tile_offset_y;
> -} StrokeGC;
> -
> -static void stroke_fill_spans(lineGC * pGC,
> - int num_spans,
> - SpicePoint *points,
> - int *widths,
> - int sorted,
> - int foreground)
> -{
> - SpiceCanvas *canvas;
> - StrokeGC *strokeGC;
> - int i;
> - SpiceROP rop;
> -
> - strokeGC = (StrokeGC *)pGC;
> - canvas = strokeGC->canvas;
> -
> - num_spans = spice_canvas_clip_spans(&strokeGC->dest_region,
> - points, widths, num_spans,
> - points, widths, sorted);
> -
> - if (foreground) {
> - rop = strokeGC->fore_rop;
> - } else {
> - rop = strokeGC->back_rop;
> - }
> -
> - if (strokeGC->solid) {
> - if (rop == SPICE_ROP_COPY) {
> - canvas->ops->fill_solid_spans(canvas, points, widths, num_spans,
> - strokeGC->color);
> - } else {
> - for (i = 0; i< num_spans; i++) {
> - pixman_box32_t r;
> - r.x1 = points[i].x;
> - r.y1 = points[i].y;
> - r.x2 = points[i].x + widths[i];
> - r.y2 = r.y1 + 1;
> - canvas->ops->fill_solid_rects_rop(canvas,&r, 1,
> - strokeGC->color, rop);
> - }
> - }
> - } else {
> - if (rop == SPICE_ROP_COPY) {
> - for (i = 0; i< num_spans; i++) {
> - pixman_box32_t r;
> - r.x1 = points[i].x;
> - r.y1 = points[i].y;
> - r.x2 = points[i].x + widths[i];
> - r.y2 = r.y1 + 1;
> - canvas->ops->fill_tiled_rects(canvas,&r, 1,
> - strokeGC->tile,
> - strokeGC->tile_offset_x,
> - strokeGC->tile_offset_y);
> - }
> - } else {
> - for (i = 0; i< num_spans; i++) {
> - pixman_box32_t r;
> - r.x1 = points[i].x;
> - r.y1 = points[i].y;
> - r.x2 = points[i].x + widths[i];
> - r.y2 = r.y1 + 1;
> - canvas->ops->fill_tiled_rects_rop(canvas,&r, 1,
> - strokeGC->tile,
> - strokeGC->tile_offset_x,
> - strokeGC->tile_offset_y, rop);
> - }
> - }
> - }
> -}
> -
> -static void stroke_fill_rects(lineGC * pGC,
> - int num_rects,
> - pixman_rectangle32_t *rects,
> - int foreground)
> -{
> - SpiceCanvas *canvas;
> - pixman_region32_t area;
> - pixman_box32_t *boxes;
> - StrokeGC *strokeGC;
> - SpiceROP rop;
> - int i;
> - pixman_box32_t *area_rects;
> - int n_area_rects;
> -
> - strokeGC = (StrokeGC *)pGC;
> - canvas = strokeGC->canvas;
> -
> - if (foreground) {
> - rop = strokeGC->fore_rop;
> - } else {
> - rop = strokeGC->back_rop;
> - }
> -
> - /* TODO: We can optimize this for more common cases where
> - dest is one rect */
> -
> - boxes = spice_new(pixman_box32_t, num_rects);
> - for (i = 0; i< num_rects; i++) {
> - boxes[i].x1 = rects[i].x;
> - boxes[i].y1 = rects[i].y;
> - boxes[i].x2 = rects[i].x + rects[i].width;
> - boxes[i].y2 = rects[i].y + rects[i].height;
> - }
> - pixman_region32_init_rects(&area, boxes, num_rects);
> - pixman_region32_intersect(&area,&area,&strokeGC->dest_region);
> - free(boxes);
> -
> - area_rects = pixman_region32_rectangles(&area,&n_area_rects);
> -
> - if (strokeGC->solid) {
> - if (rop == SPICE_ROP_COPY) {
> - canvas->ops->fill_solid_rects(canvas, area_rects, n_area_rects,
> - strokeGC->color);
> - } else {
> - canvas->ops->fill_solid_rects_rop(canvas, area_rects, n_area_rects,
> - strokeGC->color, rop);
> - }
> - } else {
> - if (rop == SPICE_ROP_COPY) {
> - if (strokeGC->use_surface_canvas) {
> - canvas->ops->fill_tiled_rects_from_surface(canvas, area_rects, n_area_rects,
> - strokeGC->surface_canvas,
> - strokeGC->tile_offset_x,
> - strokeGC->tile_offset_y);
> - } else {
> - canvas->ops->fill_tiled_rects(canvas, area_rects, n_area_rects,
> - strokeGC->tile,
> - strokeGC->tile_offset_x,
> - strokeGC->tile_offset_y);
> - }
> - } else {
> - if (strokeGC->use_surface_canvas) {
> - canvas->ops->fill_tiled_rects_rop_from_surface(canvas, area_rects, n_area_rects,
> - strokeGC->surface_canvas,
> - strokeGC->tile_offset_x,
> - strokeGC->tile_offset_y,
> - rop);
> - } else {
> - canvas->ops->fill_tiled_rects_rop(canvas, area_rects, n_area_rects,
> - strokeGC->tile,
> - strokeGC->tile_offset_x,
> - strokeGC->tile_offset_y,
> - rop);
> - }
> - }
> - }
> -
> - pixman_region32_fini(&area);
> -}
> -
> -typedef struct {
> - SpicePoint *points;
> - int num_points;
> - int size;
> -} StrokeLines;
> -
> -static void stroke_lines_init(StrokeLines *lines)
> -{
> - lines->points = spice_new(SpicePoint, 10);
> - lines->size = 10;
> - lines->num_points = 0;
> -}
> -
> -static void stroke_lines_free(StrokeLines *lines)
> -{
> - free(lines->points);
> -}
> -
> -static void stroke_lines_append(StrokeLines *lines,
> - int x, int y)
> -{
> - if (lines->num_points == lines->size) {
> - lines->size *= 2;
> - lines->points = spice_renew(SpicePoint, lines->points, lines->size);
> - }
> - lines->points[lines->num_points].x = x;
> - lines->points[lines->num_points].y = y;
> - lines->num_points++;
> -}
> -
> -static void stroke_lines_append_fix(StrokeLines *lines,
> - SpicePointFix *point)
> -{
> - stroke_lines_append(lines,
> - fix_to_int(point->x),
> - fix_to_int(point->y));
> -}
> -
> -static inline int64_t dot(SPICE_FIXED28_4 x1,
> - SPICE_FIXED28_4 y1,
> - SPICE_FIXED28_4 x2,
> - SPICE_FIXED28_4 y2)
> -{
> - return (((int64_t)x1) *((int64_t)x2) +
> - ((int64_t)y1) *((int64_t)y2))>> 4;
> -}
> -
> -static inline int64_t dot2(SPICE_FIXED28_4 x,
> - SPICE_FIXED28_4 y)
> -{
> - return (((int64_t)x) *((int64_t)x) +
> - ((int64_t)y) *((int64_t)y))>> 4;
> -}
> -
> -static void subdivide_bezier(StrokeLines *lines,
> - SpicePointFix point0,
> - SpicePointFix point1,
> - SpicePointFix point2,
> - SpicePointFix point3)
> -{
> - int64_t A2, B2, C2, AB, CB, h1, h2;
> -
> - A2 = dot2(point1.x - point0.x,
> - point1.y - point0.y);
> - B2 = dot2(point3.x - point0.x,
> - point3.y - point0.y);
> - C2 = dot2(point2.x - point3.x,
> - point2.y - point3.y);
> -
> - AB = dot(point1.x - point0.x,
> - point1.y - point0.y,
> - point3.x - point0.x,
> - point3.y - point0.y);
> -
> - CB = dot(point2.x - point3.x,
> - point2.y - point3.y,
> - point0.x - point3.x,
> - point0.y - point3.y);
> -
> - h1 = (A2*B2 - AB*AB)>> 3;
> - h2 = (C2*B2 - CB*CB)>> 3;
> -
> - if (h1< B2&& h2< B2) {
> - /* deviation squared less than half a pixel, use straight line */
> - stroke_lines_append_fix(lines,&point3);
> - } else {
> - SpicePointFix point01, point23, point12, point012, point123, point0123;
> -
> - point01.x = (point0.x + point1.x) / 2;
> - point01.y = (point0.y + point1.y) / 2;
> - point12.x = (point1.x + point2.x) / 2;
> - point12.y = (point1.y + point2.y) / 2;
> - point23.x = (point2.x + point3.x) / 2;
> - point23.y = (point2.y + point3.y) / 2;
> - point012.x = (point01.x + point12.x) / 2;
> - point012.y = (point01.y + point12.y) / 2;
> - point123.x = (point12.x + point23.x) / 2;
> - point123.y = (point12.y + point23.y) / 2;
> - point0123.x = (point012.x + point123.x) / 2;
> - point0123.y = (point012.y + point123.y) / 2;
> -
> - subdivide_bezier(lines, point0, point01, point012, point0123);
> - subdivide_bezier(lines, point0123, point123, point23, point3);
> - }
> -}
> -
> -static void stroke_lines_append_bezier(StrokeLines *lines,
> - SpicePointFix *point1,
> - SpicePointFix *point2,
> - SpicePointFix *point3)
> -{
> - SpicePointFix point0;
> -
> - point0.x = int_to_fix(lines->points[lines->num_points-1].x);
> - point0.y = int_to_fix(lines->points[lines->num_points-1].y);
> -
> - subdivide_bezier(lines, point0, *point1, *point2, *point3);
> -}
> -
> -static void stroke_lines_draw(StrokeLines *lines,
> - lineGC *gc,
> - int dashed)
> -{
> - if (lines->num_points != 0) {
> - if (dashed) {
> - spice_canvas_zero_dash_line(gc, CoordModeOrigin,
> - lines->num_points, lines->points);
> - } else {
> - spice_canvas_zero_line(gc, CoordModeOrigin,
> - lines->num_points, lines->points);
> - }
> - lines->num_points = 0;
> - }
> -}
> -
> -
> -static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
> - SpiceClip *clip, SpiceStroke *stroke)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - SpiceCanvas *surface_canvas = NULL;
> - StrokeGC gc = { { 0 } };
> - lineGCOps ops = {
> - stroke_fill_spans,
> - stroke_fill_rects
> - };
> - StrokeLines lines;
> - unsigned int i;
> - int dashed;
> -
> - pixman_region32_init_rect(&gc.dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> - canvas_clip_pixman(canvas,&gc.dest_region, clip);
> -
> - if (!pixman_region32_not_empty(&gc.dest_region)) {
> - touch_brush(canvas,&stroke->brush);
> - pixman_region32_fini(&gc.dest_region);
> - return;
> - }
> -
> - gc.canvas = spice_canvas;
> - gc.fore_rop = ropd_descriptor_to_rop(stroke->fore_mode,
> - ROP_INPUT_BRUSH,
> - ROP_INPUT_DEST);
> - gc.back_rop = ropd_descriptor_to_rop(stroke->back_mode,
> - ROP_INPUT_BRUSH,
> - ROP_INPUT_DEST);
> -
> - gc.base.width = canvas->width;
> - gc.base.height = canvas->height;
> - gc.base.alu = gc.fore_rop;
> - gc.base.lineWidth = 0;
> -
> - /* dash */
> - gc.base.dashOffset = 0;
> - gc.base.dash = NULL;
> - gc.base.numInDashList = 0;
> - gc.base.lineStyle = LineSolid;
> - /* win32 cosmetic lines are endpoint-exclusive, so use CapNotLast */
> - gc.base.capStyle = CapNotLast;
> - gc.base.joinStyle = JoinMiter;
> - gc.base.ops =&ops;
> -
> - dashed = 0;
> - if (stroke->attr.flags& SPICE_LINE_FLAGS_STYLED) {
> - SPICE_FIXED28_4 *style = stroke->attr.style;
> - int nseg;
> -
> - dashed = 1;
> -
> - nseg = stroke->attr.style_nseg;
> -
> - /* To truly handle back_mode we should use LineDoubleDash here
> - and treat !foreground as back_rop using the same brush.
> - However, using the same brush for that seems wrong.
> - The old cairo backend was stroking the non-dashed line with
> - rop_mode before enabling dashes for the foreground which is
> - not right either. The gl an gdi backend don't use back_mode
> - at all */
> - gc.base.lineStyle = LineOnOffDash;
> - gc.base.dash = (unsigned char *)spice_malloc(nseg);
> - gc.base.numInDashList = nseg;
> -
> - if (stroke->attr.flags& SPICE_LINE_FLAGS_START_WITH_GAP) {
> - gc.base.dash[stroke->attr.style_nseg - 1] = fix_to_int(style[0]);
> - for (i = 0; i< (unsigned int)(stroke->attr.style_nseg - 1); i++) {
> - gc.base.dash[i] = fix_to_int(style[i+1]);
> - }
> - gc.base.dashOffset = gc.base.dash[0];
> - } else {
> - for (i = 0; i< stroke->attr.style_nseg; i++) {
> - gc.base.dash[i] = fix_to_int(style[i]);
> - }
> - }
> - }
> -
> - switch (stroke->brush.type) {
> - case SPICE_BRUSH_TYPE_NONE:
> - gc.solid = TRUE;
> - gc.color = 0;
> - break;
> - case SPICE_BRUSH_TYPE_SOLID:
> - gc.solid = TRUE;
> - gc.color = stroke->brush.u.color;
> - break;
> - case SPICE_BRUSH_TYPE_PATTERN:
> - gc.solid = FALSE;
> - surface_canvas = canvas_get_surface(canvas,
> - stroke->brush.u.pattern.pat);
> - if (surface_canvas) {
> - gc.use_surface_canvas = TRUE;
> - gc.surface_canvas = surface_canvas;
> - } else {
> - gc.use_surface_canvas = FALSE;
> - gc.tile = canvas_get_image(canvas,
> - stroke->brush.u.pattern.pat,
> - FALSE);
> - }
> - gc.tile_offset_x = stroke->brush.u.pattern.pos.x;
> - gc.tile_offset_y = stroke->brush.u.pattern.pos.y;
> - break;
> - default:
> - spice_warn_if_reached();
> - return;
> - }
> -
> - stroke_lines_init(&lines);
> -
> - for (i = 0; i< stroke->path->num_segments; i++) {
> - SpicePathSeg *seg = stroke->path->segments[i];
> - SpicePointFix* point, *end_point;
> -
> - point = seg->points;
> - end_point = point + seg->count;
> -
> - if (seg->flags& SPICE_PATH_BEGIN) {
> - stroke_lines_draw(&lines, (lineGC *)&gc, dashed);
> - stroke_lines_append_fix(&lines, point);
> - point++;
> - }
> -
> - if (seg->flags& SPICE_PATH_BEZIER) {
> - spice_return_if_fail((point - end_point) % 3 == 0);
> - for (; point + 2< end_point; point += 3) {
> - stroke_lines_append_bezier(&lines,
> -&point[0],
> -&point[1],
> -&point[2]);
> - }
> - } else
> - {
> - for (; point< end_point; point++) {
> - stroke_lines_append_fix(&lines, point);
> - }
> - }
> - if (seg->flags& SPICE_PATH_END) {
> - if (seg->flags& SPICE_PATH_CLOSE) {
> - stroke_lines_append(&lines,
> - lines.points[0].x, lines.points[0].y);
> - }
> - stroke_lines_draw(&lines, (lineGC *)&gc, dashed);
> - }
> - }
> -
> - stroke_lines_draw(&lines, (lineGC *)&gc, dashed);
> -
> - if (gc.base.dash) {
> - free(gc.base.dash);
> - }
> - stroke_lines_free(&lines);
> -
> - if (!gc.solid&& gc.tile&& !surface_canvas) {
> - pixman_image_unref(gc.tile);
> - }
> -
> - pixman_region32_fini(&gc.dest_region);
> -}
> -
> -
> -//need surfaces handling here !!!
> -static void canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox,
> - SpiceClip *clip, SpiceRop3 *rop3)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - SpiceCanvas *surface_canvas;
> - pixman_region32_t dest_region;
> - pixman_image_t *d;
> - pixman_image_t *s;
> - SpicePoint src_pos;
> - int width;
> - int heigth;
> -
> - pixman_region32_init_rect(&dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> - canvas_clip_pixman(canvas,&dest_region, clip);
> - canvas_mask_pixman(canvas,&dest_region,&rop3->mask,
> - bbox->left, bbox->top);
> -
> - width = bbox->right - bbox->left;
> - heigth = bbox->bottom - bbox->top;
> -
> - d = canvas_get_image_from_self(spice_canvas, bbox->left, bbox->top, width, heigth);
> - surface_canvas = canvas_get_surface(canvas, rop3->src_bitmap);
> - if (surface_canvas) {
> - s = surface_canvas->ops->get_image(surface_canvas);
> - } else {
> - s = canvas_get_image(canvas, rop3->src_bitmap, FALSE);
> - }
> -
> - if (!rect_is_same_size(bbox,&rop3->src_area)) {
> - pixman_image_t *scaled_s = canvas_scale_surface(s,&rop3->src_area, width, heigth,
> - rop3->scale_mode);
> - pixman_image_unref(s);
> - s = scaled_s;
> - src_pos.x = 0;
> - src_pos.y = 0;
> - } else {
> - src_pos.x = rop3->src_area.left;
> - src_pos.y = rop3->src_area.top;
> - }
> - if (pixman_image_get_width(s) - src_pos.x< width ||
> - pixman_image_get_height(s) - src_pos.y< heigth) {
> - spice_critical("bad src bitmap size");
> - return;
> - }
> - if (rop3->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
> - SpiceCanvas *_surface_canvas;
> - pixman_image_t *p;
> -
> - _surface_canvas = canvas_get_surface(canvas, rop3->brush.u.pattern.pat);
> - if (_surface_canvas) {
> - p = _surface_canvas->ops->get_image(_surface_canvas);
> - } else {
> - p = canvas_get_image(canvas, rop3->brush.u.pattern.pat, FALSE);
> - }
> - SpicePoint pat_pos;
> -
> - pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % pixman_image_get_width(p);
> - pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % pixman_image_get_height(p);
> - do_rop3_with_pattern(rop3->rop3, d, s,&src_pos, p,&pat_pos);
> - pixman_image_unref(p);
> - } else {
> - do_rop3_with_color(rop3->rop3, d, s,&src_pos, rop3->brush.u.color);
> - }
> - pixman_image_unref(s);
> -
> - spice_canvas->ops->blit_image(spice_canvas,&dest_region, d,
> - bbox->left,
> - bbox->top);
> -
> - pixman_image_unref(d);
> -
> - pixman_region32_fini(&dest_region);
> -}
> -
> -static void canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - pixman_region32_t dest_region;
> - int dx, dy;
> -
> - pixman_region32_init_rect(&dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> - canvas_clip_pixman(canvas,&dest_region, clip);
> -
> - dx = bbox->left - src_pos->x;
> - dy = bbox->top - src_pos->y;
> -
> - if (dx != 0 || dy != 0) {
> - pixman_region32_t src_region;
> -
> - /* Clip so we don't read outside canvas */
> - pixman_region32_init_rect(&src_region,
> - dx, dy,
> - canvas->width,
> - canvas->height);
> - pixman_region32_intersect(&dest_region,&dest_region,&src_region);
> - pixman_region32_fini(&src_region);
> -
> - spice_canvas->ops->copy_region(spice_canvas,&dest_region, dx, dy);
> - }
> -
> - pixman_region32_fini(&dest_region);
> -}
> -
> -
> -
> -static void canvas_base_group_start(SpiceCanvas *spice_canvas, QRegion *region)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - pixman_region32_fini(&canvas->canvas_region);
> -
> - /* Make sure we always clip to canvas size */
> - pixman_region32_init_rect(&canvas->canvas_region,
> - 0, 0,
> - canvas->width,
> - canvas->height);
> -
> - pixman_region32_intersect(&canvas->canvas_region,&canvas->canvas_region, region);
> -}
> -
> -static void canvas_base_group_end(SpiceCanvas *spice_canvas)
> -{
> - CanvasBase *canvas = (CanvasBase *)spice_canvas;
> - pixman_region32_fini(&canvas->canvas_region);
> - pixman_region32_init_rect(&canvas->canvas_region,
> - 0, 0,
> - canvas->width,
> - canvas->height);
> -}
> -
> -
> -static void unimplemented_op(SpiceCanvas *canvas)
> -{
> - spice_critical("unimplemented canvas operation");
> -}
> -
> -inline static void canvas_base_init_ops(SpiceCanvasOps *ops)
> -{
> - void **ops_cast;
> - unsigned i;
> -
> - ops_cast = (void **)ops;
> - for (i = 0; i< sizeof(SpiceCanvasOps) / sizeof(void *); i++) {
> - ops_cast[i] = (void *) unimplemented_op;
> - }
> -
> - ops->draw_fill = canvas_draw_fill;
> - ops->draw_copy = canvas_draw_copy;
> - ops->draw_opaque = canvas_draw_opaque;
> - ops->copy_bits = canvas_copy_bits;
> - ops->draw_blend = canvas_draw_blend;
> - ops->draw_blackness = canvas_draw_blackness;
> - ops->draw_whiteness = canvas_draw_whiteness;
> - ops->draw_invers = canvas_draw_invers;
> - ops->draw_transparent = canvas_draw_transparent;
> - ops->draw_alpha_blend = canvas_draw_alpha_blend;
> - ops->draw_stroke = canvas_draw_stroke;
> - ops->draw_rop3 = canvas_draw_rop3;
> - ops->group_start = canvas_base_group_start;
> - ops->group_end = canvas_base_group_end;
> -}
> -
> -static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops,
> - int width, int height, uint32_t format
> -#ifdef SW_CANVAS_CACHE
> - , SpiceImageCache *bits_cache
> - , SpicePaletteCache *palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , SpiceImageCache *bits_cache
> -#endif
> - , SpiceImageSurfaces *surfaces
> - , SpiceGlzDecoder *glz_decoder
> - , SpiceJpegDecoder *jpeg_decoder
> - , SpiceZlibDecoder *zlib_decoder
> - )
> -{
> - canvas->parent.ops = ops;
> - canvas->quic_data.usr.error = quic_usr_error;
> - canvas->quic_data.usr.warn = quic_usr_warn;
> - canvas->quic_data.usr.info = quic_usr_warn;
> - canvas->quic_data.usr.malloc = quic_usr_malloc;
> - canvas->quic_data.usr.free = quic_usr_free;
> - canvas->quic_data.usr.more_space = quic_usr_more_space;
> - canvas->quic_data.usr.more_lines = quic_usr_more_lines;
> - if (!(canvas->quic_data.quic = quic_create(&canvas->quic_data.usr))) {
> - return 0;
> - }
> -
> - canvas->lz_data.usr.error = lz_usr_error;
> - canvas->lz_data.usr.warn = lz_usr_warn;
> - canvas->lz_data.usr.info = lz_usr_warn;
> - canvas->lz_data.usr.malloc = lz_usr_malloc;
> - canvas->lz_data.usr.free = lz_usr_free;
> - canvas->lz_data.usr.more_space = lz_usr_more_space;
> - canvas->lz_data.usr.more_lines = lz_usr_more_lines;
> - if (!(canvas->lz_data.lz = lz_create(&canvas->lz_data.usr))) {
> - return 0;
> - }
> -
> - canvas->surfaces = surfaces;
> - canvas->glz_data.decoder = glz_decoder;
> - canvas->jpeg = jpeg_decoder;
> - canvas->zlib = zlib_decoder;
> -
> - canvas->format = format;
> -
> - /* TODO: This is all wrong now */
> - if (SPICE_SURFACE_FMT_DEPTH(format) == 16) {
> - canvas->color_shift = 5;
> - canvas->color_mask = 0x1f;
> - } else {
> - canvas->color_shift = 8;
> - canvas->color_mask = 0xff;
> - }
> -
> - canvas->width = width;
> - canvas->height = height;
> - pixman_region32_init_rect(&canvas->canvas_region,
> - 0, 0,
> - canvas->width,
> - canvas->height);
> -
> -#if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
> - canvas->bits_cache = bits_cache;
> -#endif
> -#ifdef SW_CANVAS_CACHE
> - canvas->palette_cache = palette_cache;
> -#endif
> -
> -#ifdef WIN32
> - canvas->dc = NULL;
> -#endif
> -
> -#ifdef GDI_CANVAS
> - canvas->dc = create_compatible_dc();
> - if (!canvas->dc) {
> - lz_destroy(canvas->lz_data.lz);
> - return 0;
> - }
> -#endif
> - return 1;
> -}
> diff --git a/common/canvas_base.h b/common/canvas_base.h
> deleted file mode 100644
> index bea041f..0000000
> --- a/common/canvas_base.h
> +++ /dev/null
> @@ -1,316 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H_CANVAS_BASE
> -#define _H_CANVAS_BASE
> -
> -
> -#include "pixman_utils.h"
> -#include "lz.h"
> -#include "region.h"
> -#include "draw.h"
> -#ifdef WIN32
> -#include<windows.h>
> -#endif
> -
> -typedef void (*spice_destroy_fn_t)(void *data);
> -
> -typedef struct _SpiceImageCache SpiceImageCache;
> -typedef struct _SpiceImageSurfaces SpiceImageSurfaces;
> -typedef struct _SpicePaletteCache SpicePaletteCache;
> -typedef struct _SpiceGlzDecoder SpiceGlzDecoder;
> -typedef struct _SpiceJpegDecoder SpiceJpegDecoder;
> -typedef struct _SpiceZlibDecoder SpiceZlibDecoder;
> -typedef struct _SpiceCanvas SpiceCanvas;
> -
> -typedef struct {
> - void (*put)(SpiceImageCache *cache,
> - uint64_t id,
> - pixman_image_t *surface);
> - pixman_image_t *(*get)(SpiceImageCache *cache,
> - uint64_t id);
> -#ifdef SW_CANVAS_CACHE
> - void (*put_lossy)(SpiceImageCache *cache,
> - uint64_t id,
> - pixman_image_t *surface);
> - void (*replace_lossy)(SpiceImageCache *cache,
> - uint64_t id,
> - pixman_image_t *surface);
> - pixman_image_t *(*get_lossless)(SpiceImageCache *cache,
> - uint64_t id);
> -#endif
> -} SpiceImageCacheOps;
> -
> -struct _SpiceImageCache {
> - SpiceImageCacheOps *ops;
> -};
> -
> -typedef struct {
> - SpiceCanvas *(*get)(SpiceImageSurfaces *surfaces,
> - uint32_t surface_id);
> -} SpiceImageSurfacesOps;
> -
> -struct _SpiceImageSurfaces {
> - SpiceImageSurfacesOps *ops;
> -};
> -
> -typedef struct {
> - void (*put)(SpicePaletteCache *cache,
> - SpicePalette *palette);
> - SpicePalette *(*get)(SpicePaletteCache *cache,
> - uint64_t id);
> - void (*release)(SpicePaletteCache *cache,
> - SpicePalette *palette);
> -} SpicePaletteCacheOps;
> -
> -struct _SpicePaletteCache {
> - SpicePaletteCacheOps *ops;
> -};
> -
> -typedef struct {
> - void (*decode)(SpiceGlzDecoder *decoder,
> - uint8_t *data,
> - SpicePalette *plt,
> - void *usr_data);
> -} SpiceGlzDecoderOps;
> -
> -struct _SpiceGlzDecoder {
> - SpiceGlzDecoderOps *ops;
> -};
> -
> -
> -typedef struct SpiceJpegDecoderOps {
> - void (*begin_decode)(SpiceJpegDecoder *decoder,
> - uint8_t* data,
> - int data_size,
> - int* out_width,
> - int* out_height);
> - void (*decode)(SpiceJpegDecoder *decoder,
> - uint8_t* dest,
> - int stride,
> - int format);
> -} SpiceJpegDecoderOps;
> -
> -struct _SpiceJpegDecoder {
> - SpiceJpegDecoderOps *ops;
> -};
> -
> -typedef struct {
> - void (*decode)(SpiceZlibDecoder *decoder,
> - uint8_t *data,
> - int data_size,
> - uint8_t *dest,
> - int dest_size);
> -} SpiceZlibDecoderOps;
> -
> -struct _SpiceZlibDecoder {
> - SpiceZlibDecoderOps *ops;
> -};
> -
> -typedef struct {
> - void (*draw_fill)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
> - void (*draw_copy)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy);
> - void (*draw_opaque)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque);
> - void (*copy_bits)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos);
> - void (*draw_text)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text);
> - void (*draw_stroke)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke);
> - void (*draw_rop3)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3);
> - void (*draw_blend)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend);
> - void (*draw_blackness)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness);
> - void (*draw_whiteness)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness);
> - void (*draw_invers)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers);
> - void (*draw_transparent)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent);
> - void (*draw_alpha_blend)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend* alpha_blend);
> - void (*put_image)(SpiceCanvas *canvas,
> -#ifdef WIN32
> - HDC dc,
> -#endif
> - const SpiceRect *dest, const uint8_t *src_data,
> - uint32_t src_width, uint32_t src_height, int src_stride,
> - const QRegion *clip);
> - void (*clear)(SpiceCanvas *canvas);
> - void (*read_bits)(SpiceCanvas *canvas, uint8_t *dest, int dest_stride, const SpiceRect *area);
> - void (*group_start)(SpiceCanvas *canvas, QRegion *region);
> - void (*group_end)(SpiceCanvas *canvas);
> - void (*destroy)(SpiceCanvas *canvas);
> -
> - /* Implementation vfuncs */
> - void (*fill_solid_spans)(SpiceCanvas *canvas,
> - SpicePoint *points,
> - int *widths,
> - int n_spans,
> - uint32_t color);
> - void (*fill_solid_rects)(SpiceCanvas *canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - uint32_t color);
> - void (*fill_solid_rects_rop)(SpiceCanvas *canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - uint32_t color,
> - SpiceROP rop);
> - void (*fill_tiled_rects)(SpiceCanvas *canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - pixman_image_t *tile,
> - int offset_x, int offset_y);
> - void (*fill_tiled_rects_from_surface)(SpiceCanvas *canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - SpiceCanvas *tile,
> - int offset_x, int offset_y);
> - void (*fill_tiled_rects_rop)(SpiceCanvas *canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - pixman_image_t *tile,
> - int offset_x, int offset_y,
> - SpiceROP rop);
> - void (*fill_tiled_rects_rop_from_surface)(SpiceCanvas *canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - SpiceCanvas *tile,
> - int offset_x, int offset_y,
> - SpiceROP rop);
> - void (*blit_image)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src_image,
> - int offset_x, int offset_y);
> - void (*blit_image_from_surface)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - SpiceCanvas *src_image,
> - int offset_x, int offset_y);
> - void (*blit_image_rop)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src_image,
> - int offset_x, int offset_y,
> - SpiceROP rop);
> - void (*blit_image_rop_from_surface)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - SpiceCanvas *src_image,
> - int offset_x, int offset_y,
> - SpiceROP rop);
> - void (*scale_image)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src_image,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode);
> - void (*scale_image_from_surface)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - SpiceCanvas *src_image,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode);
> - void (*scale_image_rop)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src_image,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode, SpiceROP rop);
> - void (*scale_image_rop_from_surface)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - SpiceCanvas *src_image,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode, SpiceROP rop);
> - void (*blend_image)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - int dest_has_alpha,
> - pixman_image_t *src_image,
> - int src_x, int src_y,
> - int dest_x, int dest_y,
> - int width, int height,
> - int overall_alpha);
> - void (*blend_image_from_surface)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - int dest_has_alpha,
> - SpiceCanvas *src_image,
> - int src_has_alpha,
> - int src_x, int src_y,
> - int dest_x, int dest_y,
> - int width, int height,
> - int overall_alpha);
> - void (*blend_scale_image)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - int dest_has_alpha,
> - pixman_image_t *src_image,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode,
> - int overall_alpha);
> - void (*blend_scale_image_from_surface)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - int dest_has_alpha,
> - SpiceCanvas *src_image,
> - int src_has_alpha,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode,
> - int overall_alpha);
> - void (*colorkey_image)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src_image,
> - int offset_x, int offset_y,
> - uint32_t transparent_color);
> - void (*colorkey_image_from_surface)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - SpiceCanvas *src_image,
> - int offset_x, int offset_y,
> - uint32_t transparent_color);
> - void (*colorkey_scale_image)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src_image,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - uint32_t transparent_color);
> - void (*colorkey_scale_image_from_surface)(SpiceCanvas *canvas,
> - pixman_region32_t *region,
> - SpiceCanvas *src_image,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - uint32_t transparent_color);
> - void (*copy_region)(SpiceCanvas *canvas,
> - pixman_region32_t *dest_region,
> - int dx, int dy);
> - pixman_image_t *(*get_image)(SpiceCanvas *canvas);
> -} SpiceCanvasOps;
> -
> -void spice_canvas_set_usr_data(SpiceCanvas *canvas, void *data, spice_destroy_fn_t destroy_fn);
> -void *spice_canvas_get_usr_data(SpiceCanvas *canvas);
> -
> -struct _SpiceCanvas {
> - SpiceCanvasOps *ops;
> -};
> -
> -#endif
> diff --git a/common/canvas_utils.c b/common/canvas_utils.c
> deleted file mode 100644
> index 743c86c..0000000
> --- a/common/canvas_utils.c
> +++ /dev/null
> @@ -1,307 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include "canvas_utils.h"
> -
> -#include<spice/macros.h>
> -
> -#ifdef __GNUC__
> -#include<stdlib.h>
> -#include<stdio.h>
> -#endif
> -#include "mem.h"
> -
> -#ifdef WIN32
> -static int gdi_handlers = 0;
> -#endif
> -
> -#ifndef ASSERT
> -#define ASSERT(x) if (!(x)) { \
> - printf("%s: ASSERT %s failed\n", __FUNCTION__, #x); \
> - abort(); \
> -}
> -#endif
> -
> -
> -#ifndef CANVAS_ERROR
> -#define CANVAS_ERROR(format, ...) { \
> - printf("%s: " format "\n", __FUNCTION__, ## __VA_ARGS__); \
> - abort(); \
> -}
> -#endif
> -
> -static void release_data(pixman_image_t *image, void *release_data)
> -{
> - PixmanData *data = (PixmanData *)release_data;
> -
> -#ifdef WIN32
> - if (data->bitmap) {
> - DeleteObject((HBITMAP)data->bitmap);
> - CloseHandle(data->mutex);
> - gdi_handlers--;
> - }
> -#endif
> - if (data->data) {
> - free(data->data);
> - }
> -
> - free(data);
> -}
> -
> -static PixmanData *
> -pixman_image_add_data(pixman_image_t *image)
> -{
> - PixmanData *data;
> -
> - data = (PixmanData *)pixman_image_get_destroy_data(image);
> - if (data == NULL) {
> - data = (PixmanData *)calloc(1, sizeof(PixmanData));
> - if (data == NULL) {
> - CANVAS_ERROR("out of memory");
> - }
> - pixman_image_set_destroy_function(image,
> - release_data,
> - data);
> - }
> -
> - return data;
> -}
> -
> -void
> -spice_pixman_image_set_format(pixman_image_t *image,
> - pixman_format_code_t format)
> -{
> - PixmanData *data;
> -
> - data = pixman_image_add_data(image);
> - data->format = format;
> -}
> -
> -pixman_format_code_t
> -spice_pixman_image_get_format(pixman_image_t *image)
> -{
> - PixmanData *data;
> -
> - data = (PixmanData *)pixman_image_get_destroy_data(image);
> - if (data != NULL&&
> - data->format != 0)
> - return data->format;
> -
> - CANVAS_ERROR("Unknown pixman image type");
> -}
> -
> -static inline pixman_image_t *__surface_create_stride(pixman_format_code_t format, int width, int height,
> - int stride)
> -{
> - uint8_t *data;
> - uint8_t *stride_data;
> - pixman_image_t *surface;
> - PixmanData *pixman_data;
> -
> - data = (uint8_t *)spice_malloc_n(abs(stride), height);
> - if (stride< 0) {
> - stride_data = data + (-stride) * (height - 1);
> - } else {
> - stride_data = data;
> - }
> -
> - surface = pixman_image_create_bits(format, width, height, (uint32_t *)stride_data, stride);
> -
> - if (surface == NULL) {
> - free(data);
> - CANVAS_ERROR("create surface failed, out of memory");
> - }
> -
> - pixman_data = pixman_image_add_data(surface);
> - pixman_data->data = data;
> - pixman_data->format = format;
> -
> - return surface;
> -}
> -
> -#ifdef WIN32
> -pixman_image_t *surface_create(HDC dc, pixman_format_code_t format,
> - int width, int height, int top_down)
> -#else
> -pixman_image_t * surface_create(pixman_format_code_t format, int width, int height, int top_down)
> -#endif
> -{
> -#ifdef WIN32
> - /*
> - * Windows xp allow only 10,000 of gdi handlers, considering the fact that
> - * we limit here the number to 5000, we dont use atomic operations to sync
> - * this calculation against the other canvases (in case of multiple
> - * monitors), in worst case there will be little more than 5000 gdi
> - * handlers.
> - */
> - if (dc&& gdi_handlers< 5000) {
> - uint8_t *data;
> - uint8_t *src;
> - struct {
> - BITMAPINFO inf;
> - RGBQUAD palette[255];
> - } bitmap_info;
> - int nstride;
> - pixman_image_t *surface;
> - PixmanData *pixman_data;
> - HBITMAP bitmap;
> - HANDLE mutex;
> -
> - memset(&bitmap_info, 0, sizeof(bitmap_info));
> - bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader);
> - bitmap_info.inf.bmiHeader.biWidth = width;
> -
> - bitmap_info.inf.bmiHeader.biHeight = (!top_down) ? height : -height;
> -
> - bitmap_info.inf.bmiHeader.biPlanes = 1;
> - switch (format) {
> - case PIXMAN_a8r8g8b8:
> - case PIXMAN_x8r8g8b8:
> - bitmap_info.inf.bmiHeader.biBitCount = 32;
> - nstride = width * 4;
> - break;
> - case PIXMAN_x1r5g5b5:
> - case PIXMAN_r5g6b5:
> - bitmap_info.inf.bmiHeader.biBitCount = 16;
> - nstride = SPICE_ALIGN(width * 2, 4);
> - break;
> - case PIXMAN_a8:
> - bitmap_info.inf.bmiHeader.biBitCount = 8;
> - nstride = SPICE_ALIGN(width, 4);
> - break;
> - case PIXMAN_a1:
> - bitmap_info.inf.bmiHeader.biBitCount = 1;
> - nstride = SPICE_ALIGN(width, 32) / 8;
> - break;
> - default:
> - CANVAS_ERROR("invalid format");
> - }
> -
> - bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
> -
> - mutex = CreateMutex(NULL, 0, NULL);
> - if (!mutex) {
> - CANVAS_ERROR("Unable to CreateMutex");
> - }
> -
> - bitmap = CreateDIBSection(dc,&bitmap_info.inf, 0, (VOID **)&data, NULL, 0);
> - if (!bitmap) {
> - CloseHandle(mutex);
> - CANVAS_ERROR("Unable to CreateDIBSection");
> - }
> -
> - if (top_down) {
> - src = data;
> - } else {
> - src = data + nstride * (height - 1);
> - nstride = -nstride;
> - }
> -
> - surface = pixman_image_create_bits(format, width, height, (uint32_t *)src, nstride);
> - if (surface == NULL) {
> - CloseHandle(mutex);
> - DeleteObject(bitmap);
> - CANVAS_ERROR("create surface failed, out of memory");
> - }
> - pixman_data = pixman_image_add_data(surface);
> - pixman_data->format = format;
> - pixman_data->bitmap = bitmap;
> - pixman_data->mutex = mutex;
> - gdi_handlers++;
> - return surface;
> - } else {
> -#endif
> - if (top_down) {
> - pixman_image_t *surface;
> - PixmanData *data;
> -
> - surface = pixman_image_create_bits(format, width, height, NULL, 0);
> - data = pixman_image_add_data(surface);
> - data->format = format;
> - return surface;
> - } else {
> - // NOTE: we assume here that the lz decoders always decode to RGB32.
> - int stride = 0;
> - switch (format) {
> - case PIXMAN_a8r8g8b8:
> - case PIXMAN_x8r8g8b8:
> - stride = width * 4;
> - break;
> - case PIXMAN_x1r5g5b5:
> - case PIXMAN_r5g6b5:
> - stride = SPICE_ALIGN(width * 2, 4);
> - break;
> - case PIXMAN_a8:
> - stride = SPICE_ALIGN(width, 4);
> - break;
> - case PIXMAN_a1:
> - stride = SPICE_ALIGN(width, 32) / 8;
> - break;
> - default:
> - CANVAS_ERROR("invalid format");
> - }
> - stride = -stride;
> - return __surface_create_stride(format, width, height, stride);
> - }
> -#ifdef WIN32
> -}
> -
> -#endif
> -}
> -
> -#ifdef WIN32
> -pixman_image_t *surface_create_stride(HDC dc, pixman_format_code_t format, int width, int height,
> - int stride)
> -#else
> -pixman_image_t *surface_create_stride(pixman_format_code_t format, int width, int height,
> - int stride)
> -#endif
> -{
> -#ifdef WIN32
> - if (dc) {
> - if (abs(stride) == (width * 4)) {
> - return surface_create(dc, format, width, height, (stride> 0));
> - }
> - }
> -#endif
> -
> - return __surface_create_stride(format, width, height, stride);
> -}
> -
> -pixman_image_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data,
> - pixman_format_code_t pixman_format, int width,
> - int height, int gross_pixels, int top_down)
> -{
> - int stride;
> - pixman_image_t *surface = NULL;
> -
> - stride = (gross_pixels / height) * (PIXMAN_FORMAT_BPP (pixman_format) / 8);
> -
> - if (!top_down) {
> - stride = -stride;
> - }
> -
> - surface = surface_create_stride(
> -#ifdef WIN32
> - canvas_data->dc,
> -#endif
> - pixman_format, width, height, stride);
> - canvas_data->out_surface = surface;
> - return surface;
> -}
> -
> diff --git a/common/canvas_utils.h b/common/canvas_utils.h
> deleted file mode 100644
> index fe66f85..0000000
> --- a/common/canvas_utils.h
> +++ /dev/null
> @@ -1,72 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H_CANVAS_UTILS
> -#define _H_CANVAS_UTILS
> -
> -#ifdef WIN32
> -#include<windows.h>
> -#endif
> -
> -#include<spice/types.h>
> -
> -#include "pixman_utils.h"
> -#include "lz.h"
> -
> -typedef struct PixmanData {
> -#ifdef WIN32
> - HBITMAP bitmap;
> - HANDLE mutex;
> -#endif
> - uint8_t *data;
> - pixman_format_code_t format;
> -} PixmanData;
> -
> -void spice_pixman_image_set_format(pixman_image_t *image,
> - pixman_format_code_t format);
> -pixman_format_code_t spice_pixman_image_get_format(pixman_image_t *image);
> -
> -
> -#ifdef WIN32
> -pixman_image_t *surface_create(HDC dc, pixman_format_code_t format,
> - int width, int height, int top_down);
> -#else
> -pixman_image_t *surface_create(pixman_format_code_t format, int width, int height, int top_down);
> -#endif
> -
> -#ifdef WIN32
> -pixman_image_t *surface_create_stride(HDC dc, pixman_format_code_t format, int width, int height,
> - int stride);
> -#else
> -pixman_image_t *surface_create_stride(pixman_format_code_t format, int width, int height,
> - int stride);
> -#endif
> -
> -
> -typedef struct LzDecodeUsrData {
> -#ifdef WIN32
> - HDC dc;
> -#endif
> - pixman_image_t *out_surface;
> -} LzDecodeUsrData;
> -
> -
> -pixman_image_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data,
> - pixman_format_code_t pixman_format, int width,
> - int height, int gross_pixels, int top_down);
> -#endif
> diff --git a/common/demarshallers.h b/common/demarshallers.h
> deleted file mode 100644
> index fc2f75a..0000000
> --- a/common/demarshallers.h
> +++ /dev/null
> @@ -1,28 +0,0 @@
> -/*
> - Copyright (C) 2010 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -#ifndef _H_DEMARSHAL
> -#define _H_DEMARSHAL
> -
> -typedef void (*message_destructor_t)(uint8_t *message);
> -typedef uint8_t * (*spice_parse_channel_func_t)(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, int minor,
> - size_t *size_out, message_destructor_t *free_message);
> -
> -spice_parse_channel_func_t spice_get_server_channel_parser(uint32_t channel, unsigned int *max_message_type);
> -spice_parse_channel_func_t spice_get_server_channel_parser1(uint32_t channel, unsigned int *max_message_type);
> -
> -#endif
> -
> diff --git a/common/draw.h b/common/draw.h
> deleted file mode 100644
> index 994aebb..0000000
> --- a/common/draw.h
> +++ /dev/null
> @@ -1,274 +0,0 @@
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - Redistribution and use in source and binary forms, with or without
> - modification, are permitted provided that the following conditions are
> - met:
> -
> - * Redistributions of source code must retain the above copyright
> - notice, this list of conditions and the following disclaimer.
> - * Redistributions in binary form must reproduce the above copyright
> - notice, this list of conditions and the following disclaimer in
> - the documentation and/or other materials provided with the
> - distribution.
> - * Neither the name of the copyright holder nor the names of its
> - contributors may be used to endorse or promote products derived
> - from this software without specific prior written permission.
> -
> - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
> - IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
> - TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> -*/
> -
> -#ifndef _H_SPICE_DRAW
> -#define _H_SPICE_DRAW
> -
> -#include<spice/types.h>
> -#include<spice/enums.h>
> -#include "mem.h"
> -
> -#define SPICE_GET_ADDRESS(addr) ((void *)(uintptr_t)(addr))
> -#define SPICE_SET_ADDRESS(addr, val) ((addr) = (unsigned long)(val))
> -
> -typedef int32_t SPICE_FIXED28_4;
> -typedef uint64_t SPICE_ADDRESS;
> -
> -typedef struct SpicePointFix {
> - SPICE_FIXED28_4 x;
> - SPICE_FIXED28_4 y;
> -} SpicePointFix;
> -
> -typedef struct SpicePoint {
> - int32_t x;
> - int32_t y;
> -} SpicePoint;
> -
> -typedef struct SpicePoint16 {
> - int16_t x;
> - int16_t y;
> -} SpicePoint16;
> -
> -typedef struct SpiceRect {
> - int32_t left;
> - int32_t top;
> - int32_t right;
> - int32_t bottom;
> -} SpiceRect;
> -
> -typedef struct SpicePathSeg {
> - uint32_t flags;
> - uint32_t count;
> - SpicePointFix points[0];
> -} SpicePathSeg;
> -
> -typedef struct SpicePath {
> - uint32_t num_segments;
> - SpicePathSeg *segments[0];
> -} SpicePath;
> -
> -typedef struct SpiceClipRects {
> - uint32_t num_rects;
> - SpiceRect rects[0];
> -} SpiceClipRects;
> -
> -typedef struct SpiceClip {
> - uint32_t type;
> - SpiceClipRects *rects;
> -} SpiceClip;
> -
> -typedef struct SpicePalette {
> - uint64_t unique;
> - uint16_t num_ents;
> - uint32_t ents[0];
> -} SpicePalette;
> -
> -#define SPICE_SURFACE_FMT_DEPTH(_d) ((_d)& 0x3f)
> -
> -typedef struct SpiceImageDescriptor {
> - uint64_t id;
> - uint8_t type;
> - uint8_t flags;
> - uint32_t width;
> - uint32_t height;
> -} SpiceImageDescriptor;
> -
> -typedef struct SpiceBitmap {
> - uint8_t format;
> - uint8_t flags;
> - uint32_t x;
> - uint32_t y;
> - uint32_t stride;
> - SpicePalette *palette;
> - uint64_t palette_id;
> - SpiceChunks *data;
> -} SpiceBitmap;
> -
> -typedef struct SpiceSurface {
> - uint32_t surface_id;
> -} SpiceSurface;
> -
> -typedef struct SpiceQUICData {
> - uint32_t data_size;
> - SpiceChunks *data;
> -} SpiceQUICData, SpiceLZRGBData, SpiceJPEGData;
> -
> -typedef struct SpiceLZPLTData {
> - uint8_t flags;
> - uint32_t data_size;
> - SpicePalette *palette;
> - uint64_t palette_id;
> - SpiceChunks *data;
> -} SpiceLZPLTData;
> -
> -typedef struct SpiceZlibGlzRGBData {
> - uint32_t glz_data_size;
> - uint32_t data_size;
> - SpiceChunks *data;
> -} SpiceZlibGlzRGBData;
> -
> -typedef struct SpiceJPEGAlphaData {
> - uint8_t flags;
> - uint32_t jpeg_size;
> - uint32_t data_size;
> - SpiceChunks *data;
> -} SpiceJPEGAlphaData;
> -
> -
> -typedef struct SpiceImage {
> - SpiceImageDescriptor descriptor;
> - union {
> - SpiceBitmap bitmap;
> - SpiceQUICData quic;
> - SpiceSurface surface;
> - SpiceLZRGBData lz_rgb;
> - SpiceLZPLTData lz_plt;
> - SpiceJPEGData jpeg;
> - SpiceZlibGlzRGBData zlib_glz;
> - SpiceJPEGAlphaData jpeg_alpha;
> - } u;
> -} SpiceImage;
> -
> -typedef struct SpicePattern {
> - SpiceImage *pat;
> - SpicePoint pos;
> -} SpicePattern;
> -
> -typedef struct SpiceBrush {
> - uint32_t type;
> - union {
> - uint32_t color;
> - SpicePattern pattern;
> - } u;
> -} SpiceBrush;
> -
> -typedef struct SpiceQMask {
> - uint8_t flags;
> - SpicePoint pos;
> - SpiceImage *bitmap;
> -} SpiceQMask;
> -
> -typedef struct SpiceFill {
> - SpiceBrush brush;
> - uint16_t rop_descriptor;
> - SpiceQMask mask;
> -} SpiceFill;
> -
> -typedef struct SpiceOpaque {
> - SpiceImage *src_bitmap;
> - SpiceRect src_area;
> - SpiceBrush brush;
> - uint16_t rop_descriptor;
> - uint8_t scale_mode;
> - SpiceQMask mask;
> -} SpiceOpaque;
> -
> -typedef struct SpiceCopy {
> - SpiceImage *src_bitmap;
> - SpiceRect src_area;
> - uint16_t rop_descriptor;
> - uint8_t scale_mode;
> - SpiceQMask mask;
> -} SpiceCopy, SpiceBlend;
> -
> -typedef struct SpiceTransparent {
> - SpiceImage *src_bitmap;
> - SpiceRect src_area;
> - uint32_t src_color;
> - uint32_t true_color;
> -} SpiceTransparent;
> -
> -typedef struct SpiceAlphaBlend {
> - uint16_t alpha_flags;
> - uint8_t alpha;
> - SpiceImage *src_bitmap;
> - SpiceRect src_area;
> -} SpiceAlphaBlend;
> -
> -typedef struct SpiceRop3 {
> - SpiceImage *src_bitmap;
> - SpiceRect src_area;
> - SpiceBrush brush;
> - uint8_t rop3;
> - uint8_t scale_mode;
> - SpiceQMask mask;
> -} SpiceRop3;
> -
> -typedef struct SpiceBlackness {
> - SpiceQMask mask;
> -} SpiceBlackness, SpiceInvers, SpiceWhiteness;
> -
> -typedef struct SpiceLineAttr {
> - uint8_t flags;
> - uint8_t style_nseg;
> - SPICE_FIXED28_4 *style;
> -} SpiceLineAttr;
> -
> -typedef struct SpiceStroke {
> - SpicePath *path;
> - SpiceLineAttr attr;
> - SpiceBrush brush;
> - uint16_t fore_mode;
> - uint16_t back_mode;
> -} SpiceStroke;
> -
> -typedef struct SpiceRasterGlyph {
> - SpicePoint render_pos;
> - SpicePoint glyph_origin;
> - uint16_t width;
> - uint16_t height;
> - uint8_t data[0];
> -} SpiceRasterGlyph;
> -
> -typedef struct SpiceString {
> - uint16_t length;
> - uint16_t flags;
> - SpiceRasterGlyph *glyphs[0];
> -} SpiceString;
> -
> -typedef struct SpiceText {
> - SpiceString *str;
> - SpiceRect back_area;
> - SpiceBrush fore_brush;
> - SpiceBrush back_brush;
> - uint16_t fore_mode;
> - uint16_t back_mode;
> -} SpiceText;
> -
> -typedef struct SpiceCursorHeader {
> - uint64_t unique;
> - uint16_t type;
> - uint16_t width;
> - uint16_t height;
> - uint16_t hot_spot_x;
> - uint16_t hot_spot_y;
> -} SpiceCursorHeader;
> -
> -#endif /* _H_SPICE_DRAW */
> diff --git a/common/gdi_canvas.c b/common/gdi_canvas.c
> deleted file mode 100644
> index a11ba90..0000000
> --- a/common/gdi_canvas.c
> +++ /dev/null
> @@ -1,1870 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include<windows.h>
> -#include<wingdi.h>
> -#include "gdi_canvas.h"
> -#define GDI_CANVAS
> -#include "canvas_base.c"
> -#include "rop3.h"
> -#include "rect.h"
> -#include "region.h"
> -#include "threads.h"
> -
> -typedef struct GdiCanvas GdiCanvas;
> -
> -struct GdiCanvas {
> - CanvasBase base;
> - HDC dc;
> - RecurciveMutex* lock;
> -};
> -
> -
> -struct BitmapData {
> - HBITMAP hbitmap;
> - HBITMAP prev_hbitmap;
> - SpicePoint pos;
> - uint8_t flags;
> - HDC dc;
> - int cache;
> - int from_surface;
> -};
> -
> -#define _rop3_brush 0xf0
> -#define _rop3_src 0xcc
> -#define _rop3_dest 0xaa
> -
> -uint32_t raster_ops[] = {
> - 0x00000042,
> - 0x00010289,
> - 0x00020C89,
> - 0x000300AA,
> - 0x00040C88,
> - 0x000500A9,
> - 0x00060865,
> - 0x000702C5,
> - 0x00080F08,
> - 0x00090245,
> - 0x000A0329,
> - 0x000B0B2A,
> - 0x000C0324,
> - 0x000D0B25,
> - 0x000E08A5,
> - 0x000F0001,
> - 0x00100C85,
> - 0x001100A6,
> - 0x00120868,
> - 0x001302C8,
> - 0x00140869,
> - 0x001502C9,
> - 0x00165CCA,
> - 0x00171D54,
> - 0x00180D59,
> - 0x00191CC8,
> - 0x001A06C5,
> - 0x001B0768,
> - 0x001C06CA,
> - 0x001D0766,
> - 0x001E01A5,
> - 0x001F0385,
> - 0x00200F09,
> - 0x00210248,
> - 0x00220326,
> - 0x00230B24,
> - 0x00240D55,
> - 0x00251CC5,
> - 0x002606C8,
> - 0x00271868,
> - 0x00280369,
> - 0x002916CA,
> - 0x002A0CC9,
> - 0x002B1D58,
> - 0x002C0784,
> - 0x002D060A,
> - 0x002E064A,
> - 0x002F0E2A,
> - 0x0030032A,
> - 0x00310B28,
> - 0x00320688,
> - 0x00330008,
> - 0x003406C4,
> - 0x00351864,
> - 0x003601A8,
> - 0x00370388,
> - 0x0038078A, // PSDPoax
> - 0x00390604, // SPDnox
> - 0x003A0644, // SPDSxox
> - 0x003B0E24, // SPDnoan
> - 0x003C004A, // PSx
> - 0x003D18A4, // SPDSonox
> - 0x003E1B24, // SPDSnaox
> - 0x003F00EA, // PSan
> - 0x00400F0A, // PSDnaa
> - 0x00410249, // DPSxon
> - 0x00420D5D, // SDxPDxa
> - 0x00431CC4, // SPDSanaxn
> - 0x00440328, // SDna SRCERASE
> - 0x00450B29, // DPSnaon
> - 0x004606C6, // DSPDaox
> - 0x0047076A, // PSDPxaxn
> - 0x00480368, // SDPxa
> - 0x004916C5, // PDSPDaoxxn
> - 0x004A0789, // DPSDoax
> - 0x004B0605, // PDSnox
> - 0x004C0CC8, // SDPana
> - 0x004D1954, // SSPxDSxoxn
> - 0x004E0645, // PDSPxox
> - 0x004F0E25, // PDSnoan
> - 0x00500325, // PDna
> - 0x00510B26, // DSPnaon
> - 0x005206C9, // DPSDaox
> - 0x00530764, // SPDSxaxn
> - 0x005408A9, // DPSonon
> - 0x00550009, // Dn DSTINVERT
> - 0x005601A9, // DPSox
> - 0x00570389, // DPSoan
> - 0x00580785, // PDSPoax
> - 0x00590609, // DPSnox
> - 0x005A0049, // DPx PATINVERT
> - 0x005B18A9, // DPSDonox
> - 0x005C0649, // DPSDxox
> - 0x005D0E29, // DPSnoan
> - 0x005E1B29, // DPSDnaox
> - 0x005F00E9, // DPan
> - 0x00600365, // PDSxa
> - 0x006116C6, // DSPDSaoxxn
> - 0x00620786, // DSPDoax
> - 0x00630608, // SDPnox
> - 0x00640788, // SDPSoax
> - 0x00650606, // DSPnox
> - 0x00660046, // DSx SRCINVERT
> - 0x006718A8, // SDPSonox
> - 0x006858A6, // DSPDSonoxxn
> - 0x00690145, // PDSxxn
> - 0x006A01E9, // DPSax
> - 0x006B178A, // PSDPSoaxxn
> - 0x006C01E8, // SDPax
> - 0x006D1785, // PDSPDoaxxn
> - 0x006E1E28, // SDPSnoax
> - 0x006F0C65, // PDSxnan
> - 0x00700CC5, // PDSana
> - 0x00711D5C, // SSDxPDxaxn
> - 0x00720648, // SDPSxox
> - 0x00730E28, // SDPnoan
> - 0x00740646, // DSPDxox
> - 0x00750E26, // DSPnoan
> - 0x00761B28, // SDPSnaox
> - 0x007700E6, // DSan
> - 0x007801E5, // PDSax
> - 0x00791786, // DSPDSoaxxn
> - 0x007A1E29, // DPSDnoax
> - 0x007B0C68, // SDPxnan
> - 0x007C1E24, // SPDSnoax
> - 0x007D0C69, // DPSxnan
> - 0x007E0955, // SPxDSxo
> - 0x007F03C9, // DPSaan
> - 0x008003E9, // DPSaa
> - 0x00810975, // SPxDSxon
> - 0x00820C49, // DPSxna
> - 0x00831E04, // SPDSnoaxn
> - 0x00840C48, // SDPxna
> - 0x00851E05, // PDSPnoaxn
> - 0x008617A6, // DSPDSoaxx
> - 0x008701C5, // PDSaxn
> - 0x008800C6, // DSa SRCAND
> - 0x00891B08, // SDPSnaoxn
> - 0x008A0E06, // DSPnoa
> - 0x008B0666, // DSPDxoxn
> - 0x008C0E08, // SDPnoa
> - 0x008D0668, // SDPSxoxn
> - 0x008E1D7C, // SSDxPDxax
> - 0x008F0CE5, // PDSanan
> - 0x00900C45, // PDSxna
> - 0x00911E08, // SDPSnoaxn
> - 0x009217A9, // DPSDPoaxx
> - 0x009301C4, // SPDaxn
> - 0x009417AA, // PSDPSoaxx
> - 0x009501C9, // DPSaxn
> - 0x00960169, // DPSxx
> - 0x0097588A, // PSDPSonoxx
> - 0x00981888, // SDPSonoxn
> - 0x00990066, // DSxn
> - 0x009A0709, // DPSnax
> - 0x009B07A8, // SDPSoaxn
> - 0x009C0704, // SPDnax
> - 0x009D07A6, // DSPDoaxn
> - 0x009E16E6, // DSPDSaoxx
> - 0x009F0345, // PDSxan
> - 0x00A000C9, // DPa
> - 0x00A11B05, // PDSPnaoxn
> - 0x00A20E09, // DPSnoa
> - 0x00A30669, // DPSDxoxn
> - 0x00A41885, // PDSPonoxn
> - 0x00A50065, // PDxn
> - 0x00A60706, // DSPnax
> - 0x00A707A5, // PDSPoaxn
> - 0x00A803A9, // DPSoa
> - 0x00A90189, // DPSoxn
> - 0x00AA0029, // D
> - 0x00AB0889, // DPSono
> - 0x00AC0744, // SPDSxax
> - 0x00AD06E9, // DPSDaoxn
> - 0x00AE0B06, // DSPnao
> - 0x00AF0229, // DPno
> - 0x00B00E05, // PDSnoa
> - 0x00B10665, // PDSPxoxn
> - 0x00B21974, // SSPxDSxox
> - 0x00B30CE8, // SDPanan
> - 0x00B4070A, // PSDnax
> - 0x00B507A9, // DPSDoaxn
> - 0x00B616E9, // DPSDPaoxx
> - 0x00B70348, // SDPxan
> - 0x00B8074A, // PSDPxax
> - 0x00B906E6, // DSPDaoxn
> - 0x00BA0B09, // DPSnao
> - 0x00BB0226, // DSno MERGEPAINT
> - 0x00BC1CE4, // SPDSanax
> - 0x00BD0D7D, // SDxPDxan
> - 0x00BE0269, // DPSxo
> - 0x00BF08C9, // DPSano
> - 0x00C000CA, // PSa MERGECOPY
> - 0x00C11B04, // SPDSnaoxn
> - 0x00C21884, // SPDSonoxn
> - 0x00C3006A, // PSxn
> - 0x00C40E04, // SPDnoa
> - 0x00C50664, // SPDSxoxn
> - 0x00C60708, // SDPnax
> - 0x00C707AA, // PSDPoaxn
> - 0x00C803A8, // SDPoa
> - 0x00C90184, // SPDoxn
> - 0x00CA0749, // DPSDxax
> - 0x00CB06E4, // SPDSaoxn
> - 0x00CC0020, // S SRCCOPY
> - 0x00CD0888, // SDPono
> - 0x00CE0B08, // SDPnao
> - 0x00CF0224, // SPno
> - 0x00D00E0A, // PSDnoa
> - 0x00D1066A, // PSDPxoxn
> - 0x00D20705, // PDSnax
> - 0x00D307A4, // SPDSoaxn
> - 0x00D41D78, // SSPxPDxax
> - 0x00D50CE9, // DPSanan
> - 0x00D616EA, // PSDPSaoxx
> - 0x00D70349, // DPSxan
> - 0x00D80745, // PDSPxax
> - 0x00D906E8, // SDPSaoxn
> - 0x00DA1CE9, // DPSDanax
> - 0x00DB0D75, // SPxDSxan
> - 0x00DC0B04, // SPDnao
> - 0x00DD0228, // SDno
> - 0x00DE0268, // SDPxo
> - 0x00DF08C8, // SDPano
> - 0x00E003A5, // PDSoa
> - 0x00E10185, // PDSoxn
> - 0x00E20746, // DSPDxax
> - 0x00E306EA, // PSDPaoxn
> - 0x00E40748, // SDPSxax
> - 0x00E506E5, // PDSPaoxn
> - 0x00E61CE8, // SDPSanax
> - 0x00E70D79, // SPxPDxan
> - 0x00E81D74, // SSPxDSxax
> - 0x00E95CE6, // DSPDSanaxxn
> - 0x00EA02E9, // DPSao
> - 0x00EB0849, // DPSxno
> - 0x00EC02E8, // SDPao
> - 0x00ED0848, // SDPxno
> - 0x00EE0086, // DSo SRCPAINT
> - 0x00EF0A08, // SDPnoo
> - 0x00F00021, // P PATCOPY
> - 0x00F10885, // PDSono
> - 0x00F20B05, // PDSnao
> - 0x00F3022A, // PSno
> - 0x00F40B0A, // PSDnao
> - 0x00F50225, // PDno
> - 0x00F60265, // PDSxo
> - 0x00F708C5, // PDSano
> - 0x00F802E5, // PDSao
> - 0x00F90845, // PDSxno
> - 0x00FA0089, // DPo
> - 0x00FB0A09, // DPSnoo PATPAINT
> - 0x00FC008A, // PSo
> - 0x00FD0A0A, // PSDnoo
> - 0x00FE02A9, // DPSoo
> - 0x00FF0062 // 1 WHITENESS
> -};
> -
> -static void set_path(GdiCanvas *canvas, SpicePath *s)
> -{
> - unsigned int i;
> -
> - for (i = 0; i< s->num_segments; i++) {
> - SpicePathSeg* seg = s->segments[0];
> - SpicePointFix* point = seg->points;
> - SpicePointFix* end_point = point + seg->count;
> -
> - if (seg->flags& SPICE_PATH_BEGIN) {
> - BeginPath(canvas->dc);
> - if (!MoveToEx(canvas->dc, (int)fix_to_double(point->x), (int)fix_to_double(point->y),
> - NULL)) {
> - spice_critical("MoveToEx failed");
> - return;
> - }
> - point++;
> - }
> -
> - if (seg->flags& SPICE_PATH_BEZIER) {
> - spice_return_if_fail((point - end_point) % 3 == 0);
> - for (; point + 2< end_point; point += 3) {
> - POINT points[3];
> -
> - points[0].x = (int)fix_to_double(point[0].x);
> - points[0].y = (int)fix_to_double(point[0].y);
> - points[1].x = (int)fix_to_double(point[1].x);
> - points[1].y = (int)fix_to_double(point[1].y);
> - points[2].x = (int)fix_to_double(point[2].x);
> - points[2].y = (int)fix_to_double(point[2].y);
> - if (!PolyBezierTo(canvas->dc, points, 3)) {
> - spice_critical("PolyBezierTo failed");
> - return;
> - }
> - }
> - } else {
> - for (; point< end_point; point++) {
> - if (!LineTo(canvas->dc, (int)fix_to_double(point->x),
> - (int)fix_to_double(point->y))) {
> - spice_critical("LineTo failed");
> - }
> - }
> - }
> -
> - if (seg->flags& SPICE_PATH_END) {
> -
> - if (seg->flags& SPICE_PATH_CLOSE) {
> - if (!CloseFigure(canvas->dc)) {
> - spice_critical("CloseFigure failed");
> - }
> - }
> -
> - if (!EndPath(canvas->dc)) {
> - spice_critical("EndPath failed");
> - }
> - }
> -
> - }
> -}
> -
> -static void set_scale_mode(GdiCanvas *canvas, uint8_t scale_mode)
> -{
> - if (scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE) {
> - SetStretchBltMode(canvas->dc, HALFTONE);
> - } else if (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) {
> - SetStretchBltMode(canvas->dc, COLORONCOLOR);
> - } else {
> - spice_critical("Unknown ScaleMode");
> - }
> -}
> -
> -static void set_clip(GdiCanvas *canvas, SpiceClip *clip)
> -{
> - switch (clip->type) {
> - case SPICE_CLIP_TYPE_NONE:
> - if (SelectClipRgn(canvas->dc, NULL) == ERROR) {
> - spice_critical("SelectClipRgn failed");
> - }
> - break;
> - case SPICE_CLIP_TYPE_RECTS: {
> - uint32_t n = clip->rects->num_rects;
> -
> - SpiceRect *now = clip->rects->rects;
> - SpiceRect *end = now + n;
> -
> - if (now< end) {
> - HRGN main_hrgn;
> -
> - main_hrgn = CreateRectRgn(now->left, now->top, now->right, now->bottom);
> - if (!main_hrgn) {
> - return;
> - }
> - now++;
> - for (; now< end; now++) {
> - HRGN combaine_hrgn;
> - combaine_hrgn = CreateRectRgn(now->left, now->top, now->right,
> - now->bottom);
> - if (!combaine_hrgn) {
> - spice_critical("Unable to CreateRectRgn");
> - DeleteObject(main_hrgn);
> - return;
> - }
> - if (CombineRgn(main_hrgn, main_hrgn, combaine_hrgn, RGN_OR) == ERROR) {
> - spice_critical("Unable to CombineRgn");
> - DeleteObject(combaine_hrgn);
> - return;
> - }
> - DeleteObject(combaine_hrgn);
> - }
> - if (SelectClipRgn(canvas->dc, main_hrgn) == ERROR) {
> - spice_critical("Unable to SelectClipRgn");
> - }
> - DeleteObject(main_hrgn);
> - }
> - break;
> - }
> - default:
> - spice_warn_if_reached();
> - return;
> - }
> -}
> -
> -static void copy_bitmap(const uint8_t *src_image, int height, int src_stride,
> - uint8_t *dest_bitmap, int dest_stride)
> -{
> - int copy_width = MIN(dest_stride, src_stride);
> - int y = 0;
> -
> - spice_return_if_fail(dest_stride>= 0&& src_stride>= 0);
> -
> - while (y< height) {
> - memcpy(dest_bitmap, src_image, copy_width);
> - src_image += src_stride;
> - dest_bitmap += dest_stride;
> - y++;
> - }
> -}
> -
> -static void copy_bitmap_alpha(const uint8_t *src_alpha, int height, int width, int src_stride,
> - uint8_t *dest_bitmap, int dest_stride, int alpha_bits_size)
> -{
> - int y = 0;
> - uint8_t i_offset;
> - int i_count = 0;
> - int i = 0;
> - int width_div_stride;
> -
> - width_div_stride = width / src_stride;
> -
> - if (alpha_bits_size == 1) {
> - i_offset = 1;
> - } else {
> - i_offset = 8;
> - }
> -
> -
> - while (y< height) {
> - int x;
> -
> - for (x = 0; x< width; ++x) {
> - uint8_t alphaval;
> - double alpha;
> -
> - alphaval = src_alpha[i];
> - alphaval = alphaval>> (i_count * i_offset);
> - alphaval&= ((uint8_t)0xff>> (8 - i_offset));
> - alphaval = ((255 * alphaval) / ((uint8_t)0xff>> (8 - i_offset)));
> -
> - dest_bitmap[x * 4 + 3] = alphaval;
> - alpha = (double)alphaval / 0xff;
> - dest_bitmap[x * 4 + 2] = (uint8_t)(alpha * dest_bitmap[x * 4 + 2]);
> - dest_bitmap[x * 4 + 1] = (uint8_t)(alpha * dest_bitmap[x * 4 + 1]);
> - dest_bitmap[x * 4] = (uint8_t)(alpha * dest_bitmap[x * 4]);
> -
> - i_count++;
> - if (i_count == (8 / i_offset)) {
> - i++;
> - i_count = 0;
> - }
> - }
> -
> - dest_bitmap += width * 4;
> - i = 0;
> - src_alpha += src_stride;
> - i_count = 0;
> - y++;
> - }
> -}
> -
> -static uint8_t *create_bitmap(HBITMAP *bitmap, HBITMAP *prev_bitmap, HDC *dc,
> - const uint8_t *bitmap_data, int width, int height,
> - int stride, int bits, int rotate)
> -{
> - uint8_t *data;
> - const uint8_t *src_data;
> - uint32_t nstride;
> - struct {
> - BITMAPINFO inf;
> - RGBQUAD palette[255];
> - } bitmap_info;
> -
> - memset(&bitmap_info, 0, sizeof(bitmap_info));
> - bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader);
> - bitmap_info.inf.bmiHeader.biWidth = width;
> - if (stride< 0) {
> - bitmap_info.inf.bmiHeader.biHeight = height;
> - } else {
> - bitmap_info.inf.bmiHeader.biHeight = -height;
> - }
> -
> - if (rotate) {
> - bitmap_info.inf.bmiHeader.biHeight = -bitmap_info.inf.bmiHeader.biHeight;
> - }
> -
> - bitmap_info.inf.bmiHeader.biPlanes = 1;
> - bitmap_info.inf.bmiHeader.biBitCount = bits;
> - bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
> -
> - *dc = create_compatible_dc();
> - if (!*dc) {
> - spice_critical("create_compatible_dc() failed");
> - return NULL;
> - }
> -
> - *bitmap = CreateDIBSection(*dc,&bitmap_info.inf, 0, (VOID **)&data, NULL, 0);
> - if (!*bitmap) {
> - spice_critical("Unable to CreateDIBSection");
> - DeleteDC(*dc);
> - return NULL;
> - }
> - *prev_bitmap = (HBITMAP)SelectObject(*dc, *bitmap);
> -
> - if (stride< 0) {
> - src_data = bitmap_data - (height - 1) * -stride;
> - } else {
> - src_data = bitmap_data;
> - }
> -
> - switch (bits) {
> - case 1:
> - nstride = SPICE_ALIGN(width, 32) / 8;
> - break;
> - case 8:
> - nstride = SPICE_ALIGN(width, 4);
> - break;
> - case 16:
> - nstride = SPICE_ALIGN(width * 2, 4);
> - break;
> - case 32:
> - nstride = width * 4;
> - break;
> - default:
> - spice_warn_if_reached();
> - return;
> - }
> -
> - if (bitmap_data) {
> - if (stride< 0) {
> - copy_bitmap(src_data, height, -stride, data, nstride);
> - } else {
> - copy_bitmap(src_data, height, stride, data, nstride);
> - }
> - }
> -
> - return data;
> -}
> -
> -static uint8_t *create_bitmap_from_pixman(HBITMAP *bitmap, HBITMAP *prev_bitmap, HDC *dc,
> - pixman_image_t *surface, int rotate)
> -{
> - return create_bitmap(bitmap, prev_bitmap, dc,
> - (uint8_t*)pixman_image_get_data(surface),
> - pixman_image_get_width(surface),
> - pixman_image_get_height(surface),
> - pixman_image_get_stride(surface),
> - spice_pixman_image_get_bpp(surface),
> - rotate);
> -}
> -
> -
> -static void release_bitmap(HDC dc, HBITMAP bitmap, HBITMAP prev_bitmap, int cache)
> -{
> - bitmap = (HBITMAP)SelectObject(dc, prev_bitmap);
> - if (!cache) {
> - DeleteObject(bitmap);
> - }
> - DeleteDC(dc);
> -}
> -
> -static inline uint8_t get_converted_color(uint8_t color)
> -{
> - uint8_t msb;
> -
> - msb = color& 0xE0;
> - msb = msb>> 5;
> - color |= msb;
> - return color;
> -}
> -
> -static inline COLORREF get_color_ref(GdiCanvas *canvas, uint32_t color)
> -{
> - int shift = canvas->base.color_shift == 8 ? 0 : 3;
> - uint8_t r, g, b;
> -
> - b = (color& canvas->base.color_mask);
> - color>>= canvas->base.color_shift;
> - g = (color& canvas->base.color_mask);
> - color>>= canvas->base.color_shift;
> - r = (color& canvas->base.color_mask);
> - if (shift) {
> - r = get_converted_color(r<< shift);
> - g = get_converted_color(g<< shift);
> - b = get_converted_color(b<< shift);
> - }
> - return RGB(r, g, b);
> -}
> -
> -static HBRUSH get_brush(GdiCanvas *canvas, SpiceBrush *brush, RecurciveMutex **brush_lock)
> -{
> - HBRUSH hbrush;
> -
> - *brush_lock = NULL;
> -
> - switch (brush->type) {
> - case SPICE_BRUSH_TYPE_SOLID:
> - if (!(hbrush = CreateSolidBrush(get_color_ref(canvas, brush->u.color)))) {
> - spice_critical("CreateSolidBrush failed");
> - return NULL;
> - }
> - return hbrush;
> - case SPICE_BRUSH_TYPE_PATTERN: {
> - GdiCanvas *gdi_surface = NULL;
> - HBRUSH hbrush;
> - pixman_image_t *surface = NULL;
> - HDC dc;
> - HBITMAP bitmap;
> - HBITMAP prev_bitmap;
> -
> - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, brush->u.pattern.pat);
> - if (gdi_surface) {
> - bitmap = (HBITMAP)GetCurrentObject(gdi_surface->dc, OBJ_BITMAP);
> - if (!bitmap) {
> - spice_critical("GetCurrentObject failed");
> - return NULL;
> - }
> - *brush_lock = gdi_surface->lock;
> - } else {
> - surface = canvas_get_image(&canvas->base, brush->u.pattern.pat, FALSE);
> - if (!create_bitmap_from_pixman(&bitmap,&prev_bitmap,&dc, surface, 0)) {
> - spice_critical("create_bitmap failed");
> - return NULL;
> - }
> - }
> -
> - if (!(hbrush = CreatePatternBrush(bitmap))) {
> - spice_critical("CreatePatternBrush failed");
> - return NULL;
> - }
> -
> - if (!gdi_surface) {
> - release_bitmap(dc, bitmap, prev_bitmap, 0);
> - pixman_image_unref(surface);
> - }
> - return hbrush;
> - }
> - case SPICE_BRUSH_TYPE_NONE:
> - return NULL;
> - default:
> - spice_warn_if_reached();
> - return NULL;
> - }
> -}
> -
> -static HBRUSH set_brush(HDC dc, HBRUSH hbrush, SpiceBrush *brush)
> -{
> - switch (brush->type) {
> - case SPICE_BRUSH_TYPE_SOLID: {
> - return (HBRUSH)SelectObject(dc, hbrush);
> - }
> - case SPICE_BRUSH_TYPE_PATTERN: {
> - HBRUSH prev_hbrush;
> - prev_hbrush = (HBRUSH)SelectObject(dc, hbrush);
> - if (!SetBrushOrgEx(dc, brush->u.pattern.pos.x, brush->u.pattern.pos.y, NULL)) {
> - spice_critical("SetBrushOrgEx failed");
> - return NULL;
> - }
> - return prev_hbrush;
> - }
> - default:
> - spice_warn_if_reached();
> - return NULL;
> - }
> -}
> -
> -static void unset_brush(HDC dc, HBRUSH prev_hbrush)
> -{
> - if (!prev_hbrush) {
> - return;
> - }
> - prev_hbrush = (HBRUSH)SelectObject(dc, prev_hbrush);
> - DeleteObject(prev_hbrush);
> -}
> -
> -uint8_t calc_rop3(uint16_t rop3_bits, int brush)
> -{
> - uint8_t rop3 = 0;
> - uint8_t rop3_src = _rop3_src;
> - uint8_t rop3_dest = _rop3_dest;
> - uint8_t rop3_brush = _rop3_brush;
> - uint8_t rop3_src_brush;
> -
> - if (rop3_bits& SPICE_ROPD_INVERS_SRC) {
> - rop3_src = ~rop3_src;
> - }
> - if (rop3_bits& SPICE_ROPD_INVERS_BRUSH) {
> - rop3_brush = ~rop3_brush;
> - }
> - if (rop3_bits& SPICE_ROPD_INVERS_DEST) {
> - rop3_dest = ~rop3_dest;
> - }
> -
> - if (brush) {
> - rop3_src_brush = rop3_brush;
> - } else {
> - rop3_src_brush = rop3_src;
> - }
> -
> - if (rop3_bits& SPICE_ROPD_OP_PUT) {
> - rop3 = rop3_src_brush;
> - }
> - if (rop3_bits& SPICE_ROPD_OP_OR) {
> - rop3 = rop3_src_brush | rop3_dest;
> - }
> - if (rop3_bits& SPICE_ROPD_OP_AND) {
> - rop3 = rop3_src_brush& rop3_dest;
> - }
> - if (rop3_bits& SPICE_ROPD_OP_XOR) {
> - rop3 = rop3_src_brush ^ rop3_dest;
> - }
> - if (rop3_bits& SPICE_ROPD_INVERS_RES) {
> - rop3 = ~rop3_dest;
> - }
> -
> - if (rop3_bits& SPICE_ROPD_OP_BLACKNESS || rop3_bits& SPICE_ROPD_OP_WHITENESS ||
> - rop3_bits& SPICE_ROPD_OP_INVERS) {
> - spice_warn_if_reached("invalid rop3 type");
> - return 0;
> - }
> - return rop3;
> -}
> -
> -uint8_t calc_rop3_src_brush(uint16_t rop3_bits)
> -{
> - uint8_t rop3 = 0;
> - uint8_t rop3_src = _rop3_src;
> - uint8_t rop3_brush = _rop3_brush;
> -
> - if (rop3_bits& SPICE_ROPD_INVERS_SRC) {
> - rop3_src = ~rop3_src;
> - }
> - if (rop3_bits& SPICE_ROPD_INVERS_BRUSH) {
> - rop3_brush = ~rop3_brush;
> - }
> -
> - if (rop3_bits& SPICE_ROPD_OP_OR) {
> - rop3 = rop3_src | rop3_brush;
> - }
> - if (rop3_bits& SPICE_ROPD_OP_AND) {
> - rop3 = rop3_src& rop3_brush;
> - }
> - if (rop3_bits& SPICE_ROPD_OP_XOR) {
> - rop3 = rop3_src ^ rop3_brush;
> - }
> -
> - return rop3;
> -}
> -
> -static struct BitmapData get_mask_bitmap(struct GdiCanvas *canvas, struct SpiceQMask *mask)
> -{
> - GdiCanvas *gdi_surface;
> - pixman_image_t *surface;
> - struct BitmapData bitmap;
> - PixmanData *pixman_data;
> -
> - bitmap.hbitmap = NULL;
> - if (!mask->bitmap) {
> - return bitmap;
> - }
> -
> - gdi_surface = (GdiCanvas *)canvas_get_surface_mask(&canvas->base, mask->bitmap);
> - if (gdi_surface) {
> - HBITMAP _bitmap;
> -
> - _bitmap = (HBITMAP)GetCurrentObject(gdi_surface->dc, OBJ_BITMAP);
> - if (!_bitmap) {
> - spice_critical("GetCurrentObject failed");
> - return bitmap;
> - }
> - bitmap.dc = gdi_surface->dc;
> - bitmap.hbitmap = _bitmap;
> - bitmap.prev_hbitmap = (HBITMAP)0;
> - bitmap.cache = 0;
> - bitmap.from_surface = 1;
> - } else {
> -
> - if (!(surface = canvas_get_mask(&canvas->base, mask, NULL))) {
> - return bitmap;
> - }
> -
> - pixman_data = (PixmanData *)pixman_image_get_destroy_data (surface);
> - if (pixman_data&& (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
> - bitmap.dc = create_compatible_dc();
> - bitmap.prev_hbitmap = (HBITMAP)SelectObject(bitmap.dc, pixman_data->bitmap);
> - bitmap.hbitmap = pixman_data->bitmap;
> - ReleaseMutex(pixman_data->mutex);
> - bitmap.cache = 1;
> - } else if (!create_bitmap_from_pixman(&bitmap.hbitmap,&bitmap.prev_hbitmap,&bitmap.dc,
> - surface, 0)) {
> - bitmap.hbitmap = NULL;
> - } else {
> - bitmap.cache = 0;
> - }
> -
> - bitmap.from_surface = 0;
> - }
> -
> - bitmap.flags = mask->flags;
> - bitmap.pos = mask->pos;
> -
> - return bitmap;
> -}
> -
> -static void gdi_draw_bitmap(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
> - HDC src_dc, struct BitmapData *bitmapmask, uint32_t rop3_val)
> -{
> - uint32_t rast_oper;
> -
> - rast_oper = raster_ops[rop3_val];
> -
> - if (!bitmapmask || !bitmapmask->hbitmap) {
> - if ((dest->right - dest->left) == (src->right - src->left)&&
> - (dest->bottom - dest->top) == (src->bottom - src->top)) {
> - if (!BitBlt(dest_dc, dest->left, dest->top, dest->right - dest->left,
> - dest->bottom - dest->top, src_dc, src->left, src->top, rast_oper)) {
> - spice_critical("BitBlt failed");
> - return;
> - }
> - } else {
> - if (!StretchBlt(dest_dc, dest->left, dest->top, dest->right - dest->left,
> - dest->bottom - dest->top, src_dc, src->left, src->top,
> - src->right - src->left, src->bottom - src->top, rast_oper)) {
> - spice_critical("StretchBlt failed");
> - return;
> - }
> - }
> - } else {
> - rast_oper = MAKEROP4(rast_oper, raster_ops[_rop3_dest]);
> -
> - if (!MaskBlt(dest_dc, dest->left, dest->top, dest->right - dest->left,
> - dest->bottom - dest->top, src_dc, src->left, src->top,
> - bitmapmask->hbitmap, bitmapmask->pos.x, bitmapmask->pos.y,
> - rast_oper)) {
> - spice_critical("MaskBlt failed");
> - return;
> - }
> - }
> -}
> -
> -static void gdi_draw_bitmap_redrop(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
> - HDC src_dc, struct BitmapData *bitmapmask,
> - uint16_t rop, int brush)
> -{
> - uint32_t rop3_val;
> -
> - rop3_val = calc_rop3(rop, brush);
> - gdi_draw_bitmap(dest_dc, src, dest, src_dc, bitmapmask, rop3_val);
> -}
> -
> -static void free_mask(struct BitmapData *bitmap)
> -{
> - if (bitmap->hbitmap) {
> - if (!bitmap->from_surface) {
> - release_bitmap(bitmap->dc, bitmap->hbitmap, bitmap->prev_hbitmap, bitmap->cache);
> - }
> - }
> -}
> -
> -static void draw_str_mask_bitmap(struct GdiCanvas *canvas,
> - SpiceString *str, int n, SpiceRect *dest,
> - SpiceRect *src, SpiceBrush *brush)
> -{
> - pixman_image_t *surface;
> - struct BitmapData bitmap;
> - SpicePoint pos;
> - int dest_stride;
> - uint8_t *bitmap_data;
> - HBRUSH prev_hbrush;
> - HBRUSH hbrush;
> - RecurciveMutex *brush_lock;
> -
> - bitmap.hbitmap = (HBITMAP)1;
> - if (!(surface = canvas_get_str_mask(&canvas->base, str, n,&pos))) {
> - spice_critical("unable to canvas_get_str_mask");
> - return;
> - }
> -
> - bitmap.from_surface = 0;
> - bitmap.cache = 0;
> - bitmap_data = create_bitmap(&bitmap.hbitmap,&bitmap.prev_hbitmap,
> -&bitmap.dc, NULL,
> - pixman_image_get_width(surface),
> - pixman_image_get_height(surface),
> - pixman_image_get_stride(surface), 32, 0);
> -
> - if (!bitmap_data) {
> - return;
> - }
> -
> - bitmap.flags = 0;
> - bitmap.pos.x = 0;
> - bitmap.pos.y = 0;
> -
> - dest->left = pos.x;
> - dest->top = pos.y;
> - dest->right = pos.x + pixman_image_get_width(surface);
> - dest->bottom = pos.y + pixman_image_get_height(surface);
> - src->left = 0;
> - src->top = 0;
> - src->right = pixman_image_get_width(surface);
> - src->bottom = pixman_image_get_height(surface);
> -
> - dest_stride = pixman_image_get_width(surface);
> - switch (n) {
> - case 1:
> - dest_stride = dest_stride / 8;
> - break;
> - case 4:
> - dest_stride = dest_stride / 2;
> - break;
> - case 32:
> - dest_stride = dest_stride * 4;
> - break;
> - default:
> - spice_warn_if_reached();
> - return;
> - }
> - dest_stride = dest_stride + 3;
> - dest_stride = dest_stride& ~3;
> -
> - hbrush = get_brush(canvas, brush,&brush_lock);
> - prev_hbrush = set_brush(bitmap.dc, hbrush, brush);
> - if (brush_lock) {
> - RecurciveLock b_lock(*brush_lock);
> - gdi_draw_bitmap(bitmap.dc, src, src, bitmap.dc, NULL, _rop3_brush);
> - } else {
> - gdi_draw_bitmap(bitmap.dc, src, src, bitmap.dc, NULL, _rop3_brush);
> - }
> -
> - unset_brush(bitmap.dc, prev_hbrush);
> -
> - copy_bitmap_alpha((uint8_t *)pixman_image_get_data(surface),
> - pixman_image_get_height(surface),
> - pixman_image_get_width(surface),
> - pixman_image_get_stride(surface),
> - bitmap_data, dest_stride, n);
> -
> - BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
> -
> - RecurciveLock lock(*canvas->lock);
> - AlphaBlend(canvas->dc, dest->left, dest->top, dest->right - dest->left,
> - dest->bottom - dest->top, bitmap.dc, src->left, src->top,
> - src->right - src->left, src->bottom - src->top, bf);
> -
> - free_mask(&bitmap);
> -}
> -
> -static void gdi_draw_image(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
> - pixman_image_t *image, struct BitmapData *bitmapmask, uint16_t rop,
> - int rotate)
> -{
> - HDC dc;
> - HBITMAP bitmap;
> - HBITMAP prev_bitmap;
> -
> - create_bitmap_from_pixman(&bitmap,&prev_bitmap,&dc, image, rotate);
> -
> - gdi_draw_bitmap_redrop(dest_dc, src, dest, dc, bitmapmask, rop, 0);
> -
> - release_bitmap(dc, bitmap, prev_bitmap, 0);
> -}
> -
> -static void gdi_draw_image_rop3(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
> - pixman_image_t *image, struct BitmapData *bitmapmask, uint8_t rop3,
> - int rotate)
> -{
> - HDC dc;
> - HBITMAP bitmap;
> - HBITMAP prev_bitmap;
> -
> - create_bitmap_from_pixman(&bitmap,&prev_bitmap,&dc, image, rotate);
> -
> - gdi_draw_bitmap(dest_dc, src, dest, dc, bitmapmask, rop3);
> -
> - release_bitmap(dc, bitmap, prev_bitmap, 0);
> -}
> -
> -static void gdi_canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
> -{
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - HBRUSH prev_hbrush;
> - HBRUSH brush;
> - struct BitmapData bitmapmask;
> - RecurciveMutex *brush_lock;
> -
> - RecurciveLock lock(*canvas->lock);
> -
> - brush = get_brush(canvas,&fill->brush,&brush_lock);
> - spice_return_if_fail(brush != NULL);
> -
> - bitmapmask = get_mask_bitmap(canvas,&fill->mask);
> -
> - set_clip(canvas, clip);
> - prev_hbrush = set_brush(canvas->dc, brush,&fill->brush);
> - if (brush_lock) {
> - RecurciveLock b_lock(*brush_lock);
> - gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc,&bitmapmask,
> - fill->rop_descriptor, fill->brush.type != SPICE_BRUSH_TYPE_NONE);
> - } else {
> - gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc,&bitmapmask,
> - fill->rop_descriptor, fill->brush.type != SPICE_BRUSH_TYPE_NONE);
> - }
> -
> - free_mask(&bitmapmask);
> - unset_brush(canvas->dc, prev_hbrush);
> -}
> -
> -static void gdi_canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
> -{
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - GdiCanvas *gdi_surface;
> - pixman_image_t *surface;
> - struct BitmapData bitmapmask;
> - PixmanData *pixman_data;
> -
> - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, copy->src_bitmap);
> - if (gdi_surface) {
> - RecurciveLock lock(*canvas->lock);
> - RecurciveLock s_lock(*gdi_surface->lock);
> - bitmapmask = get_mask_bitmap(canvas,©->mask);
> - set_scale_mode(canvas, copy->scale_mode);
> - set_clip(canvas, clip);
> - gdi_draw_bitmap_redrop(canvas->dc,©->src_area, bbox, gdi_surface->dc,
> -&bitmapmask, copy->rop_descriptor, 0);
> - } else {
> - surface = canvas_get_image(&canvas->base, copy->src_bitmap, FALSE);
> - pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
> -
> - RecurciveLock lock(*canvas->lock);
> - bitmapmask = get_mask_bitmap(canvas,©->mask);
> - set_scale_mode(canvas, copy->scale_mode);
> - set_clip(canvas, clip);
> -
> - if (pixman_data&& (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
> - HDC dc;
> - HBITMAP prev_bitmap;
> -
> - dc = create_compatible_dc();
> - prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
> - gdi_draw_bitmap_redrop(canvas->dc,©->src_area, bbox, dc,
> -&bitmapmask, copy->rop_descriptor, 0);
> - SelectObject(dc, prev_bitmap);
> - DeleteObject(dc);
> - ReleaseMutex(pixman_data->mutex);
> - } else {
> - gdi_draw_image(canvas->dc,©->src_area, bbox, surface,&bitmapmask,
> - copy->rop_descriptor, 0);
> - }
> -
> - pixman_image_unref(surface);
> -
> - }
> - free_mask(&bitmapmask);
> -}
> -
> -static void gdi_canvas_put_image(SpiceCanvas *spice_canvas, HDC dc, const SpiceRect *dest, const uint8_t *src_data,
> - uint32_t src_width, uint32_t src_height, int src_stride,
> - const QRegion *clip)
> -{
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - SpiceRect src;
> - src.top = 0;
> - src.bottom = src_height;
> - src.left = 0;
> - src.right = src_width;
> - int num_rects;
> - pixman_box32_t *rects;
> -
> - RecurciveLock lock(*canvas->lock);
> - set_scale_mode(canvas, SPICE_IMAGE_SCALE_MODE_NEAREST);
> - if (clip) {
> - rects = pixman_region32_rectangles((pixman_region32_t*)clip,&num_rects);
> - if (num_rects == 0) {
> - return;
> - } else {
> - HRGN main_hrgn;
> - int i;
> -
> - main_hrgn = CreateRectRgn(rects[0].x1, rects[0].y1, rects[0].x2,
> - rects[0].y2);
> - if (!main_hrgn) {
> - return;
> - }
> -
> - for (i = 1; i< num_rects; i++) {
> - HRGN combaine_hrgn;
> -
> - combaine_hrgn = CreateRectRgn(rects[i].x1, rects[i].y1,
> - rects[i].x2,
> - rects[i].y2);
> - if (!combaine_hrgn) {
> - spice_critical("CreateRectRgn failed");
> - DeleteObject(main_hrgn);
> - return;
> - }
> - if (!CombineRgn(main_hrgn, main_hrgn, combaine_hrgn, RGN_OR)) {
> - spice_critical("CombineRgn failed in put_image");
> - return;
> - }
> - DeleteObject(combaine_hrgn);
> - }
> - if (SelectClipRgn(canvas->dc, main_hrgn) == ERROR) {
> - spice_critical("SelectClipRgn failed in put_image");
> - DeleteObject(main_hrgn);
> - return;
> - }
> - DeleteObject(main_hrgn);
> - }
> - } else {
> - SelectClipRgn(canvas->dc, NULL);
> - }
> -
> - if (dc) {
> - gdi_draw_bitmap_redrop(canvas->dc,&src, dest, dc,
> - NULL, SPICE_ROPD_OP_PUT, 0);
> - } else {
> - pixman_image_t *image = pixman_image_create_bits(PIXMAN_a8r8g8b8, src_width, src_height,
> - (uint32_t *)src_data, src_stride);
> - gdi_draw_image(canvas->dc,&src, dest, image, NULL, SPICE_ROPD_OP_PUT, 0);
> - pixman_image_unref(image);
> - }
> -}
> -
> -static void gdi_draw_bitmap_transparent(GdiCanvas *canvas, HDC dest_dc, const SpiceRect *src,
> - const SpiceRect *dest, HDC src_dc, uint32_t color)
> -{
> - TransparentBlt(dest_dc, dest->left, dest->top, dest->right - dest->left,
> - dest->bottom - dest->top, src_dc, src->left, src->top,
> - src->right - src->left, src->bottom - src->top,
> - RGB(((uint8_t*)&color)[2], ((uint8_t*)&color)[1], ((uint8_t*)&color)[0]));
> -}
> -
> -static void gdi_draw_image_transparent(GdiCanvas *canvas, HDC dest_dc, const SpiceRect *src,
> - const SpiceRect *dest, pixman_image_t *image,
> - uint32_t color, int rotate)
> -{
> - HDC dc;
> - HBITMAP bitmap;
> - HBITMAP prev_bitmap;
> -
> - create_bitmap_from_pixman(&bitmap,&prev_bitmap,&dc, image, rotate);
> -
> - gdi_draw_bitmap_transparent(canvas, dest_dc, src, dest, dc, color);
> -
> - release_bitmap(dc, bitmap, prev_bitmap, 0);
> -}
> -
> -static void gdi_canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip,
> - SpiceTransparent* transparent)
> -{
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - GdiCanvas *gdi_surface;
> - pixman_image_t *surface;
> - PixmanData *pixman_data;
> -
> - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, transparent->src_bitmap);
> - if (gdi_surface) {
> - RecurciveLock lock(*canvas->lock);
> - RecurciveLock s_lock(*gdi_surface->lock);
> - set_clip(canvas, clip);
> - gdi_draw_bitmap_transparent(canvas, canvas->dc,&transparent->src_area, bbox,
> - gdi_surface->dc, transparent->true_color);
> - } else {
> - surface = canvas_get_image(&canvas->base, transparent->src_bitmap, FALSE);
> - pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
> - RecurciveLock lock(*canvas->lock);
> - set_clip(canvas, clip);
> - if (pixman_data&& (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
> - HDC dc;
> - HBITMAP prev_bitmap;
> -
> - dc = create_compatible_dc();
> - prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
> - gdi_draw_bitmap_transparent(canvas, canvas->dc,&transparent->src_area, bbox, dc,
> - transparent->true_color);
> -
> - SelectObject(dc, prev_bitmap);
> - DeleteObject(dc);
> - ReleaseMutex(pixman_data->mutex);
> - } else {
> - gdi_draw_image_transparent(canvas, canvas->dc,&transparent->src_area, bbox, surface,
> - transparent->true_color, 0);
> - }
> -
> - pixman_image_unref(surface);
> - }
> -}
> -
> -static void gdi_draw_bitmap_alpha(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
> - HDC src_dc, uint8_t alpha, int use_bitmap_alpha)
> -{
> - BLENDFUNCTION bf;
> -
> - bf.BlendOp = AC_SRC_OVER;
> - bf.BlendFlags = 0;
> - bf.SourceConstantAlpha = alpha;
> -
> - if (use_bitmap_alpha) {
> - bf.AlphaFormat = AC_SRC_ALPHA;
> - } else {
> - bf.AlphaFormat = 0;
> - }
> -
> - if (!AlphaBlend(dest_dc, dest->left, dest->top, dest->right - dest->left,
> - dest->bottom - dest->top, src_dc, src->left, src->top,
> - src->right - src->left, src->bottom - src->top, bf)) {
> - spice_critical("AlphaBlend failed");
> - return;
> - }
> -}
> -
> -static void gdi_draw_image_alpha(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
> - pixman_image_t *image, uint8_t alpha,
> - int rotate, int use_bitmap_alpha)
> -{
> - HDC dc;
> - HBITMAP bitmap;
> - HBITMAP prev_bitmap;
> -
> - create_bitmap_from_pixman(&bitmap,&prev_bitmap,&dc, image, rotate);
> -
> - gdi_draw_bitmap_alpha(dest_dc, src, dest, dc, alpha, use_bitmap_alpha);
> -
> - release_bitmap(dc, bitmap, prev_bitmap, 0);
> -}
> -
> -static void gdi_canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend* alpha_blend)
> -{
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - GdiCanvas *gdi_surface;
> - pixman_image_t *surface;
> - PixmanData *pixman_data;
> - int use_bitmap_alpha;
> -
> - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, alpha_blend->src_bitmap);
> - if (gdi_surface) {
> - RecurciveLock lock(*canvas->lock);
> - RecurciveLock s_lock(*gdi_surface->lock);
> - set_clip(canvas, clip);
> - use_bitmap_alpha = alpha_blend->alpha_flags& SPICE_ALPHA_FLAGS_SRC_SURFACE_HAS_ALPHA;
> - gdi_draw_bitmap_alpha(canvas->dc,&alpha_blend->src_area, bbox, gdi_surface->dc,
> - alpha_blend->alpha, use_bitmap_alpha);
> - } else {
> - surface = canvas_get_image(&canvas->base, alpha_blend->src_bitmap, TRUE);
> - use_bitmap_alpha = pixman_image_get_depth(surface) == 32;
> - pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
> -
> - RecurciveLock lock(*canvas->lock);
> - set_clip(canvas, clip);
> - if (pixman_data&& (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
> - HDC dc;
> - HBITMAP prev_bitmap;
> -
> - dc = create_compatible_dc();
> - prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
> - gdi_draw_bitmap_alpha(canvas->dc,&alpha_blend->src_area, bbox, dc, alpha_blend->alpha,
> - use_bitmap_alpha);
> - SelectObject(dc, prev_bitmap);
> - DeleteObject(dc);
> - ReleaseMutex(pixman_data->mutex);
> - } else {
> - gdi_draw_image_alpha(canvas->dc,&alpha_blend->src_area, bbox, surface,
> - alpha_blend->alpha, 0, use_bitmap_alpha);
> - }
> -
> - pixman_image_unref(surface);
> - }
> -}
> -
> -static void gdi_canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
> -{
> - GdiCanvas *gdi_surface;
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - pixman_image_t *surface;
> - struct BitmapData bitmapmask;
> - PixmanData *pixman_data;
> - HBRUSH prev_hbrush;
> - HBRUSH hbrush;
> - uint8_t rop3;
> - RecurciveMutex *brush_lock;
> -
> - rop3 = calc_rop3_src_brush(opaque->rop_descriptor);
> -
> - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, opaque->src_bitmap);
> - if (gdi_surface) {
> - RecurciveLock lock(*canvas->lock);
> - RecurciveLock s_lock(*gdi_surface->lock);
> - bitmapmask = get_mask_bitmap(canvas,&opaque->mask);
> - hbrush = get_brush(canvas,&opaque->brush,&brush_lock);
> - set_scale_mode(canvas, opaque->scale_mode);
> - set_clip(canvas, clip);
> - prev_hbrush = set_brush(canvas->dc, hbrush,&opaque->brush);
> - if (brush_lock) {
> - RecurciveLock b_lock(*brush_lock);
> - gdi_draw_bitmap(canvas->dc,&opaque->src_area, bbox, gdi_surface->dc,&bitmapmask, rop3);
> - } else {
> - gdi_draw_bitmap(canvas->dc,&opaque->src_area, bbox, gdi_surface->dc,&bitmapmask, rop3);
> - }
> - unset_brush(canvas->dc, prev_hbrush);
> - } else {
> - surface = canvas_get_image(&canvas->base, opaque->src_bitmap, FALSE);
> - pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
> -
> - RecurciveLock lock(*canvas->lock);
> - bitmapmask = get_mask_bitmap(canvas,&opaque->mask);
> - hbrush = get_brush(canvas,&opaque->brush,&brush_lock);
> - set_scale_mode(canvas, opaque->scale_mode);
> - set_clip(canvas, clip);
> - prev_hbrush = set_brush(canvas->dc, hbrush,&opaque->brush);
> -
> - if (pixman_data&& (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
> - HDC dc;
> - HBITMAP prev_bitmap;
> -
> - dc = create_compatible_dc();
> - prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
> - if (brush_lock) {
> - RecurciveLock b_lock(*brush_lock);
> - gdi_draw_bitmap(canvas->dc,&opaque->src_area, bbox, dc,&bitmapmask, rop3);
> - } else {
> - gdi_draw_bitmap(canvas->dc,&opaque->src_area, bbox, dc,&bitmapmask, rop3);
> - }
> - SelectObject(dc, prev_bitmap);
> - DeleteObject(dc);
> - ReleaseMutex(pixman_data->mutex);
> - } else {
> - if (brush_lock) {
> - RecurciveLock b_lock(*brush_lock);
> - gdi_draw_image_rop3(canvas->dc,&opaque->src_area, bbox, surface,&bitmapmask, rop3, 0);
> - } else {
> - gdi_draw_image_rop3(canvas->dc,&opaque->src_area, bbox, surface,&bitmapmask, rop3, 0);
> - }
> - }
> - unset_brush(canvas->dc, prev_hbrush);
> - pixman_image_unref(surface);
> - }
> -
> - free_mask(&bitmapmask);
> -}
> -
> -static void gdi_canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
> -{
> - GdiCanvas *gdi_surface;
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - pixman_image_t *surface;
> - struct BitmapData bitmapmask;
> - PixmanData *pixman_data;
> -
> - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, blend->src_bitmap);
> - if (gdi_surface) {
> - RecurciveLock lock(*canvas->lock);
> - RecurciveLock s_lock(*gdi_surface->lock);
> - bitmapmask = get_mask_bitmap(canvas,&blend->mask);
> - set_scale_mode(canvas, blend->scale_mode);
> - set_clip(canvas, clip);
> - gdi_draw_bitmap_redrop(canvas->dc,&blend->src_area, bbox, gdi_surface->dc,
> -&bitmapmask, blend->rop_descriptor, 0);
> - } else {
> - surface = canvas_get_image(&canvas->base, blend->src_bitmap, FALSE);
> - pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
> -
> - RecurciveLock lock(*canvas->lock);
> - bitmapmask = get_mask_bitmap(canvas,&blend->mask);
> - set_scale_mode(canvas, blend->scale_mode);
> - set_clip(canvas, clip);
> -
> - if (pixman_data&& (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
> - HDC dc;
> - HBITMAP prev_bitmap;
> -
> - dc = create_compatible_dc();
> - prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
> - gdi_draw_bitmap_redrop(canvas->dc,&blend->src_area, bbox, dc,
> -&bitmapmask, blend->rop_descriptor, 0);
> - SelectObject(dc, prev_bitmap);
> - DeleteObject(dc);
> - ReleaseMutex(pixman_data->mutex);
> - } else {
> - gdi_draw_image(canvas->dc,&blend->src_area, bbox, surface,
> - &bitmapmask, blend->rop_descriptor, 0);
> - }
> -
> - pixman_image_unref(surface);
> - }
> -
> - free_mask(&bitmapmask);
> -}
> -
> -static void gdi_canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
> -{
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - struct BitmapData bitmapmask;
> -
> - RecurciveLock lock(*canvas->lock);
> - bitmapmask = get_mask_bitmap(canvas,&blackness->mask);
> - set_clip(canvas, clip);
> - gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc,&bitmapmask, 0x0);
> -
> - free_mask(&bitmapmask);
> -}
> -
> -static void gdi_canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
> -{
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - struct BitmapData bitmapmask;
> -
> - RecurciveLock lock(*canvas->lock);
> - bitmapmask = get_mask_bitmap(canvas,&invers->mask);
> - set_clip(canvas, clip);
> - gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc,&bitmapmask, 0x55);
> -
> - free_mask(&bitmapmask);
> -}
> -
> -static void gdi_canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
> -{
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - struct BitmapData bitmapmask;
> -
> - RecurciveLock lock(*canvas->lock);
> - bitmapmask = get_mask_bitmap(canvas,&whiteness->mask);
> - set_clip(canvas, clip);
> - gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc,&bitmapmask, 0xff);
> -
> - free_mask(&bitmapmask);
> -}
> -
> -static void gdi_canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
> -{
> - GdiCanvas *gdi_surface;
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - pixman_image_t *surface;
> - struct BitmapData bitmapmask;
> - HBRUSH prev_hbrush;
> - HBRUSH hbrush;
> - PixmanData *pixman_data;
> - RecurciveMutex *brush_lock;
> -
> - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, rop3->src_bitmap);
> - if (gdi_surface) {
> - RecurciveLock lock(*canvas->lock);
> - RecurciveLock s_lock(*gdi_surface->lock);
> - hbrush = get_brush(canvas,&rop3->brush,&brush_lock);
> - bitmapmask = get_mask_bitmap(canvas,&rop3->mask);
> - set_scale_mode(canvas, rop3->scale_mode);
> - set_clip(canvas, clip);
> - prev_hbrush = set_brush(canvas->dc, hbrush,&rop3->brush);
> - if (brush_lock) {
> - RecurciveLock b_lock(*brush_lock);
> - gdi_draw_bitmap(canvas->dc,&rop3->src_area, bbox, gdi_surface->dc,
> -&bitmapmask, rop3->rop3);
> - } else {
> - gdi_draw_bitmap(canvas->dc,&rop3->src_area, bbox, gdi_surface->dc,
> -&bitmapmask, rop3->rop3);
> - }
> - unset_brush(canvas->dc, prev_hbrush);
> - } else {
> - surface = canvas_get_image(&canvas->base, rop3->src_bitmap, FALSE);
> - pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
> - RecurciveLock lock(*canvas->lock);
> - hbrush = get_brush(canvas,&rop3->brush,&brush_lock);
> - bitmapmask = get_mask_bitmap(canvas,&rop3->mask);
> - set_scale_mode(canvas, rop3->scale_mode);
> - set_clip(canvas, clip);
> - prev_hbrush = set_brush(canvas->dc, hbrush,&rop3->brush);
> -
> - if (pixman_data&& (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
> - HDC dc;
> - HBITMAP prev_bitmap;
> -
> - dc = create_compatible_dc();
> - prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
> - if (brush_lock) {
> - RecurciveLock b_lock(*brush_lock);
> - gdi_draw_bitmap(canvas->dc,&rop3->src_area, bbox, dc,
> -&bitmapmask, rop3->rop3);
> - } else {
> - gdi_draw_bitmap(canvas->dc,&rop3->src_area, bbox, dc,
> -&bitmapmask, rop3->rop3);
> - }
> - SelectObject(dc, prev_bitmap);
> - DeleteObject(dc);
> - ReleaseMutex(pixman_data->mutex);
> - } else {
> - if (brush_lock) {
> - RecurciveLock b_lock(*brush_lock);
> - gdi_draw_image_rop3(canvas->dc,&rop3->src_area, bbox, surface,&bitmapmask, rop3->rop3, 0);
> - } else {
> - gdi_draw_image_rop3(canvas->dc,&rop3->src_area, bbox, surface,&bitmapmask, rop3->rop3, 0);
> - }
> - }
> -
> - unset_brush(canvas->dc, prev_hbrush);
> - pixman_image_unref(surface);
> - }
> -
> - free_mask(&bitmapmask);
> -}
> -
> -static void gdi_canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
> -{
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - RecurciveLock lock(*canvas->lock);
> -
> - set_clip(canvas, clip);
> -
> - BitBlt(canvas->dc, bbox->left, bbox->top, bbox->right - bbox->left,
> - bbox->bottom - bbox->top, canvas->dc, src_pos->x, src_pos->y, SRCCOPY);
> -}
> -
> -static void gdi_canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
> -{
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - SpiceString *str;
> - RecurciveMutex *brush_lock;
> -
> - RecurciveLock lock(*canvas->lock);
> - set_clip(canvas, clip);
> - lock.unlock();
> -
> - if (!rect_is_empty(&text->back_area)) {
> - HBRUSH prev_hbrush;
> - HBRUSH hbrush;
> -
> - RecurciveLock lock(*canvas->lock);
> - hbrush = get_brush(canvas,&text->back_brush,&brush_lock);
> - prev_hbrush = set_brush(canvas->dc, hbrush,&text->back_brush);
> - if (brush_lock) {
> - RecurciveLock b_lock(*brush_lock);
> - gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, NULL,
> - text->back_mode, 1);
> - } else {
> - gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, NULL,
> - text->back_mode, 1);
> - }
> - unset_brush(canvas->dc, prev_hbrush);
> - }
> -
> - str = (SpiceString *)SPICE_GET_ADDRESS(text->str);
> -
> - if (str->flags& SPICE_STRING_FLAGS_RASTER_A1) {
> - SpiceRect dest;
> - SpiceRect src;
> -
> - draw_str_mask_bitmap(canvas, str, 1,&dest,&src,&text->fore_brush);
> - } else if (str->flags& SPICE_STRING_FLAGS_RASTER_A4) {
> - SpiceRect dest;
> - SpiceRect src;
> -
> - draw_str_mask_bitmap(canvas, str, 4,&dest,&src,&text->fore_brush);
> - } else if (str->flags& SPICE_STRING_FLAGS_RASTER_A8) {
> - spice_warning("untested path A8 glyphs, doing nothing");
> - if (0) {
> - SpiceRect dest;
> - SpiceRect src;
> -
> - draw_str_mask_bitmap(canvas, str, 8,&dest,&src,&text->fore_brush);
> - }
> - } else {
> - spice_warning("untested path vector glyphs, doing nothing");
> - if (0) {
> - }
> - }
> -}
> -
> -static uint32_t *gdi_get_userstyle(GdiCanvas *canvas, uint8_t nseg, SPICE_FIXED28_4* style, int start_is_gap)
> -{
> - double offset = 0;
> - uint32_t *local_style;
> - int i;
> -
> - spice_return_val_if_fail(nseg != 0, NULL);
> -
> - local_style = spice_new(uint32_t , nseg);
> -
> - if (start_is_gap) {
> - offset = (uint32_t)fix_to_double(*style);
> - local_style[nseg - 1] = (uint32_t)fix_to_double(*style);
> - style++;
> -
> - for (i = 0; i< nseg - 1; i++, style++) {
> - local_style[i] = (uint32_t)fix_to_double(*style);
> - }
> - } else {
> - for (i = 0; i< nseg; i++, style++) {
> - local_style[i] = (uint32_t)fix_to_double(*style);
> - }
> - }
> -
> - return local_style;
> -}
> -
> -static void gdi_canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
> -{
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - HPEN hpen;
> - HPEN prev_hpen;
> - LOGBRUSH logbrush;
> - uint32_t *user_style = NULL;
> - pixman_image_t *surface = NULL;
> -
> - if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
> - surface = canvas_get_image(&canvas->base, stroke->brush.u.pattern.pat, FALSE);
> - }
> -
> - RecurciveLock lock(*canvas->lock);
> - set_clip(canvas, clip);
> -
> - switch (stroke->fore_mode) {
> - case SPICE_ROPD_OP_WHITENESS:
> - SetROP2(canvas->dc, R2_WHITE); //0
> - break;
> - case SPICE_ROPD_OP_BLACKNESS:
> - SetROP2(canvas->dc, R2_BLACK); //1
> - break;
> - case SPICE_ROPD_OP_INVERS:
> - SetROP2(canvas->dc, R2_NOT); //Dn
> - break;
> - case SPICE_ROPD_OP_PUT:
> - SetROP2(canvas->dc, R2_COPYPEN); //P
> - break;
> - case SPICE_ROPD_OP_OR:
> - SetROP2(canvas->dc, R2_MERGEPEN); //DPo
> - break;
> - case SPICE_ROPD_OP_XOR:
> - SetROP2(canvas->dc, R2_XORPEN); //DPx
> - break;
> - case SPICE_ROPD_OP_AND:
> - SetROP2(canvas->dc, R2_MASKPEN); //DPa
> - break;
> - case SPICE_ROPD_INVERS_BRUSH | SPICE_ROPD_OP_PUT: //Pn
> - SetROP2(canvas->dc, R2_NOTCOPYPEN);
> - break;
> - case SPICE_ROPD_OP_XOR | SPICE_ROPD_INVERS_RES:
> - SetROP2(canvas->dc, R2_NOTXORPEN); //DPxn
> - break;
> - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_RES:
> - SetROP2(canvas->dc, R2_NOTMERGEPEN); //DPon
> - break;
> - case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_RES:
> - SetROP2(canvas->dc, R2_NOTMASKPEN); //DPan
> - break;
> - case SPICE_ROPD_INVERS_DEST | SPICE_ROPD_OP_AND:
> - SetROP2(canvas->dc, R2_MASKPENNOT); //PDna
> - break;
> - case SPICE_ROPD_INVERS_BRUSH | SPICE_ROPD_OP_AND:
> - SetROP2(canvas->dc, R2_MASKNOTPEN); //DPna
> - break;
> - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_BRUSH:
> - SetROP2(canvas->dc, R2_MERGENOTPEN); //DPno
> - break;
> - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_DEST:
> - SetROP2(canvas->dc, R2_MERGEPENNOT); //PDno
> - break;
> - default:
> - SetROP2(canvas->dc, R2_NOP); //D
> - }
> -
> -
> - if (stroke->brush.type == SPICE_BRUSH_TYPE_SOLID) {
> - logbrush.lbStyle = BS_SOLID | DIB_RGB_COLORS;
> - logbrush.lbHatch = 0;
> - logbrush.lbColor = get_color_ref(canvas, stroke->brush.u.color);
> - } else if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
> -#if 0
> - struct {
> - BITMAPINFO inf;
> - RGBQUAD palette[255];
> - } bitmap_info;
> - GdiImage image;
> -#endif
> -#if 0
> - spice_return_if_fail(surface != NULL)
> - surface_to_image(surface,&image);
> -
> - memset(&bitmap_info, 0, sizeof(bitmap_info));
> - bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader);
> - bitmap_info.inf.bmiHeader.biWidth = image.width;
> - if (image.stride< 0) {
> - bitmap_info.inf.bmiHeader.biHeight = image.height;
> - } else {
> - bitmap_info.inf.bmiHeader.biHeight = -image.height;
> - }
> - bitmap_info.inf.bmiHeader.biPlanes = 1;
> - bitmap_info.inf.bmiHeader.biBitCount = 32;
> - bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
> -
> - if (image.stride< 0) {
> - logbrush.lbHatch = (LONG)GlobalAlloc(GMEM_MOVEABLE,
> - image.height * -image.stride + sizeof(BITMAPINFO));
> - if (!logbrush.lbHatch) {
> - spice_critical("GlobalAlloc failed");
> - return;
> - }
> - copy_bitmap(image.pixels - (image.height - 1) * -image.stride,
> - image.height, -image.stride,
> - (uint8_t *)logbrush.lbHatch, image.width);
> - } else {
> - logbrush.lbHatch = (LONG)GlobalAlloc(GMEM_MOVEABLE,
> - image.height * image.stride + sizeof(BITMAPINFO));
> - if (!logbrush.lbHatch) {
> - spice_critical("GlobalAlloc failed");
> - return;
> - }
> - copy_bitmap(image.pixels, image.height, image.stride,
> - (uint8_t *)logbrush.lbHatch, image.width);
> - }
> -
> - memcpy((void *)logbrush.lbHatch,&bitmap_info.inf, sizeof(BITMAPINFO));
> -
> - logbrush.lbStyle = BS_DIBPATTERN | DIB_RGB_COLORS;
> - logbrush.lbColor = 0;
> -#endif
> - pixman_image_unref(surface);
> - }
> -
> - if (stroke->attr.flags& SPICE_LINE_FLAGS_STYLED) {
> - user_style = gdi_get_userstyle(canvas, stroke->attr.style_nseg,
> - stroke->attr.style,
> - !!(stroke->attr.flags& SPICE_LINE_FLAGS_START_WITH_GAP));
> - hpen = ExtCreatePen(PS_COSMETIC | PS_USERSTYLE,
> - 1,
> -&logbrush, stroke->attr.style_nseg, (DWORD *)user_style);
> - } else {
> - hpen = ExtCreatePen(PS_COSMETIC,
> - 1,
> -&logbrush, 0, NULL);
> - }
> - prev_hpen = (HPEN)SelectObject(canvas->dc, hpen);
> -
> - set_path(canvas, stroke->path);
> -
> - StrokePath(canvas->dc);
> -
> - SelectObject(canvas->dc, prev_hpen);
> - DeleteObject(hpen);
> -
> -#if 0
> - if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
> - GlobalFree((HGLOBAL)logbrush.lbHatch);
> - }
> -#endif
> -
> - if (user_style) {
> - free(user_style);
> - }
> -}
> -
> -static void gdi_canvas_clear(SpiceCanvas *spice_canvas)
> -{
> -}
> -
> -static void gdi_canvas_destroy(SpiceCanvas *spice_canvas)
> -{
> - GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
> - if (!canvas) {
> - return;
> - }
> - canvas_base_destroy(&canvas->base);
> - free(canvas);
> -}
> -
> -static int need_init = 1;
> -static SpiceCanvasOps gdi_canvas_ops;
> -
> -SpiceCanvas *gdi_canvas_create(int width, int height,
> - HDC dc, RecurciveMutex* lock, uint32_t format
> -#ifdef SW_CANVAS_CACHE
> - , SpiceImageCache *bits_cache
> - , SpicePaletteCache *palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , SpiceImageCache *bits_cache
> -#endif
> - , SpiceImageSurfaces *surfaces
> - , SpiceGlzDecoder *glz_decoder
> - , SpiceJpegDecoder *jpeg_decoder
> - , SpiceZlibDecoder *zlib_decoder
> - )
> -{
> - GdiCanvas *canvas;
> - int init_ok;
> -
> - if (need_init) {
> - return NULL;
> - }
> - canvas = spice_new0(GdiCanvas, 1);
> - init_ok = canvas_base_init(&canvas->base,&gdi_canvas_ops,
> - width, height, format
> -#ifdef SW_CANVAS_CACHE
> - ,bits_cache
> - ,palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , bits_cache
> -#endif
> - , surfaces
> - , glz_decoder
> - , jpeg_decoder
> - , zlib_decoder);
> - canvas->dc = dc;
> - canvas->lock = lock;
> - return (SpiceCanvas *)canvas;
> -}
> -
> -void gdi_canvas_init() //unsafe global function
> -{
> - if (!need_init) {
> - return;
> - }
> - need_init = 0;
> -
> - canvas_base_init_ops(&gdi_canvas_ops);
> - gdi_canvas_ops.draw_fill = gdi_canvas_draw_fill;
> - gdi_canvas_ops.draw_copy = gdi_canvas_draw_copy;
> - gdi_canvas_ops.draw_opaque = gdi_canvas_draw_opaque;
> - gdi_canvas_ops.copy_bits = gdi_canvas_copy_bits;
> - gdi_canvas_ops.draw_text = gdi_canvas_draw_text;
> - gdi_canvas_ops.draw_stroke = gdi_canvas_draw_stroke;
> - gdi_canvas_ops.draw_rop3 = gdi_canvas_draw_rop3;
> - gdi_canvas_ops.draw_blend = gdi_canvas_draw_blend;
> - gdi_canvas_ops.draw_blackness = gdi_canvas_draw_blackness;
> - gdi_canvas_ops.draw_whiteness = gdi_canvas_draw_whiteness;
> - gdi_canvas_ops.draw_invers = gdi_canvas_draw_invers;
> - gdi_canvas_ops.draw_transparent = gdi_canvas_draw_transparent;
> - gdi_canvas_ops.draw_alpha_blend = gdi_canvas_draw_alpha_blend;
> - gdi_canvas_ops.put_image = gdi_canvas_put_image;
> - gdi_canvas_ops.clear = gdi_canvas_clear;
> - gdi_canvas_ops.destroy = gdi_canvas_destroy;
> -
> - rop3_init();
> -}
> -
> diff --git a/common/gdi_canvas.h b/common/gdi_canvas.h
> deleted file mode 100644
> index b3d4b15..0000000
> --- a/common/gdi_canvas.h
> +++ /dev/null
> @@ -1,39 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H__GDI_CANVAS
> -#define _H__GDI_CANVAS
> -
> -#include<stdint.h>
> -
> -#include "pixman_utils.h"
> -#include "canvas_base.h"
> -#include "region.h"
> -
> -SpiceCanvas *gdi_canvas_create(int width, int height,
> - HDC dc, class RecurciveMutex *lock, uint32_t format,
> - SpiceImageCache *bits_cache,
> - SpicePaletteCache *palette_cache,
> - SpiceImageSurfaces *surfaces,
> - SpiceGlzDecoder *glz_decoder,
> - SpiceJpegDecoder *jpeg_decoder,
> - SpiceZlibDecoder *zlib_decoder);
> -
> -void gdi_canvas_init();
> -
> -#endif
> diff --git a/common/gl_canvas.c b/common/gl_canvas.c
> deleted file mode 100644
> index 9baf7e8..0000000
> --- a/common/gl_canvas.c
> +++ /dev/null
> @@ -1,909 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include<stdio.h>
> -#include<stdlib.h>
> -#include<string.h>
> -
> -#include "gl_canvas.h"
> -#include "quic.h"
> -#include "rop3.h"
> -#include "region.h"
> -
> -#define GL_CANVAS
> -#include "canvas_base.c"
> -
> -typedef struct GLCanvas GLCanvas;
> -
> -struct GLCanvas {
> - CanvasBase base;
> - GLCCtx glc;
> - void *private_data;
> - int private_data_size;
> - int textures_lost;
> -};
> -
> -static inline uint8_t *copy_opposite_image(GLCanvas *canvas, void *data, int stride, int height)
> -{
> - uint8_t *ret_data = (uint8_t *)data;
> - uint8_t *dest;
> - uint8_t *src;
> - int i;
> -
> - if (!canvas->private_data) {
> - canvas->private_data = spice_malloc_n(height, stride);
> - if (!canvas->private_data) {
> - return ret_data;
> - }
> - canvas->private_data_size = stride * height;
> - }
> -
> - if (canvas->private_data_size< (stride * height)) {
> - free(canvas->private_data);
> - canvas->private_data = spice_malloc_n(height, stride);
> - if (!canvas->private_data) {
> - return ret_data;
> - }
> - canvas->private_data_size = stride * height;
> - }
> -
> - dest = (uint8_t *)canvas->private_data;
> - src = (uint8_t *)data + (height - 1) * stride;
> -
> - for (i = 0; i< height; ++i) {
> - memcpy(dest, src, stride);
> - dest += stride;
> - src -= stride;
> - }
> - return (uint8_t *)canvas->private_data;
> -}
> -
> -static pixman_image_t *canvas_surf_to_trans_surf(GLCImage *image,
> - uint32_t trans_color)
> -{
> - int width = image->width;
> - int height = image->height;
> - uint8_t *src_line;
> - uint8_t *end_src_line;
> - int src_stride;
> - uint8_t *dest_line;
> - int dest_stride;
> - pixman_image_t *ret;
> - int i;
> -
> - ret = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, NULL, 0);
> - if (ret == NULL) {
> - spice_critical("create surface failed");
> - return NULL;
> - }
> -
> - src_line = image->pixels;
> - src_stride = image->stride;
> - end_src_line = src_line + src_stride * height;
> -
> - dest_line = (uint8_t *)pixman_image_get_data(ret);
> - dest_stride = pixman_image_get_stride(ret);
> -
> - for (; src_line< end_src_line; src_line += src_stride, dest_line += dest_stride) {
> - for (i = 0; i< width; i++) {
> - if ((((uint32_t*)src_line)[i]& 0x00ffffff) == trans_color) {
> - ((uint32_t*)dest_line)[i] = 0;
> - } else {
> - ((uint32_t*)dest_line)[i] = (((uint32_t*)src_line)[i]) | 0xff000000;
> - }
> - }
> - }
> -
> - return ret;
> -}
> -
> -static GLCPath get_path(GLCanvas *canvas, SpicePath *s)
> -{
> - GLCPath path = glc_path_create(canvas->glc);
> - int i;
> -
> - for (i = 0; i< s->num_segments; i++) {
> - SpicePathSeg* seg = s->segments[i];
> - SpicePointFix* point = seg->points;
> - SpicePointFix* end_point = point + seg->count;
> -
> - if (seg->flags& SPICE_PATH_BEGIN) {
> - glc_path_move_to(path, fix_to_double(point->x), fix_to_double(point->y));
> - point++;
> - }
> -
> - if (seg->flags& SPICE_PATH_BEZIER) {
> - spice_return_val_if_fail((point - end_point) % 3 == 0, path);
> - for (; point + 2< end_point; point += 3) {
> - glc_path_curve_to(path,
> - fix_to_double(point[0].x), fix_to_double(point[0].y),
> - fix_to_double(point[1].x), fix_to_double(point[1].y),
> - fix_to_double(point[2].x), fix_to_double(point[2].y));
> - }
> - } else {
> - for (; point< end_point; point++) {
> - glc_path_line_to(path, fix_to_double(point->x), fix_to_double(point->y));
> - }
> - }
> - if (seg->flags& SPICE_PATH_END) {
> - if (seg->flags& SPICE_PATH_CLOSE) {
> - glc_path_close(path);
> - }
> - }
> - }
> -
> - return path;
> -}
> -
> -#define SET_GLC_RECT(dest, src) { \
> - (dest)->x = (src)->left; \
> - (dest)->y = (src)->top; \
> - (dest)->width = (src)->right - (src)->left; \
> - (dest)->height = (src)->bottom - (src)->top; \
> -}
> -
> -#define SET_GLC_BOX(dest, src) { \
> - (dest)->x = (src)->x1; \
> - (dest)->y = (src)->y1; \
> - (dest)->width = (src)->x2 - (src)->x1; \
> - (dest)->height = (src)->y2 - (src)->y1; \
> -}
> -
> -static void set_clip(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip)
> -{
> - GLCRect rect;
> - glc_clip_reset(canvas->glc);
> -
> - switch (clip->type) {
> - case SPICE_CLIP_TYPE_NONE:
> - break;
> - case SPICE_CLIP_TYPE_RECTS: {
> - uint32_t n = clip->rects->num_rects;
> - SpiceRect *now = clip->rects->rects;
> - SpiceRect *end = now + n;
> -
> - if (n == 0) {
> - rect.x = rect.y = 0;
> - rect.width = rect.height = 0;
> - glc_clip_rect(canvas->glc,&rect, GLC_CLIP_OP_SET);
> - break;
> - } else {
> - SET_GLC_RECT(&rect, now);
> - glc_clip_rect(canvas->glc,&rect, GLC_CLIP_OP_SET);
> - }
> -
> - for (now++; now< end; now++) {
> - SET_GLC_RECT(&rect, now);
> - glc_clip_rect(canvas->glc,&rect, GLC_CLIP_OP_OR);
> - }
> - break;
> - }
> - default:
> - spice_warn_if_reached();
> - return;
> - }
> -}
> -
> -static void set_mask(GLCanvas *canvas, SpiceQMask *mask, int x, int y)
> -{
> - pixman_image_t *image;
> -
> - if (!(image = canvas_get_mask(&canvas->base, mask, NULL))) {
> - glc_clear_mask(canvas->glc, GLC_MASK_A);
> - return;
> - }
> -
> -
> - glc_set_mask(canvas->glc, x - mask->pos.x, y - mask->pos.y,
> - pixman_image_get_width(image),
> - pixman_image_get_height(image),
> - pixman_image_get_stride(image),
> - (uint8_t *)pixman_image_get_data(image), GLC_MASK_A);
> -}
> -
> -static inline void surface_to_image(GLCanvas *canvas, pixman_image_t *surface, GLCImage *image,
> - int ignore_stride)
> -{
> - int depth = pixman_image_get_depth(surface);
> -
> - spice_return_if_fail(depth == 32 || depth == 24);
> - image->format = (depth == 24) ? GLC_IMAGE_RGB32 : GLC_IMAGE_ARGB32;
> - image->width = pixman_image_get_width(surface);
> - image->height = pixman_image_get_height(surface);
> - image->stride = pixman_image_get_stride(surface);
> - image->pixels = (uint8_t *)pixman_image_get_data(surface);
> - image->pallet = NULL;
> - if (ignore_stride) {
> - return;
> - }
> - if (image->stride< 0) {
> - image->stride = -image->stride;
> - image->pixels = image->pixels - (image->height - 1) * image->stride;
> - } else {
> - image->pixels = copy_opposite_image(canvas, image->pixels, image->stride, image->height);
> - }
> -}
> -
> -static void set_brush(GLCanvas *canvas, SpiceBrush *brush)
> -{
> - switch (brush->type) {
> - case SPICE_BRUSH_TYPE_SOLID: {
> - uint32_t color = brush->u.color;
> - double r, g, b;
> -
> - b = (double)(color& canvas->base.color_mask) / canvas->base.color_mask;
> - color>>= canvas->base.color_shift;
> - g = (double)(color& canvas->base.color_mask) / canvas->base.color_mask;
> - color>>= canvas->base.color_shift;
> - r = (double)(color& canvas->base.color_mask) / canvas->base.color_mask;
> - glc_set_rgb(canvas->glc, r, g, b);
> - break;
> - }
> - case SPICE_BRUSH_TYPE_PATTERN: {
> - GLCImage image;
> - GLCPattern pattern;
> - pixman_image_t *surface;
> -
> - surface = canvas_get_image(&canvas->base, brush->u.pattern.pat, FALSE);
> - surface_to_image(canvas, surface,&image, 0);
> -
> - pattern = glc_pattern_create(canvas->glc, -brush->u.pattern.pos.x,
> - -brush->u.pattern.pos.y,&image);
> -
> - glc_set_pattern(canvas->glc, pattern);
> - glc_pattern_destroy(pattern);
> - pixman_image_unref (surface);
> - }
> - case SPICE_BRUSH_TYPE_NONE:
> - return;
> - default:
> - spice_warn_if_reached();
> - return;
> - }
> -}
> -
> -static void set_op(GLCanvas *canvas, uint16_t rop_decriptor)
> -{
> - GLCOp op;
> -
> - switch (rop_decriptor) {
> - case SPICE_ROPD_OP_PUT:
> - op = GLC_OP_COPY;
> - break;
> - case SPICE_ROPD_OP_XOR:
> - op = GLC_OP_XOR;
> - break;
> - case SPICE_ROPD_OP_BLACKNESS:
> - op = GLC_OP_CLEAR;
> - break;
> - case SPICE_ROPD_OP_WHITENESS:
> - op = GLC_OP_SET;
> - break;
> - case SPICE_ROPD_OP_PUT | SPICE_ROPD_INVERS_BRUSH:
> - case SPICE_ROPD_OP_PUT | SPICE_ROPD_INVERS_SRC:
> - op = GLC_OP_COPY_INVERTED;
> - break;
> - case SPICE_ROPD_OP_INVERS:
> - op = GLC_OP_INVERT;
> - break;
> - case SPICE_ROPD_OP_AND:
> - op = GLC_OP_AND;
> - break;
> - case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_RES:
> - op = GLC_OP_NAND;
> - break;
> - case SPICE_ROPD_OP_OR:
> - op = GLC_OP_OR;
> - break;
> - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_RES:
> - op = GLC_OP_NOR;
> - break;
> - case SPICE_ROPD_OP_XOR | SPICE_ROPD_INVERS_RES:
> - op = GLC_OP_EQUIV;
> - break;
> - case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_DEST:
> - op = GLC_OP_AND_REVERSE;
> - break;
> - case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_BRUSH:
> - case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_SRC:
> - op = GLC_OP_AND_INVERTED;
> - break;
> - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_DEST:
> - op = GLC_OP_OR_REVERSE;
> - break;
> - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_BRUSH:
> - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_SRC:
> - op = GLC_OP_OR_INVERTED;
> - break;
> - default:
> - spice_warning("GLC_OP_NOOP");
> - op = GLC_OP_NOOP;
> - }
> - glc_set_op(canvas->glc, op);
> -}
> -
> -static void gl_canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - GLCRect rect;
> - set_clip(canvas, bbox, clip);
> - set_mask(canvas,&fill->mask, bbox->left, bbox->top);
> - set_brush(canvas,&fill->brush);
> - set_op(canvas, fill->rop_descriptor);
> - SET_GLC_RECT(&rect, bbox);
> -
> - glc_fill_rect(canvas->glc,&rect);
> - glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - pixman_image_t *surface;
> - GLCRecti src;
> - GLCRecti dest;
> - GLCImage image;
> -
> - set_clip(canvas, bbox, clip);
> - set_mask(canvas,©->mask, bbox->left, bbox->top);
> - set_op(canvas, copy->rop_descriptor);
> -
> - //todo: optimize get_image (use ogl conversion + remove unnecessary copy of 32bpp)
> - surface = canvas_get_image(&canvas->base, copy->src_bitmap, FALSE);
> - surface_to_image(canvas, surface,&image, 0);
> - SET_GLC_RECT(&dest, bbox);
> - SET_GLC_RECT(&src,©->src_area);
> - glc_draw_image(canvas->glc,&dest,&src,&image, 0, 1);
> -
> - pixman_image_unref(surface);
> - glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - pixman_image_t *surface;
> - GLCRecti src;
> - GLCRecti dest;
> - GLCRect fill_rect;
> - GLCImage image;
> -
> - set_clip(canvas, bbox, clip);
> - set_mask(canvas,&opaque->mask, bbox->left, bbox->top);
> -
> - glc_set_op(canvas->glc, (opaque->rop_descriptor& SPICE_ROPD_INVERS_SRC) ? GLC_OP_COPY_INVERTED :
> - GLC_OP_COPY);
> - surface = canvas_get_image(&canvas->base, opaque->src_bitmap, FALSE);
> - surface_to_image(canvas, surface,&image, 0);
> - SET_GLC_RECT(&dest, bbox);
> - SET_GLC_RECT(&src,&opaque->src_area);
> - glc_draw_image(canvas->glc,&dest,&src,&image, 0, 1);
> - pixman_image_unref(surface);
> -
> - set_brush(canvas,&opaque->brush);
> - set_op(canvas, opaque->rop_descriptor& ~SPICE_ROPD_INVERS_SRC);
> - SET_GLC_RECT(&fill_rect, bbox);
> - glc_fill_rect(canvas->glc,&fill_rect);
> -
> - glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend *alpha_blend)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - pixman_image_t *surface;
> - GLCRecti src;
> - GLCRecti dest;
> - GLCImage image;
> -
> - set_clip(canvas, bbox, clip);
> - glc_clear_mask(canvas->glc, GLC_MASK_A);
> - glc_set_op(canvas->glc, GLC_OP_COPY);
> -
> - surface = canvas_get_image(&canvas->base, alpha_blend->src_bitmap, FALSE);
> - surface_to_image(canvas, surface,&image, 0);
> - SET_GLC_RECT(&dest, bbox);
> - SET_GLC_RECT(&src,&alpha_blend->src_area);
> - glc_draw_image(canvas->glc,&dest,&src,&image, 0, (double)alpha_blend->alpha / 0xff);
> -
> - pixman_image_unref(surface);
> - glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - pixman_image_t *surface;
> - GLCRecti src;
> - GLCRecti dest;
> - GLCImage image;
> -
> - set_clip(canvas, bbox, clip);
> - set_mask(canvas,&blend->mask, bbox->left, bbox->top);
> - set_op(canvas, blend->rop_descriptor);
> -
> - surface = canvas_get_image(&canvas->base, blend->src_bitmap, FALSE);
> - SET_GLC_RECT(&dest, bbox);
> - SET_GLC_RECT(&src,&blend->src_area);
> - surface_to_image(canvas, surface,&image, 0);
> - glc_draw_image(canvas->glc,&dest,&src,&image, 0, 1);
> -
> - pixman_image_unref(surface);
> - glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent *transparent)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - pixman_image_t *surface;
> - pixman_image_t *trans_surf;
> - GLCImage image;
> - GLCRecti src;
> - GLCRecti dest;
> -
> - set_clip(canvas, bbox, clip);
> - glc_clear_mask(canvas->glc, GLC_MASK_A);
> - glc_set_op(canvas->glc, GLC_OP_COPY);
> -
> - surface = canvas_get_image(&canvas->base, transparent->src_bitmap, FALSE);
> - surface_to_image(canvas, surface,&image, 0);
> -
> - trans_surf = canvas_surf_to_trans_surf(&image, transparent->true_color);
> - pixman_image_unref(surface);
> -
> - surface_to_image(canvas, trans_surf,&image, 1);
> - SET_GLC_RECT(&dest, bbox);
> - SET_GLC_RECT(&src,&transparent->src_area);
> - glc_draw_image(canvas->glc,&dest,&src,&image, 0, 1);
> -
> - pixman_image_unref(trans_surf);
> - glc_flush(canvas->glc);
> -}
> -
> -static inline void fill_common(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceQMask * mask, GLCOp op)
> -{
> - GLCRect rect;
> -
> - set_clip(canvas, bbox, clip);
> - set_mask(canvas, mask, bbox->left, bbox->top);
> - glc_set_op(canvas->glc, op);
> - SET_GLC_RECT(&rect, bbox);
> - glc_fill_rect(canvas->glc,&rect);
> -}
> -
> -static void gl_canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - fill_common(canvas, bbox, clip,&whiteness->mask, GLC_OP_SET);
> -}
> -
> -static void gl_canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - fill_common(canvas, bbox, clip,&blackness->mask, GLC_OP_CLEAR);
> -}
> -
> -static void gl_canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - fill_common(canvas, bbox, clip,&invers->mask, GLC_OP_INVERT);
> -}
> -
> -static void gl_canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - pixman_image_t *d;
> - pixman_image_t *s;
> - GLCImage image;
> - SpicePoint src_pos;
> - uint8_t *data_opp;
> - int src_stride;
> -
> - set_clip(canvas, bbox, clip);
> - set_mask(canvas,&rop3->mask, bbox->left, bbox->top);
> -
> - glc_set_op(canvas->glc, GLC_OP_COPY);
> -
> - image.format = GLC_IMAGE_RGB32;
> - image.width = bbox->right - bbox->left;
> - image.height = bbox->bottom - bbox->top;
> -
> - image.pallet = NULL;
> -
> - d = pixman_image_create_bits(PIXMAN_x8r8g8b8, image.width, image.height, NULL, 0);
> - if (d == NULL) {
> - spice_critical("create surface failed");
> - return;
> - }
> - image.pixels = (uint8_t *)pixman_image_get_data(d);
> - image.stride = pixman_image_get_stride(d);
> -
> - glc_read_pixels(canvas->glc, bbox->left, bbox->top,&image);
> - data_opp = copy_opposite_image(canvas, image.pixels,
> - image.stride,
> - pixman_image_get_height(d));
> - memcpy(image.pixels, data_opp,
> - image.stride * pixman_image_get_height(d));
> -
> - s = canvas_get_image(&canvas->base, rop3->src_bitmap, FALSE);
> - src_stride = pixman_image_get_stride(s);
> - if (src_stride> 0) {
> - data_opp = copy_opposite_image(canvas, (uint8_t *)pixman_image_get_data(s),
> - src_stride, pixman_image_get_height(s));
> - memcpy((uint8_t *)pixman_image_get_data(s), data_opp,
> - src_stride * pixman_image_get_height(s));
> - }
> -
> - if (!rect_is_same_size(bbox,&rop3->src_area)) {
> - pixman_image_t *scaled_s = canvas_scale_surface(s,&rop3->src_area, image.width,
> - image.height, rop3->scale_mode);
> - pixman_image_unref(s);
> - s = scaled_s;
> - src_pos.x = 0;
> - src_pos.y = 0;
> - } else {
> - src_pos.x = rop3->src_area.left;
> - src_pos.y = rop3->src_area.top;
> - }
> -
> - if (pixman_image_get_width(s) - src_pos.x< image.width ||
> - pixman_image_get_height(s) - src_pos.y< image.height) {
> - spice_critical("bad src bitmap size");
> - return;
> - }
> -
> - if (rop3->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
> - pixman_image_t *p = canvas_get_image(&canvas->base, rop3->brush.u.pattern.pat, FALSE);
> - SpicePoint pat_pos;
> -
> - pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % pixman_image_get_width(p);
> -
> - pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % pixman_image_get_height(p);
> -
> - //for now (bottom-top)
> - if (pat_pos.y< 0) {
> - pat_pos.y = pixman_image_get_height(p) + pat_pos.y;
> - }
> - pat_pos.y = (image.height + pat_pos.y) % pixman_image_get_height(p);
> - pat_pos.y = pixman_image_get_height(p) - pat_pos.y;
> -
> - do_rop3_with_pattern(rop3->rop3, d, s,&src_pos, p,&pat_pos);
> - pixman_image_unref(p);
> - } else {
> - uint32_t color = (canvas->base.color_shift) == 8 ? rop3->brush.u.color :
> - canvas_16bpp_to_32bpp(rop3->brush.u.color);
> - do_rop3_with_color(rop3->rop3, d, s,&src_pos, color);
> - }
> -
> - pixman_image_unref(s);
> -
> - GLCRecti dest;
> - GLCRecti src;
> - dest.x = bbox->left;
> - dest.y = bbox->top;
> -
> - image.pixels = copy_opposite_image(canvas, image.pixels, pixman_image_get_stride(d),
> - pixman_image_get_height(d));
> -
> - src.x = src.y = 0;
> - dest.width = src.width = image.width;
> - dest.height = src.height = image.height;
> - glc_draw_image(canvas->glc,&dest,&src,&image, 0, 1);
> - pixman_image_unref(d);
> -}
> -
> -static void gl_canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - GLCPath path;
> -
> - set_clip(canvas, bbox, clip);
> - glc_clear_mask(canvas->glc, GLC_MASK_A);
> - set_op(canvas, stroke->fore_mode);
> - set_brush(canvas,&stroke->brush);
> -
> - if (stroke->attr.flags& SPICE_LINE_FLAGS_STYLED) {
> - spice_warning("SPICE_LINE_FLAGS_STYLED");
> - }
> - glc_set_line_width(canvas->glc, 1.0);
> -
> - path = get_path(canvas, stroke->path);
> - glc_stroke_path(canvas->glc, path);
> - glc_path_destroy(path);
> -}
> -
> -static void gl_canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - GLCRect rect;
> - SpiceString *str;
> -
> - set_clip(canvas, bbox, clip);
> - glc_clear_mask(canvas->glc, GLC_MASK_A);
> -
> - if (!rect_is_empty(&text->back_area)) {
> - set_brush(canvas,&text->back_brush);
> - set_op(canvas, text->back_mode);
> - SET_GLC_RECT(&rect, bbox);
> - glc_fill_rect(canvas->glc,&rect);
> - }
> -
> - str = (SpiceString *)SPICE_GET_ADDRESS(text->str);
> - set_brush(canvas,&text->fore_brush);
> - set_op(canvas, text->fore_mode);
> - if (str->flags& SPICE_STRING_FLAGS_RASTER_A1) {
> - SpicePoint pos;
> - pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 1,&pos);
> - _glc_fill_mask(canvas->glc, pos.x, pos.y,
> - pixman_image_get_width(mask),
> - pixman_image_get_height(mask),
> - pixman_image_get_stride(mask),
> - (uint8_t *)pixman_image_get_data(mask));
> - pixman_image_unref(mask);
> - } else if (str->flags& SPICE_STRING_FLAGS_RASTER_A4) {
> - SpicePoint pos;
> - pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 4,&pos);
> - glc_fill_alpha(canvas->glc, pos.x, pos.y,
> - pixman_image_get_width(mask),
> - pixman_image_get_height(mask),
> - pixman_image_get_stride(mask),
> - (uint8_t *)pixman_image_get_data(mask));
> -
> - pixman_image_unref(mask);
> - } else if (str->flags& SPICE_STRING_FLAGS_RASTER_A8) {
> - spice_warning("untested path A8 glyphs, doing nothing");
> - if (0) {
> - SpicePoint pos;
> - pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 8,&pos);
> - glc_fill_alpha(canvas->glc, pos.x, pos.y,
> - pixman_image_get_width(mask),
> - pixman_image_get_height(mask),
> - pixman_image_get_stride(mask),
> - (uint8_t *)pixman_image_get_data(mask));
> - pixman_image_unref(mask);
> - }
> - } else {
> - spice_warning("untested path vector glyphs, doing nothing");
> - if (0) {
> - //draw_vector_str(canvas, str,&text->fore_brush, text->fore_mode);
> - }
> - }
> - glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_clear(SpiceCanvas *spice_canvas)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - glc_clear(canvas->glc);
> - glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - set_clip(canvas, bbox, clip);
> - glc_clear_mask(canvas->glc, GLC_MASK_A);
> - glc_set_op(canvas->glc, GLC_OP_COPY);
> - glc_copy_pixels(canvas->glc, bbox->left, bbox->top, src_pos->x, src_pos->y,
> - bbox->right - bbox->left, bbox->bottom - bbox->top);
> -}
> -
> -static void gl_canvas_read_bits(SpiceCanvas *spice_canvas, uint8_t *dest, int dest_stride, const SpiceRect *area)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - GLCImage image;
> -
> - spice_return_if_fail(dest_stride> 0);
> -
> - image.format = GLC_IMAGE_RGB32;
> - image.height = area->bottom - area->top;
> - image.width = area->right - area->left;
> - image.pixels = dest;
> - image.stride = dest_stride;
> - glc_read_pixels(canvas->glc, area->left, area->top,&image);
> -}
> -
> -static void gl_canvas_group_start(SpiceCanvas *spice_canvas, QRegion *region)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - GLCRect *glc_rects;
> - GLCRect *now, *end;
> - int num_rect;
> - pixman_box32_t *rects;
> -
> - canvas_base_group_start(spice_canvas, region);
> -
> - rects = pixman_region32_rectangles(region,&num_rect);
> -
> - glc_rects = spice_new(GLCRect, num_rect);
> - now = glc_rects;
> - end = glc_rects + num_rect;
> -
> - for (; now< end; now++, rects++) {
> - SET_GLC_BOX(now, rects);
> - }
> - glc_mask_rects(canvas->glc, num_rect, glc_rects, GLC_MASK_B);
> -
> - free(glc_rects);
> -}
> -
> -static void gl_canvas_put_image(SpiceCanvas *spice_canvas, const SpiceRect *dest, const uint8_t *src_data,
> - uint32_t src_width, uint32_t src_height, int src_stride,
> - const QRegion *clip)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> - GLCRecti src;
> - GLCRecti gldest;
> - GLCImage image;
> - uint32_t i;
> -
> - spice_return_if_fail(src_stride<= 0)
> -
> - glc_clip_reset(canvas->glc);
> -
> - if (clip) {
> - int num_rects;
> - pixman_box32_t *rects = pixman_region32_rectangles((pixman_region32_t *)clip,
> -&num_rects);
> - GLCRect rect;
> - if (num_rects == 0) {
> - rect.x = rect.y = rect.width = rect.height = 0;
> - glc_clip_rect(canvas->glc,&rect, GLC_CLIP_OP_SET);
> - } else {
> - SET_GLC_BOX(&rect, rects);
> - glc_clip_rect(canvas->glc,&rect, GLC_CLIP_OP_SET);
> - for (i = 1; i< num_rects; i++) {
> - SET_GLC_BOX(&rect, rects + i);
> - glc_clip_rect(canvas->glc,&rect, GLC_CLIP_OP_OR);
> - }
> - }
> - }
> -
> - SET_GLC_RECT(&gldest, dest);
> - src.x = src.y = 0;
> - src.width = src_width;
> - src.height = src_height;
> -
> - image.format = GLC_IMAGE_RGB32;
> - image.width = src_width;
> - image.height = src_height;
> - src_stride = -src_stride;
> - image.stride = src_stride;
> - image.pixels = (uint8_t *)src_data - (src_height - 1) * src_stride;
> - image.pallet = NULL;
> - glc_draw_image(canvas->glc,&gldest,&src,&image, 0, 1);
> -
> - glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_group_end(SpiceCanvas *spice_canvas)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -
> - canvas_base_group_end(spice_canvas);
> - glc_clear_mask(canvas->glc, GLC_MASK_B);
> -}
> -
> -static int need_init = 1;
> -static SpiceCanvasOps gl_canvas_ops;
> -
> -SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format
> -#ifdef SW_CANVAS_CACHE
> - , SpiceImageCache *bits_cache
> - , SpicePaletteCache *palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , SpiceImageCache *bits_cache
> -#endif
> - , SpiceImageSurfaces *surfaces
> - , SpiceGlzDecoder *glz_decoder
> - , SpiceJpegDecoder *jpeg_decoder
> - , SpiceZlibDecoder *zlib_decoder
> - )
> -{
> - GLCanvas *canvas;
> - int init_ok;
> -
> - if (need_init) {
> - return NULL;
> - }
> - canvas = spice_new0(GLCanvas, 1);
> -
> - if (!(canvas->glc = glc_create(width, height))) {
> - goto error_1;
> - }
> - canvas->private_data = NULL;
> - init_ok = canvas_base_init(&canvas->base,&gl_canvas_ops,
> - width, height, format
> -#ifdef SW_CANVAS_CACHE
> - , bits_cache
> - , palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , bits_cache
> -#endif
> - , surfaces
> - , glz_decoder
> - , jpeg_decoder
> - , zlib_decoder
> - );
> - if (!init_ok) {
> - goto error_2;
> - }
> -
> - return (SpiceCanvas *)canvas;
> -
> -error_2:
> - glc_destroy(canvas->glc, 0);
> -error_1:
> - free(canvas);
> -
> - return NULL;
> -}
> -
> -void gl_canvas_set_textures_lost(SpiceCanvas *spice_canvas,
> - int textures_lost)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -
> - canvas->textures_lost = textures_lost;
> -}
> -
> -static void gl_canvas_destroy(SpiceCanvas *spice_canvas)
> -{
> - GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -
> - if (!canvas) {
> - return;
> - }
> - canvas_base_destroy(&canvas->base);
> - glc_destroy(canvas->glc, canvas->textures_lost);
> - if (canvas->private_data) {
> - free(canvas->private_data);
> - }
> - free(canvas);
> -}
> -
> -void gl_canvas_init() //unsafe global function
> -{
> - if (!need_init) {
> - return;
> - }
> - need_init = 0;
> -
> - canvas_base_init_ops(&gl_canvas_ops);
> - gl_canvas_ops.draw_fill = gl_canvas_draw_fill;
> - gl_canvas_ops.draw_copy = gl_canvas_draw_copy;
> - gl_canvas_ops.draw_opaque = gl_canvas_draw_opaque;
> - gl_canvas_ops.copy_bits = gl_canvas_copy_bits;
> - gl_canvas_ops.draw_text = gl_canvas_draw_text;
> - gl_canvas_ops.draw_stroke = gl_canvas_draw_stroke;
> - gl_canvas_ops.draw_rop3 = gl_canvas_draw_rop3;
> - gl_canvas_ops.draw_blend = gl_canvas_draw_blend;
> - gl_canvas_ops.draw_blackness = gl_canvas_draw_blackness;
> - gl_canvas_ops.draw_whiteness = gl_canvas_draw_whiteness;
> - gl_canvas_ops.draw_invers = gl_canvas_draw_invers;
> - gl_canvas_ops.draw_transparent = gl_canvas_draw_transparent;
> - gl_canvas_ops.draw_alpha_blend = gl_canvas_draw_alpha_blend;
> - gl_canvas_ops.put_image = gl_canvas_put_image;
> - gl_canvas_ops.clear = gl_canvas_clear;
> - gl_canvas_ops.read_bits = gl_canvas_read_bits;
> - gl_canvas_ops.group_start = gl_canvas_group_start;
> - gl_canvas_ops.group_end = gl_canvas_group_end;
> - gl_canvas_ops.destroy = gl_canvas_destroy;
> -
> - rop3_init();
> -}
> diff --git a/common/gl_canvas.h b/common/gl_canvas.h
> deleted file mode 100644
> index d7125e6..0000000
> --- a/common/gl_canvas.h
> +++ /dev/null
> @@ -1,37 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include "glc.h"
> -#include "canvas_base.h"
> -#include "region.h"
> -
> -SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format
> -#ifdef SW_CANVAS_CACHE
> - , SpiceImageCache *bits_cache
> - , SpicePaletteCache *palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , SpiceImageCache *bits_cache
> -#endif
> - , SpiceImageSurfaces *surfaces
> - , SpiceGlzDecoder *glz_decoder
> - , SpiceJpegDecoder *jpeg_decoder
> - , SpiceZlibDecoder *zlib_decoder
> - );
> -void gl_canvas_set_textures_lost(SpiceCanvas *canvas, int textures_lost);
> -void gl_canvas_init();
> -
> diff --git a/common/gl_utils.h b/common/gl_utils.h
> deleted file mode 100644
> index eecff26..0000000
> --- a/common/gl_utils.h
> +++ /dev/null
> @@ -1,105 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, write to the Free Software
> -
> - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> -*/
> -
> -#ifndef GL_UTILS_H
> -#define GL_UTILS_H
> -
> -#ifdef RED_DEBUG
> -#define GLC_ERROR_TEST_FLUSH { \
> - GLenum gl_err; glFlush(); \
> - if ((gl_err = glGetError()) != GL_NO_ERROR) { \
> - printf("%s[%d]: opengl error: %s\n", __FUNCTION__, __LINE__, \
> - gluErrorString(gl_err)); \
> - abort(); \
> - } \
> -}
> -
> -#define GLC_ERROR_TEST_FINISH { \
> - GLenum gl_err; glFinish(); \
> - if ((gl_err = glGetError()) != GL_NO_ERROR) { \
> - printf("%s[%d]: opengl error: %s\n", __FUNCTION__, __LINE__, \
> - gluErrorString(gl_err)); \
> - abort(); \
> - } \
> -}
> -#else
> -#define GLC_ERROR_TEST_FLUSH ;
> -
> -#define GLC_ERROR_TEST_FINISH ;
> -#endif
> -
> -#ifdef WIN32
> -static inline int find_msb(uint32_t val)
> -{
> - uint32_t r;
> - __asm {
> - bsr eax, val
> - jnz found
> - mov eax, -1
> -
> -found:
> - mov r, eax
> - }
> - return r + 1;
> -}
> -
> -#elif defined(__GNUC__)&& (defined(__i386__) || defined(__x86_64__))
> -static inline int find_msb(unsigned int val)
> -{
> - int ret;
> -
> - asm ("bsrl %1,%0\n\t"
> - "jnz 1f\n\t"
> - "movl $-1,%0\n"
> - "1:"
> - : "=r"(ret) : "r"(val));
> - return ret + 1;
> -}
> -
> -#else
> -static inline int find_msb(unsigned int val)
> -{
> - signed char index = 31;
> -
> - if(val == 0) {
> - return 0;
> - }
> -
> - do {
> - if(val& 0x80000000) {
> - break;
> - }
> - val<<= 1;
> - } while(--index>= 0);
> -
> - return index+1;
> -}
> -
> -#endif
> -
> -static inline int gl_get_to_power_two(unsigned int val)
> -{
> - if ((val& (val - 1)) == 0) {
> - return val;
> - }
> - return 1<< find_msb(val);
> -}
> -
> -#endif
> diff --git a/common/glc.c b/common/glc.c
> deleted file mode 100644
> index e4263cd..0000000
> --- a/common/glc.c
> +++ /dev/null
> @@ -1,1521 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, write to the Free Software
> -
> - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> -*/
> -
> -#include<stdlib.h>
> -#include<string.h>
> -#include<stdio.h>
> -#include<math.h>
> -#include<spice/macros.h>
> -
> -#include<GL/gl.h>
> -#include<GL/glu.h>
> -#include<GL/glext.h>
> -
> -#ifdef WIN32
> -#include "glext.h"
> -#include "wglext.h"
> -#endif
> -
> -#include "mem.h"
> -#include "glc.h"
> -#include "gl_utils.h"
> -
> -#define ASSERT(x) if (!(x)) {printf("%s: assert failed %s\n", __FUNCTION__, #x); abort();}
> -
> -#define WARN_ONCE(x) { \
> - static int warn = TRUE; \
> - if (warn) { \
> - printf x; \
> - warn = FALSE; \
> - } \
> -}
> -
> -#define TESS_VERTEX_ALLOC_BUNCH 20
> -
> -typedef struct InternaCtx InternaCtx;
> -typedef struct InternalPat {
> - InternaCtx *owner;
> - int refs;
> - GLuint texture;
> - int x_orign;
> - int y_orign;
> - int width;
> - int height;
> -} InternalPat;
> -
> -typedef struct Pathpath {
> - int start_point;
> - int num_segments;
> -} Path;
> -
> -enum {
> - GLC_PATH_SEG_LINES,
> - GLC_PATH_SEG_BEIZER,
> -};
> -
> -//todo: flatten cache
> -typedef struct PathSegment {
> - int type;
> - int count;
> -} PathSegment;
> -
> -typedef struct PathPoint {
> - double x;
> - double y;
> - double z;
> -} PathPoint;
> -
> -typedef GLdouble Vertex[3];
> -
> -typedef struct InternalPath {
> - InternaCtx *owner;
> -
> - Path *paths;
> - int paths_size;
> - int paths_pos;
> -
> - PathSegment *segments;
> - int segments_size;
> - int segments_pos;
> -
> - PathPoint *points;
> - int points_size;
> - int points_pos;
> -
> - Path *current_path;
> - PathSegment *current_segment;
> -} InternalPath;
> -
> -typedef struct TassVertex TassVertex;
> -struct TassVertex {
> - PathPoint point;
> - TassVertex *list_link;
> - TassVertex *next;
> -};
> -
> -typedef struct TassVertexBuf TassVertexBuf;
> -struct TassVertexBuf {
> - TassVertexBuf *next;
> - TassVertex vertexs[0];
> -};
> -
> -#define USE_LINE_ANTIALIAS 0
> -
> -typedef struct LineDash {
> - double *dashes;
> - int num_dashes;
> - double offset;
> - int cur_dash;
> - double dash_pos;
> -} LineDash;
> -
> -enum {
> - GLC_STROKE_NONACTIVE,
> - GLC_STROKE_FIRST,
> - GLC_STROKE_ACTIVE,
> -};
> -
> -typedef struct PathStroke {
> - double x;
> - double y;
> - int state;
> -} PathStroke;
> -
> -struct InternaCtx {
> - int draw_mode;
> - int stencil_refs;
> - int stencil_mask;
> - int width;
> - int height;
> - GLfloat line_width;
> - LineDash line_dash;
> - PathStroke path_stroke;
> - InternalPat *pat;
> - int max_texture_size;
> - GLUtesselator* tesselator;
> - TassVertex *free_tess_vertex;
> - TassVertex *used_tess_vertex;
> - TassVertexBuf *vertex_bufs;
> - int private_tex_width;
> - int private_tex_height;
> - GLuint private_tex;
> -#ifdef WIN32
> - PFNGLBLENDEQUATIONPROC glBlendEquation;
> -#endif
> -};
> -
> -#define Y(y) -(y)
> -#define VERTEX2(x, y) glVertex2d(x, Y(y))
> -
> -static void fill_rect(InternaCtx *ctx, void *rect);
> -static void fill_path(InternaCtx *ctx, void *path);
> -static void fill_mask(InternaCtx *ctx, int x_dest, int y_dest, int width, int height, int stride,
> - const uint8_t *bitmap);
> -static void set_pat(InternaCtx *ctx, InternalPat *pat);
> -
> -static inline void set_raster_pos(InternaCtx *ctx, int x, int y)
> -{
> - if (x>= 0&& y>= 0&& x< ctx->width&& y< ctx->height) {
> - glRasterPos2i(x, Y(y));
> - return;
> - }
> - glRasterPos2i(0, 0);
> - glBitmap(0, 0, 0, 0, (GLfloat)x, (GLfloat)Y(y), NULL);
> -}
> -
> -static TassVertex *alloc_tess_vertex(InternaCtx *ctx)
> -{
> - TassVertex *vertex;
> -
> - if (!ctx->free_tess_vertex) {
> - TassVertexBuf *buf;
> - int i;
> -
> - buf = (TassVertexBuf *)spice_malloc(sizeof(TassVertexBuf) +
> - sizeof(TassVertex) * TESS_VERTEX_ALLOC_BUNCH);
> - buf->next = ctx->vertex_bufs;
> - ctx->vertex_bufs = buf;
> - for (i = 0; i< TESS_VERTEX_ALLOC_BUNCH; i++) {
> - buf->vertexs[i].point.z = 0;
> - buf->vertexs[i].next = ctx->free_tess_vertex;
> - ctx->free_tess_vertex =&buf->vertexs[i];
> - }
> - }
> -
> - vertex = ctx->free_tess_vertex;
> - ctx->free_tess_vertex = vertex->next;
> - vertex->next = ctx->used_tess_vertex;
> - ctx->used_tess_vertex = vertex;
> - return vertex;
> -}
> -
> -static void reset_tass_vertex(InternaCtx *ctx)
> -{
> - TassVertex *vertex;
> - while ((vertex = ctx->used_tess_vertex)) {
> - ctx->used_tess_vertex = vertex->next;
> - vertex->next = ctx->free_tess_vertex;
> - ctx->free_tess_vertex = vertex;
> - }
> -}
> -
> -static void free_tass_vertex_bufs(InternaCtx *ctx)
> -{
> - TassVertexBuf *buf;
> -
> - ctx->used_tess_vertex = NULL;
> - ctx->free_tess_vertex = NULL;
> - while ((buf = ctx->vertex_bufs)) {
> - ctx->vertex_bufs = buf->next;
> - free(buf);
> - }
> -}
> -
> -//naive bezier flattener
> -static TassVertex *bezier_flattener(InternaCtx *ctx, PathPoint *points)
> -{
> - double ax, bx, cx;
> - double ay, by, cy;
> - const int num_points = 30;
> - double dt;
> - int i;
> -
> - TassVertex *vertex_list = NULL;
> - TassVertex *curr_vertex;
> -
> - for (i = 0; i< num_points - 2; i++) {
> - TassVertex *vertex;
> -
> - vertex = alloc_tess_vertex(ctx);
> - vertex->list_link = vertex_list;
> - vertex_list = vertex;
> - }
> -
> - curr_vertex = vertex_list;
> -
> - cx = 3.0 * (points[1].x - points[0].x);
> - bx = 3.0 * (points[2].x - points[1].x) - cx;
> - ax = points[3].x - points[0].x - cx - bx;
> -
> - cy = 3.0 * (points[1].y - points[0].y);
> - by = 3.0 * (points[2].y - points[1].y) - cy;
> - ay = points[3].y - points[0].y - cy - by;
> -
> - dt = 1.0 / (num_points - 1);
> -
> - for (i = 1; i< num_points - 1; i++, curr_vertex = curr_vertex->list_link) {
> - double tSquared, tCubed;
> - double t;
> - t = i * dt;
> -
> - tSquared = t * t;
> - tCubed = tSquared * t;
> -
> - curr_vertex->point.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + points[0].x;
> - curr_vertex->point.y = (ay * tCubed) + (by * tSquared) + (cy * t) + points[0].y;
> - }
> -
> - return vertex_list;
> -}
> -
> -#define MORE_X(path, Type, name) { \
> - Type *name; \
> - \
> - name = spice_new0(Type, path->name##_size * 2); \
> - memcpy(name, path->name, sizeof(*name) * path->name##_size); \
> - free(path->name); \
> - path->name = name; \
> - path->name##_size *= 2; \
> -}
> -
> -static void more_points(InternalPath *path)
> -{
> - MORE_X(path, PathPoint, points);
> -}
> -
> -static void more_segments(InternalPath *path)
> -{
> - MORE_X(path, PathSegment, segments);
> -}
> -
> -static void more_paths(InternalPath *path)
> -{
> - MORE_X(path, Path, paths);
> -}
> -
> -static inline void put_point(InternalPath *path, double x, double y)
> -{
> - path->points[path->points_pos].x = x;
> - path->points[path->points_pos].y = Y(y + 0.5);
> - path->points[path->points_pos++].z = 0;
> -}
> -
> -void glc_path_move_to(GLCPath path, double x, double y)
> -{
> - InternalPath *internal = (InternalPath *)path;
> -
> - ASSERT(internal);
> -
> - if (internal->current_segment) {
> - internal->current_segment = NULL;
> - internal->current_path = NULL;
> - if (internal->points_pos == internal->points_size) {
> - more_points(internal);
> - }
> - internal->points_pos++;
> - }
> - internal->points[internal->points_pos - 1].x = x;
> - internal->points[internal->points_pos - 1].y = Y(y + 0.5);
> - internal->points[internal->points_pos - 1].z = 0;
> -}
> -
> -static void add_segment_common(InternalPath *internal, int type, int num_points)
> -{
> - if (internal->points_size - internal->points_pos< num_points) {
> - more_points(internal);
> - }
> -
> - if (internal->current_segment) {
> - if (internal->current_segment->type == type) {
> - internal->current_segment->count++;
> - return;
> - }
> - if (internal->segments_pos == internal->segments_size) {
> - more_segments(internal);
> - }
> - internal->current_segment =&internal->segments[internal->segments_pos++];
> - internal->current_segment->type = type;
> - internal->current_segment->count = 1;
> - internal->current_path->num_segments++;
> - return;
> - }
> -
> - if (internal->paths_pos == internal->paths_size) {
> - more_paths(internal);
> - }
> -
> - if (internal->segments_pos == internal->segments_size) {
> - more_segments(internal);
> - }
> -
> - internal->current_path =&internal->paths[internal->paths_pos++];
> - internal->current_path->start_point = internal->points_pos - 1;
> - internal->current_path->num_segments = 1;
> - internal->current_segment =&internal->segments[internal->segments_pos++];
> - internal->current_segment->type = type;
> - internal->current_segment->count = 1;
> -}
> -
> -void glc_path_line_to(GLCPath path, double x, double y)
> -{
> - InternalPath *internal = (InternalPath *)path;
> -
> - ASSERT(internal);
> -
> - add_segment_common(internal, GLC_PATH_SEG_LINES, 1);
> - put_point(internal, x, y);
> -}
> -
> -void glc_path_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y,
> - double p3_x, double p3_y)
> -{
> - InternalPath *internal = (InternalPath *)path;
> -
> - ASSERT(internal);
> -
> - add_segment_common(internal, GLC_PATH_SEG_BEIZER, 3);
> - put_point(internal, p1_x, p1_y);
> - put_point(internal, p2_x, p2_y);
> - put_point(internal, p3_x, p3_y);
> -}
> -
> -void glc_path_close(GLCPath path)
> -{
> - InternalPath *internal = (InternalPath *)path;
> -
> - ASSERT(internal);
> - if (!internal->current_path) {
> - return;
> - }
> - PathPoint *end_point =&internal->points[internal->current_path->start_point];
> - glc_path_line_to(path, end_point->x, Y(end_point->y));
> - glc_path_move_to(path, end_point->x, Y(end_point->y));
> -}
> -
> -void glc_path_cleare(GLCPath path)
> -{
> - InternalPath *internal = (InternalPath *)path;
> -
> - ASSERT(internal);
> - internal->paths_pos = internal->segments_pos = 0;
> - internal->current_segment = NULL;
> - internal->current_path = NULL;
> -
> - internal->points[0].x = 0;
> - internal->points[0].y = 0;
> - internal->points_pos = 1;
> -}
> -
> -GLCPath glc_path_create(GLCCtx glc)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - InternalPath *path;
> -
> - ASSERT(ctx);
> - path = spice_new0(InternalPath, 1);
> - path->paths_size = 2;
> - path->paths = spice_new(Path, path->paths_size);
> -
> - path->segments_size = 4;
> - path->segments = spice_new(PathSegment, path->segments_size);
> -
> - path->points_size = 20;
> - path->points = spice_new(PathPoint, path->points_size);
> -
> - path->owner = ctx;
> - path->points_pos = 1;
> - return path;
> -}
> -
> -void glc_path_destroy(GLCPath path)
> -{
> - InternalPath *internal = (InternalPath *)path;
> -
> - if (!path) {
> - return;
> - }
> -
> - free(internal->points);
> - free(internal->segments);
> - free(internal->paths);
> - free(internal);
> -}
> -
> -static inline void unref_pat(InternalPat *pat)
> -{
> - if (!pat) {
> - return;
> - }
> - ASSERT(pat->refs> 0);
> - if (--pat->refs == 0) {
> - glFinish();
> - glDeleteTextures(1,&pat->texture);
> - free(pat);
> - }
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static inline InternalPat *ref_pat(InternalPat *pat)
> -{
> - pat->refs++;
> - return pat;
> -}
> -
> -static void scale(uint32_t *dest, uint32_t dest_width, uint32_t dest_height,
> - uint32_t *src, uint32_t src_width, uint32_t src_height, int src_stride)
> -{
> - double x_scale = (double)src_width / dest_width;
> - double y_scale = (double)src_height / dest_height;
> - uint32_t i;
> - uint32_t j;
> - int prev_row = -1;
> -
> - for (i = 0; i< dest_height; i++) {
> - int row = (int)(y_scale * i);
> - if (row == prev_row) {
> - memcpy(dest, dest - dest_width, dest_width * sizeof(uint32_t));
> - dest += dest_width;
> - continue;
> - }
> - for (j = 0; j< dest_width; j++) {
> - int col = (int)(x_scale * j);
> - *(dest++) = *(src + col);
> - }
> - prev_row = row;
> - src = (uint32_t *)((uint8_t *)src + src_stride);
> - }
> -}
> -
> -static inline void init_pattern(InternalPat *pat, int x_orign, int y_orign, const GLCImage *image)
> -{
> - InternaCtx *ctx = pat->owner;
> - uint32_t *tmp_pixmap = NULL;
> - int width;
> - int height;
> - int width2;
> - int height2;
> -
> - const int pix_bytes = 4;
> -
> - ASSERT(image->format == GLC_IMAGE_RGB32); //for now
> -
> - width = image->width;
> - height = image->height;
> - width2 = gl_get_to_power_two(width);
> - height2 = gl_get_to_power_two(height);
> -
> - ASSERT(width> 0&& height> 0);
> - ASSERT(width> 0&& width<= pat->owner->max_texture_size);
> - ASSERT(height> 0&& height<= pat->owner->max_texture_size);
> -
> - if (width2 != width || height2 != height) {
> - tmp_pixmap = (uint32_t *)spice_malloc(width2 * height2 * sizeof(uint32_t));
> - scale(tmp_pixmap, width2, height2, (uint32_t *)image->pixels, width, height, image->stride);
> - }
> -
> - glBindTexture(GL_TEXTURE_2D, pat->texture);
> -
> - //glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
> -
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
> -
> - if (tmp_pixmap) {
> - glPixelStorei(GL_UNPACK_ROW_LENGTH, width2);
> - glTexImage2D(GL_TEXTURE_2D, 0, 4, width2, height2, 0, GL_BGRA, GL_UNSIGNED_BYTE,
> - tmp_pixmap);
> - free(tmp_pixmap);
> - } else {
> - ASSERT(image->stride % pix_bytes == 0);
> - glPixelStorei(GL_UNPACK_ROW_LENGTH, image->stride / pix_bytes);
> - glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
> - image->pixels);
> - }
> -
> - GLC_ERROR_TEST_FLUSH;
> - pat->x_orign = x_orign % width;
> - pat->y_orign = y_orign % height;
> - pat->width = width;
> - pat->height = height;
> -
> - if (ctx->pat == pat) {
> - set_pat(pat->owner, pat);
> - } else if (ctx->pat) {
> - glBindTexture(GL_TEXTURE_2D, ctx->pat->texture);
> - }
> -}
> -
> -GLCPattern glc_pattern_create(GLCCtx glc, int x_orign, int y_orign, const GLCImage *image)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - InternalPat *pat;
> -
> - ASSERT(ctx&& image);
> -
> - pat = spice_new0(InternalPat, 1);
> - pat->refs = 1;
> - pat->owner = ctx;
> - glGenTextures(1,&pat->texture);
> - init_pattern(pat, x_orign, y_orign, image);
> - return pat;
> -}
> -
> -void glc_pattern_set(GLCPattern pattern, int x_orign, int y_orign, const GLCImage *image)
> -{
> - InternalPat *pat = (InternalPat *)pattern;
> - ASSERT(pat&& pat->owner);
> -
> - glFinish();
> - init_pattern(pat, x_orign, y_orign, image);
> -}
> -
> -void glc_pattern_destroy(GLCPattern pat)
> -{
> - unref_pat((InternalPat *)pat);
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static void set_pat(InternaCtx *ctx, InternalPat *pat)
> -{
> - pat = ref_pat(pat);
> - unref_pat(ctx->pat);
> - ctx->pat = pat;
> -
> - glEnable(GL_TEXTURE_2D);
> - glBindTexture(GL_TEXTURE_2D, pat->texture);
> -
> - GLfloat s_gen_params[] = { (GLfloat)1.0 / pat->width, 0, 0, 0 };
> - GLfloat t_gen_params[] = { 0, (GLfloat)1.0 / (GLfloat)pat->height, 0, 0 };
> - glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params);
> - glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params);
> -
> - glMatrixMode(GL_TEXTURE);
> - glLoadIdentity();
> - glTranslatef((float)pat->x_orign / pat->width, (float)Y(pat->y_orign) / pat->height, 0);
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_set_pattern(GLCCtx glc, GLCPattern pattern)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - InternalPat *pat = (InternalPat *)pattern;
> -
> - ASSERT(ctx&& pat&& pat->owner == ctx);
> - set_pat(ctx, pat);
> -}
> -
> -void glc_set_rgb(GLCCtx glc, double red, double green, double blue)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx);
> -
> - glDisable(GL_TEXTURE_2D);
> - unref_pat(ctx->pat);
> - ctx->pat = NULL;
> - glColor4d(red, green, blue, 1);
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_set_op(GLCCtx glc, GLCOp op)
> -{
> - if (op == GL_COPY) {
> - glDisable(GL_COLOR_LOGIC_OP);
> - return;
> - }
> - glLogicOp(op);
> - glEnable(GL_COLOR_LOGIC_OP);
> -}
> -
> -void glc_set_line_width(GLCCtx glc, double width)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx);
> - ctx->line_width = (GLfloat)width;
> - if (ctx->line_width> 0) {
> - glLineWidth(ctx->line_width);
> - } else {
> - ctx->line_width = 0;
> - }
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_set_line_dash(GLCCtx glc, const double *dashes, int num_dashes, double offset)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx);
> - if (dashes&& num_dashes>= 0&& offset>= 0) {
> - ctx->line_dash.dashes = spice_new(double, num_dashes);
> - memcpy(ctx->line_dash.dashes, dashes, sizeof(double) * num_dashes);
> - ctx->line_dash.num_dashes = num_dashes;
> - ctx->line_dash.offset = offset;
> - ctx->line_dash.cur_dash = offset ? -1 : 0;
> - ctx->line_dash.dash_pos = 0;
> - } else {
> - free(ctx->line_dash.dashes);
> - memset(&ctx->line_dash, 0, sizeof(ctx->line_dash));
> - }
> -}
> -
> -void glc_set_fill_mode(GLCCtx glc, GLCFillMode fill_mode)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx);
> - int mode;
> - switch (fill_mode) {
> - case GLC_FILL_MODE_WINDING_ODD:
> - mode = GLU_TESS_WINDING_ODD;
> - break;
> - case GLC_FILL_MODE_WINDING_NONZERO:
> - mode = GLU_TESS_WINDING_NONZERO;
> - break;
> - default:
> - //warn
> - return;
> - }
> - gluTessProperty(ctx->tesselator, GLU_TESS_WINDING_RULE, mode);
> -}
> -
> -static inline void add_stencil_client(InternaCtx *ctx)
> -{
> - if (!ctx->stencil_refs) {
> - glEnable(GL_STENCIL_TEST);
> - }
> - ctx->stencil_refs++;
> -}
> -
> -static inline void remove_stencil_client(InternaCtx *ctx)
> -{
> - ctx->stencil_refs--;
> - if (!ctx->stencil_refs) {
> - glDisable(GL_STENCIL_TEST);
> - }
> -}
> -
> -void glc_set_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
> - int stride, const uint8_t *bitmap, GLCMaskID id)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
> - ASSERT(ctx&& bitmap);
> - ASSERT(id == GLC_MASK_A || id == GLC_MASK_B);
> -
> - if (ctx->pat) {
> - glDisable(GL_TEXTURE_2D);
> - }
> -
> - glDisable(GL_BLEND);
> -
> - if (!(ctx->stencil_mask& mask)) {
> - add_stencil_client(ctx);
> - ctx->stencil_mask |= mask;
> - }
> -
> - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
> - ctx->draw_mode = FALSE;
> - glStencilMask(mask);
> - glClear(GL_STENCIL_BUFFER_BIT);
> -
> - glStencilFunc(GL_ALWAYS, mask, mask);
> - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
> - fill_mask(ctx, x_dest, y_dest, width, height, stride, bitmap);
> -}
> -
> -void glc_mask_rects(GLCCtx glc, int num_rect, GLCRect *rects, GLCMaskID id)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
> - GLCRect *end;
> - ASSERT(ctx&& rects);
> - ASSERT(id == GLC_MASK_A || id == GLC_MASK_B);
> -
> - if (ctx->pat) {
> - glDisable(GL_TEXTURE_2D);
> - }
> -
> - glDisable(GL_BLEND);
> -
> - if (!(ctx->stencil_mask& mask)) {
> - add_stencil_client(ctx);
> - ctx->stencil_mask |= mask;
> - }
> -
> - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
> - ctx->draw_mode = FALSE;
> - glStencilMask(mask);
> - glClear(GL_STENCIL_BUFFER_BIT);
> -
> - glStencilFunc(GL_ALWAYS, mask, mask);
> - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
> - end = rects + num_rect;
> - for (; rects< end; rects++) {
> - fill_rect(ctx, rects);
> - }
> -}
> -
> -void glc_clear_mask(GLCCtx glc, GLCMaskID id)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
> - ASSERT(ctx);
> - ASSERT(id == GLC_MASK_A || id == GLC_MASK_B);
> -
> - if ((ctx->stencil_mask& mask)) {
> - ctx->stencil_mask&= ~mask;
> - remove_stencil_client(ctx);
> - }
> -}
> -
> -void glc_clip_reset(GLCCtx glc)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - if (!(ctx->stencil_mask& 0x03)) {
> - return;
> - }
> - remove_stencil_client(ctx);
> - ctx->stencil_mask&= ~0x03;
> - glStencilMask(0x03);
> - glClear(GL_STENCIL_BUFFER_BIT);
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static void clip_common(InternaCtx *ctx, GLCClipOp op, void (*fill_func)(InternaCtx *, void *),
> - void *data)
> -{
> - int stencil_val;
> -
> - if (ctx->pat) {
> - glDisable(GL_TEXTURE_2D);
> - }
> - glDisable(GL_BLEND);
> - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
> - ctx->draw_mode = FALSE;
> -
> - if (op == GLC_CLIP_OP_SET) {
> - glc_clip_reset(ctx);
> - add_stencil_client(ctx);
> - ctx->stencil_mask |= 0x01;
> - } else if (!(ctx->stencil_mask& 0x03)) {
> - GLCRect area;
> - if (op == GLC_CLIP_OP_OR) {
> - return;
> - }
> - area.x = area.y = 0;
> - area.width = ctx->width;
> - area.height = ctx->height;
> - clip_common(ctx, GLC_CLIP_OP_SET, fill_rect,&area);
> - }
> - glStencilMask(0x03);
> - switch (op) {
> - case GLC_CLIP_OP_SET:
> - case GLC_CLIP_OP_OR:
> - stencil_val = ctx->stencil_mask& 0x03;
> - glStencilFunc(GL_ALWAYS, stencil_val, stencil_val);
> - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
> - fill_func(ctx, data);
> - break;
> - case GLC_CLIP_OP_AND: {
> - int clear_mask;
> - stencil_val = ctx->stencil_mask& 0x03;
> - glStencilFunc(GL_EQUAL, stencil_val, stencil_val);
> - if (stencil_val == 0x01) {
> - glStencilOp(GL_ZERO, GL_INCR, GL_INCR);
> - stencil_val = 0x02;
> - clear_mask = 0x01;
> - } else {
> - glStencilOp(GL_ZERO, GL_DECR, GL_DECR);
> - stencil_val = 0x01;
> - clear_mask = 0x02;
> - }
> - fill_func(ctx, data);
> -
> - glStencilMask(clear_mask);
> - glClear(GL_STENCIL_BUFFER_BIT);
> - ctx->stencil_mask = (ctx->stencil_mask& ~clear_mask) | stencil_val;
> - break;
> - }
> - case GLC_CLIP_OP_EXCLUDE:
> - stencil_val = ctx->stencil_mask& 0x03;
> - glStencilFunc(GL_EQUAL, stencil_val, stencil_val);
> - glStencilOp(GL_KEEP, GL_ZERO, GL_ZERO);
> - fill_func(ctx, data);
> - break;
> - }
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_clip_rect(GLCCtx glc, const GLCRect *rect, GLCClipOp op)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx&& rect);
> - clip_common(ctx, op, fill_rect, (void *)rect);
> -}
> -
> -void glc_clip_path(GLCCtx glc, GLCPath path, GLCClipOp op)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx&& path);
> - clip_common(ctx, op, fill_path, path);
> -}
> -
> -typedef struct FillMaskInfo {
> - int x_dest;
> - int y_dest;
> - int width;
> - int height;
> - int stride;
> - const uint8_t *bitmap;
> -} FillMaskInfo;
> -
> -static void __fill_mask(InternaCtx *ctx, void *data)
> -{
> - FillMaskInfo *info = (FillMaskInfo *)data;
> - fill_mask(ctx, info->x_dest, info->y_dest, info->width, info->height, info->stride,
> - info->bitmap);
> -}
> -
> -void glc_clip_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
> - int stride, const uint8_t *bitmap, GLCClipOp op)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - FillMaskInfo mask_info;
> -
> - ASSERT(ctx&& bitmap);
> - mask_info.x_dest = x_dest;
> - mask_info.y_dest = y_dest;
> - mask_info.width = width;
> - mask_info.height = height;
> - mask_info.stride = stride;
> - mask_info.bitmap = bitmap;
> - clip_common(ctx, op, __fill_mask,&mask_info);
> -}
> -
> -static inline void start_draw(InternaCtx *ctx)
> -{
> - if (ctx->draw_mode) {
> - return;
> - }
> - ctx->draw_mode = TRUE;
> - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
> - glStencilFunc(GL_EQUAL, ctx->stencil_mask, ctx->stencil_mask);
> - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
> - if (ctx->pat) {
> - glEnable(GL_TEXTURE_2D);
> - } else {
> - glDisable(GL_TEXTURE_2D);
> - }
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static void fill_rect(InternaCtx *ctx, void *r)
> -{
> - GLCRect *rect = (GLCRect *)r;
> - glRectd(rect->x, Y(rect->y), rect->x + rect->width, Y(rect->y + rect->height));
> - /*glBegin(GL_POLYGON);
> - VERTEX2(rect->x, rect->y);
> - VERTEX2 (rect->x + rect->width, rect->y);
> - VERTEX2 (rect->x + rect->width, rect->y + rect->height);
> - VERTEX2 (rect->x , rect->y + rect->height);
> - glEnd();*/
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_fill_rect(GLCCtx glc, const GLCRect *rect)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - GLCRect *r = (GLCRect *)rect; // to avoid bugs in gcc older than 4.3
> -
> - ASSERT(ctx);
> - start_draw(ctx);
> - fill_rect(ctx, (void *)r);
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static void fill_path(InternaCtx *ctx, void *p)
> -{
> - InternalPath *path = (InternalPath *)p;
> -
> - PathPoint *current_point = path->points;
> - PathSegment *current_segment = path->segments;
> - Path *current_path = path->paths;
> - Path *end_path = current_path + path->paths_pos;
> - reset_tass_vertex(ctx);
> - gluTessBeginPolygon(ctx->tesselator, ctx);
> - for (; current_path< end_path; current_path++) {
> - gluTessBeginContour(ctx->tesselator);
> - PathSegment *end_segment = current_segment + current_path->num_segments;
> - gluTessVertex(ctx->tesselator, (GLdouble *)current_point, current_point);
> - current_point++;
> - for (; current_segment< end_segment; current_segment++) {
> - PathPoint *end_point;
> - if (current_segment->type == GLC_PATH_SEG_BEIZER) {
> - end_point = current_point + current_segment->count * 3;
> - for (; current_point< end_point; current_point += 3) {
> - TassVertex *vertex = bezier_flattener(ctx, current_point - 1);
> - while (vertex) {
> - gluTessVertex(ctx->tesselator, (GLdouble *)&vertex->point,
> - (GLdouble *)&vertex->point);
> - vertex = vertex->list_link;
> - }
> - gluTessVertex(ctx->tesselator, (GLdouble *)¤t_point[2],
> - (GLdouble *)¤t_point[2]);
> - }
> - } else {
> - ASSERT(current_segment->type == GLC_PATH_SEG_LINES);
> - end_point = current_point + current_segment->count;
> - for (; current_point< end_point; current_point++) {
> - gluTessVertex(ctx->tesselator, (GLdouble *)current_point,
> - (GLdouble *)current_point);
> - }
> - }
> - }
> - gluTessEndContour(ctx->tesselator);
> - }
> - gluTessEndPolygon(ctx->tesselator);
> -}
> -
> -void glc_fill_path(GLCCtx glc, GLCPath path_ref)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx&& path_ref);
> - start_draw(ctx);
> - fill_path(ctx, path_ref);
> -}
> -
> -static void fill_mask(InternaCtx *ctx, int x_dest, int y_dest, int width, int height,
> - int stride, const uint8_t *bitmap)
> -{
> - set_raster_pos(ctx, x_dest, y_dest + height);
> - glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
> - glBitmap(width, height, 0, 0, 0, 0, bitmap);
> -}
> -
> -void _glc_fill_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
> - const uint8_t *bitmap)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx&& bitmap);
> - start_draw(ctx);
> - if (ctx->pat) {
> - WARN_ONCE(("%s: unimplemented fill mask with pattern\n", __FUNCTION__));
> - }
> - fill_mask(ctx, x_dest, y_dest, width, height, stride, bitmap);
> -}
> -
> -void glc_fill_alpha(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
> - const uint8_t *alpha_mask)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - GLCRect r;
> -
> - ASSERT(ctx);
> - start_draw(ctx);
> -
> - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
> - set_raster_pos(ctx, x_dest, y_dest + height);
> - glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
> - glPixelZoom(1, 1);
> - glDrawPixels(width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_mask);
> -
> - r.x = x_dest;
> - r.y = y_dest;
> - r.width = width;
> - r.height = height;
> -
> - //todo: support color/texture alpah vals (GL_MODULATE)
> - glEnable(GL_BLEND);
> - glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
> - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
> - fill_rect(ctx,&r);
> - glDisable(GL_BLEND);
> -}
> -
> -void glc_stroke_rect(GLCCtx glc, const GLCRect *rect)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx);
> - if (ctx->line_width == 0) {
> - return;
> - }
> -
> - start_draw(ctx);
> -
> - glBegin(GL_LINES);
> - VERTEX2(rect->x, rect->y + 0.5);
> - VERTEX2(rect->x + rect->width, rect->y + 0.5);
> - VERTEX2(rect->x + rect->width - 0.5, rect->y);
> - VERTEX2(rect->x + rect->width - 0.5, rect->y + rect->height);
> - VERTEX2(rect->x + rect->width, rect->y + rect->height - 0.5);
> - VERTEX2(rect->x, rect->y + rect->height - 0.5);
> - VERTEX2(rect->x + 0.5, rect->y + rect->height);
> - VERTEX2(rect->x + 0.5, rect->y);
> - glEnd();
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static void glc_stroke_line(double x1, double y1, double x2, double y2, double width)
> -{
> - double ax, ay, bx, by, cx, cy, dx, dy;
> - double norm, tx;
> -
> - if (width == 1 || y1 == y2 || x1 == x2) {
> - glBegin(GL_LINES);
> - glVertex2d(x1, y1);
> - glVertex2d(x2, y2);
> - glEnd();
> - return;
> - }
> - norm = (x1 - x2) / (y2 - y1);
> - tx = width / (2 * sqrt(1 + norm * norm));
> - ax = x1 + tx;
> - ay = y1 + norm * (ax - x1);
> - bx = x2 + tx;
> - by = y2 + norm * (bx - x2);
> - cx = x2 - tx;
> - cy = y2 + norm * (cx - x2);
> - dx = x1 - tx;
> - dy = y1 + norm * (dx - x1);
> - glBegin(GL_POLYGON);
> - glVertex2d(ax, ay);
> - glVertex2d(bx, by);
> - glVertex2d(cx, cy);
> - glVertex2d(dx, dy);
> - glEnd();
> -}
> -
> -static double glc_stroke_line_dash(double x1, double y1, double x2, double y2,
> - double width, LineDash *dash)
> -{
> - double ax, ay, bx, by;
> - double mx, my, len;
> - double dash_len, total = 0;
> -
> - len = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
> - if (!dash->dashes || !dash->num_dashes) {
> - glc_stroke_line(x1, y1, x2, y2, width);
> - return len;
> - }
> - mx = (x2 - x1) / len;
> - my = (y2 - y1) / len;
> - ax = x1;
> - ay = y1;
> - while (total< len) {
> - if (dash->cur_dash>= 0) {
> - dash_len = dash->dashes[dash->cur_dash % dash->num_dashes] - dash->dash_pos;
> - } else {
> - dash_len = dash->offset - dash->dash_pos;
> - }
> - total += dash_len;
> - if (total< len) {
> - bx = x1 + mx * total;
> - by = y1 + my * total;
> - dash->dash_pos = 0;
> - } else {
> - bx = x2;
> - by = y2;
> - dash->dash_pos = dash->dashes[dash->cur_dash % dash->num_dashes] - (total - len);
> - }
> - if (dash->cur_dash % 2 == 0) {
> - glc_stroke_line(ax, ay, bx, by, width);
> - }
> - if (dash->dash_pos == 0) {
> - dash->cur_dash = (dash->cur_dash + 1) % (2 * dash->num_dashes);
> - }
> - ax = bx;
> - ay = by;
> - }
> - return len;
> -}
> -
> -static void glc_vertex2d(InternaCtx *ctx, double x, double y)
> -{
> - double len;
> - if (ctx->path_stroke.state == GLC_STROKE_ACTIVE) {
> - len = glc_stroke_line_dash(ctx->path_stroke.x, ctx->path_stroke.y, x, y,
> - ctx->line_width,&ctx->line_dash);
> - ctx->path_stroke.x = x;
> - ctx->path_stroke.y = y;
> - } else if (ctx->path_stroke.state == GLC_STROKE_FIRST) {
> - ctx->path_stroke.x = x;
> - ctx->path_stroke.y = y;
> - ctx->path_stroke.state = GLC_STROKE_ACTIVE;
> - } else {
> - ASSERT(ctx->path_stroke.state == GLC_STROKE_NONACTIVE);
> - //error
> - }
> -}
> -
> -static void glc_begin_path(InternaCtx *ctx)
> -{
> - ctx->path_stroke.state = GLC_STROKE_FIRST;
> - ctx->line_dash.cur_dash = ctx->line_dash.offset ? -1 : 0;
> - ctx->line_dash.dash_pos = 0;
> -}
> -
> -static void glc_end_path(InternaCtx *ctx)
> -{
> - ctx->path_stroke.state = GLC_STROKE_NONACTIVE;
> -}
> -
> -void glc_stroke_path(GLCCtx glc, GLCPath path_ref)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - InternalPath *path = (InternalPath *)path_ref;
> -
> - ASSERT(ctx&& path);
> - if (ctx->line_width == 0) {
> - return;
> - }
> - start_draw(ctx);
> -
> - reset_tass_vertex(ctx);
> - PathPoint *current_point = path->points;
> - PathSegment *current_segment = path->segments;
> - Path *current_path = path->paths;
> - Path *end_path = current_path + path->paths_pos;
> - for (; current_path< end_path; current_path++) {
> - glc_begin_path(ctx);
> - PathSegment *end_segment = current_segment + current_path->num_segments;
> - glc_vertex2d(ctx, current_point->x, current_point->y);
> - current_point++;
> - for (; current_segment< end_segment; current_segment++) {
> - PathPoint *end_point;
> - if (current_segment->type == GLC_PATH_SEG_BEIZER) {
> - end_point = current_point + current_segment->count * 3;
> - for (; current_point< end_point; current_point += 3) {
> - TassVertex *vertex = bezier_flattener(ctx, current_point - 1);
> - while (vertex) {
> - glc_vertex2d(ctx, vertex->point.x, vertex->point.y);
> - vertex = vertex->list_link;
> - }
> - glc_vertex2d(ctx, current_point[2].x, current_point[2].y);
> - }
> - } else {
> - ASSERT(current_segment->type == GLC_PATH_SEG_LINES);
> - end_point = current_point + current_segment->count;
> - for (; current_point< end_point; current_point++) {
> - glc_vertex2d(ctx, current_point->x, current_point->y);
> - }
> - }
> - }
> - glc_end_path(ctx);
> - }
> -}
> -
> -void glc_draw_image(GLCCtx glc, const GLCRecti *dest, const GLCRecti *src, const GLCImage *image,
> - int scale_mode, double alpha)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - uint8_t *pixels;
> - const int pix_bytes = 4;
> -
> - ASSERT(ctx&& image);
> - ASSERT(src->width> 0&& src->height> 0);
> -
> - ASSERT(image->format == GLC_IMAGE_RGB32 || image->format == GLC_IMAGE_ARGB32); //for now
> - start_draw(ctx);
> - if (ctx->pat) {
> - glDisable(GL_TEXTURE_2D);
> - }
> - set_raster_pos(ctx, dest->x, dest->y + dest->height);
> -
> - if (dest->width == src->width&& src->height == dest->height) {
> - glPixelZoom(1, 1);
> - } else {
> - glPixelZoom((float)dest->width / src->width, (float)dest->height / src->height);
> - }
> -
> - pixels = image->pixels + src->x * 4 + (image->height - (src->y + src->height)) * image->stride;
> - if (image->format == GLC_IMAGE_ARGB32 || alpha != 1) {
> - glPixelTransferf(GL_ALPHA_SCALE, (GLfloat)alpha);
> - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
> - glEnable(GL_BLEND);
> - }
> - ASSERT(image->stride % pix_bytes == 0);
> - glPixelStorei(GL_UNPACK_ROW_LENGTH, image->stride / pix_bytes);
> - glDrawPixels(src->width, src->height, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
> -
> - if (image->format == GLC_IMAGE_ARGB32 || alpha != 1) {
> - glDisable(GL_BLEND);
> - }
> -
> - if (ctx->pat) {
> - glEnable(GL_TEXTURE_2D);
> - }
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_copy_pixels(GLCCtx glc, int x_dest, int y_dest, int x_src, int y_src, int width,
> - int height)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - int recreate = 0;
> -
> - ASSERT(ctx);
> -#ifdef USE_COPY_PIXELS
> - start_draw(ctx);
> - if (ctx->pat) {
> - glDisable(GL_TEXTURE_2D);
> - }
> - set_raster_pos(ctx, x_dest, y_dest + height);
> - glPixelZoom(1, 1);
> - glCopyPixels(x_src, ctx->height - (y_src + height), width, height, GL_COLOR);
> - if (ctx->pat) {
> - glEnable(GL_TEXTURE_2D);
> - }
> -#else
> - int width2 = gl_get_to_power_two(width);
> - int height2 = gl_get_to_power_two(height);
> -
> - start_draw(ctx);
> - glEnable(GL_TEXTURE_2D);
> - glBindTexture(GL_TEXTURE_2D, 0);
> -
> - if (width2> ctx->private_tex_width) {
> - ctx->private_tex_width = width2;
> - recreate = 1;
> - }
> - if (height2> ctx->private_tex_height) {
> - ctx->private_tex_height = height2;
> - recreate = 1;
> - }
> - if (recreate) {
> - glDeleteTextures(1,&ctx->private_tex);
> - glGenTextures(1,&ctx->private_tex);
> - glBindTexture(GL_TEXTURE_2D, ctx->private_tex);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
> - ctx->private_tex_width = gl_get_to_power_two(width);
> - ctx->private_tex_height = gl_get_to_power_two(height);
> - glTexImage2D(GL_TEXTURE_2D, 0, 4, ctx->private_tex_width,
> - ctx->private_tex_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
> - }
> - ASSERT(ctx->private_tex);
> - glBindTexture(GL_TEXTURE_2D, ctx->private_tex);
> - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x_src, ctx->height - (y_src + height),
> - width2, height2, 0);
> -
> - GLfloat s_gen_params[] = { (GLfloat)1.0 / width2, 0, 0, 0 };
> - GLfloat t_gen_params[] = { 0, (GLfloat)1.0 / height2, 0, 0 };
> - glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params);
> - glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params);
> -
> - glMatrixMode(GL_TEXTURE);
> - glLoadIdentity();
> - glTranslatef((float)-x_dest / width2, (float)-Y(y_dest + height) / height2, 0);
> -
> - glRecti(x_dest, Y(y_dest), x_dest + width, Y(y_dest + height));
> - glFlush();
> - if (!ctx->pat) {
> - glDisable(GL_TEXTURE_2D);
> - } else {
> - set_pat(ctx, ctx->pat);
> - }
> -#endif
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_read_pixels(GLCCtx glc, int x, int y, GLCImage *image)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx&& image);
> - ASSERT(image->format == GLC_IMAGE_RGB32); //for now
> - ASSERT((image->stride % 4) == 0); //for now
> - glPixelStorei(GL_PACK_ROW_LENGTH, image->stride / 4);
> - glReadPixels(x, ctx->height - (y + image->height), image->width, image->height,
> - GL_BGRA, GL_UNSIGNED_BYTE, image->pixels);
> -}
> -
> -void glc_clear(GLCCtx glc)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx);
> - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
> - glClear(GL_COLOR_BUFFER_BIT);
> -}
> -
> -void glc_flush(GLCCtx glc)
> -{
> - glFlush();
> -
> - GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static void tessellation_combine(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4],
> - GLdouble **data_out, void *usr_data)
> -{
> - TassVertex *vertex;
> -
> - vertex = alloc_tess_vertex((InternaCtx *)usr_data);
> - vertex->point.x = coords[0];
> - vertex->point.y = coords[1];
> - //vertex->point.z = coords[2];
> - *data_out = (GLdouble *)&vertex->point;
> -}
> -
> -static void tessellation_error(GLenum errorCode)
> -{
> - printf("%s: %s\n", __FUNCTION__, gluErrorString(errorCode));
> -}
> -
> -#ifdef WIN32
> -#define TESS_CALL_BACK_TYPE void(CALLBACK *)()
> -#else
> -#define TESS_CALL_BACK_TYPE void(*)()
> -#endif
> -
> -static int init(InternaCtx *ctx, int width, int height)
> -{
> -#ifdef WIN32
> - if (!(ctx->glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquation"))) {
> - return FALSE;
> - }
> -#endif
> - ctx->width = width;
> - ctx->height = height;
> - ctx->line_width = 1;
> -
> - glClearColor(0, 0, 0, 0);
> - glClearStencil(0);
> -
> - if (!(ctx->tesselator = gluNewTess())) {
> - return FALSE;
> - }
> -
> - glGenTextures(1,&ctx->private_tex);
> - glBindTexture(GL_TEXTURE_2D, ctx->private_tex);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
> - glTexImage2D(GL_TEXTURE_2D, 0, 4, gl_get_to_power_two(width),
> - gl_get_to_power_two(height), 0,
> - GL_BGRA, GL_UNSIGNED_BYTE, NULL);
> - ctx->private_tex_width = gl_get_to_power_two(width);
> - ctx->private_tex_height = gl_get_to_power_two(height);
> - glBindTexture(GL_TEXTURE_2D, 0);
> -
> - glViewport(0, 0, width, height);
> - glMatrixMode(GL_PROJECTION);
> - glLoadIdentity();
> - glOrtho(0, width, 0, height, -1, 1);
> -
> - gluTessProperty(ctx->tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
> - gluTessCallback(ctx->tesselator, GLU_BEGIN, (TESS_CALL_BACK_TYPE)glBegin);
> - gluTessCallback(ctx->tesselator, GLU_VERTEX, (TESS_CALL_BACK_TYPE)glVertex3dv);
> - gluTessCallback(ctx->tesselator, GLU_END, (TESS_CALL_BACK_TYPE)glEnd);
> - gluTessCallback(ctx->tesselator, GLU_TESS_COMBINE_DATA,
> - (TESS_CALL_BACK_TYPE)tessellation_combine);
> - gluTessCallback(ctx->tesselator, GLU_TESS_ERROR, (TESS_CALL_BACK_TYPE)tessellation_error);
> -
> - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
> - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
> - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
> - glEnable(GL_TEXTURE_GEN_S);
> - glEnable(GL_TEXTURE_GEN_T);
> -
> - glMatrixMode(GL_MODELVIEW);
> - glLoadIdentity();
> - glTranslatef(0, (GLfloat)height, 0);
> -
> - glGetIntegerv(GL_MAX_TEXTURE_SIZE,&ctx->max_texture_size);
> -
> - glPixelStorei(GL_PACK_ALIGNMENT, 1);
> -
> - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
> - glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
> - glPixelTransferf(GL_ALPHA_BIAS, 0);
> -#ifdef WIN32
> - ctx->glBlendEquation(GL_FUNC_ADD);
> -#else
> - glBlendEquation(GL_FUNC_ADD);
> -#endif
> -
> - glStencilMask(0xff);
> - glClear(GL_STENCIL_BUFFER_BIT);
> -
> - glClear(GL_COLOR_BUFFER_BIT);
> -
> - return TRUE;
> -}
> -
> -GLCCtx glc_create(int width, int height)
> -{
> - InternaCtx *ctx;
> -
> - ASSERT(sizeof(PathPoint) == sizeof(Vertex));
> -
> - ctx = spice_new0(InternaCtx, 1);
> - if (!init(ctx, width, height)) {
> - free(ctx);
> - return NULL;
> - }
> - return ctx;
> -}
> -
> -/*
> - * In glx video mode change the textures will be destroyed, therefore
> - * if we will try to glDeleteTextures() them we might get seagfault.
> - * (this why we use the textures_lost parameter)
> - */
> -void glc_destroy(GLCCtx glc, int textures_lost)
> -{
> - InternaCtx *ctx;
> -
> - if (!(ctx = (InternaCtx *)glc)) {
> - return;
> - }
> -
> - if (!textures_lost) {
> - unref_pat(ctx->pat);
> - ctx->pat = NULL;
> - if (ctx->private_tex) {
> - glDeleteTextures(1,&ctx->private_tex);
> - }
> - }
> -
> - free_tass_vertex_bufs(ctx);
> - free(ctx->line_dash.dashes);
> - free(ctx);
> - GLC_ERROR_TEST_FINISH;
> -}
> -
> -/*
> - todo:
> - 1. test double vs float in gl calls
> - 2. int vs flat raster position
> - 3. pixels stride vs bytes stride
> - 4. improve non power of two.
> - glGetString(GL_EXTENSIONS);
> - ARB_texture_non_power_of_two
> - ARB_texture_rectangle
> - GL_TEXTURE_RECTANGLE_ARB
> - 5. scale
> - 6. origin
> - 7. fonts
> - 8. support more image formats
> - 9. use GLCImage in mask ops?
> -*/
> -
> diff --git a/common/glc.c.save b/common/glc.c.save
> deleted file mode 100644
> index 1958110..0000000
> --- a/common/glc.c.save
> +++ /dev/null
> @@ -1,1413 +0,0 @@
> -#include<stdlib.h>
> -#include<string.h>
> -#include<stdio.h>
> -
> -#include<GL/gl.h>
> -#include<GL/glu.h>
> -
> -#ifdef WIN32
> -#include "glext.h"
> -#include "wglext.h"
> -#endif
> -
> -#include "glc.h"
> -
> -#define TRUE 1
> -#define FALSE 0
> -
> -#define ASSERT(x) if (!(x)) {printf("%s: assert failed %s\n", __FUNCTION__, #x); for (;;);}
> -
> -#define GLC_ERROR_TETS { \
> - GLenum gl_err; glFlush(); \
> - if ((gl_err = glGetError()) != GL_NO_ERROR) { \
> - printf("%s[%d]: opengl error: %s\n", __FUNCTION__, __LINE__, gluErrorString(gl_err)); \
> - for(;;); \
> - } \
> -}
> -
> -#define WARN_ONCE(x) { \
> - static int warn = TRUE; \
> - if (warn) { \
> - printf x; \
> - warn = FALSE; \
> - } \
> -}
> -
> -#define TESS_VERTEX_ALLOC_BUNCH 20
> -
> -typedef struct InternaCtx InternaCtx;
> -typedef struct InternalPat {
> - InternaCtx *owner;
> - int refs;
> - GLuint texture;
> - int x_orign;
> - int y_orign;
> - int width;
> - int height;
> -} InternalPat;
> -
> -typedef struct Pathpath {
> - int start_point;
> - int num_segments;
> -} Path;
> -
> -enum {
> - GLC_PATH_SEG_LINES,
> - GLC_PATH_SEG_BEIZER,
> -};
> -
> -//todo: flatten cache
> -typedef struct PathSegment {
> - int type;
> - int count;
> -} PathSegment;
> -
> -typedef struct PathPoint {
> - double x;
> - double y;
> - double z;
> -} PathPoint;
> -
> -typedef GLdouble Vertex[3];
> -
> -typedef struct InternalPath {
> - InternaCtx *owner;
> -
> - Path *paths;
> - int paths_size;
> - int paths_pos;
> -
> - PathSegment *segments;
> - int segments_size;
> - int segments_pos;
> -
> - PathPoint *points;
> - int points_size;
> - int points_pos;
> -
> - Path *current_path;
> - PathSegment *current_segment;
> -
> -} InternalPath;
> -
> -typedef struct TassVertex TassVertex;
> -struct TassVertex {
> - PathPoint point;
> - TassVertex *list_link;
> - TassVertex *next;
> -};
> -
> -typedef struct TassVertexBuf TassVertexBuf;
> -struct TassVertexBuf {
> - TassVertexBuf *next;
> - TassVertex vertexs[0];
> -};
> -
> -struct InternaCtx {
> - int draw_mode;
> - int stencil_refs;
> - int stencil_mask;
> - int width;
> - int height;
> - GLfloat line_width;
> - InternalPat *pat;
> - int max_texture_size;
> - GLUtesselator* tesselator;
> - TassVertex *free_tess_vertex;
> - TassVertex *used_tess_vertex;
> - TassVertexBuf *vertex_bufs;
> -#ifdef WIN32
> - PFNGLBLENDEQUATIONPROC glBlendEquation;
> -#endif
> -};
> -
> -#define Y(y) -(y)
> -#define VERTEX2(x, y) glVertex2d(x, Y(y))
> -
> -static void fill_rect(InternaCtx *ctx, void *rect);
> -static void fill_path(InternaCtx *ctx, void *path);
> -static void fill_mask(InternaCtx *ctx, int x_dest, int y_dest, int width, int height, int stride,
> - const uint8_t *bitmap);
> -static void set_pat(InternaCtx *ctx, InternalPat *pat);
> -
> -static inline void *zmalloc(size_t size)
> -{
> - return calloc(1, size);
> -}
> -
> -static inline void set_raster_pos(InternaCtx *ctx, int x, int y)
> -{
> - if (x>= 0&& y>= 0&& x< ctx->width&& y< ctx->height) {
> - glRasterPos2i(x, Y(y));
> - return;
> - }
> - glRasterPos2i(0, 0);
> - glBitmap(0, 0, 0, 0, (GLfloat)x, (GLfloat)Y(y), NULL);
> -}
> -
> -static TassVertex *alloc_tess_vertex(InternaCtx *ctx)
> -{
> - TassVertex *vertex;
> -
> - if (!ctx->free_tess_vertex) {
> - TassVertexBuf *buf;
> - int i;
> -
> - if (!(buf = (TassVertexBuf *)malloc(sizeof(TassVertexBuf) +
> - sizeof(TassVertex) * TESS_VERTEX_ALLOC_BUNCH))) {
> - //warn
> - return NULL;
> - }
> - buf->next = ctx->vertex_bufs;
> - ctx->vertex_bufs = buf;
> - for (i = 0; i< TESS_VERTEX_ALLOC_BUNCH; i++) {
> - buf->vertexs[i].point.z = 0;
> - buf->vertexs[i].next = ctx->free_tess_vertex;
> - ctx->free_tess_vertex =&buf->vertexs[i];
> - }
> - }
> -
> - vertex = ctx->free_tess_vertex;
> - ctx->free_tess_vertex = vertex->next;
> - vertex->next = ctx->used_tess_vertex;
> - ctx->used_tess_vertex = vertex;
> - return vertex;
> -}
> -
> -static void reset_tass_vertex(InternaCtx *ctx)
> -{
> - TassVertex *vertex;
> - while ((vertex = ctx->used_tess_vertex)) {
> - ctx->used_tess_vertex = vertex->next;
> - vertex->next = ctx->free_tess_vertex;
> - ctx->free_tess_vertex = vertex;
> - }
> -}
> -
> -static void free_tass_vertex_bufs(InternaCtx *ctx)
> -{
> - TassVertexBuf *buf;
> -
> - ctx->used_tess_vertex = NULL;
> - ctx->free_tess_vertex = NULL;
> - while ((buf = ctx->vertex_bufs)) {
> - ctx->vertex_bufs = buf->next;
> - free(buf);
> - }
> -}
> -
> -//naiev bezier flattener
> -static TassVertex *bezier_flattener(InternaCtx *ctx, PathPoint *points)
> -{
> - double ax, bx, cx;
> - double ay, by, cy;
> - const int num_points = 30;
> - double dt;
> - int i;
> -
> - TassVertex *vertex_list = NULL;
> - TassVertex *curr_vertex;
> -
> - for (i = 0; i< num_points - 2; i++) {
> - TassVertex *vertex;
> -
> - if (!(vertex = alloc_tess_vertex(ctx))) {
> - //warn
> - return NULL;
> - }
> - vertex->list_link = vertex_list;
> - vertex_list = vertex;
> - }
> -
> - curr_vertex = vertex_list;
> -
> - cx = 3.0 * (points[1].x - points[0].x);
> - bx = 3.0 * (points[2].x - points[1].x) - cx;
> - ax = points[3].x - points[0].x - cx - bx;
> -
> - cy = 3.0 * (points[1].y - points[0].y);
> - by = 3.0 * (points[2].y - points[1].y) - cy;
> - ay = points[3].y - points[0].y - cy - by;
> -
> - dt = 1.0 / ( num_points - 1 );
> -
> - for( i = 1; i< num_points - 1; i++, curr_vertex = curr_vertex->list_link) {
> - double tSquared, tCubed;
> - double t;
> - t = i * dt;
> -
> - tSquared = t * t;
> - tCubed = tSquared * t;
> -
> - curr_vertex->point.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + points[0].x;
> - curr_vertex->point.y = (ay * tCubed) + (by * tSquared) + (cy * t) + points[0].y;
> - }
> -
> - return vertex_list;
> -}
> -
> -#define MORE_X(path, Type, name) {\
> - Type *name;\
> - \
> - if (!(name = (Type *)zmalloc(sizeof(*name) * path->name##_size * 2))) {\
> - return FALSE;\
> - }\
> - memcpy(name, path->name, sizeof(*name) * path->name##_size);\
> - free(path->name);\
> - path->name = name;\
> - path->name##_size *= 2;\
> - return TRUE;\
> -}
> -
> -static int more_points(InternalPath *path)
> -{
> - MORE_X(path, PathPoint, points);
> -}
> -
> -static int more_segments(InternalPath *path)
> -{
> - MORE_X(path, PathSegment, segments);
> -}
> -
> -static int more_paths(InternalPath *path)
> -{
> - MORE_X(path, Path, paths);
> -}
> -
> -static inline void put_point(InternalPath *path, double x, double y)
> -{
> - path->points[path->points_pos].x = x;
> - path->points[path->points_pos++].y = Y(y + 0.5);
> - path->points[path->points_pos].z = 0;
> -}
> -
> -void glc_path_move_to(GLCPath path, double x, double y)
> -{
> - InternalPath *internal = (InternalPath *)path;
> -
> - ASSERT(internal);
> -
> - if (internal->current_segment) {
> - internal->current_segment = NULL;
> - internal->current_path = NULL;
> - if (internal->points_pos == internal->points_size&& !more_points(internal)) {
> - //warn
> - return;
> - }
> - internal->points_pos++;
> - }
> - internal->points[internal->points_pos - 1].x = x;
> - internal->points[internal->points_pos - 1].y = Y(y + 0.5);
> - internal->points[internal->points_pos - 1].z = 0;
> -}
> -
> -static int add_segment_common(InternalPath *internal, int type, int num_points)
> -{
> - if (internal->points_size - internal->points_pos< num_points&& !more_points(internal)) {
> - //warn
> - return FALSE;
> - }
> -
> - if (internal->current_segment) {
> - if (internal->current_segment->type == type) {
> - internal->current_segment->count++;
> - return TRUE;
> - }
> - if (internal->segments_pos == internal->segments_size&& !more_segments(internal)) {
> - //warn
> - return FALSE;
> - }
> - internal->current_segment =&internal->segments[internal->segments_pos++];
> - internal->current_segment->type = type;
> - internal->current_segment->count = 1;
> - internal->current_path->num_segments++;
> - return TRUE;
> - }
> -
> - if (internal->paths_pos == internal->paths_size&& !more_paths(internal)) {
> - //warn
> - return FALSE;
> - }
> -
> - if (internal->segments_pos == internal->segments_size&& !more_segments(internal)) {
> - //warn
> - return FALSE;
> - }
> -
> - internal->current_path =&internal->paths[internal->paths_pos++];
> - internal->current_path->start_point = internal->points_pos - 1;
> - internal->current_path->num_segments = 1;
> - internal->current_segment =&internal->segments[internal->segments_pos++];
> - internal->current_segment->type = type;
> - internal->current_segment->count = 1;
> - return TRUE;
> -}
> -
> -void glc_path_line_to(GLCPath path, double x, double y)
> -{
> - InternalPath *internal = (InternalPath *)path;
> -
> - ASSERT(internal);
> -
> - if (!add_segment_common(internal, GLC_PATH_SEG_LINES, 1)) {
> - return;
> - }
> - put_point(internal, x, y);
> -}
> -
> -void glc_path_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y,
> - double p3_x, double p3_y)
> -{
> - InternalPath *internal = (InternalPath *)path;
> -
> - ASSERT(internal);
> -
> - if (!add_segment_common(internal, GLC_PATH_SEG_BEIZER, 3)) {
> - return;
> - }
> - put_point(internal, p1_x, p1_y);
> - put_point(internal, p2_x, p2_y);
> - put_point(internal, p3_x, p3_y);
> -}
> -
> -void glc_path_close(GLCPath path)
> -{
> - InternalPath *internal = (InternalPath *)path;
> -
> - ASSERT(internal);
> - if (!internal->current_path) {
> - return;
> - }
> - PathPoint *end_point =&internal->points[internal->current_path->start_point];
> - glc_path_line_to(path, end_point->x, Y(end_point->y));
> - glc_path_move_to(path, end_point->x, Y(end_point->y));
> -}
> -
> -void glc_path_cleare(GLCPath path)
> -{
> - InternalPath *internal = (InternalPath *)path;
> -
> - ASSERT(internal);
> - internal->paths_pos = internal->segments_pos = 0;
> - internal->current_segment = NULL;
> - internal->current_path = NULL;
> -
> - internal->points[0].x = 0;
> - internal->points[0].y = 0;
> - internal->points_pos = 1;
> -}
> -
> -GLCPath glc_path_create(GLCCtx glc)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - InternalPath *path;
> -
> - ASSERT(ctx);
> - if (!(path = (InternalPath *)zmalloc(sizeof(*path)))) {
> - return NULL;
> - }
> -
> - path->paths = (Path *)malloc(sizeof(*path->paths) * (path->paths_size = 2));
> - if (!path->paths) {
> - goto error_1;
> - }
> -
> - path->segments = (PathSegment *)malloc(sizeof(*path->segments) * (path->segments_size = 4));
> - if (!path->segments) {
> - goto error_2;
> - }
> -
> - path->points = (PathPoint *)malloc(sizeof(*path->points) * (path->points_size = 20));
> - if (!path->points) {
> - goto error_3;
> - }
> -
> - path->owner = ctx;
> - path->points_pos = 1;
> - return path;
> -
> -error_3:
> - free(path->segments);
> -
> -error_2:
> - free(path->paths);
> -
> -error_1:
> - free(path);
> -
> - return NULL;
> -}
> -
> -void glc_path_destroy(GLCPath path)
> -{
> - InternalPath *internal = (InternalPath *)path;
> -
> - if (!path) {
> - return;
> - }
> -
> - free(internal->points);
> - free(internal->segments);
> - free(internal->paths);
> - free(internal);
> -}
> -
> -static inline void unref_pat(InternalPat *pat)
> -{
> - if (!pat) {
> - return;
> - }
> - ASSERT(pat->refs> 0);
> - if (--pat->refs == 0) {
> - glFinish();
> - glDeleteTextures(1,&pat->texture);
> - free(pat);
> - }
> - GLC_ERROR_TETS;
> -}
> -
> -static inline InternalPat *ref_pat(InternalPat *pat)
> -{
> - pat->refs++;
> - return pat;
> -}
> -
> -#ifdef WIN32
> -static inline int find_msb(uint32_t val)
> -{
> - uint32_t r;
> - __asm {
> - bsr eax, val
> - jnz found
> - mov eax, -1
> -
> - found:
> - mov r, eax
> - }
> - return r + 1;
> -}
> -#else
> -static inline int find_msb(uint32_t val)
> -{
> - int ret;
> -
> - asm("bsrl %1,%0\n\t"
> - "jnz 1f\n\t"
> - "movl $-1,%0\n"
> - "1:"
> - : "=r"(ret) : "r"(val));
> - return ret + 1;
> -}
> -#endif
> -
> -static int to_pwoer_two(uint32_t val)
> -{
> - if ((val& (val - 1)) == 0) {
> - return val;
> - }
> - return 1<< find_msb(val);
> -}
> -
> -static void scale(uint32_t *dest, uint32_t dest_width, uint32_t dest_height,
> - uint32_t *src, uint32_t src_width, uint32_t src_height, int src_stride)
> -{
> - double x_scale = (double)src_width / dest_width;
> - double y_scale = (double)src_height / dest_height;
> - uint32_t i;
> - uint32_t j;
> - int prev_row = -1;
> -
> - for (i = 0; i< dest_height; i++) {
> - int row = (int)(y_scale * i);
> - if (row == prev_row) {
> - memcpy(dest, dest - dest_width, dest_width * sizeof(uint32_t));
> - dest += dest_width;
> - continue;
> - }
> - for (j = 0; j< dest_width; j++) {
> - int col = (int)(x_scale * j);
> - *(dest++) = *(src + col);
> - }
> - prev_row = row;
> - src = (uint32_t *)((uint8_t *)src + src_stride);
> - }
> -}
> -
> -static inline void init_pattern(InternalPat *pat, int x_orign, int y_orign, const GLCImage *image)
> -{
> - InternaCtx *ctx = pat->owner;
> - uint32_t *tmp_pixmap = NULL;
> - int width;
> - int height;
> - int width2;
> - int height2;
> -
> - const int pix_bytes = 4;
> -
> - ASSERT(image->format == GLC_IMAGE_RGB32); //for now
> -
> - width = image->width;
> - height = image->height;
> - width2 = to_pwoer_two(width);
> - height2 = to_pwoer_two(height);
> -
> - ASSERT(width> 0&& height> 0);
> - ASSERT(width> 0&& width<= pat->owner->max_texture_size);
> - ASSERT(height> 0&& height<= pat->owner->max_texture_size);
> -
> - if (width2 != width || height2 != height) {
> - if (!(tmp_pixmap = (uint32_t *)malloc(width2 * height2 * sizeof(uint32_t)))) {
> - //warn
> - return;
> - }
> - scale(tmp_pixmap, width2, height2, (uint32_t *)image->pixels, width, height, image->stride);
> - }
> -
> - glBindTexture(GL_TEXTURE_2D, pat->texture);
> -
> - //glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
> -
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
> -
> - if (tmp_pixmap) {
> - glPixelStorei(GL_UNPACK_ROW_LENGTH, width2);
> - glTexImage2D(GL_TEXTURE_2D, 0, 4, width2, height2, 0, GL_BGRA, GL_UNSIGNED_BYTE,
> - tmp_pixmap);
> - free(tmp_pixmap);
> - } else {
> - ASSERT(image->stride % pix_bytes == 0);
> - glPixelStorei(GL_UNPACK_ROW_LENGTH, image->stride / pix_bytes);
> - glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
> - image->pixels);
> - }
> -
> - GLC_ERROR_TETS;
> - pat->x_orign = x_orign % width;
> - pat->y_orign = y_orign % height;
> - pat->width = width;
> - pat->height = height;
> -
> - if (ctx->pat == pat) {
> - set_pat(pat->owner, pat);
> - } else if (ctx->pat) {
> - glBindTexture(GL_TEXTURE_2D, ctx->pat->texture);
> - }
> -}
> -
> -GLCPattern glc_pattern_create(GLCCtx glc, int x_orign, int y_orign, const GLCImage *image)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - InternalPat *pat;
> -
> - ASSERT(ctx&& image);
> -
> - if (!(pat = (InternalPat *)zmalloc(sizeof(*pat)))) {
> - return NULL;
> - }
> - pat->refs = 1;
> - pat->owner = ctx;
> - glGenTextures(1,&pat->texture);
> - init_pattern(pat, x_orign, y_orign, image);
> - return pat;
> -}
> -
> -void glc_pattern_set(GLCPattern pattern, int x_orign, int y_orign, const GLCImage *image)
> -{
> - InternalPat *pat = (InternalPat *)pattern;
> - ASSERT(pat&& pat->owner);
> -
> - glFinish();
> - init_pattern(pat, x_orign, y_orign, image);
> -}
> -
> -void glc_pattern_destroy(GLCPattern pat)
> -{
> - unref_pat((InternalPat *)pat);
> - GLC_ERROR_TETS;
> -}
> -
> -static void set_pat(InternaCtx *ctx, InternalPat *pat)
> -{
> - pat = ref_pat(pat);
> - unref_pat(ctx->pat);
> - ctx->pat = pat;
> -
> - glEnable(GL_TEXTURE_2D);
> - glBindTexture(GL_TEXTURE_2D, pat->texture);
> -
> - GLfloat s_gen_params[] = { (GLfloat)1.0 / pat->width, 0, 0, 0 };
> - GLfloat t_gen_params[] = { 0, (GLfloat)1.0 / (GLfloat)pat->height, 0, 0 };
> - glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params);
> - glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params);
> -
> - glMatrixMode(GL_TEXTURE);
> - glLoadIdentity();
> - glTranslatef((float)pat->x_orign / pat->width, (float)Y(pat->y_orign) / pat->height, 0);
> - GLC_ERROR_TETS;
> -}
> -
> -void glc_set_pattern(GLCCtx glc, GLCPattern pattern)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - InternalPat *pat = (InternalPat *)pattern;
> -
> - ASSERT(ctx&& pat&& pat->owner == ctx);
> - set_pat(ctx, pat);
> -}
> -
> -void glc_set_rgb(GLCCtx glc, double red, double green, double blue)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx);
> -
> - glDisable(GL_TEXTURE_2D);
> - unref_pat(ctx->pat);
> - ctx->pat = NULL;
> - glColor4d(red, green, blue, 1);
> - GLC_ERROR_TETS;
> -}
> -
> -void glc_set_op(GLCCtx glc, GLCOp op)
> -{
> - if (op == GL_COPY) {
> - glDisable(GL_COLOR_LOGIC_OP);
> - return;
> - }
> - glLogicOp(op);
> - glEnable(GL_COLOR_LOGIC_OP);
> -}
> -
> -void glc_set_line_width(GLCCtx glc, double width)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx);
> - ctx->line_width = (GLfloat)width;
> - if (ctx->line_width> 0) {
> - glLineWidth(ctx->line_width);
> - } else {
> - ctx->line_width = 0;
> - }
> - GLC_ERROR_TETS;
> -}
> -
> -void glc_set_fill_mode(GLCCtx glc, GLCFillMode fill_mode)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx);
> - int mode;
> - switch (fill_mode) {
> - case GLC_FILL_MODE_WINDING_ODD:
> - mode = GLU_TESS_WINDING_ODD;
> - break;
> - case GLC_FILL_MODE_WINDING_NONZERO:
> - mode = GLU_TESS_WINDING_NONZERO;
> - break;
> - default:
> - //warn
> - return;
> - }
> - gluTessProperty(ctx->tesselator, GLU_TESS_WINDING_RULE, mode);
> -}
> -
> -static inline void add_stencil_client(InternaCtx *ctx)
> -{
> - if (!ctx->stencil_refs) {
> - glEnable(GL_STENCIL_TEST);
> - }
> - ctx->stencil_refs++;
> -}
> -
> -static inline void remove_stencil_client(InternaCtx *ctx)
> -{
> - ctx->stencil_refs--;
> - if (!ctx->stencil_refs) {
> - glDisable(GL_STENCIL_TEST);
> - }
> -}
> -
> -void glc_set_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
> - int stride, const uint8_t *bitmap, GLCMaskID id)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
> - ASSERT(ctx&& bitmap);
> - ASSERT(id == GLC_MASK_A || id == GLC_MASK_B);
> -
> - if (ctx->pat) {
> - glDisable(GL_TEXTURE_2D);
> - }
> -
> - glDisable(GL_BLEND);
> -
> - if (!(ctx->stencil_mask& mask)) {
> - add_stencil_client(ctx);
> - ctx->stencil_mask |= mask;
> - }
> -
> - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
> - ctx->draw_mode = FALSE;
> - glStencilMask(mask);
> - glClear(GL_STENCIL_BUFFER_BIT);
> -
> - glStencilFunc(GL_ALWAYS, mask, mask);
> - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
> - fill_mask(ctx, x_dest, y_dest, width, height, stride, bitmap);
> -}
> -
> -
> -void glc_mask_rects(GLCCtx glc, int num_rect, GLCRect *rects, GLCMaskID id)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
> - GLCRect *end;
> - ASSERT(ctx&& rects);
> - ASSERT(id == GLC_MASK_A || id == GLC_MASK_B);
> -
> - if (ctx->pat) {
> - glDisable(GL_TEXTURE_2D);
> - }
> -
> - glDisable(GL_BLEND);
> -
> - if (!(ctx->stencil_mask& mask)) {
> - add_stencil_client(ctx);
> - ctx->stencil_mask |= mask;
> - }
> -
> - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
> - ctx->draw_mode = FALSE;
> - glStencilMask(mask);
> - glClear(GL_STENCIL_BUFFER_BIT);
> -
> - glStencilFunc(GL_ALWAYS, mask, mask);
> - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
> - end = rects + num_rect;
> - for (; rects< end; rects++) {
> - fill_rect(ctx, rects);
> - }
> -}
> -
> -void glc_clear_mask(GLCCtx glc, GLCMaskID id)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
> - ASSERT(ctx);
> - ASSERT(id == GLC_MASK_A || id == GLC_MASK_B);
> -
> - if ((ctx->stencil_mask& mask)) {
> - ctx->stencil_mask&= ~mask;
> - remove_stencil_client(ctx);
> - }
> -}
> -
> -void glc_clip_reset(GLCCtx glc)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - if (!(ctx->stencil_mask& 0x03)) {
> - return;
> - }
> - remove_stencil_client(ctx);
> - ctx->stencil_mask&= ~0x03;
> - glStencilMask(0x03);
> - glClear(GL_STENCIL_BUFFER_BIT);
> - GLC_ERROR_TETS;
> -}
> -
> -static void clip_common(InternaCtx *ctx, GLCClipOp op, void (*fill_func)(InternaCtx *, void *),
> - void *data)
> -{
> - int stencil_val;
> -
> - if (ctx->pat) {
> - glDisable(GL_TEXTURE_2D);
> - }
> - glDisable(GL_BLEND);
> - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
> - ctx->draw_mode = FALSE;
> -
> - if (op == GLC_CLIP_OP_SET) {
> - glc_clip_reset(ctx);
> - add_stencil_client(ctx);
> - ctx->stencil_mask |= 0x01;
> - } else if (!(ctx->stencil_mask& 0x03)) {
> - GLCRect area;
> - if (op == GLC_CLIP_OP_OR) {
> - return;
> - }
> - area.x = area.y = 0;
> - area.width= ctx->width;
> - area.height = ctx->height;
> - clip_common(ctx, GLC_CLIP_OP_SET, fill_rect,&area);
> - }
> - glStencilMask(0x03);
> - switch (op) {
> - case GLC_CLIP_OP_SET:
> - case GLC_CLIP_OP_OR:
> - stencil_val = ctx->stencil_mask& 0x03;
> - glStencilFunc(GL_ALWAYS, stencil_val, stencil_val);
> - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
> - fill_func(ctx, data);
> - break;
> - case GLC_CLIP_OP_AND: {
> - int clear_mask;
> - stencil_val = ctx->stencil_mask& 0x03;
> - glStencilFunc(GL_EQUAL, stencil_val, stencil_val);
> - if (stencil_val == 0x01) {
> - glStencilOp(GL_ZERO, GL_INCR, GL_INCR);
> - stencil_val = 0x02;
> - clear_mask = 0x01;
> - } else {
> - glStencilOp(GL_ZERO, GL_DECR, GL_DECR);
> - stencil_val = 0x01;
> - clear_mask = 0x02;
> - }
> - fill_func(ctx, data);
> -
> - glStencilMask(clear_mask);
> - glClear(GL_STENCIL_BUFFER_BIT);
> - ctx->stencil_mask = (ctx->stencil_mask& ~clear_mask) |stencil_val;
> - break;
> - }
> - case GLC_CLIP_OP_EXCLUDE:
> - stencil_val = ctx->stencil_mask& 0x03;
> - glStencilFunc(GL_EQUAL, stencil_val, stencil_val);
> - glStencilOp(GL_KEEP, GL_ZERO, GL_ZERO);
> - fill_func(ctx, data);
> - break;
> - }
> - GLC_ERROR_TETS;
> -}
> -
> -void glc_clip_rect(GLCCtx glc, const GLCRect *rect, GLCClipOp op)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx&& rect);
> - clip_common(ctx, op, fill_rect, (void *)rect);
> -}
> -
> -void glc_clip_path(GLCCtx glc, GLCPath path, GLCClipOp op)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx&& path);
> - clip_common(ctx, op, fill_path, path);
> -}
> -
> -typedef struct FillMaskInfo {
> - int x_dest;
> - int y_dest;
> - int width;
> - int height;
> - int stride;
> - const uint8_t *bitmap;
> -} FillMaskInfo;
> -
> -static void __fill_mask(InternaCtx *ctx, void *data)
> -{
> - FillMaskInfo *info = (FillMaskInfo *)data;
> - fill_mask(ctx, info->x_dest, info->y_dest, info->width, info->height, info->stride,
> - info->bitmap);
> -}
> -
> -void glc_clip_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
> - int stride, const uint8_t *bitmap, GLCClipOp op)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - FillMaskInfo mask_info;
> -
> - ASSERT(ctx&& bitmap);
> - mask_info.x_dest = x_dest;
> - mask_info.y_dest = y_dest;
> - mask_info.width = width;
> - mask_info.height = height;
> - mask_info.stride = stride;
> - mask_info.bitmap = bitmap;
> - clip_common(ctx, op, __fill_mask,&mask_info);
> -}
> -
> -static inline void start_draw(InternaCtx *ctx)
> -{
> - if (ctx->draw_mode) {
> - return;
> - }
> - ctx->draw_mode = TRUE;
> - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
> - glStencilFunc(GL_EQUAL, ctx->stencil_mask, ctx->stencil_mask);
> - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
> - if (ctx->pat) {
> - glEnable(GL_TEXTURE_2D);
> - } else {
> - glDisable(GL_TEXTURE_2D);
> - }
> - GLC_ERROR_TETS;
> -}
> -
> -static void fill_rect(InternaCtx *ctx, void *r)
> -{
> - GLCRect *rect = (GLCRect *)r;
> - glRectd(rect->x, Y(rect->y), rect->x + rect->width, Y(rect->y + rect->height));
> - /*glBegin(GL_POLYGON);
> - VERTEX2(rect->x, rect->y);
> - VERTEX2 (rect->x + rect->width, rect->y);
> - VERTEX2 (rect->x + rect->width, rect->y + rect->height);
> - VERTEX2 (rect->x , rect->y + rect->height);
> - glEnd();*/
> - GLC_ERROR_TETS;
> -}
> -
> -void glc_fill_rect(GLCCtx glc, const GLCRect *rect)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx);
> - start_draw(ctx);
> - fill_rect(ctx, (void *)rect);
> - GLC_ERROR_TETS;
> -}
> -
> -static void fill_path(InternaCtx *ctx, void *p)
> -{
> - InternalPath *path = (InternalPath *)p;
> -
> - PathPoint *current_point = path->points;
> - PathSegment *current_segment = path->segments;
> - Path *current_path = path->paths;
> - Path *end_path = current_path + path->paths_pos;
> - reset_tass_vertex(ctx);
> - gluTessBeginPolygon(ctx->tesselator, ctx);
> - for (; current_path< end_path; current_path++) {
> - gluTessBeginContour(ctx->tesselator);
> - PathSegment *end_segment = current_segment + current_path->num_segments;
> - gluTessVertex(ctx->tesselator, (GLdouble *)current_point, current_point);
> - current_point++;
> - for (; current_segment< end_segment; current_segment++) {
> - PathPoint *end_point;
> - if (current_segment->type == GLC_PATH_SEG_BEIZER) {
> - end_point = current_point + current_segment->count * 3;
> - for (; current_point< end_point; current_point += 3) {
> - TassVertex *vertex = bezier_flattener(ctx, current_point - 1);
> - while (vertex) {
> - gluTessVertex(ctx->tesselator, (GLdouble *)&vertex->point,
> - (GLdouble *)&vertex->point);
> - vertex = vertex->list_link;
> - }
> - gluTessVertex(ctx->tesselator, (GLdouble *)¤t_point[2],
> - (GLdouble *)¤t_point[2]);
> - }
> - } else {
> - ASSERT(current_segment->type == GLC_PATH_SEG_LINES);
> - end_point = current_point + current_segment->count;
> - for (; current_point< end_point; current_point++) {
> - gluTessVertex(ctx->tesselator, (GLdouble *)current_point ,
> - (GLdouble *)current_point);
> - }
> - }
> - }
> - gluTessEndContour(ctx->tesselator);
> - }
> - gluTessEndPolygon(ctx->tesselator);
> -}
> -
> -void glc_fill_path(GLCCtx glc, GLCPath path_ref)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx&& path_ref);
> - start_draw(ctx);
> - fill_path(ctx, path_ref);
> -}
> -
> -static void fill_mask(InternaCtx *ctx, int x_dest, int y_dest, int width, int height,
> - int stride, const uint8_t *bitmap)
> -{
> - set_raster_pos(ctx, x_dest, y_dest + height);
> - glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
> - glBitmap(width, height, 0, 0, 0, 0, bitmap);
> -}
> -
> -void _glc_fill_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
> - const uint8_t *bitmap)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx&& bitmap);
> - start_draw(ctx);
> - if (ctx->pat) {
> - WARN_ONCE(("%s: unimplemented fill mask with pattern\n", __FUNCTION__));
> - }
> - fill_mask(ctx, x_dest, y_dest, width, height, stride, bitmap);
> -}
> -
> -void glc_fill_alpha(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
> - const uint8_t *alpha_mask)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - GLCRect r;
> -
> - ASSERT(ctx);
> - start_draw(ctx);
> -
> - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
> - set_raster_pos(ctx, x_dest, y_dest + height);
> - glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
> - glPixelZoom(1, 1);
> - glDrawPixels(width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_mask);
> -
> - r.x = x_dest;
> - r.y = y_dest;
> - r.width = width;
> - r.height = height;
> -
> - //todo: support color/texture alpah vals (GL_MODULATE)
> - glEnable(GL_BLEND);
> - glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
> - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
> - fill_rect(ctx,&r);
> - glDisable(GL_BLEND);
> -}
> -
> -void glc_stroke_rect(GLCCtx glc, const GLCRect *rect)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx);
> - if (ctx->line_width == 0) {
> - return;
> - }
> -
> - start_draw(ctx);
> -
> - glBegin(GL_LINES);
> - VERTEX2 (rect->x , rect->y + 0.5);
> - VERTEX2 (rect->x + rect->width, rect->y + 0.5);
> - glEnd();
> -
> - glBegin(GL_LINES);
> - VERTEX2 (rect->x + rect->width - 0.5, rect->y);
> - VERTEX2 (rect->x + rect->width - 0.5, rect->y + rect->height);
> - glEnd();
> -
> - glBegin(GL_LINES);
> - VERTEX2 (rect->x + rect->width, rect->y + rect->height - 0.5);
> - VERTEX2 (rect->x, rect->y + rect->height - 0.5);
> - glEnd();
> -
> - glBegin(GL_LINES);
> - VERTEX2(rect->x + 0.5, rect->y + rect->height);
> - VERTEX2(rect->x + 0.5 , rect->y);
> - glEnd();
> - GLC_ERROR_TETS;
> -}
> -
> -void glc_stroke_path(GLCCtx glc, GLCPath path_ref)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - InternalPath *path = (InternalPath *)path_ref;
> -
> - ASSERT(ctx&& path);
> - if (ctx->line_width == 0) {
> - return;
> - }
> - start_draw(ctx);
> -
> - reset_tass_vertex(ctx);
> - PathPoint *current_point = path->points;
> - PathSegment *current_segment = path->segments;
> - Path *current_path = path->paths;
> - Path *end_path = current_path + path->paths_pos;
> - for (; current_path< end_path; current_path++) {
> - glBegin(GL_LINE_STRIP);
> - PathSegment *end_segment = current_segment + current_path->num_segments;
> - glVertex2d(current_point->x , current_point->y);
> - current_point++;
> - for (; current_segment< end_segment; current_segment++) {
> - PathPoint *end_point;
> - if (current_segment->type == GLC_PATH_SEG_BEIZER) {
> - end_point = current_point + current_segment->count * 3;
> - for (; current_point< end_point; current_point += 3) {
> - TassVertex *vertex = bezier_flattener(ctx, current_point - 1);
> - while (vertex) {
> - glVertex2d(vertex->point.x, vertex->point.y);
> - vertex = vertex->list_link;
> - }
> - glVertex2d(current_point[2].x , current_point[2].y);
> - }
> - } else {
> - ASSERT(current_segment->type == GLC_PATH_SEG_LINES);
> - end_point = current_point + current_segment->count;
> - for (; current_point< end_point; current_point++) {
> - glVertex2d(current_point->x , current_point->y);
> - }
> - }
> - }
> - glEnd();
> - }
> -}
> -
> -void glc_draw_image(GLCCtx glc, const GLCRecti *dest, const GLCRecti *src, const GLCImage *image,
> - int scale_mode, double alpha)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - uint8_t *pixels;
> - const int pix_bytes = 4;
> -
> - ASSERT(ctx&& image);
> - ASSERT(src->width> 0&& src->height> 0);
> -
> - ASSERT(image->format == GLC_IMAGE_RGB32 || image->format == GLC_IMAGE_ARGB32); //for now
> - start_draw(ctx);
> - if (ctx->pat) {
> - glDisable(GL_TEXTURE_2D);
> - }
> - set_raster_pos(ctx, dest->x, dest->y + dest->height);
> -
> - if (dest->width == src->width&& src->height == dest->height) {
> - glPixelZoom(1, 1);
> - } else {
> - glPixelZoom((float)dest->width / src->width, (float)dest->height / src->height);
> - }
> -
> - pixels = image->pixels + src->x * 4 + (image->height - (src->y + src->height)) * image->stride;
> - if (image->format == GLC_IMAGE_ARGB32 || alpha != 1) {
> - glPixelTransferf(GL_ALPHA_SCALE, (GLfloat)alpha);
> - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
> - glEnable(GL_BLEND);
> - }
> - ASSERT(image->stride % pix_bytes == 0);
> - glPixelStorei(GL_UNPACK_ROW_LENGTH, image->stride / pix_bytes);
> - glDrawPixels(src->width, src->height, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
> -
> - if (image->format == GLC_IMAGE_ARGB32 || alpha != 1) {
> - glDisable(GL_BLEND);
> - }
> -
> - if (ctx->pat) {
> - glEnable(GL_TEXTURE_2D);
> - }
> - GLC_ERROR_TETS;
> -}
> -
> -void glc_copy_pixels(GLCCtx glc, int x_dest, int y_dest, int x_src, int y_src, int width,
> - int height)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> - ASSERT(ctx);
> -#ifdef USE_COPY_PIXELS
> - start_draw(ctx);
> - if (ctx->pat) {
> - glDisable(GL_TEXTURE_2D);
> - }
> - set_raster_pos(ctx, x_dest, y_dest + height);
> - glPixelZoom(1, 1);
> - glCopyPixels(x_src, ctx->height - (y_src + height), width, height, GL_COLOR);
> - if (ctx->pat) {
> - glEnable(GL_TEXTURE_2D);
> - }
> -#else
> - GLuint texture;
> - int width2 = to_pwoer_two(width);
> - int height2 = to_pwoer_two(height);
> -
> - start_draw(ctx);
> - glEnable(GL_TEXTURE_2D);
> - glGenTextures(1,&texture);
> - glBindTexture(GL_TEXTURE_2D, texture);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
> - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
> -
> - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x_src, ctx->height - (y_src + height),
> - width2, height2, 0);
> -
> - GLfloat s_gen_params[] = { (GLfloat)1.0 / width2, 0, 0, 0 };
> - GLfloat t_gen_params[] = { 0, (GLfloat)1.0 / height2, 0, 0 };
> - glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params);
> - glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params);
> -
> - glMatrixMode(GL_TEXTURE);
> - glLoadIdentity();
> - glTranslatef((float)-x_dest / width2, (float)-Y(y_dest + height) / height2, 0);
> -
> - glRecti(x_dest, Y(y_dest), x_dest + width, Y(y_dest + height));
> - glFinish();
> - glDeleteTextures(1,&texture);
> - if (!ctx->pat) {
> - glDisable(GL_TEXTURE_2D);
> - } else {
> - set_pat(ctx, ctx->pat);
> - }
> -#endif
> - GLC_ERROR_TETS;
> -}
> -
> -void glc_read_pixels(GLCCtx glc, int x, int y, GLCImage *image)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx&& image);
> - ASSERT(image->format == GLC_IMAGE_RGB32); //for now
> - ASSERT((image->stride % 4) == 0); //for now
> - glPixelStorei(GL_PACK_ROW_LENGTH, image->stride / 4);
> - glReadPixels(x, ctx->height - (y + image->height), image->width, image->height,
> - GL_BGRA, GL_UNSIGNED_BYTE, image->pixels);
> -}
> -
> -void glc_clear(GLCCtx glc)
> -{
> - InternaCtx *ctx = (InternaCtx *)glc;
> -
> - ASSERT(ctx);
> - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
> - glClear(GL_COLOR_BUFFER_BIT);
> -}
> -
> -void glc_flush(GLCCtx glc)
> -{
> - glFlush();
> -
> - GLC_ERROR_TETS;
> -}
> -
> -static void tessellation_combine(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4],
> - GLdouble **data_out, void *usr_data)
> -{
> - TassVertex *vertex;
> -
> - if (!(vertex = alloc_tess_vertex((InternaCtx *)usr_data))) {
> - *data_out = NULL;
> - return;
> - }
> - vertex->point.x = coords[0];
> - vertex->point.y = coords[1];
> - //vertex->point.z = coords[2];
> - *data_out = (GLdouble *)&vertex->point;
> -}
> -
> -static void tessellation_error(GLenum errorCode)
> -{
> - printf ("%s: %s\n", __FUNCTION__, gluErrorString(errorCode));
> -}
> -
> -#ifdef WIN32
> -#define TESS_CALL_BACK_TYPE void (CALLBACK *)()
> -#else
> -#define TESS_CALL_BACK_TYPE void (*)()
> -#endif
> -
> -static int init(InternaCtx *ctx, int width, int height)
> -{
> -#ifdef WIN32
> - if (!(ctx->glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquation"))) {
> - return FALSE;
> - }
> -#endif
> - ctx->width = width;
> - ctx->height = height;
> - ctx->line_width = 1;
> -
> - glClearColor(0, 0, 0, 0);
> - glClearStencil(0);
> -
> - if (!(ctx->tesselator = gluNewTess())) {
> - return FALSE;
> - }
> -
> - glViewport(0, 0, width, height);
> - glMatrixMode(GL_PROJECTION);
> - glLoadIdentity();
> - glOrtho(0, width, 0, height, -1, 1);
> -
> - gluTessProperty(ctx->tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
> - gluTessCallback(ctx->tesselator, GLU_BEGIN, (TESS_CALL_BACK_TYPE)glBegin);
> - gluTessCallback(ctx->tesselator, GLU_VERTEX, (TESS_CALL_BACK_TYPE)glVertex3dv);
> - gluTessCallback(ctx->tesselator, GLU_END, (TESS_CALL_BACK_TYPE)glEnd);
> - gluTessCallback(ctx->tesselator, GLU_TESS_COMBINE_DATA, (TESS_CALL_BACK_TYPE)tessellation_combine);
> - gluTessCallback(ctx->tesselator, GLU_TESS_ERROR, (TESS_CALL_BACK_TYPE)tessellation_error);
> -
> - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
> - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
> - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
> - glEnable(GL_TEXTURE_GEN_S);
> - glEnable(GL_TEXTURE_GEN_T);
> -
> - glMatrixMode(GL_MODELVIEW);
> - glLoadIdentity();
> - glTranslatef(0, (GLfloat)height, 0);
> -
> - glGetIntegerv( GL_MAX_TEXTURE_SIZE,&ctx->max_texture_size);
> -
> - glPixelStorei(GL_PACK_ALIGNMENT, 1);
> -
> - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
> - glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
> - glPixelTransferf(GL_ALPHA_BIAS, 0);
> -#ifdef WIN32
> - ctx->glBlendEquation(GL_FUNC_ADD);
> -#else
> - glBlendEquation(GL_FUNC_ADD);
> -#endif
> -
> - glStencilMask(0xff);
> - glClear(GL_STENCIL_BUFFER_BIT);
> -
> - glClear(GL_COLOR_BUFFER_BIT);
> -
> - return TRUE;
> -}
> -
> -GLCCtx glc_create(int width, int height)
> -{
> - InternaCtx *ctx;
> -
> - ASSERT(sizeof(PathPoint) == sizeof(Vertex));
> -
> - if (!(ctx = (InternaCtx *)zmalloc(sizeof(*ctx)))) {
> - return NULL;
> - }
> -
> - if (!init(ctx, width, height)) {
> - free(ctx);
> - return NULL;
> - }
> - return ctx;
> -}
> -
> -void glc_destroy(GLCCtx glc)
> -{
> - InternaCtx *ctx;
> -
> - if (!(ctx = (InternaCtx *)glc)) {
> - return;
> - }
> -
> - unref_pat(ctx->pat);
> - free_tass_vertex_bufs(ctx);
> - free(ctx);
> -}
> -
> -/*
> - todo:
> - 1. test double vs float in gl calls
> - 2. int vs flat raster position
> - 3. pixels stride vs bytes stride
> - 4. improve non power of two.
> - glGetString(GL_EXTENSIONS);
> - ARB_texture_non_power_of_two
> - ARB_texture_rectangle
> - GL_TEXTURE_RECTANGLE_ARB
> - 5. scale
> - 6. origin
> - 7. fonts
> - 8. support more image formats
> - 9. use GLCImage in mask ops?
> -*/
> -
> diff --git a/common/glc.h b/common/glc.h
> deleted file mode 100644
> index a6b8579..0000000
> --- a/common/glc.h
> +++ /dev/null
> @@ -1,159 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, write to the Free Software
> -
> - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> -*/
> -
> -#ifndef _H_GL_CANVASE
> -#define _H_GL_CANVASE
> -
> -#include<stdint.h>
> -
> -typedef void * GLCCtx;
> -typedef void * GLCPattern;
> -typedef void * GLCPath;
> -
> -typedef struct GLCRect {
> - double x;
> - double y;
> - double width;
> - double height;
> -} GLCRect;
> -
> -typedef struct GLCRecti {
> - int x;
> - int y;
> - int width;
> - int height;
> -} GLCRecti;
> -
> -typedef enum {
> - GLC_IMAGE_RGB32,
> - GLC_IMAGE_ARGB32,
> -} GLCImageFormat;
> -
> -typedef struct GLCPImage {
> - GLCImageFormat format;
> - int width;
> - int height;
> - int stride;
> - uint8_t *pixels;
> - uint32_t *pallet;
> -} GLCImage;
> -
> -GLCPattern glc_pattern_create(GLCCtx glc, int x_orign, int y_orign, const GLCImage *image);
> -void glc_pattern_set(GLCPattern pattern, int x_orign, int y_orign, const GLCImage *image);
> -void glc_pattern_destroy(GLCPattern pattern);
> -
> -void glc_path_move_to(GLCPath path, double x, double y);
> -void glc_path_line_to(GLCPath path, double x, double y);
> -void glc_path_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y,
> - double p3_x, double p3_y);
> -void glc_path_rel_move_to(GLCPath path, double x, double y);
> -void glc_path_rel_line_to(GLCPath path, double x, double y);
> -void glc_path_rel_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y,
> - double p3_x, double p3_y);
> -void glc_path_close(GLCPath path);
> -
> -void glc_path_cleare(GLCPath);
> -GLCPath glc_path_create(GLCCtx glc);
> -void glc_path_destroy(GLCPath path);
> -
> -void glc_set_rgb(GLCCtx glc, double red, double green, double blue);
> -void glc_set_rgba(GLCCtx glc, double red, double green, double blue, double alpha);
> -void glc_set_pattern(GLCCtx glc, GLCPattern pattern);
> -
> -typedef enum {
> - GLC_OP_CLEAR = 0x1500,
> - GLC_OP_SET = 0x150F,
> - GLC_OP_COPY = 0x1503,
> - GLC_OP_COPY_INVERTED = 0x150C,
> - GLC_OP_NOOP = 0x1505,
> - GLC_OP_INVERT = 0x150A,
> - GLC_OP_AND = 0x1501,
> - GLC_OP_NAND = 0x150E,
> - GLC_OP_OR = 0x1507,
> - GLC_OP_NOR = 0x1508,
> - GLC_OP_XOR = 0x1506,
> - GLC_OP_EQUIV = 0x1509,
> - GLC_OP_AND_REVERSE = 0x1502,
> - GLC_OP_AND_INVERTED = 0x1504,
> - GLC_OP_OR_REVERSE = 0x150B,
> - GLC_OP_OR_INVERTED = 0x150D,
> -} GLCOp;
> -
> -void glc_set_op(GLCCtx glc, GLCOp op);
> -void glc_set_alpha_factor(GLCCtx glc, double alpah);
> -
> -typedef enum {
> - GLC_FILL_MODE_WINDING_ODD,
> - GLC_FILL_MODE_WINDING_NONZERO,
> -} GLCFillMode;
> -
> -void glc_set_fill_mode(GLCCtx glc, GLCFillMode mode);
> -void glc_set_line_width(GLCCtx glc, double width);
> -void glc_set_line_end_cap(GLCCtx glc, int style);
> -void glc_set_line_join(GLCCtx glc, int style);
> -void glc_set_miter_limit(GLCCtx glc, int limit);
> -void glc_set_line_dash(GLCCtx glc, const double *dashes, int num_dashes, double offset);
> -
> -typedef enum {
> - GLC_MASK_A,
> - GLC_MASK_B,
> -} GLCMaskID;
> -
> -void glc_set_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
> - int stride, const uint8_t *bitmap, GLCMaskID id);
> -void glc_mask_rects(GLCCtx glc, int num_rect, GLCRect *rects, GLCMaskID id);
> -void glc_clear_mask(GLCCtx glc, GLCMaskID id);
> -
> -typedef enum {
> - GLC_CLIP_OP_SET,
> - GLC_CLIP_OP_OR,
> - GLC_CLIP_OP_AND,
> - GLC_CLIP_OP_EXCLUDE,
> -} GLCClipOp;
> -
> -void glc_clip_rect(GLCCtx glc, const GLCRect *rect, GLCClipOp op);
> -void glc_clip_path(GLCCtx glc, GLCPath path, GLCClipOp op);
> -void glc_clip_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
> - const uint8_t *bitmap, GLCClipOp op);
> -void glc_clip_reset(GLCCtx glc);
> -
> -void glc_fill_rect(GLCCtx glc, const GLCRect *rect);
> -void glc_fill_path(GLCCtx glc, GLCPath path);
> -void _glc_fill_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
> - const uint8_t *bitmap);
> -void glc_fill_alpha(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
> - const uint8_t *alpha_mask);
> -
> -void glc_stroke_rect(GLCCtx glc, const GLCRect *rect);
> -void glc_stroke_path(GLCCtx glc, GLCPath path);
> -
> -void glc_draw_image(GLCCtx glc, const GLCRecti *dest, const GLCRecti *src, const GLCImage *image,
> - int scale_mode, double alpha);
> -
> -void glc_copy_pixels(GLCCtx glc, int x_dest, int y_dest, int x_src, int y_src, int width,
> - int height);
> -void glc_read_pixels(GLCCtx glc, int x, int y, GLCImage *image);
> -
> -void glc_flush(GLCCtx glc);
> -void glc_clear(GLCCtx glc);
> -GLCCtx glc_create(int width, int height);
> -void glc_destroy(GLCCtx glc, int textures_lost);
> -
> -#endif
> diff --git a/common/lines.c b/common/lines.c
> deleted file mode 100644
> index ee52a46..0000000
> --- a/common/lines.c
> +++ /dev/null
> @@ -1,3618 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/***********************************************************
> -
> -Copyright 1989, 1998 The Open Group
> -
> -Permission to use, copy, modify, distribute, and sell this software and its
> -documentation for any purpose is hereby granted without fee, provided that
> -the above copyright notice appear in all copies and that both that
> -copyright notice and this permission notice appear in supporting
> -documentation.
> -
> -The above copyright notice and this permission notice shall be included in
> -all copies or substantial portions of the Software.
> -
> -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
> -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> -
> -Except as contained in this notice, the name of The Open Group shall not be
> -used in advertising or otherwise to promote the sale, use or other dealings
> -in this Software without prior written authorization from The Open Group.
> -
> -
> -Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
> -
> - All Rights Reserved
> -
> -Permission to use, copy, modify, and distribute this software and its
> -documentation for any purpose and without fee is hereby granted,
> -provided that the above copyright notice appear in all copies and that
> -both that copyright notice and this permission notice appear in
> -supporting documentation, and that the name of Digital not be
> -used in advertising or publicity pertaining to distribution of the
> -software without specific, written prior permission.
> -
> -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
> -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
> -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
> -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
> -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
> -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
> -SOFTWARE.
> -
> -******************************************************************/
> -
> -
> -#include<stdio.h>
> -#include<spice/macros.h>
> -#ifdef _XOPEN_SOURCE
> -#include<math.h>
> -#else
> -#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
> -#include<math.h>
> -#undef _XOPEN_SOURCE
> -#endif
> -#include "lines.h"
> -#include "mem.h"
> -
> -#define xalloc(i) spice_malloc(i)
> -#define xrealloc(a,b) spice_realloc(a,b)
> -#define xfree(i) free(i)
> -
> -typedef unsigned int CARD32;
> -typedef int Boolean;
> -typedef pixman_rectangle32_t xRectangle;
> -typedef SpicePoint DDXPointRec;
> -typedef DDXPointRec *DDXPointPtr;
> -typedef struct lineGC *GCPtr;
> -
> -/* largest positive value that can fit into a component of a point.
> - * Assumes that the point structure is {type x, y;} where type is
> - * a signed type.
> - */
> -#define MAX_COORDINATE 2147483647
> -#define MIN_COORDINATE -2147483647
> -
> -#define miZeroLine spice_canvas_zero_line
> -#define miZeroDashLine spice_canvas_zero_dash_line
> -#define miWideDash spice_canvas_wide_dash_line
> -#define miWideLine spice_canvas_wide_line
> -
> -static inline int
> -ICEIL (double x)
> -{
> - int _cTmp = (int)x;
> - return ((x == _cTmp) || (x< 0.0)) ? _cTmp : _cTmp + 1;
> -}
> -
> -typedef struct {
> - int count; /* number of spans */
> - DDXPointPtr points; /* pointer to list of start points */
> - int *widths; /* pointer to list of widths */
> -} Spans;
> -
> -typedef struct {
> - int size; /* Total number of *Spans allocated */
> - int count; /* Number of *Spans actually in group */
> - Spans *group; /* List of Spans */
> - int ymin, ymax; /* Min, max y values encountered */
> -} SpanGroup;
> -
> -/* Initialize SpanGroup. MUST BE DONE before use. */
> -static void miInitSpanGroup (SpanGroup * /*spanGroup */
> - );
> -
> -/* Add a Spans to a SpanGroup. The spans MUST BE in y-sorted order */
> -static void miAppendSpans (SpanGroup * /*spanGroup */ ,
> - SpanGroup * /*otherGroup */ ,
> - Spans * /*spans */
> - );
> -
> -/* Paint a span group, insuring that each pixel is painted at most once */
> -static void miFillUniqueSpanGroup (GCPtr /*pGC */ ,
> - SpanGroup * /*spanGroup */ ,
> - Boolean /* foreground */
> - );
> -
> -/* Free up data in a span group. MUST BE DONE or you'll suffer memory leaks */
> -static void miFreeSpanGroup (SpanGroup * /*spanGroup */
> - );
> -
> -/* Rops which must use span groups */
> -#define miSpansCarefulRop(rop) (((rop)& 0xc) == 0x8 || ((rop)& 0x3) == 0x2)
> -#define miSpansEasyRop(rop) (!miSpansCarefulRop(rop))
> -
> -/*
> - * Public definitions used for configuring basic pixelization aspects
> - * of the sample implementation line-drawing routines provided in
> - * {mfb,mi,cfb*} at run-time.
> - */
> -
> -#define XDECREASING 4
> -#define YDECREASING 2
> -#define YMAJOR 1
> -
> -#define OCTANT1 (1<< (YDECREASING))
> -#define OCTANT2 (1<< (YDECREASING|YMAJOR))
> -#define OCTANT3 (1<< (XDECREASING|YDECREASING|YMAJOR))
> -#define OCTANT4 (1<< (XDECREASING|YDECREASING))
> -#define OCTANT5 (1<< (XDECREASING))
> -#define OCTANT6 (1<< (XDECREASING|YMAJOR))
> -#define OCTANT7 (1<< (YMAJOR))
> -#define OCTANT8 (1<< (0))
> -
> -#define XMAJOROCTANTS (OCTANT1 | OCTANT4 | OCTANT5 | OCTANT8)
> -
> -#define DEFAULTZEROLINEBIAS (OCTANT2 | OCTANT3 | OCTANT4 | OCTANT5)
> -
> -/*
> - * Devices can configure the rendering of routines in mi, mfb, and cfb*
> - * by specifying a thin line bias to be applied to a particular screen
> - * using the following function. The bias parameter is an OR'ing of
> - * the appropriate OCTANT constants defined above to indicate which
> - * octants to bias a line to prefer an axial step when the Bresenham
> - * error term is exactly zero. The octants are mapped as follows:
> - *
> - * \ | /
> - * \ 3 | 2 /
> - * \ | /
> - * 4 \ | / 1
> - * \|/
> - * -----------
> - * /|\
> - * 5 / | \ 8
> - * / | \
> - * / 6 | 7 \
> - * / | \
> - *
> - * For more information, see "Ambiguities in Incremental Line Rastering,"
> - * Jack E. Bresenham, IEEE CG&A, May 1987.
> - */
> -
> -/*
> - * Private definitions needed for drawing thin (zero width) lines
> - * Used by the mi, mfb, and all cfb* components.
> - */
> -
> -#define X_AXIS 0
> -#define Y_AXIS 1
> -
> -#define OUT_LEFT 0x08
> -#define OUT_RIGHT 0x04
> -#define OUT_ABOVE 0x02
> -#define OUT_BELOW 0x01
> -
> -#define OUTCODES(_result, _x, _y, _pbox) \
> - if ( (_x)< (_pbox)->x1) (_result) |= OUT_LEFT; \
> - else if ( (_x)>= (_pbox)->x2) (_result) |= OUT_RIGHT; \
> - if ( (_y)< (_pbox)->y1) (_result) |= OUT_ABOVE; \
> - else if ( (_y)>= (_pbox)->y2) (_result) |= OUT_BELOW;
> -
> -#define MIOUTCODES(outcode, x, y, xmin, ymin, xmax, ymax) \
> -{\
> - if (x< xmin) outcode |= OUT_LEFT;\
> - if (x> xmax) outcode |= OUT_RIGHT;\
> - if (y< ymin) outcode |= OUT_ABOVE;\
> - if (y> ymax) outcode |= OUT_BELOW;\
> -}
> -
> -#define SWAPINT(i, j) \
> -{ int _t = i; i = j; j = _t; }
> -
> -#define SWAPPT(i, j) \
> -{ DDXPointRec _t; _t = i; i = j; j = _t; }
> -
> -#define SWAPINT_PAIR(x1, y1, x2, y2)\
> -{ int t = x1; x1 = x2; x2 = t;\
> - t = y1; y1 = y2; y2 = t;\
> -}
> -
> -#define miGetZeroLineBias(_pScreen) (DEFAULTZEROLINEBIAS)
> -
> -#define CalcLineDeltas(_x1,_y1,_x2,_y2,_adx,_ady,_sx,_sy,_SX,_SY,_octant) \
> - (_octant) = 0; \
> - (_sx) = (_SX); \
> - if (((_adx) = (_x2) - (_x1))< 0) { \
> - (_adx) = -(_adx); \
> - (_sx = -(_sx)); \
> - (_octant) |= XDECREASING; \
> - } \
> - (_sy) = (_SY); \
> - if (((_ady) = (_y2) - (_y1))< 0) { \
> - (_ady) = -(_ady); \
> - (_sy = -(_sy)); \
> - (_octant) |= YDECREASING; \
> - }
> -
> -#define SetYMajorOctant(_octant) ((_octant) |= YMAJOR)
> -
> -#define FIXUP_ERROR(_e, _octant, _bias) \
> - (_e) -= (((_bias)>> (_octant))& 1)
> -
> -#define IsXMajorOctant(_octant) (!((_octant)& YMAJOR))
> -#define IsYMajorOctant(_octant) ((_octant)& YMAJOR)
> -#define IsXDecreasingOctant(_octant) ((_octant)& XDECREASING)
> -#define IsYDecreasingOctant(_octant) ((_octant)& YDECREASING)
> -
> -static int miZeroClipLine (int /*xmin */ ,
> - int /*ymin */ ,
> - int /*xmax */ ,
> - int /*ymax */ ,
> - int * /*new_x1 */ ,
> - int * /*new_y1 */ ,
> - int * /*new_x2 */ ,
> - int * /*new_y2 */ ,
> - unsigned int /*adx */ ,
> - unsigned int /*ady */ ,
> - int * /*pt1_clipped */ ,
> - int * /*pt2_clipped */ ,
> - int /*octant */ ,
> - unsigned int /*bias */ ,
> - int /*oc1 */ ,
> - int /*oc2 */
> - );
> -
> -/*
> - * interface data to span-merging polygon filler
> - */
> -
> -typedef struct _SpanData {
> - SpanGroup fgGroup, bgGroup;
> -} SpanDataRec, *SpanDataPtr;
> -
> -#define AppendSpanGroup(pGC, foreground, spanPtr, spanData) { \
> - SpanGroup *group, *othergroup = NULL; \
> - if (foreground) \
> - { \
> - group =&spanData->fgGroup; \
> - if (pGC->lineStyle == LineDoubleDash) \
> - othergroup =&spanData->bgGroup; \
> - } \
> - else \
> - { \
> - group =&spanData->bgGroup; \
> - othergroup =&spanData->fgGroup; \
> - } \
> - miAppendSpans (group, othergroup, spanPtr); \
> -}
> -
> -/*
> - * Polygon edge description for integer wide-line routines
> - */
> -
> -typedef struct _PolyEdge {
> - int height; /* number of scanlines to process */
> - int x; /* starting x coordinate */
> - int stepx; /* fixed integral dx */
> - int signdx; /* variable dx sign */
> - int e; /* initial error term */
> - int dy;
> - int dx;
> -} PolyEdgeRec, *PolyEdgePtr;
> -
> -#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - miter limit constant */
> -
> -/*
> - * types for general polygon routines
> - */
> -
> -typedef struct _PolyVertex {
> - double x, y;
> -} PolyVertexRec, *PolyVertexPtr;
> -
> -typedef struct _PolySlope {
> - int dx, dy;
> - double k; /* x0 * dy - y0 * dx */
> -} PolySlopeRec, *PolySlopePtr;
> -
> -/*
> - * Line face description for caps/joins
> - */
> -
> -typedef struct _LineFace {
> - double xa, ya;
> - int dx, dy;
> - int x, y;
> - double k;
> -} LineFaceRec, *LineFacePtr;
> -
> -/*
> - * macros for polygon fillers
> - */
> -
> -#define MIPOLYRELOADLEFT if (!left_height&& left_count) { \
> - left_height = left->height; \
> - left_x = left->x; \
> - left_stepx = left->stepx; \
> - left_signdx = left->signdx; \
> - left_e = left->e; \
> - left_dy = left->dy; \
> - left_dx = left->dx; \
> - --left_count; \
> - ++left; \
> - }
> -
> -#define MIPOLYRELOADRIGHT if (!right_height&& right_count) { \
> - right_height = right->height; \
> - right_x = right->x; \
> - right_stepx = right->stepx; \
> - right_signdx = right->signdx; \
> - right_e = right->e; \
> - right_dy = right->dy; \
> - right_dx = right->dx; \
> - --right_count; \
> - ++right; \
> - }
> -
> -#define MIPOLYSTEPLEFT left_x += left_stepx; \
> - left_e += left_dx; \
> - if (left_e> 0) \
> - { \
> - left_x += left_signdx; \
> - left_e -= left_dy; \
> - }
> -
> -#define MIPOLYSTEPRIGHT right_x += right_stepx; \
> - right_e += right_dx; \
> - if (right_e> 0) \
> - { \
> - right_x += right_signdx; \
> - right_e -= right_dy; \
> - }
> -
> -static void miRoundJoinClip (LineFacePtr /*pLeft */ ,
> - LineFacePtr /*pRight */ ,
> - PolyEdgePtr /*edge1 */ ,
> - PolyEdgePtr /*edge2 */ ,
> - int * /*y1 */ ,
> - int * /*y2 */ ,
> - Boolean * /*left1 */ ,
> - Boolean * /*left2 */
> - );
> -
> -static int miRoundCapClip (LineFacePtr /*face */ ,
> - Boolean /*isInt */ ,
> - PolyEdgePtr /*edge */ ,
> - Boolean * /*leftEdge */
> - );
> -
> -static int miPolyBuildEdge (double x0, double y0, double k, int dx, int dy,
> - int xi, int yi, int left, PolyEdgePtr edge);
> -static int miPolyBuildPoly (PolyVertexPtr vertices, PolySlopePtr slopes,
> - int count, int xi, int yi, PolyEdgePtr left,
> - PolyEdgePtr right, int *pnleft, int *pnright, int *h);
> -
> -
> -static void
> -miStepDash (int dist, /* distance to step */
> - int *pDashIndex, /* current dash */
> - unsigned char *pDash, /* dash list */
> - int numInDashList, /* total length of dash list */
> - int *pDashOffset /* offset into current dash */
> - )
> -{
> - int dashIndex, dashOffset;
> - int totallen;
> - int i;
> -
> - dashIndex = *pDashIndex;
> - dashOffset = *pDashOffset;
> - if (dist< pDash[dashIndex] - dashOffset) {
> - *pDashOffset = dashOffset + dist;
> - return;
> - }
> - dist -= pDash[dashIndex] - dashOffset;
> - if (++dashIndex == numInDashList)
> - dashIndex = 0;
> - totallen = 0;
> - for (i = 0; i< numInDashList; i++)
> - totallen += pDash[i];
> - if (totallen<= dist)
> - dist = dist % totallen;
> - while (dist>= pDash[dashIndex]) {
> - dist -= pDash[dashIndex];
> - if (++dashIndex == numInDashList)
> - dashIndex = 0;
> - }
> - *pDashIndex = dashIndex;
> - *pDashOffset = dist;
> -}
> -
> -/*
> -
> -These routines maintain lists of Spans, in order to implement the
> -``touch-each-pixel-once'' rules of wide lines and arcs.
> -
> -Written by Joel McCormack, Summer 1989.
> -
> -*/
> -
> -
> -static void
> -miInitSpanGroup (SpanGroup * spanGroup)
> -{
> - spanGroup->size = 0;
> - spanGroup->count = 0;
> - spanGroup->group = NULL;
> - spanGroup->ymin = MAX_COORDINATE;
> - spanGroup->ymax = MIN_COORDINATE;
> -} /* InitSpanGroup */
> -
> -#define YMIN(spans) (spans->points[0].y)
> -#define YMAX(spans) (spans->points[spans->count-1].y)
> -
> -static void
> -miSubtractSpans (SpanGroup * spanGroup, Spans * sub)
> -{
> - int i, subCount, spansCount;
> - int ymin, ymax, xmin, xmax;
> - Spans *spans;
> - DDXPointPtr subPt, spansPt;
> - int *subWid, *spansWid;
> - int extra;
> -
> - ymin = YMIN (sub);
> - ymax = YMAX (sub);
> - spans = spanGroup->group;
> - for (i = spanGroup->count; i; i--, spans++) {
> - if (YMIN (spans)<= ymax&& ymin<= YMAX (spans)) {
> - subCount = sub->count;
> - subPt = sub->points;
> - subWid = sub->widths;
> - spansCount = spans->count;
> - spansPt = spans->points;
> - spansWid = spans->widths;
> - extra = 0;
> - for (;;) {
> - while (spansCount&& spansPt->y< subPt->y) {
> - spansPt++;
> - spansWid++;
> - spansCount--;
> - }
> - if (!spansCount)
> - break;
> - while (subCount&& subPt->y< spansPt->y) {
> - subPt++;
> - subWid++;
> - subCount--;
> - }
> - if (!subCount)
> - break;
> - if (subPt->y == spansPt->y) {
> - xmin = subPt->x;
> - xmax = xmin + *subWid;
> - if (xmin>= spansPt->x + *spansWid || spansPt->x>= xmax) {
> - ;
> - } else if (xmin<= spansPt->x) {
> - if (xmax>= spansPt->x + *spansWid) {
> - memmove (spansPt, spansPt + 1, sizeof *spansPt * (spansCount - 1));
> - memmove (spansWid, spansWid + 1, sizeof *spansWid * (spansCount - 1));
> - spansPt--;
> - spansWid--;
> - spans->count--;
> - extra++;
> - } else {
> - *spansWid = *spansWid - (xmax - spansPt->x);
> - spansPt->x = xmax;
> - }
> - } else {
> - if (xmax>= spansPt->x + *spansWid) {
> - *spansWid = xmin - spansPt->x;
> - } else {
> - if (!extra) {
> - DDXPointPtr newPt;
> - int *newwid;
> -
> -#define EXTRA 8
> - newPt =
> - (DDXPointPtr) xrealloc (spans->points,
> - (spans->count +
> - EXTRA) * sizeof (DDXPointRec));
> - if (!newPt)
> - break;
> - spansPt = newPt + (spansPt - spans->points);
> - spans->points = newPt;
> - newwid =
> - (int *) xrealloc (spans->widths,
> - (spans->count + EXTRA) * sizeof (int));
> - if (!newwid)
> - break;
> - spansWid = newwid + (spansWid - spans->widths);
> - spans->widths = newwid;
> - extra = EXTRA;
> - }
> - memmove (spansPt + 1, spansPt, sizeof *spansPt * (spansCount));
> - memmove (spansWid + 1, spansWid, sizeof *spansWid * (spansCount));
> - spans->count++;
> - extra--;
> - *spansWid = xmin - spansPt->x;
> - spansWid++;
> - spansPt++;
> - *spansWid = *spansWid - (xmax - spansPt->x);
> - spansPt->x = xmax;
> - }
> - }
> - }
> - spansPt++;
> - spansWid++;
> - spansCount--;
> - }
> - }
> - }
> -}
> -
> -static void
> -miAppendSpans (SpanGroup * spanGroup, SpanGroup * otherGroup, Spans * spans)
> -{
> - int ymin, ymax;
> - int spansCount;
> -
> - spansCount = spans->count;
> - if (spansCount> 0) {
> - if (spanGroup->size == spanGroup->count) {
> - spanGroup->size = (spanGroup->size + 8) * 2;
> - spanGroup->group = (Spans *)
> - xrealloc (spanGroup->group, sizeof (Spans) * spanGroup->size);
> - }
> -
> - spanGroup->group[spanGroup->count] = *spans;
> - (spanGroup->count)++;
> - ymin = spans->points[0].y;
> - if (ymin< spanGroup->ymin)
> - spanGroup->ymin = ymin;
> - ymax = spans->points[spansCount - 1].y;
> - if (ymax> spanGroup->ymax)
> - spanGroup->ymax = ymax;
> - if (otherGroup&& otherGroup->ymin< ymax&& ymin< otherGroup->ymax) {
> - miSubtractSpans (otherGroup, spans);
> - }
> - } else {
> - xfree (spans->points);
> - xfree (spans->widths);
> - }
> -} /* AppendSpans */
> -
> -static void
> -miFreeSpanGroup (SpanGroup * spanGroup)
> -{
> - if (spanGroup->group != NULL)
> - xfree (spanGroup->group);
> -}
> -
> -static void
> -QuickSortSpansX (DDXPointRec points[], int widths[], int numSpans)
> -{
> - int x;
> - int i, j, m;
> - DDXPointPtr r;
> -
> -/* Always called with numSpans> 1 */
> -/* Sorts only by x, as all y should be the same */
> -
> -#define ExchangeSpans(a, b) \
> -{ \
> - DDXPointRec tpt; \
> - int tw; \
> - \
> - tpt = points[a]; points[a] = points[b]; points[b] = tpt; \
> - tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
> -}
> -
> - do {
> - if (numSpans< 9) {
> - /* Do insertion sort */
> - int xprev;
> -
> - xprev = points[0].x;
> - i = 1;
> - do { /* while i != numSpans */
> - x = points[i].x;
> - if (xprev> x) {
> - /* points[i] is out of order. Move into proper location. */
> - DDXPointRec tpt;
> - int tw, k;
> -
> - for (j = 0; x>= points[j].x; j++) {
> - }
> - tpt = points[i];
> - tw = widths[i];
> - for (k = i; k != j; k--) {
> - points[k] = points[k - 1];
> - widths[k] = widths[k - 1];
> - }
> - points[j] = tpt;
> - widths[j] = tw;
> - x = points[i].x;
> - } /* if out of order */
> - xprev = x;
> - i++;
> - } while (i != numSpans);
> - return;
> - }
> -
> - /* Choose partition element, stick in location 0 */
> - m = numSpans / 2;
> - if (points[m].x> points[0].x)
> - ExchangeSpans (m, 0);
> - if (points[m].x> points[numSpans - 1].x)
> - ExchangeSpans (m, numSpans - 1);
> - if (points[m].x> points[0].x)
> - ExchangeSpans (m, 0);
> - x = points[0].x;
> -
> - /* Partition array */
> - i = 0;
> - j = numSpans;
> - do {
> - r =&(points[i]);
> - do {
> - r++;
> - i++;
> - } while (i != numSpans&& r->x< x);
> - r =&(points[j]);
> - do {
> - r--;
> - j--;
> - } while (x< r->x);
> - if (i< j)
> - ExchangeSpans (i, j);
> - } while (i< j);
> -
> - /* Move partition element back to middle */
> - ExchangeSpans (0, j);
> -
> - /* Recurse */
> - if (numSpans - j - 1> 1)
> - QuickSortSpansX (&points[j + 1],&widths[j + 1], numSpans - j - 1);
> - numSpans = j;
> - } while (numSpans> 1);
> -} /* QuickSortSpans */
> -
> -
> -static int
> -UniquifySpansX (Spans * spans, DDXPointRec * newPoints, int *newWidths)
> -{
> - int newx1, newx2, oldpt, i, y;
> - DDXPointRec *oldPoints;
> - int *oldWidths;
> - int *startNewWidths;
> -
> -/* Always called with numSpans> 1 */
> -/* Uniquify the spans, and stash them into newPoints and newWidths. Return the
> - number of unique spans. */
> -
> -
> - startNewWidths = newWidths;
> -
> - oldPoints = spans->points;
> - oldWidths = spans->widths;
> -
> - y = oldPoints->y;
> - newx1 = oldPoints->x;
> - newx2 = newx1 + *oldWidths;
> -
> - for (i = spans->count - 1; i != 0; i--) {
> - oldPoints++;
> - oldWidths++;
> - oldpt = oldPoints->x;
> - if (oldpt> newx2) {
> - /* Write current span, start a new one */
> - newPoints->x = newx1;
> - newPoints->y = y;
> - *newWidths = newx2 - newx1;
> - newPoints++;
> - newWidths++;
> - newx1 = oldpt;
> - newx2 = oldpt + *oldWidths;
> - } else {
> - /* extend current span, if old extends beyond new */
> - oldpt = oldpt + *oldWidths;
> - if (oldpt> newx2)
> - newx2 = oldpt;
> - }
> - } /* for */
> -
> - /* Write final span */
> - newPoints->x = newx1;
> - *newWidths = newx2 - newx1;
> - newPoints->y = y;
> -
> - return (newWidths - startNewWidths) + 1;
> -} /* UniquifySpansX */
> -
> -static void
> -miDisposeSpanGroup (SpanGroup * spanGroup)
> -{
> - int i;
> - Spans *spans;
> -
> - for (i = 0; i< spanGroup->count; i++) {
> - spans = spanGroup->group + i;
> - xfree (spans->points);
> - xfree (spans->widths);
> - }
> -}
> -
> -static void
> -miFillUniqueSpanGroup (GCPtr pGC, SpanGroup * spanGroup, Boolean foreground)
> -{
> - int i;
> - Spans *spans;
> - Spans *yspans;
> - int *ysizes;
> - int ymin, ylength;
> -
> - /* Outgoing spans for one big call to FillSpans */
> - DDXPointPtr points;
> - int *widths;
> - int count;
> -
> - if (spanGroup->count == 0)
> - return;
> -
> - if (spanGroup->count == 1) {
> - /* Already should be sorted, unique */
> - spans = spanGroup->group;
> - (*pGC->ops->FillSpans)
> - (pGC, spans->count, spans->points, spans->widths, TRUE, foreground);
> - xfree (spans->points);
> - xfree (spans->widths);
> - } else {
> - /* Yuck. Gross. Radix sort into y buckets, then sort x and uniquify */
> - /* This seems to be the fastest thing to do. I've tried sorting on
> - both x and y at the same time rather than creating into all those
> - y buckets, but it was somewhat slower. */
> -
> - ymin = spanGroup->ymin;
> - ylength = spanGroup->ymax - ymin + 1;
> -
> - /* Allocate Spans for y buckets */
> - yspans = (Spans*)xalloc (ylength * sizeof (Spans));
> - ysizes = (int *)xalloc (ylength * sizeof (int));
> -
> - if (!yspans || !ysizes) {
> - if (yspans)
> - xfree (yspans);
> - if (ysizes)
> - xfree (ysizes);
> - miDisposeSpanGroup (spanGroup);
> - return;
> - }
> -
> - for (i = 0; i != ylength; i++) {
> - ysizes[i] = 0;
> - yspans[i].count = 0;
> - yspans[i].points = NULL;
> - yspans[i].widths = NULL;
> - }
> -
> - /* Go through every single span and put it into the correct bucket */
> - count = 0;
> - for (i = 0, spans = spanGroup->group; i != spanGroup->count; i++, spans++) {
> - int index;
> - int j;
> -
> - for (j = 0, points = spans->points, widths = spans->widths;
> - j != spans->count; j++, points++, widths++) {
> - index = points->y - ymin;
> - if (index>= 0&& index< ylength) {
> - Spans *newspans =&(yspans[index]);
> - if (newspans->count == ysizes[index]) {
> - DDXPointPtr newpoints;
> - int *newwidths;
> - ysizes[index] = (ysizes[index] + 8) * 2;
> - newpoints = (DDXPointPtr) xrealloc (newspans->points,
> - ysizes[index] * sizeof (DDXPointRec));
> - newwidths = (int *) xrealloc (newspans->widths,
> - ysizes[index] * sizeof (int));
> - if (!newpoints || !newwidths) {
> - int i;
> -
> - for (i = 0; i< ylength; i++) {
> - xfree (yspans[i].points);
> - xfree (yspans[i].widths);
> - }
> - xfree (yspans);
> - xfree (ysizes);
> - miDisposeSpanGroup (spanGroup);
> - return;
> - }
> - newspans->points = newpoints;
> - newspans->widths = newwidths;
> - }
> - newspans->points[newspans->count] = *points;
> - newspans->widths[newspans->count] = *widths;
> - (newspans->count)++;
> - } /* if y value of span in range */
> - } /* for j through spans */
> - count += spans->count;
> - xfree (spans->points);
> - spans->points = NULL;
> - xfree (spans->widths);
> - spans->widths = NULL;
> - } /* for i thorough Spans */
> -
> - /* Now sort by x and uniquify each bucket into the final array */
> - points = (DDXPointRec*)xalloc (count * sizeof (DDXPointRec));
> - widths = (int *)xalloc (count * sizeof (int));
> - if (!points || !widths) {
> - int i;
> -
> - for (i = 0; i< ylength; i++) {
> - xfree (yspans[i].points);
> - xfree (yspans[i].widths);
> - }
> - xfree (yspans);
> - xfree (ysizes);
> - if (points)
> - xfree (points);
> - if (widths)
> - xfree (widths);
> - return;
> - }
> - count = 0;
> - for (i = 0; i != ylength; i++) {
> - int ycount = yspans[i].count;
> - if (ycount> 0) {
> - if (ycount> 1) {
> - QuickSortSpansX (yspans[i].points, yspans[i].widths, ycount);
> - count += UniquifySpansX (&(yspans[i]),&(points[count]),&(widths[count]));
> - } else {
> - points[count] = yspans[i].points[0];
> - widths[count] = yspans[i].widths[0];
> - count++;
> - }
> - xfree (yspans[i].points);
> - xfree (yspans[i].widths);
> - }
> - }
> -
> - (*pGC->ops->FillSpans) (pGC, count, points, widths, TRUE, foreground);
> - xfree (points);
> - xfree (widths);
> - xfree (yspans);
> - xfree (ysizes); /* use (DE)xalloc for these? */
> - }
> -
> - spanGroup->count = 0;
> - spanGroup->ymin = MAX_COORDINATE;
> - spanGroup->ymax = MIN_COORDINATE;
> -}
> -
> -/*
> -
> -The bresenham error equation used in the mi/mfb/cfb line routines is:
> -
> - e = error
> - dx = difference in raw X coordinates
> - dy = difference in raw Y coordinates
> - M = # of steps in X direction
> - N = # of steps in Y direction
> - B = 0 to prefer diagonal steps in a given octant,
> - 1 to prefer axial steps in a given octant
> -
> - For X major lines:
> - e = 2Mdy - 2Ndx - dx - B
> - -2dx<= e< 0
> -
> - For Y major lines:
> - e = 2Ndx - 2Mdy - dy - B
> - -2dy<= e< 0
> -
> -At the start of the line, we have taken 0 X steps and 0 Y steps,
> -so M = 0 and N = 0:
> -
> - X major e = 2Mdy - 2Ndx - dx - B
> - = -dx - B
> -
> - Y major e = 2Ndx - 2Mdy - dy - B
> - = -dy - B
> -
> -At the end of the line, we have taken dx X steps and dy Y steps,
> -so M = dx and N = dy:
> -
> - X major e = 2Mdy - 2Ndx - dx - B
> - = 2dxdy - 2dydx - dx - B
> - = -dx - B
> - Y major e = 2Ndx - 2Mdy - dy - B
> - = 2dydx - 2dxdy - dy - B
> - = -dy - B
> -
> -Thus, the error term is the same at the start and end of the line.
> -
> -Let us consider clipping an X coordinate. There are 4 cases which
> -represent the two independent cases of clipping the start vs. the
> -end of the line and an X major vs. a Y major line. In any of these
> -cases, we know the number of X steps (M) and we wish to find the
> -number of Y steps (N). Thus, we will solve our error term equation.
> -If we are clipping the start of the line, we will find the smallest
> -N that satisfies our error term inequality. If we are clipping the
> -end of the line, we will find the largest number of Y steps that
> -satisfies the inequality. In that case, since we are representing
> -the Y steps as (dy - N), we will actually want to solve for the
> -smallest N in that equation.
> -
> -Case 1: X major, starting X coordinate moved by M steps
> -
> - -2dx<= 2Mdy - 2Ndx - dx - B< 0
> - 2Ndx<= 2Mdy - dx - B + 2dx 2Ndx> 2Mdy - dx - B
> - 2Ndx<= 2Mdy + dx - B N> (2Mdy - dx - B) / 2dx
> - N<= (2Mdy + dx - B) / 2dx
> -
> -Since we are trying to find the smallest N that satisfies these
> -equations, we should use the> inequality to find the smallest:
> -
> - N = floor((2Mdy - dx - B) / 2dx) + 1
> - = floor((2Mdy - dx - B + 2dx) / 2dx)
> - = floor((2Mdy + dx - B) / 2dx)
> -
> -Case 1b: X major, ending X coordinate moved to M steps
> -
> -Same derivations as Case 1, but we want the largest N that satisfies
> -the equations, so we use the<= inequality:
> -
> - N = floor((2Mdy + dx - B) / 2dx)
> -
> -Case 2: X major, ending X coordinate moved by M steps
> -
> - -2dx<= 2(dx - M)dy - 2(dy - N)dx - dx - B< 0
> - -2dx<= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B< 0
> - -2dx<= 2Ndx - 2Mdy - dx - B< 0
> - 2Ndx>= 2Mdy + dx + B - 2dx 2Ndx< 2Mdy + dx + B
> - 2Ndx>= 2Mdy - dx + B N< (2Mdy + dx + B) / 2dx
> - N>= (2Mdy - dx + B) / 2dx
> -
> -Since we are trying to find the highest number of Y steps that
> -satisfies these equations, we need to find the smallest N, so
> -we should use the>= inequality to find the smallest:
> -
> - N = ceiling((2Mdy - dx + B) / 2dx)
> - = floor((2Mdy - dx + B + 2dx - 1) / 2dx)
> - = floor((2Mdy + dx + B - 1) / 2dx)
> -
> -Case 2b: X major, starting X coordinate moved to M steps from end
> -
> -Same derivations as Case 2, but we want the smallest number of Y
> -steps, so we want the highest N, so we use the< inequality:
> -
> - N = ceiling((2Mdy + dx + B) / 2dx) - 1
> - = floor((2Mdy + dx + B + 2dx - 1) / 2dx) - 1
> - = floor((2Mdy + dx + B + 2dx - 1 - 2dx) / 2dx)
> - = floor((2Mdy + dx + B - 1) / 2dx)
> -
> -Case 3: Y major, starting X coordinate moved by M steps
> -
> - -2dy<= 2Ndx - 2Mdy - dy - B< 0
> - 2Ndx>= 2Mdy + dy + B - 2dy 2Ndx< 2Mdy + dy + B
> - 2Ndx>= 2Mdy - dy + B N< (2Mdy + dy + B) / 2dx
> - N>= (2Mdy - dy + B) / 2dx
> -
> -Since we are trying to find the smallest N that satisfies these
> -equations, we should use the>= inequality to find the smallest:
> -
> - N = ceiling((2Mdy - dy + B) / 2dx)
> - = floor((2Mdy - dy + B + 2dx - 1) / 2dx)
> - = floor((2Mdy - dy + B - 1) / 2dx) + 1
> -
> -Case 3b: Y major, ending X coordinate moved to M steps
> -
> -Same derivations as Case 3, but we want the largest N that satisfies
> -the equations, so we use the< inequality:
> -
> - N = ceiling((2Mdy + dy + B) / 2dx) - 1
> - = floor((2Mdy + dy + B + 2dx - 1) / 2dx) - 1
> - = floor((2Mdy + dy + B + 2dx - 1 - 2dx) / 2dx)
> - = floor((2Mdy + dy + B - 1) / 2dx)
> -
> -Case 4: Y major, ending X coordinate moved by M steps
> -
> - -2dy<= 2(dy - N)dx - 2(dx - M)dy - dy - B< 0
> - -2dy<= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B< 0
> - -2dy<= 2Mdy - 2Ndx - dy - B< 0
> - 2Ndx<= 2Mdy - dy - B + 2dy 2Ndx> 2Mdy - dy - B
> - 2Ndx<= 2Mdy + dy - B N> (2Mdy - dy - B) / 2dx
> - N<= (2Mdy + dy - B) / 2dx
> -
> -Since we are trying to find the highest number of Y steps that
> -satisfies these equations, we need to find the smallest N, so
> -we should use the> inequality to find the smallest:
> -
> - N = floor((2Mdy - dy - B) / 2dx) + 1
> -
> -Case 4b: Y major, starting X coordinate moved to M steps from end
> -
> -Same analysis as Case 4, but we want the smallest number of Y steps
> -which means the largest N, so we use the<= inequality:
> -
> - N = floor((2Mdy + dy - B) / 2dx)
> -
> -Now let's try the Y coordinates, we have the same 4 cases.
> -
> -Case 5: X major, starting Y coordinate moved by N steps
> -
> - -2dx<= 2Mdy - 2Ndx - dx - B< 0
> - 2Mdy>= 2Ndx + dx + B - 2dx 2Mdy< 2Ndx + dx + B
> - 2Mdy>= 2Ndx - dx + B M< (2Ndx + dx + B) / 2dy
> - M>= (2Ndx - dx + B) / 2dy
> -
> -Since we are trying to find the smallest M, we use the>= inequality:
> -
> - M = ceiling((2Ndx - dx + B) / 2dy)
> - = floor((2Ndx - dx + B + 2dy - 1) / 2dy)
> - = floor((2Ndx - dx + B - 1) / 2dy) + 1
> -
> -Case 5b: X major, ending Y coordinate moved to N steps
> -
> -Same derivations as Case 5, but we want the largest M that satisfies
> -the equations, so we use the< inequality:
> -
> - M = ceiling((2Ndx + dx + B) / 2dy) - 1
> - = floor((2Ndx + dx + B + 2dy - 1) / 2dy) - 1
> - = floor((2Ndx + dx + B + 2dy - 1 - 2dy) / 2dy)
> - = floor((2Ndx + dx + B - 1) / 2dy)
> -
> -Case 6: X major, ending Y coordinate moved by N steps
> -
> - -2dx<= 2(dx - M)dy - 2(dy - N)dx - dx - B< 0
> - -2dx<= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B< 0
> - -2dx<= 2Ndx - 2Mdy - dx - B< 0
> - 2Mdy<= 2Ndx - dx - B + 2dx 2Mdy> 2Ndx - dx - B
> - 2Mdy<= 2Ndx + dx - B M> (2Ndx - dx - B) / 2dy
> - M<= (2Ndx + dx - B) / 2dy
> -
> -Largest # of X steps means smallest M, so use the> inequality:
> -
> - M = floor((2Ndx - dx - B) / 2dy) + 1
> -
> -Case 6b: X major, starting Y coordinate moved to N steps from end
> -
> -Same derivations as Case 6, but we want the smallest # of X steps
> -which means the largest M, so use the<= inequality:
> -
> - M = floor((2Ndx + dx - B) / 2dy)
> -
> -Case 7: Y major, starting Y coordinate moved by N steps
> -
> - -2dy<= 2Ndx - 2Mdy - dy - B< 0
> - 2Mdy<= 2Ndx - dy - B + 2dy 2Mdy> 2Ndx - dy - B
> - 2Mdy<= 2Ndx + dy - B M> (2Ndx - dy - B) / 2dy
> - M<= (2Ndx + dy - B) / 2dy
> -
> -To find the smallest M, use the> inequality:
> -
> - M = floor((2Ndx - dy - B) / 2dy) + 1
> - = floor((2Ndx - dy - B + 2dy) / 2dy)
> - = floor((2Ndx + dy - B) / 2dy)
> -
> -Case 7b: Y major, ending Y coordinate moved to N steps
> -
> -Same derivations as Case 7, but we want the largest M that satisfies
> -the equations, so use the<= inequality:
> -
> - M = floor((2Ndx + dy - B) / 2dy)
> -
> -Case 8: Y major, ending Y coordinate moved by N steps
> -
> - -2dy<= 2(dy - N)dx - 2(dx - M)dy - dy - B< 0
> - -2dy<= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B< 0
> - -2dy<= 2Mdy - 2Ndx - dy - B< 0
> - 2Mdy>= 2Ndx + dy + B - 2dy 2Mdy< 2Ndx + dy + B
> - 2Mdy>= 2Ndx - dy + B M< (2Ndx + dy + B) / 2dy
> - M>= (2Ndx - dy + B) / 2dy
> -
> -To find the highest X steps, find the smallest M, use the>= inequality:
> -
> - M = ceiling((2Ndx - dy + B) / 2dy)
> - = floor((2Ndx - dy + B + 2dy - 1) / 2dy)
> - = floor((2Ndx + dy + B - 1) / 2dy)
> -
> -Case 8b: Y major, starting Y coordinate moved to N steps from the end
> -
> -Same derivations as Case 8, but we want to find the smallest # of X
> -steps which means the largest M, so we use the< inequality:
> -
> - M = ceiling((2Ndx + dy + B) / 2dy) - 1
> - = floor((2Ndx + dy + B + 2dy - 1) / 2dy) - 1
> - = floor((2Ndx + dy + B + 2dy - 1 - 2dy) / 2dy)
> - = floor((2Ndx + dy + B - 1) / 2dy)
> -
> -So, our equations are:
> -
> - 1: X major move x1 to x1+M floor((2Mdy + dx - B) / 2dx)
> - 1b: X major move x2 to x1+M floor((2Mdy + dx - B) / 2dx)
> - 2: X major move x2 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
> - 2b: X major move x1 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
> -
> - 3: Y major move x1 to x1+M floor((2Mdy - dy + B - 1) / 2dx) + 1
> - 3b: Y major move x2 to x1+M floor((2Mdy + dy + B - 1) / 2dx)
> - 4: Y major move x2 to x2-M floor((2Mdy - dy - B) / 2dx) + 1
> - 4b: Y major move x1 to x2-M floor((2Mdy + dy - B) / 2dx)
> -
> - 5: X major move y1 to y1+N floor((2Ndx - dx + B - 1) / 2dy) + 1
> - 5b: X major move y2 to y1+N floor((2Ndx + dx + B - 1) / 2dy)
> - 6: X major move y2 to y2-N floor((2Ndx - dx - B) / 2dy) + 1
> - 6b: X major move y1 to y2-N floor((2Ndx + dx - B) / 2dy)
> -
> - 7: Y major move y1 to y1+N floor((2Ndx + dy - B) / 2dy)
> - 7b: Y major move y2 to y1+N floor((2Ndx + dy - B) / 2dy)
> - 8: Y major move y2 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
> - 8b: Y major move y1 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
> -
> -We have the following constraints on all of the above terms:
> -
> - 0< M,N<= 2^15 2^15 can be imposed by miZeroClipLine
> - 0<= dx/dy<= 2^16 - 1
> - 0<= B<= 1
> -
> -The floor in all of the above equations can be accomplished with a
> -simple C divide operation provided that both numerator and denominator
> -are positive.
> -
> -Since dx,dy>= 0 and since moving an X coordinate implies that dx != 0
> -and moving a Y coordinate implies dy != 0, we know that the denominators
> -are all> 0.
> -
> -For all lines, (-B) and (B-1) are both either 0 or -1, depending on the
> -bias. Thus, we have to show that the 2MNdxy +/- dxy terms are all>= 1
> -or> 0 to prove that the numerators are positive (or zero).
> -
> -For X Major lines we know that dx> 0 and since 2Mdy is>= 0 due to the
> -constraints, the first four equations all have numerators>= 0.
> -
> -For the second four equations, M> 0, so 2Mdy>= 2dy so (2Mdy - dy)>= dy
> -So (2Mdy - dy)> 0, since they are Y major lines. Also, (2Mdy + dy)>= 3dy
> -or (2Mdy + dy)> 0. So all of their numerators are>= 0.
> -
> -For the third set of four equations, N> 0, so 2Ndx>= 2dx so (2Ndx - dx)
> ->= dx> 0. Similarly (2Ndx + dx)>= 3dx> 0. So all numerators>= 0.
> -
> -For the fourth set of equations, dy> 0 and 2Ndx>= 0, so all numerators
> -are> 0.
> -
> -To consider overflow, consider the case of 2 * M,N * dx,dy + dx,dy. This
> -is bounded<= 2 * 2^15 * (2^16 - 1) + (2^16 - 1)
> -<= 2^16 * (2^16 - 1) + (2^16 - 1)
> -<= 2^32 - 2^16 + 2^16 - 1
> -<= 2^32 - 1
> -Since the (-B) and (B-1) terms are all 0 or -1, the maximum value of
> -the numerator is therefore (2^32 - 1), which does not overflow an unsigned
> -32 bit variable.
> -
> -*/
> -
> -/* Bit codes for the terms of the 16 clipping equations defined below. */
> -
> -#define T_2NDX (1<< 0)
> -#define T_2MDY (0) /* implicit term */
> -#define T_DXNOTY (1<< 1)
> -#define T_DYNOTX (0) /* implicit term */
> -#define T_SUBDXORY (1<< 2)
> -#define T_ADDDX (T_DXNOTY) /* composite term */
> -#define T_SUBDX (T_DXNOTY | T_SUBDXORY) /* composite term */
> -#define T_ADDDY (T_DYNOTX) /* composite term */
> -#define T_SUBDY (T_DYNOTX | T_SUBDXORY) /* composite term */
> -#define T_BIASSUBONE (1<< 3)
> -#define T_SUBBIAS (0) /* implicit term */
> -#define T_DIV2DX (1<< 4)
> -#define T_DIV2DY (0) /* implicit term */
> -#define T_ADDONE (1<< 5)
> -
> -/* Bit masks defining the 16 equations used in miZeroClipLine. */
> -
> -#define EQN1 (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
> -#define EQN1B (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
> -#define EQN2 (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
> -#define EQN2B (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
> -
> -#define EQN3 (T_2MDY | T_SUBDY | T_BIASSUBONE | T_DIV2DX | T_ADDONE)
> -#define EQN3B (T_2MDY | T_ADDDY | T_BIASSUBONE | T_DIV2DX)
> -#define EQN4 (T_2MDY | T_SUBDY | T_SUBBIAS | T_DIV2DX | T_ADDONE)
> -#define EQN4B (T_2MDY | T_ADDDY | T_SUBBIAS | T_DIV2DX)
> -
> -#define EQN5 (T_2NDX | T_SUBDX | T_BIASSUBONE | T_DIV2DY | T_ADDONE)
> -#define EQN5B (T_2NDX | T_ADDDX | T_BIASSUBONE | T_DIV2DY)
> -#define EQN6 (T_2NDX | T_SUBDX | T_SUBBIAS | T_DIV2DY | T_ADDONE)
> -#define EQN6B (T_2NDX | T_ADDDX | T_SUBBIAS | T_DIV2DY)
> -
> -#define EQN7 (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
> -#define EQN7B (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
> -#define EQN8 (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
> -#define EQN8B (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
> -
> -/* miZeroClipLine
> - *
> - * returns: 1 for partially clipped line
> - * -1 for completely clipped line
> - *
> - */
> -static int
> -miZeroClipLine (int xmin, int ymin, int xmax, int ymax,
> - int *new_x1, int *new_y1, int *new_x2, int *new_y2,
> - unsigned int adx, unsigned int ady,
> - int *pt1_clipped, int *pt2_clipped, int octant, unsigned int bias, int oc1, int oc2)
> -{
> - int swapped = 0;
> - int clipDone = 0;
> - CARD32 utmp = 0;
> - int clip1, clip2;
> - int x1, y1, x2, y2;
> - int x1_orig, y1_orig, x2_orig, y2_orig;
> - int xmajor;
> - int negslope = 0, anchorval = 0;
> - unsigned int eqn = 0;
> -
> - x1 = x1_orig = *new_x1;
> - y1 = y1_orig = *new_y1;
> - x2 = x2_orig = *new_x2;
> - y2 = y2_orig = *new_y2;
> -
> - clip1 = 0;
> - clip2 = 0;
> -
> - xmajor = IsXMajorOctant (octant);
> - bias = ((bias>> octant)& 1);
> -
> - while (1) {
> - if ((oc1& oc2) != 0) { /* trivial reject */
> - clipDone = -1;
> - clip1 = oc1;
> - clip2 = oc2;
> - break;
> - } else if ((oc1 | oc2) == 0) { /* trivial accept */
> - clipDone = 1;
> - if (swapped) {
> - SWAPINT_PAIR (x1, y1, x2, y2);
> - SWAPINT (clip1, clip2);
> - }
> - break;
> - } else { /* have to clip */
> -
> - /* only clip one point at a time */
> - if (oc1 == 0) {
> - SWAPINT_PAIR (x1, y1, x2, y2);
> - SWAPINT_PAIR (x1_orig, y1_orig, x2_orig, y2_orig);
> - SWAPINT (oc1, oc2);
> - SWAPINT (clip1, clip2);
> - swapped = !swapped;
> - }
> -
> - clip1 |= oc1;
> - if (oc1& OUT_LEFT) {
> - negslope = IsYDecreasingOctant (octant);
> - utmp = xmin - x1_orig;
> - if (utmp<= 32767) { /* clip based on near endpt */
> - if (xmajor)
> - eqn = (swapped) ? EQN2 : EQN1;
> - else
> - eqn = (swapped) ? EQN4 : EQN3;
> - anchorval = y1_orig;
> - } else { /* clip based on far endpt */
> -
> - utmp = x2_orig - xmin;
> - if (xmajor)
> - eqn = (swapped) ? EQN1B : EQN2B;
> - else
> - eqn = (swapped) ? EQN3B : EQN4B;
> - anchorval = y2_orig;
> - negslope = !negslope;
> - }
> - x1 = xmin;
> - } else if (oc1& OUT_ABOVE) {
> - negslope = IsXDecreasingOctant (octant);
> - utmp = ymin - y1_orig;
> - if (utmp<= 32767) { /* clip based on near endpt */
> - if (xmajor)
> - eqn = (swapped) ? EQN6 : EQN5;
> - else
> - eqn = (swapped) ? EQN8 : EQN7;
> - anchorval = x1_orig;
> - } else { /* clip based on far endpt */
> -
> - utmp = y2_orig - ymin;
> - if (xmajor)
> - eqn = (swapped) ? EQN5B : EQN6B;
> - else
> - eqn = (swapped) ? EQN7B : EQN8B;
> - anchorval = x2_orig;
> - negslope = !negslope;
> - }
> - y1 = ymin;
> - } else if (oc1& OUT_RIGHT) {
> - negslope = IsYDecreasingOctant (octant);
> - utmp = x1_orig - xmax;
> - if (utmp<= 32767) { /* clip based on near endpt */
> - if (xmajor)
> - eqn = (swapped) ? EQN2 : EQN1;
> - else
> - eqn = (swapped) ? EQN4 : EQN3;
> - anchorval = y1_orig;
> - } else { /* clip based on far endpt */
> -
> - /*
> - * Technically since the equations can handle
> - * utmp == 32768, this overflow code isn't
> - * needed since X11 protocol can't generate
> - * a line which goes more than 32768 pixels
> - * to the right of a clip rectangle.
> - */
> - utmp = xmax - x2_orig;
> - if (xmajor)
> - eqn = (swapped) ? EQN1B : EQN2B;
> - else
> - eqn = (swapped) ? EQN3B : EQN4B;
> - anchorval = y2_orig;
> - negslope = !negslope;
> - }
> - x1 = xmax;
> - } else if (oc1& OUT_BELOW) {
> - negslope = IsXDecreasingOctant (octant);
> - utmp = y1_orig - ymax;
> - if (utmp<= 32767) { /* clip based on near endpt */
> - if (xmajor)
> - eqn = (swapped) ? EQN6 : EQN5;
> - else
> - eqn = (swapped) ? EQN8 : EQN7;
> - anchorval = x1_orig;
> - } else { /* clip based on far endpt */
> -
> - /*
> - * Technically since the equations can handle
> - * utmp == 32768, this overflow code isn't
> - * needed since X11 protocol can't generate
> - * a line which goes more than 32768 pixels
> - * below the bottom of a clip rectangle.
> - */
> - utmp = ymax - y2_orig;
> - if (xmajor)
> - eqn = (swapped) ? EQN5B : EQN6B;
> - else
> - eqn = (swapped) ? EQN7B : EQN8B;
> - anchorval = x2_orig;
> - negslope = !negslope;
> - }
> - y1 = ymax;
> - }
> -
> - if (swapped)
> - negslope = !negslope;
> -
> - utmp<<= 1; /* utmp = 2N or 2M */
> - if (eqn& T_2NDX)
> - utmp = (utmp * adx);
> - else /* (eqn& T_2MDY) */
> - utmp = (utmp * ady);
> - if (eqn& T_DXNOTY)
> - if (eqn& T_SUBDXORY)
> - utmp -= adx;
> - else
> - utmp += adx;
> - else /* (eqn& T_DYNOTX) */ if (eqn& T_SUBDXORY)
> - utmp -= ady;
> - else
> - utmp += ady;
> - if (eqn& T_BIASSUBONE)
> - utmp += bias - 1;
> - else /* (eqn& T_SUBBIAS) */
> - utmp -= bias;
> - if (eqn& T_DIV2DX)
> - utmp /= (adx<< 1);
> - else /* (eqn& T_DIV2DY) */
> - utmp /= (ady<< 1);
> - if (eqn& T_ADDONE)
> - utmp++;
> -
> - if (negslope)
> - utmp = (uint32_t)(-(int32_t)utmp);
> -
> - if (eqn& T_2NDX) /* We are calculating X steps */
> - x1 = anchorval + utmp;
> - else /* else, Y steps */
> - y1 = anchorval + utmp;
> -
> - oc1 = 0;
> - MIOUTCODES (oc1, x1, y1, xmin, ymin, xmax, ymax);
> - }
> - }
> -
> - *new_x1 = x1;
> - *new_y1 = y1;
> - *new_x2 = x2;
> - *new_y2 = y2;
> -
> - *pt1_clipped = clip1;
> - *pt2_clipped = clip2;
> -
> - return clipDone;
> -}
> -
> -/* Draw lineSolid, fillStyle-independent zero width lines.
> - *
> - * Must keep X and Y coordinates in "ints" at least until after they're
> - * translated and clipped to accomodate CoordModePrevious lines with very
> - * large coordinates.
> - *
> - * Draws the same pixels regardless of sign(dx) or sign(dy).
> - *
> - * Ken Whaley
> - *
> - */
> -
> -#define MI_OUTPUT_POINT(xx, yy)\
> -{\
> - if ( !new_span&& yy == current_y)\
> - {\
> - if (xx< spans->x)\
> - spans->x = xx;\
> - ++*widths;\
> - }\
> - else\
> - {\
> - ++Nspans;\
> - ++spans;\
> - ++widths;\
> - spans->x = xx;\
> - spans->y = yy;\
> - *widths = 1;\
> - current_y = yy;\
> - new_span = FALSE;\
> - }\
> -}
> -
> -void
> -miZeroLine (GCPtr pGC, int mode, /* Origin or Previous */
> - int npt, /* number of points */
> - DDXPointPtr pptInit)
> -{
> - int Nspans, current_y = 0;
> - DDXPointPtr ppt;
> - DDXPointPtr pspanInit, spans;
> - int *pwidthInit, *widths, list_len;
> - int xleft, ytop, xright, ybottom;
> - int new_x1, new_y1, new_x2, new_y2;
> - int x = 0, y = 0, x1, y1, x2, y2, xstart, ystart;
> - int oc1, oc2;
> - int result;
> - int pt1_clipped, pt2_clipped = 0;
> - Boolean new_span;
> - int signdx, signdy;
> - int clipdx, clipdy;
> - int width, height;
> - int adx, ady;
> - int octant;
> - unsigned int bias = miGetZeroLineBias (screen);
> - int e, e1, e2, e3; /* Bresenham error terms */
> - int length; /* length of lines == # of pixels on major axis */
> -
> - xleft = 0;
> - ytop = 0;
> - xright = pGC->width - 1;
> - ybottom = pGC->height - 1;
> -
> - /* it doesn't matter whether we're in drawable or screen coordinates,
> - * FillSpans simply cannot take starting coordinates outside of the
> - * range of a DDXPointRec component.
> - */
> - if (xright> MAX_COORDINATE)
> - xright = MAX_COORDINATE;
> - if (ybottom> MAX_COORDINATE)
> - ybottom = MAX_COORDINATE;
> -
> - /* since we're clipping to the drawable's boundaries& coordinate
> - * space boundaries, we're guaranteed that the larger of width/height
> - * is the longest span we'll need to output
> - */
> - width = xright - xleft + 1;
> - height = ybottom - ytop + 1;
> - list_len = (height>= width) ? height : width;
> - pspanInit = (DDXPointRec *)xalloc (list_len * sizeof (DDXPointRec));
> - pwidthInit = (int *)xalloc (list_len * sizeof (int));
> - if (!pspanInit || !pwidthInit)
> - return;
> -
> - Nspans = 0;
> - new_span = TRUE;
> - spans = pspanInit - 1;
> - widths = pwidthInit - 1;
> - ppt = pptInit;
> -
> - xstart = ppt->x;
> - ystart = ppt->y;
> -
> - /* x2, y2, oc2 copied to x1, y1, oc1 at top of loop to simplify
> - * iteration logic
> - */
> - x2 = xstart;
> - y2 = ystart;
> - oc2 = 0;
> - MIOUTCODES (oc2, x2, y2, xleft, ytop, xright, ybottom);
> -
> - while (--npt> 0) {
> - if (Nspans> 0)
> - (*pGC->ops->FillSpans) (pGC, Nspans, pspanInit, pwidthInit, FALSE, TRUE);
> - Nspans = 0;
> - new_span = TRUE;
> - spans = pspanInit - 1;
> - widths = pwidthInit - 1;
> -
> - x1 = x2;
> - y1 = y2;
> - oc1 = oc2;
> - ++ppt;
> -
> - x2 = ppt->x;
> - y2 = ppt->y;
> - if (mode == CoordModePrevious) {
> - x2 += x1;
> - y2 += y1;
> - }
> -
> - oc2 = 0;
> - MIOUTCODES (oc2, x2, y2, xleft, ytop, xright, ybottom);
> -
> - CalcLineDeltas (x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
> -
> - if (adx> ady) {
> - e1 = ady<< 1;
> - e2 = e1 - (adx<< 1);
> - e = e1 - adx;
> - length = adx; /* don't draw endpoint in main loop */
> -
> - FIXUP_ERROR (e, octant, bias);
> -
> - new_x1 = x1;
> - new_y1 = y1;
> - new_x2 = x2;
> - new_y2 = y2;
> - pt1_clipped = 0;
> - pt2_clipped = 0;
> -
> - if ((oc1 | oc2) != 0) {
> - result = miZeroClipLine (xleft, ytop, xright, ybottom,
> -&new_x1,&new_y1,&new_x2,&new_y2,
> - adx, ady,
> -&pt1_clipped,&pt2_clipped, octant, bias, oc1, oc2);
> - if (result == -1)
> - continue;
> -
> - length = abs (new_x2 - new_x1);
> -
> - /* if we've clipped the endpoint, always draw the full length
> - * of the segment, because then the capstyle doesn't matter
> - */
> - if (pt2_clipped)
> - length++;
> -
> - if (pt1_clipped) {
> - /* must calculate new error terms */
> - clipdx = abs (new_x1 - x1);
> - clipdy = abs (new_y1 - y1);
> - e += (clipdy * e2) + ((clipdx - clipdy) * e1);
> - }
> - }
> -
> - /* draw the segment */
> -
> - x = new_x1;
> - y = new_y1;
> -
> - e3 = e2 - e1;
> - e = e - e1;
> -
> - while (length--) {
> - MI_OUTPUT_POINT (x, y);
> - e += e1;
> - if (e>= 0) {
> - y += signdy;
> - e += e3;
> - }
> - x += signdx;
> - }
> - } else { /* Y major line */
> -
> - e1 = adx<< 1;
> - e2 = e1 - (ady<< 1);
> - e = e1 - ady;
> - length = ady; /* don't draw endpoint in main loop */
> -
> - SetYMajorOctant (octant);
> - FIXUP_ERROR (e, octant, bias);
> -
> - new_x1 = x1;
> - new_y1 = y1;
> - new_x2 = x2;
> - new_y2 = y2;
> - pt1_clipped = 0;
> - pt2_clipped = 0;
> -
> - if ((oc1 | oc2) != 0) {
> - result = miZeroClipLine (xleft, ytop, xright, ybottom,
> -&new_x1,&new_y1,&new_x2,&new_y2,
> - adx, ady,
> -&pt1_clipped,&pt2_clipped, octant, bias, oc1, oc2);
> - if (result == -1)
> - continue;
> -
> - length = abs (new_y2 - new_y1);
> -
> - /* if we've clipped the endpoint, always draw the full length
> - * of the segment, because then the capstyle doesn't matter
> - */
> - if (pt2_clipped)
> - length++;
> -
> - if (pt1_clipped) {
> - /* must calculate new error terms */
> - clipdx = abs (new_x1 - x1);
> - clipdy = abs (new_y1 - y1);
> - e += (clipdx * e2) + ((clipdy - clipdx) * e1);
> - }
> - }
> -
> - /* draw the segment */
> -
> - x = new_x1;
> - y = new_y1;
> -
> - e3 = e2 - e1;
> - e = e - e1;
> -
> - while (length--) {
> - MI_OUTPUT_POINT (x, y);
> - e += e1;
> - if (e>= 0) {
> - x += signdx;
> - e += e3;
> - }
> - y += signdy;
> - }
> - }
> - }
> -
> - /* only do the capnotlast check on the last segment
> - * and only if the endpoint wasn't clipped. And then, if the last
> - * point is the same as the first point, do not draw it, unless the
> - * line is degenerate
> - */
> - if ((!pt2_clipped)&& (pGC->capStyle != CapNotLast)&&
> - (((xstart != x2) || (ystart != y2)) || (ppt == pptInit + 1))) {
> - MI_OUTPUT_POINT (x, y);
> - }
> -
> - if (Nspans> 0)
> - (*pGC->ops->FillSpans) (pGC, Nspans, pspanInit, pwidthInit, FALSE, TRUE);
> -
> - xfree (pwidthInit);
> - xfree (pspanInit);
> -}
> -
> -void
> -miZeroDashLine (GCPtr pgc, int mode, int nptInit, /* number of points in polyline */
> - DDXPointRec * pptInit /* points in the polyline */
> - )
> -{
> - /* XXX kludge until real zero-width dash code is written */
> - pgc->lineWidth = 1;
> - miWideDash (pgc, mode, nptInit, pptInit);
> - pgc->lineWidth = 0;
> -}
> -
> -static void miLineArc (GCPtr pGC,
> - Boolean foreground, SpanDataPtr spanData,
> - LineFacePtr leftFace,
> - LineFacePtr rightFace, double xorg, double yorg, Boolean isInt);
> -
> -
> -/*
> - * spans-based polygon filler
> - */
> -
> -static void
> -miFillPolyHelper (GCPtr pGC, Boolean foreground,
> - SpanDataPtr spanData, int y, int overall_height,
> - PolyEdgePtr left, PolyEdgePtr right, int left_count, int right_count)
> -{
> - int left_x = 0, left_e = 0;
> - int left_stepx = 0;
> - int left_signdx = 0;
> - int left_dy = 0, left_dx = 0;
> -
> - int right_x = 0, right_e = 0;
> - int right_stepx = 0;
> - int right_signdx = 0;
> - int right_dy = 0, right_dx = 0;
> -
> - int height = 0;
> - int left_height = 0, right_height = 0;
> -
> - DDXPointPtr ppt;
> - DDXPointPtr pptInit = NULL;
> - int *pwidth;
> - int *pwidthInit = NULL;
> - int xorg;
> - Spans spanRec;
> -
> - left_height = 0;
> - right_height = 0;
> -
> - if (!spanData) {
> - pptInit = (DDXPointRec *)xalloc (overall_height * sizeof (*ppt));
> - if (!pptInit)
> - return;
> - pwidthInit = (int *)xalloc (overall_height * sizeof (*pwidth));
> - if (!pwidthInit) {
> - xfree (pptInit);
> - return;
> - }
> - ppt = pptInit;
> - pwidth = pwidthInit;
> - } else {
> - spanRec.points = (DDXPointRec *)xalloc (overall_height * sizeof (*ppt));
> - if (!spanRec.points)
> - return;
> - spanRec.widths = (int *)xalloc (overall_height * sizeof (int));
> - if (!spanRec.widths) {
> - xfree (spanRec.points);
> - return;
> - }
> - ppt = spanRec.points;
> - pwidth = spanRec.widths;
> - }
> -
> - xorg = 0;
> - while ((left_count || left_height)&& (right_count || right_height)) {
> - MIPOLYRELOADLEFT MIPOLYRELOADRIGHT height = left_height;
> - if (height> right_height)
> - height = right_height;
> -
> - left_height -= height;
> - right_height -= height;
> -
> - while (--height>= 0) {
> - if (right_x>= left_x) {
> - ppt->y = y;
> - ppt->x = left_x + xorg;
> - ppt++;
> - *pwidth++ = right_x - left_x + 1;
> - }
> - y++;
> -
> - MIPOLYSTEPLEFT MIPOLYSTEPRIGHT}
> - }
> - if (!spanData) {
> - (*pGC->ops->FillSpans) (pGC, ppt - pptInit, pptInit, pwidthInit, TRUE, foreground);
> - xfree (pwidthInit);
> - xfree (pptInit);
> - } else {
> - spanRec.count = ppt - spanRec.points;
> - AppendSpanGroup (pGC, foreground,&spanRec, spanData)
> - }
> -}
> -
> -static void
> -miFillRectPolyHelper (GCPtr pGC, Boolean foreground, SpanDataPtr spanData, int x, int y, int w, int h)
> -{
> - DDXPointPtr ppt;
> - int *pwidth;
> - Spans spanRec;
> - xRectangle rect;
> -
> - if (!spanData) {
> - rect.x = x;
> - rect.y = y;
> - rect.width = w;
> - rect.height = h;
> - (*pGC->ops->FillRects) (pGC, 1,&rect, foreground);
> - } else {
> - spanRec.points = (DDXPointRec *)xalloc (h * sizeof (*ppt));
> - if (!spanRec.points)
> - return;
> - spanRec.widths = (int *)xalloc (h * sizeof (int));
> - if (!spanRec.widths) {
> - xfree (spanRec.points);
> - return;
> - }
> - ppt = spanRec.points;
> - pwidth = spanRec.widths;
> -
> - while (h--) {
> - ppt->x = x;
> - ppt->y = y;
> - ppt++;
> - *pwidth++ = w;
> - y++;
> - }
> - spanRec.count = ppt - spanRec.points;
> - AppendSpanGroup (pGC, foreground,&spanRec, spanData)
> - }
> -}
> -
> -static int
> -miPolyBuildEdge (double x0, double y0, double k, /* x0 * dy - y0 * dx */
> - int dx, int dy, int xi, int yi, int left, PolyEdgePtr edge)
> -{
> - int x, y, e;
> - int xady;
> -
> - if (dy< 0) {
> - dy = -dy;
> - dx = -dx;
> - k = -k;
> - }
> -#ifdef NOTDEF
> - {
> - double realk, kerror;
> - realk = x0 * dy - y0 * dx;
> - kerror = Fabs (realk - k);
> - if (kerror> .1)
> - printf ("realk: %g k: %g\n", realk, k);
> - }
> -#endif
> - y = ICEIL (y0);
> - xady = ICEIL (k) + y * dx;
> -
> - if (xady<= 0)
> - x = -(-xady / dy) - 1;
> - else
> - x = (xady - 1) / dy;
> -
> - e = xady - x * dy;
> -
> - if (dx>= 0) {
> - edge->signdx = 1;
> - edge->stepx = dx / dy;
> - edge->dx = dx % dy;
> - } else {
> - edge->signdx = -1;
> - edge->stepx = -(-dx / dy);
> - edge->dx = -dx % dy;
> - e = dy - e + 1;
> - }
> - edge->dy = dy;
> - edge->x = x + left + xi;
> - edge->e = e - dy; /* bias to compare against 0 instead of dy */
> - return y + yi;
> -}
> -
> -#define StepAround(v, incr, max) (((v) + (incr)< 0) ? (max - 1) : ((v) + (incr) == max) ? 0 : ((v) + (incr)))
> -
> -static int
> -miPolyBuildPoly (PolyVertexPtr vertices,
> - PolySlopePtr slopes,
> - int count,
> - int xi,
> - int yi, PolyEdgePtr left, PolyEdgePtr right, int *pnleft, int *pnright, int *h)
> -{
> - int top, bottom;
> - double miny, maxy;
> - int i;
> - int j;
> - int clockwise;
> - int slopeoff;
> - int s;
> - int nright, nleft;
> - int y, lasty = 0, bottomy, topy = 0;
> -
> - /* find the top of the polygon */
> - maxy = miny = vertices[0].y;
> - bottom = top = 0;
> - for (i = 1; i< count; i++) {
> - if (vertices[i].y< miny) {
> - top = i;
> - miny = vertices[i].y;
> - }
> - if (vertices[i].y>= maxy) {
> - bottom = i;
> - maxy = vertices[i].y;
> - }
> - }
> - clockwise = 1;
> - slopeoff = 0;
> -
> - i = top;
> - j = StepAround (top, -1, count);
> -
> - if (slopes[j].dy * slopes[i].dx> slopes[i].dy * slopes[j].dx) {
> - clockwise = -1;
> - slopeoff = -1;
> - }
> -
> - bottomy = ICEIL (maxy) + yi;
> -
> - nright = 0;
> -
> - s = StepAround (top, slopeoff, count);
> - i = top;
> - while (i != bottom) {
> - if (slopes[s].dy != 0) {
> - y = miPolyBuildEdge (vertices[i].x, vertices[i].y,
> - slopes[s].k,
> - slopes[s].dx, slopes[s].dy, xi, yi, 0,&right[nright]);
> - if (nright != 0)
> - right[nright - 1].height = y - lasty;
> - else
> - topy = y;
> - nright++;
> - lasty = y;
> - }
> -
> - i = StepAround (i, clockwise, count);
> - s = StepAround (s, clockwise, count);
> - }
> - if (nright != 0)
> - right[nright - 1].height = bottomy - lasty;
> -
> - if (slopeoff == 0)
> - slopeoff = -1;
> - else
> - slopeoff = 0;
> -
> - nleft = 0;
> - s = StepAround (top, slopeoff, count);
> - i = top;
> - while (i != bottom) {
> - if (slopes[s].dy != 0) {
> - y = miPolyBuildEdge (vertices[i].x, vertices[i].y,
> - slopes[s].k, slopes[s].dx, slopes[s].dy, xi, yi, 1,&left[nleft]);
> -
> - if (nleft != 0)
> - left[nleft - 1].height = y - lasty;
> - nleft++;
> - lasty = y;
> - }
> - i = StepAround (i, -clockwise, count);
> - s = StepAround (s, -clockwise, count);
> - }
> - if (nleft != 0)
> - left[nleft - 1].height = bottomy - lasty;
> - *pnleft = nleft;
> - *pnright = nright;
> - *h = bottomy - topy;
> - return topy;
> -}
> -
> -static void
> -miLineOnePoint (GCPtr pGC, Boolean foreground, SpanDataPtr spanData, int x, int y)
> -{
> - DDXPointRec pt;
> - int wid;
> -
> - wid = 1;
> - pt.x = x;
> - pt.y = y;
> - (*pGC->ops->FillSpans) (pGC, 1,&pt,&wid, TRUE, foreground);
> -}
> -
> -static void
> -miLineJoin (GCPtr pGC, Boolean foreground, SpanDataPtr spanData, LineFacePtr pLeft, LineFacePtr pRight)
> -{
> - double mx = 0, my = 0;
> - double denom = 0.0;
> - PolyVertexRec vertices[4];
> - PolySlopeRec slopes[4];
> - int edgecount;
> - PolyEdgeRec left[4], right[4];
> - int nleft, nright;
> - int y, height;
> - int swapslopes;
> - int joinStyle = pGC->joinStyle;
> - int lw = pGC->lineWidth;
> -
> - if (lw == 1&& !spanData) {
> - /* See if one of the lines will draw the joining pixel */
> - if (pLeft->dx> 0 || (pLeft->dx == 0&& pLeft->dy> 0))
> - return;
> - if (pRight->dx> 0 || (pRight->dx == 0&& pRight->dy> 0))
> - return;
> - if (joinStyle != JoinRound) {
> - denom = -pLeft->dx * (double) pRight->dy + pRight->dx * (double) pLeft->dy;
> - if (denom == 0)
> - return; /* no join to draw */
> - }
> - if (joinStyle != JoinMiter) {
> - miLineOnePoint (pGC, foreground, spanData, pLeft->x, pLeft->y);
> - return;
> - }
> - } else {
> - if (joinStyle == JoinRound) {
> - miLineArc (pGC, foreground, spanData, pLeft, pRight, (double) 0.0, (double) 0.0, TRUE);
> - return;
> - }
> - denom = -pLeft->dx * (double) pRight->dy + pRight->dx * (double) pLeft->dy;
> - if (denom == 0.0)
> - return; /* no join to draw */
> - }
> -
> - swapslopes = 0;
> - if (denom> 0) {
> - pLeft->xa = -pLeft->xa;
> - pLeft->ya = -pLeft->ya;
> - pLeft->dx = -pLeft->dx;
> - pLeft->dy = -pLeft->dy;
> - } else {
> - swapslopes = 1;
> - pRight->xa = -pRight->xa;
> - pRight->ya = -pRight->ya;
> - pRight->dx = -pRight->dx;
> - pRight->dy = -pRight->dy;
> - }
> -
> - vertices[0].x = pRight->xa;
> - vertices[0].y = pRight->ya;
> - slopes[0].dx = -pRight->dy;
> - slopes[0].dy = pRight->dx;
> - slopes[0].k = 0;
> -
> - vertices[1].x = 0;
> - vertices[1].y = 0;
> - slopes[1].dx = pLeft->dy;
> - slopes[1].dy = -pLeft->dx;
> - slopes[1].k = 0;
> -
> - vertices[2].x = pLeft->xa;
> - vertices[2].y = pLeft->ya;
> -
> - if (joinStyle == JoinMiter) {
> - my = (pLeft->dy * (pRight->xa * pRight->dy - pRight->ya * pRight->dx) -
> - pRight->dy * (pLeft->xa * pLeft->dy - pLeft->ya * pLeft->dx)) / denom;
> - if (pLeft->dy != 0) {
> - mx = pLeft->xa + (my - pLeft->ya) * (double) pLeft->dx / (double) pLeft->dy;
> - } else {
> - mx = pRight->xa + (my - pRight->ya) * (double) pRight->dx / (double) pRight->dy;
> - }
> - /* check miter limit */
> - if ((mx * mx + my * my) * 4> SQSECANT * lw * lw)
> - joinStyle = JoinBevel;
> - }
> -
> - if (joinStyle == JoinMiter) {
> - slopes[2].dx = pLeft->dx;
> - slopes[2].dy = pLeft->dy;
> - slopes[2].k = pLeft->k;
> - if (swapslopes) {
> - slopes[2].dx = -slopes[2].dx;
> - slopes[2].dy = -slopes[2].dy;
> - slopes[2].k = -slopes[2].k;
> - }
> - vertices[3].x = mx;
> - vertices[3].y = my;
> - slopes[3].dx = pRight->dx;
> - slopes[3].dy = pRight->dy;
> - slopes[3].k = pRight->k;
> - if (swapslopes) {
> - slopes[3].dx = -slopes[3].dx;
> - slopes[3].dy = -slopes[3].dy;
> - slopes[3].k = -slopes[3].k;
> - }
> - edgecount = 4;
> - } else {
> - double scale, dx, dy, adx, ady;
> -
> - adx = dx = pRight->xa - pLeft->xa;
> - ady = dy = pRight->ya - pLeft->ya;
> - if (adx< 0)
> - adx = -adx;
> - if (ady< 0)
> - ady = -ady;
> - scale = ady;
> - if (adx> ady)
> - scale = adx;
> - slopes[2].dx = (int) ((dx * 65536) / scale);
> - slopes[2].dy = (int) ((dy * 65536) / scale);
> - slopes[2].k = ((pLeft->xa + pRight->xa) * slopes[2].dy -
> - (pLeft->ya + pRight->ya) * slopes[2].dx) / 2.0;
> - edgecount = 3;
> - }
> -
> - y = miPolyBuildPoly (vertices, slopes, edgecount, pLeft->x, pLeft->y,
> - left, right,&nleft,&nright,&height);
> - miFillPolyHelper (pGC, foreground, spanData, y, height, left, right, nleft, nright);
> -}
> -
> -static int
> -miLineArcI (GCPtr pGC, int xorg, int yorg, DDXPointPtr points, int *widths)
> -{
> - DDXPointPtr tpts, bpts;
> - int *twids, *bwids;
> - int x, y, e, ex, slw;
> -
> - tpts = points;
> - twids = widths;
> - slw = pGC->lineWidth;
> - if (slw == 1) {
> - tpts->x = xorg;
> - tpts->y = yorg;
> - *twids = 1;
> - return 1;
> - }
> - bpts = tpts + slw;
> - bwids = twids + slw;
> - y = (slw>> 1) + 1;
> - if (slw& 1)
> - e = -((y<< 2) + 3);
> - else
> - e = -(y<< 3);
> - ex = -4;
> - x = 0;
> - while (y) {
> - e += (y<< 3) - 4;
> - while (e>= 0) {
> - x++;
> - e += (ex = -((x<< 3) + 4));
> - }
> - y--;
> - slw = (x<< 1) + 1;
> - if ((e == ex)&& (slw> 1))
> - slw--;
> - tpts->x = xorg - x;
> - tpts->y = yorg - y;
> - tpts++;
> - *twids++ = slw;
> - if ((y != 0)&& ((slw> 1) || (e != ex))) {
> - bpts--;
> - bpts->x = xorg - x;
> - bpts->y = yorg + y;
> - *--bwids = slw;
> - }
> - }
> - return (pGC->lineWidth);
> -}
> -
> -#define CLIPSTEPEDGE(edgey,edge,edgeleft) \
> - if (ybase == edgey) \
> - { \
> - if (edgeleft) \
> - { \
> - if (edge->x> xcl) \
> - xcl = edge->x; \
> - } \
> - else \
> - { \
> - if (edge->x< xcr) \
> - xcr = edge->x; \
> - } \
> - edgey++; \
> - edge->x += edge->stepx; \
> - edge->e += edge->dx; \
> - if (edge->e> 0) \
> - { \
> - edge->x += edge->signdx; \
> - edge->e -= edge->dy; \
> - } \
> - }
> -
> -static int
> -miLineArcD (GCPtr pGC,
> - double xorg,
> - double yorg,
> - DDXPointPtr points,
> - int *widths,
> - PolyEdgePtr edge1,
> - int edgey1, Boolean edgeleft1, PolyEdgePtr edge2, int edgey2, Boolean edgeleft2)
> -{
> - DDXPointPtr pts;
> - int *wids;
> - double radius, x0, y0, el, er, yk, xlk, xrk, k;
> - int xbase, ybase, y, boty, xl, xr, xcl, xcr;
> - int ymin, ymax;
> - Boolean edge1IsMin, edge2IsMin;
> - int ymin1, ymin2;
> -
> - pts = points;
> - wids = widths;
> - xbase = (int)floor (xorg);
> - x0 = xorg - xbase;
> - ybase = ICEIL (yorg);
> - y0 = yorg - ybase;
> - xlk = x0 + x0 + 1.0;
> - xrk = x0 + x0 - 1.0;
> - yk = y0 + y0 - 1.0;
> - radius = ((double) pGC->lineWidth) / 2.0;
> - y = (int)floor (radius - y0 + 1.0);
> - ybase -= y;
> - ymin = ybase;
> - ymax = 65536;
> - edge1IsMin = FALSE;
> - ymin1 = edgey1;
> - if (edge1->dy>= 0) {
> - if (!edge1->dy) {
> - if (edgeleft1)
> - edge1IsMin = TRUE;
> - else
> - ymax = edgey1;
> - edgey1 = 65536;
> - } else {
> - if ((edge1->signdx< 0) == edgeleft1)
> - edge1IsMin = TRUE;
> - }
> - }
> - edge2IsMin = FALSE;
> - ymin2 = edgey2;
> - if (edge2->dy>= 0) {
> - if (!edge2->dy) {
> - if (edgeleft2)
> - edge2IsMin = TRUE;
> - else
> - ymax = edgey2;
> - edgey2 = 65536;
> - } else {
> - if ((edge2->signdx< 0) == edgeleft2)
> - edge2IsMin = TRUE;
> - }
> - }
> - if (edge1IsMin) {
> - ymin = ymin1;
> - if (edge2IsMin&& ymin1> ymin2)
> - ymin = ymin2;
> - } else if (edge2IsMin)
> - ymin = ymin2;
> - el = radius * radius - ((y + y0) * (y + y0)) - (x0 * x0);
> - er = el + xrk;
> - xl = 1;
> - xr = 0;
> - if (x0< 0.5) {
> - xl = 0;
> - el -= xlk;
> - }
> - boty = (y0< -0.5) ? 1 : 0;
> - if (ybase + y - boty> ymax)
> - boty = ymax - ybase - y;
> - while (y> boty) {
> - k = (y<< 1) + yk;
> - er += k;
> - while (er> 0.0) {
> - xr++;
> - er += xrk - (xr<< 1);
> - }
> - el += k;
> - while (el>= 0.0) {
> - xl--;
> - el += (xl<< 1) - xlk;
> - }
> - y--;
> - ybase++;
> - if (ybase< ymin)
> - continue;
> - xcl = xl + xbase;
> - xcr = xr + xbase;
> - CLIPSTEPEDGE (edgey1, edge1, edgeleft1);
> - CLIPSTEPEDGE (edgey2, edge2, edgeleft2);
> - if (xcr>= xcl) {
> - pts->x = xcl;
> - pts->y = ybase;
> - pts++;
> - *wids++ = xcr - xcl + 1;
> - }
> - }
> - er = xrk - (xr<< 1) - er;
> - el = (xl<< 1) - xlk - el;
> - boty = (int)floor (-y0 - radius + 1.0);
> - if (ybase + y - boty> ymax)
> - boty = ymax - ybase - y;
> - while (y> boty) {
> - k = (y<< 1) + yk;
> - er -= k;
> - while ((er>= 0.0)&& (xr>= 0)) {
> - xr--;
> - er += xrk - (xr<< 1);
> - }
> - el -= k;
> - while ((el> 0.0)&& (xl<= 0)) {
> - xl++;
> - el += (xl<< 1) - xlk;
> - }
> - y--;
> - ybase++;
> - if (ybase< ymin)
> - continue;
> - xcl = xl + xbase;
> - xcr = xr + xbase;
> - CLIPSTEPEDGE (edgey1, edge1, edgeleft1);
> - CLIPSTEPEDGE (edgey2, edge2, edgeleft2);
> - if (xcr>= xcl) {
> - pts->x = xcl;
> - pts->y = ybase;
> - pts++;
> - *wids++ = xcr - xcl + 1;
> - }
> - }
> - return (pts - points);
> -}
> -
> -static int
> -miRoundJoinFace (LineFacePtr face, PolyEdgePtr edge, Boolean * leftEdge)
> -{
> - int y;
> - int dx, dy;
> - double xa, ya;
> - Boolean left;
> -
> - dx = -face->dy;
> - dy = face->dx;
> - xa = face->xa;
> - ya = face->ya;
> - left = 1;
> - if (ya> 0) {
> - ya = 0.0;
> - xa = 0.0;
> - }
> - if (dy< 0 || (dy == 0&& dx> 0)) {
> - dx = -dx;
> - dy = -dy;
> - left = !left;
> - }
> - if (dx == 0&& dy == 0)
> - dy = 1;
> - if (dy == 0) {
> - y = ICEIL (face->ya) + face->y;
> - edge->x = -32767;
> - edge->stepx = 0;
> - edge->signdx = 0;
> - edge->e = -1;
> - edge->dy = 0;
> - edge->dx = 0;
> - edge->height = 0;
> - } else {
> - y = miPolyBuildEdge (xa, ya, 0.0, dx, dy, face->x, face->y, !left, edge);
> - edge->height = 32767;
> - }
> - *leftEdge = !left;
> - return y;
> -}
> -
> -static void
> -miRoundJoinClip (LineFacePtr pLeft, LineFacePtr pRight,
> - PolyEdgePtr edge1, PolyEdgePtr edge2, int *y1, int *y2, Boolean * left1, Boolean * left2)
> -{
> - double denom;
> -
> - denom = -pLeft->dx * (double) pRight->dy + pRight->dx * (double) pLeft->dy;
> -
> - if (denom>= 0) {
> - pLeft->xa = -pLeft->xa;
> - pLeft->ya = -pLeft->ya;
> - } else {
> - pRight->xa = -pRight->xa;
> - pRight->ya = -pRight->ya;
> - }
> - *y1 = miRoundJoinFace (pLeft, edge1, left1);
> - *y2 = miRoundJoinFace (pRight, edge2, left2);
> -}
> -
> -static int
> -miRoundCapClip (LineFacePtr face, Boolean isInt, PolyEdgePtr edge, Boolean * leftEdge)
> -{
> - int y;
> - int dx, dy;
> - double xa, ya, k;
> - Boolean left;
> -
> - dx = -face->dy;
> - dy = face->dx;
> - xa = face->xa;
> - ya = face->ya;
> - k = 0.0;
> - if (!isInt)
> - k = face->k;
> - left = 1;
> - if (dy< 0 || (dy == 0&& dx> 0)) {
> - dx = -dx;
> - dy = -dy;
> - xa = -xa;
> - ya = -ya;
> - left = !left;
> - }
> - if (dx == 0&& dy == 0)
> - dy = 1;
> - if (dy == 0) {
> - y = ICEIL (face->ya) + face->y;
> - edge->x = -32767;
> - edge->stepx = 0;
> - edge->signdx = 0;
> - edge->e = -1;
> - edge->dy = 0;
> - edge->dx = 0;
> - edge->height = 0;
> - } else {
> - y = miPolyBuildEdge (xa, ya, k, dx, dy, face->x, face->y, !left, edge);
> - edge->height = 32767;
> - }
> - *leftEdge = !left;
> - return y;
> -}
> -
> -static void
> -miLineArc (GCPtr pGC,
> - Boolean foreground,
> - SpanDataPtr spanData,
> - LineFacePtr leftFace, LineFacePtr rightFace, double xorg, double yorg, Boolean isInt)
> -{
> - DDXPointPtr points;
> - int *widths;
> - int xorgi = 0, yorgi = 0;
> - Spans spanRec;
> - int n;
> - PolyEdgeRec edge1, edge2;
> - int edgey1, edgey2;
> - Boolean edgeleft1, edgeleft2;
> -
> - if (isInt) {
> - xorgi = leftFace ? leftFace->x : rightFace->x;
> - yorgi = leftFace ? leftFace->y : rightFace->y;
> - }
> - edgey1 = 65536;
> - edgey2 = 65536;
> - edge1.x = 0; /* not used, keep memory checkers happy */
> - edge1.dy = -1;
> - edge2.x = 0; /* not used, keep memory checkers happy */
> - edge2.dy = -1;
> - edgeleft1 = FALSE;
> - edgeleft2 = FALSE;
> - if ((pGC->lineStyle != LineSolid || pGC->lineWidth> 2)&&
> - ((pGC->capStyle == CapRound&& pGC->joinStyle != JoinRound) ||
> - (pGC->joinStyle == JoinRound&& pGC->capStyle == CapButt))) {
> - if (isInt) {
> - xorg = (double) xorgi;
> - yorg = (double) yorgi;
> - }
> - if (leftFace&& rightFace) {
> - miRoundJoinClip (leftFace, rightFace,&edge1,&edge2,
> -&edgey1,&edgey2,&edgeleft1,&edgeleft2);
> - } else if (leftFace) {
> - edgey1 = miRoundCapClip (leftFace, isInt,&edge1,&edgeleft1);
> - } else if (rightFace) {
> - edgey2 = miRoundCapClip (rightFace, isInt,&edge2,&edgeleft2);
> - }
> - isInt = FALSE;
> - }
> - if (!spanData) {
> - points = (DDXPointRec *)xalloc (sizeof (DDXPointRec) * pGC->lineWidth);
> - if (!points)
> - return;
> - widths = (int *)xalloc (sizeof (int) * pGC->lineWidth);
> - if (!widths) {
> - xfree (points);
> - return;
> - }
> - } else {
> - points = (DDXPointRec *)xalloc (pGC->lineWidth * sizeof (DDXPointRec));
> - if (!points)
> - return;
> - widths = (int *)xalloc (pGC->lineWidth * sizeof (int));
> - if (!widths) {
> - xfree (points);
> - return;
> - }
> - spanRec.points = points;
> - spanRec.widths = widths;
> - }
> - if (isInt)
> - n = miLineArcI (pGC, xorgi, yorgi, points, widths);
> - else
> - n = miLineArcD (pGC, xorg, yorg, points, widths,
> -&edge1, edgey1, edgeleft1,&edge2, edgey2, edgeleft2);
> -
> - if (!spanData) {
> - (*pGC->ops->FillSpans) (pGC, n, points, widths, TRUE, foreground);
> - xfree (widths);
> - xfree (points);
> - } else {
> - spanRec.count = n;
> - AppendSpanGroup (pGC, foreground,&spanRec, spanData)
> - }
> -}
> -
> -static void
> -miLineProjectingCap (GCPtr pGC, Boolean foreground,
> - SpanDataPtr spanData, LineFacePtr face, Boolean isLeft,
> - double xorg, double yorg, Boolean isInt)
> -{
> - int xorgi = 0, yorgi = 0;
> - int lw;
> - PolyEdgeRec lefts[2], rights[2];
> - int lefty, righty, topy, bottomy;
> - PolyEdgePtr left, right;
> - PolyEdgePtr top, bottom;
> - double xa, ya;
> - double k;
> - double xap, yap;
> - int dx, dy;
> - double projectXoff, projectYoff;
> - double maxy;
> - int finaly;
> -
> - if (isInt) {
> - xorgi = face->x;
> - yorgi = face->y;
> - }
> - lw = pGC->lineWidth;
> - dx = face->dx;
> - dy = face->dy;
> - k = face->k;
> - if (dy == 0) {
> - lefts[0].height = lw;
> - lefts[0].x = xorgi;
> - if (isLeft)
> - lefts[0].x -= (lw>> 1);
> - lefts[0].stepx = 0;
> - lefts[0].signdx = 1;
> - lefts[0].e = -lw;
> - lefts[0].dx = 0;
> - lefts[0].dy = lw;
> - rights[0].height = lw;
> - rights[0].x = xorgi;
> - if (!isLeft)
> - rights[0].x += ((lw + 1)>> 1);
> - rights[0].stepx = 0;
> - rights[0].signdx = 1;
> - rights[0].e = -lw;
> - rights[0].dx = 0;
> - rights[0].dy = lw;
> - miFillPolyHelper (pGC, foreground, spanData, yorgi - (lw>> 1), lw, lefts, rights, 1, 1);
> - } else if (dx == 0) {
> - if (dy< 0) {
> - dy = -dy;
> - isLeft = !isLeft;
> - }
> - topy = yorgi;
> - bottomy = yorgi + dy;
> - if (isLeft)
> - topy -= (lw>> 1);
> - else
> - bottomy += (lw>> 1);
> - lefts[0].height = bottomy - topy;
> - lefts[0].x = xorgi - (lw>> 1);
> - lefts[0].stepx = 0;
> - lefts[0].signdx = 1;
> - lefts[0].e = -dy;
> - lefts[0].dx = dx;
> - lefts[0].dy = dy;
> -
> - rights[0].height = bottomy - topy;
> - rights[0].x = lefts[0].x + (lw - 1);
> - rights[0].stepx = 0;
> - rights[0].signdx = 1;
> - rights[0].e = -dy;
> - rights[0].dx = dx;
> - rights[0].dy = dy;
> - miFillPolyHelper (pGC, foreground, spanData, topy, bottomy - topy, lefts, rights, 1, 1);
> - } else {
> - xa = face->xa;
> - ya = face->ya;
> - projectXoff = -ya;
> - projectYoff = xa;
> - if (dx< 0) {
> - right =&rights[1];
> - left =&lefts[0];
> - top =&rights[0];
> - bottom =&lefts[1];
> - } else {
> - right =&rights[0];
> - left =&lefts[1];
> - top =&lefts[0];
> - bottom =&rights[1];
> - }
> - if (isLeft) {
> - righty = miPolyBuildEdge (xa, ya, k, dx, dy, xorgi, yorgi, 0, right);
> -
> - xa = -xa;
> - ya = -ya;
> - k = -k;
> - lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
> - k, dx, dy, xorgi, yorgi, 1, left);
> - if (dx> 0) {
> - ya = -ya;
> - xa = -xa;
> - }
> - xap = xa - projectXoff;
> - yap = ya - projectYoff;
> - topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
> - -dy, dx, xorgi, yorgi, dx> 0, top);
> - bottomy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, xorgi, yorgi, dx< 0, bottom);
> - maxy = -ya;
> - } else {
> - righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
> - k, dx, dy, xorgi, yorgi, 0, right);
> -
> - xa = -xa;
> - ya = -ya;
> - k = -k;
> - lefty = miPolyBuildEdge (xa, ya, k, dx, dy, xorgi, yorgi, 1, left);
> - if (dx> 0) {
> - ya = -ya;
> - xa = -xa;
> - }
> - xap = xa - projectXoff;
> - yap = ya - projectYoff;
> - topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, xorgi, xorgi, dx> 0, top);
> - bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
> - -dy, dx, xorgi, xorgi, dx< 0, bottom);
> - maxy = -ya + projectYoff;
> - }
> - finaly = ICEIL (maxy) + yorgi;
> - if (dx< 0) {
> - left->height = bottomy - lefty;
> - right->height = finaly - righty;
> - top->height = righty - topy;
> - } else {
> - right->height = bottomy - righty;
> - left->height = finaly - lefty;
> - top->height = lefty - topy;
> - }
> - bottom->height = finaly - bottomy;
> - miFillPolyHelper (pGC, foreground, spanData, topy,
> - bottom->height + bottomy - topy, lefts, rights, 2, 2);
> - }
> -}
> -
> -static void
> -miWideSegment (GCPtr pGC,
> - Boolean foreground,
> - SpanDataPtr spanData,
> - int x1,
> - int y1,
> - int x2,
> - int y2,
> - Boolean projectLeft, Boolean projectRight, LineFacePtr leftFace, LineFacePtr rightFace)
> -{
> - double l, L, r;
> - double xa, ya;
> - double projectXoff = 0.0, projectYoff = 0.0;
> - double k;
> - double maxy;
> - int x, y;
> - int dx, dy;
> - int finaly;
> - PolyEdgePtr left, right;
> - PolyEdgePtr top, bottom;
> - int lefty, righty, topy, bottomy;
> - int signdx;
> - PolyEdgeRec lefts[2], rights[2];
> - LineFacePtr tface;
> - int lw = pGC->lineWidth;
> -
> - /* draw top-to-bottom always */
> - if (y2< y1 || (y2 == y1&& x2< x1)) {
> - x = x1;
> - x1 = x2;
> - x2 = x;
> -
> - y = y1;
> - y1 = y2;
> - y2 = y;
> -
> - x = projectLeft;
> - projectLeft = projectRight;
> - projectRight = x;
> -
> - tface = leftFace;
> - leftFace = rightFace;
> - rightFace = tface;
> - }
> -
> - dy = y2 - y1;
> - signdx = 1;
> - dx = x2 - x1;
> - if (dx< 0)
> - signdx = -1;
> -
> - leftFace->x = x1;
> - leftFace->y = y1;
> - leftFace->dx = dx;
> - leftFace->dy = dy;
> -
> - rightFace->x = x2;
> - rightFace->y = y2;
> - rightFace->dx = -dx;
> - rightFace->dy = -dy;
> -
> - if (dy == 0) {
> - rightFace->xa = 0;
> - rightFace->ya = (double) lw / 2.0;
> - rightFace->k = -(double) (lw * dx) / 2.0;
> - leftFace->xa = 0;
> - leftFace->ya = -rightFace->ya;
> - leftFace->k = rightFace->k;
> - x = x1;
> - if (projectLeft)
> - x -= (lw>> 1);
> - y = y1 - (lw>> 1);
> - dx = x2 - x;
> - if (projectRight)
> - dx += ((lw + 1)>> 1);
> - dy = lw;
> - miFillRectPolyHelper (pGC, foreground, spanData, x, y, dx, dy);
> - } else if (dx == 0) {
> - leftFace->xa = (double) lw / 2.0;
> - leftFace->ya = 0;
> - leftFace->k = (double) (lw * dy) / 2.0;
> - rightFace->xa = -leftFace->xa;
> - rightFace->ya = 0;
> - rightFace->k = leftFace->k;
> - y = y1;
> - if (projectLeft)
> - y -= lw>> 1;
> - x = x1 - (lw>> 1);
> - dy = y2 - y;
> - if (projectRight)
> - dy += ((lw + 1)>> 1);
> - dx = lw;
> - miFillRectPolyHelper (pGC, foreground, spanData, x, y, dx, dy);
> - } else {
> - l = ((double) lw) / 2.0;
> - L = hypot ((double) dx, (double) dy);
> -
> - if (dx< 0) {
> - right =&rights[1];
> - left =&lefts[0];
> - top =&rights[0];
> - bottom =&lefts[1];
> - } else {
> - right =&rights[0];
> - left =&lefts[1];
> - top =&lefts[0];
> - bottom =&rights[1];
> - }
> - r = l / L;
> -
> - /* coord of upper bound at integral y */
> - ya = -r * dx;
> - xa = r * dy;
> -
> - if (projectLeft | projectRight) {
> - projectXoff = -ya;
> - projectYoff = xa;
> - }
> -
> - /* xa * dy - ya * dx */
> - k = l * L;
> -
> - leftFace->xa = xa;
> - leftFace->ya = ya;
> - leftFace->k = k;
> - rightFace->xa = -xa;
> - rightFace->ya = -ya;
> - rightFace->k = k;
> -
> - if (projectLeft)
> - righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
> - k, dx, dy, x1, y1, 0, right);
> - else
> - righty = miPolyBuildEdge (xa, ya, k, dx, dy, x1, y1, 0, right);
> -
> - /* coord of lower bound at integral y */
> - ya = -ya;
> - xa = -xa;
> -
> - /* xa * dy - ya * dx */
> - k = -k;
> -
> - if (projectLeft)
> - lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
> - k, dx, dy, x1, y1, 1, left);
> - else
> - lefty = miPolyBuildEdge (xa, ya, k, dx, dy, x1, y1, 1, left);
> -
> - /* coord of top face at integral y */
> -
> - if (signdx> 0) {
> - ya = -ya;
> - xa = -xa;
> - }
> -
> - if (projectLeft) {
> - double xap = xa - projectXoff;
> - double yap = ya - projectYoff;
> - topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy, -dy, dx, x1, y1, dx> 0, top);
> - } else
> - topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, x1, y1, dx> 0, top);
> -
> - /* coord of bottom face at integral y */
> -
> - if (projectRight) {
> - double xap = xa + projectXoff;
> - double yap = ya + projectYoff;
> - bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
> - -dy, dx, x2, y2, dx< 0, bottom);
> - maxy = -ya + projectYoff;
> - } else {
> - bottomy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, x2, y2, dx< 0, bottom);
> - maxy = -ya;
> - }
> -
> - finaly = ICEIL (maxy) + y2;
> -
> - if (dx< 0) {
> - left->height = bottomy - lefty;
> - right->height = finaly - righty;
> - top->height = righty - topy;
> - } else {
> - right->height = bottomy - righty;
> - left->height = finaly - lefty;
> - top->height = lefty - topy;
> - }
> - bottom->height = finaly - bottomy;
> - miFillPolyHelper (pGC, foreground, spanData, topy,
> - bottom->height + bottomy - topy, lefts, rights, 2, 2);
> - }
> -}
> -
> -static SpanDataPtr
> -miSetupSpanData (GCPtr pGC, SpanDataPtr spanData, int npt)
> -{
> - if ((npt< 3&& pGC->capStyle != CapRound) || miSpansEasyRop (pGC->alu))
> - return (SpanDataPtr) NULL;
> - if (pGC->lineStyle == LineDoubleDash)
> - miInitSpanGroup (&spanData->bgGroup);
> - miInitSpanGroup (&spanData->fgGroup);
> - return spanData;
> -}
> -
> -static void
> -miCleanupSpanData (GCPtr pGC, SpanDataPtr spanData)
> -{
> - if (pGC->lineStyle == LineDoubleDash) {
> - miFillUniqueSpanGroup (pGC,&spanData->bgGroup, FALSE);
> - miFreeSpanGroup (&spanData->bgGroup);
> - }
> - miFillUniqueSpanGroup (pGC,&spanData->fgGroup, TRUE);
> - miFreeSpanGroup (&spanData->fgGroup);
> -}
> -
> -void
> -miWideLine (GCPtr pGC, int mode, int npt, DDXPointPtr pPts)
> -{
> - int x1, y1, x2, y2;
> - SpanDataRec spanDataRec;
> - SpanDataPtr spanData;
> - Boolean projectLeft, projectRight;
> - LineFaceRec leftFace, rightFace, prevRightFace;
> - LineFaceRec firstFace;
> - int first;
> - Boolean somethingDrawn = FALSE;
> - Boolean selfJoin;
> -
> - spanData = miSetupSpanData (pGC,&spanDataRec, npt);
> - x2 = pPts->x;
> - y2 = pPts->y;
> - first = TRUE;
> - selfJoin = FALSE;
> - if (npt> 1) {
> - if (mode == CoordModePrevious) {
> - int nptTmp;
> - DDXPointPtr pPtsTmp;
> -
> - x1 = x2;
> - y1 = y2;
> - nptTmp = npt;
> - pPtsTmp = pPts + 1;
> - while (--nptTmp) {
> - x1 += pPtsTmp->x;
> - y1 += pPtsTmp->y;
> - ++pPtsTmp;
> - }
> - if (x2 == x1&& y2 == y1)
> - selfJoin = TRUE;
> - } else if (x2 == pPts[npt - 1].x&& y2 == pPts[npt - 1].y) {
> - selfJoin = TRUE;
> - }
> - }
> - projectLeft = pGC->capStyle == CapProjecting&& !selfJoin;
> - projectRight = FALSE;
> - while (--npt) {
> - x1 = x2;
> - y1 = y2;
> - ++pPts;
> - x2 = pPts->x;
> - y2 = pPts->y;
> - if (mode == CoordModePrevious) {
> - x2 += x1;
> - y2 += y1;
> - }
> - if (x1 != x2 || y1 != y2) {
> - somethingDrawn = TRUE;
> - if (npt == 1&& pGC->capStyle == CapProjecting&& !selfJoin)
> - projectRight = TRUE;
> - miWideSegment (pGC, TRUE, spanData, x1, y1, x2, y2,
> - projectLeft, projectRight,&leftFace,&rightFace);
> - if (first) {
> - if (selfJoin)
> - firstFace = leftFace;
> - else if (pGC->capStyle == CapRound) {
> - if (pGC->lineWidth == 1&& !spanData)
> - miLineOnePoint (pGC, TRUE, spanData, x1, y1);
> - else
> - miLineArc (pGC, TRUE, spanData,
> -&leftFace, (LineFacePtr) NULL, (double) 0.0, (double) 0.0, TRUE);
> - }
> - } else {
> - miLineJoin (pGC, TRUE, spanData,&leftFace,&prevRightFace);
> - }
> - prevRightFace = rightFace;
> - first = FALSE;
> - projectLeft = FALSE;
> - }
> - if (npt == 1&& somethingDrawn) {
> - if (selfJoin)
> - miLineJoin (pGC, TRUE, spanData,&firstFace,&rightFace);
> - else if (pGC->capStyle == CapRound) {
> - if (pGC->lineWidth == 1&& !spanData)
> - miLineOnePoint (pGC, TRUE, spanData, x2, y2);
> - else
> - miLineArc (pGC, TRUE, spanData,
> - (LineFacePtr) NULL,&rightFace, (double) 0.0, (double) 0.0, TRUE);
> - }
> - }
> - }
> - /* handle crock where all points are coincedent */
> - if (!somethingDrawn) {
> - projectLeft = pGC->capStyle == CapProjecting;
> - miWideSegment (pGC, TRUE, spanData,
> - x2, y2, x2, y2, projectLeft, projectLeft,&leftFace,&rightFace);
> - if (pGC->capStyle == CapRound) {
> - miLineArc (pGC, TRUE, spanData,
> -&leftFace, (LineFacePtr) NULL, (double) 0.0, (double) 0.0, TRUE);
> - rightFace.dx = -1; /* sleezy hack to make it work */
> - miLineArc (pGC, TRUE, spanData,
> - (LineFacePtr) NULL,&rightFace, (double) 0.0, (double) 0.0, TRUE);
> - }
> - }
> - if (spanData)
> - miCleanupSpanData (pGC, spanData);
> -}
> -
> -#define V_TOP 0
> -#define V_RIGHT 1
> -#define V_BOTTOM 2
> -#define V_LEFT 3
> -
> -static void
> -miWideDashSegment (GCPtr pGC,
> - SpanDataPtr spanData,
> - int *pDashOffset,
> - int *pDashIndex,
> - int x1,
> - int y1,
> - int x2,
> - int y2,
> - Boolean projectLeft, Boolean projectRight, LineFacePtr leftFace, LineFacePtr rightFace)
> -{
> - int dashIndex, dashRemain;
> - unsigned char *pDash;
> - double L, l;
> - double k;
> - PolyVertexRec vertices[4];
> - PolyVertexRec saveRight = { 0 }, saveBottom;
> - PolySlopeRec slopes[4];
> - PolyEdgeRec left[2], right[2];
> - LineFaceRec lcapFace, rcapFace;
> - int nleft, nright;
> - int h;
> - int y;
> - int dy, dx;
> - Boolean foreground;
> - double LRemain;
> - double r;
> - double rdx, rdy;
> - double dashDx, dashDy;
> - double saveK = 0.0;
> - Boolean first = TRUE;
> - double lcenterx, lcentery, rcenterx = 0.0, rcentery = 0.0;
> -
> - dx = x2 - x1;
> - dy = y2 - y1;
> - dashIndex = *pDashIndex;
> - pDash = pGC->dash;
> - dashRemain = pDash[dashIndex] - *pDashOffset;
> -
> - l = ((double) pGC->lineWidth) / 2.0;
> - if (dx == 0) {
> - L = dy;
> - rdx = 0;
> - rdy = l;
> - if (dy< 0) {
> - L = -dy;
> - rdy = -l;
> - }
> - } else if (dy == 0) {
> - L = dx;
> - rdx = l;
> - rdy = 0;
> - if (dx< 0) {
> - L = -dx;
> - rdx = -l;
> - }
> - } else {
> - L = hypot ((double) dx, (double) dy);
> - r = l / L;
> -
> - rdx = r * dx;
> - rdy = r * dy;
> - }
> - k = l * L;
> - LRemain = L;
> - /* All position comments are relative to a line with dx and dy> 0,
> - * but the code does not depend on this */
> - /* top */
> - slopes[V_TOP].dx = dx;
> - slopes[V_TOP].dy = dy;
> - slopes[V_TOP].k = k;
> - /* right */
> - slopes[V_RIGHT].dx = -dy;
> - slopes[V_RIGHT].dy = dx;
> - slopes[V_RIGHT].k = 0;
> - /* bottom */
> - slopes[V_BOTTOM].dx = -dx;
> - slopes[V_BOTTOM].dy = -dy;
> - slopes[V_BOTTOM].k = k;
> - /* left */
> - slopes[V_LEFT].dx = dy;
> - slopes[V_LEFT].dy = -dx;
> - slopes[V_LEFT].k = 0;
> -
> - /* preload the start coordinates */
> - vertices[V_RIGHT].x = vertices[V_TOP].x = rdy;
> - vertices[V_RIGHT].y = vertices[V_TOP].y = -rdx;
> -
> - vertices[V_BOTTOM].x = vertices[V_LEFT].x = -rdy;
> - vertices[V_BOTTOM].y = vertices[V_LEFT].y = rdx;
> -
> - if (projectLeft) {
> - vertices[V_TOP].x -= rdx;
> - vertices[V_TOP].y -= rdy;
> -
> - vertices[V_LEFT].x -= rdx;
> - vertices[V_LEFT].y -= rdy;
> -
> - slopes[V_LEFT].k = rdx * dx + rdy * dy;
> - }
> -
> - lcenterx = x1;
> - lcentery = y1;
> -
> - if (pGC->capStyle == CapRound) {
> - lcapFace.dx = dx;
> - lcapFace.dy = dy;
> - lcapFace.x = x1;
> - lcapFace.y = y1;
> -
> - rcapFace.dx = -dx;
> - rcapFace.dy = -dy;
> - rcapFace.x = x1;
> - rcapFace.y = y1;
> - }
> - while (LRemain> dashRemain) {
> - dashDx = (dashRemain * dx) / L;
> - dashDy = (dashRemain * dy) / L;
> -
> - rcenterx = lcenterx + dashDx;
> - rcentery = lcentery + dashDy;
> -
> - vertices[V_RIGHT].x += dashDx;
> - vertices[V_RIGHT].y += dashDy;
> -
> - vertices[V_BOTTOM].x += dashDx;
> - vertices[V_BOTTOM].y += dashDy;
> -
> - slopes[V_RIGHT].k = vertices[V_RIGHT].x * dx + vertices[V_RIGHT].y * dy;
> -
> - if (pGC->lineStyle == LineDoubleDash || !(dashIndex& 1)) {
> - if (pGC->lineStyle == LineOnOffDash&& pGC->capStyle == CapProjecting) {
> - saveRight = vertices[V_RIGHT];
> - saveBottom = vertices[V_BOTTOM];
> - saveK = slopes[V_RIGHT].k;
> -
> - if (!first) {
> - vertices[V_TOP].x -= rdx;
> - vertices[V_TOP].y -= rdy;
> -
> - vertices[V_LEFT].x -= rdx;
> - vertices[V_LEFT].y -= rdy;
> -
> - slopes[V_LEFT].k = vertices[V_LEFT].x *
> - slopes[V_LEFT].dy - vertices[V_LEFT].y * slopes[V_LEFT].dx;
> - }
> -
> - vertices[V_RIGHT].x += rdx;
> - vertices[V_RIGHT].y += rdy;
> -
> - vertices[V_BOTTOM].x += rdx;
> - vertices[V_BOTTOM].y += rdy;
> -
> - slopes[V_RIGHT].k = vertices[V_RIGHT].x *
> - slopes[V_RIGHT].dy - vertices[V_RIGHT].y * slopes[V_RIGHT].dx;
> - }
> - y = miPolyBuildPoly (vertices, slopes, 4, x1, y1, left, right,&nleft,&nright,&h);
> - foreground = (dashIndex& 1) == 0;
> - miFillPolyHelper (pGC, foreground, spanData, y, h, left, right, nleft, nright);
> -
> - if (pGC->lineStyle == LineOnOffDash) {
> - switch (pGC->capStyle) {
> - case CapProjecting:
> - vertices[V_BOTTOM] = saveBottom;
> - vertices[V_RIGHT] = saveRight;
> - slopes[V_RIGHT].k = saveK;
> - break;
> - case CapRound:
> - if (!first) {
> - if (dx< 0) {
> - lcapFace.xa = -vertices[V_LEFT].x;
> - lcapFace.ya = -vertices[V_LEFT].y;
> - lcapFace.k = slopes[V_LEFT].k;
> - } else {
> - lcapFace.xa = vertices[V_TOP].x;
> - lcapFace.ya = vertices[V_TOP].y;
> - lcapFace.k = -slopes[V_LEFT].k;
> - }
> - miLineArc (pGC, foreground, spanData,
> -&lcapFace, (LineFacePtr) NULL, lcenterx, lcentery, FALSE);
> - }
> - if (dx< 0) {
> - rcapFace.xa = vertices[V_BOTTOM].x;
> - rcapFace.ya = vertices[V_BOTTOM].y;
> - rcapFace.k = slopes[V_RIGHT].k;
> - } else {
> - rcapFace.xa = -vertices[V_RIGHT].x;
> - rcapFace.ya = -vertices[V_RIGHT].y;
> - rcapFace.k = -slopes[V_RIGHT].k;
> - }
> - miLineArc (pGC, foreground, spanData,
> - (LineFacePtr) NULL,&rcapFace, rcenterx, rcentery, FALSE);
> - break;
> - }
> - }
> - }
> - LRemain -= dashRemain;
> - ++dashIndex;
> - if (dashIndex == pGC->numInDashList)
> - dashIndex = 0;
> - dashRemain = pDash[dashIndex];
> -
> - lcenterx = rcenterx;
> - lcentery = rcentery;
> -
> - vertices[V_TOP] = vertices[V_RIGHT];
> - vertices[V_LEFT] = vertices[V_BOTTOM];
> - slopes[V_LEFT].k = -slopes[V_RIGHT].k;
> - first = FALSE;
> - }
> -
> - if (pGC->lineStyle == LineDoubleDash || !(dashIndex& 1)) {
> - vertices[V_TOP].x -= dx;
> - vertices[V_TOP].y -= dy;
> -
> - vertices[V_LEFT].x -= dx;
> - vertices[V_LEFT].y -= dy;
> -
> - vertices[V_RIGHT].x = rdy;
> - vertices[V_RIGHT].y = -rdx;
> -
> - vertices[V_BOTTOM].x = -rdy;
> - vertices[V_BOTTOM].y = rdx;
> -
> -
> - if (projectRight) {
> - vertices[V_RIGHT].x += rdx;
> - vertices[V_RIGHT].y += rdy;
> -
> - vertices[V_BOTTOM].x += rdx;
> - vertices[V_BOTTOM].y += rdy;
> - slopes[V_RIGHT].k = vertices[V_RIGHT].x *
> - slopes[V_RIGHT].dy - vertices[V_RIGHT].y * slopes[V_RIGHT].dx;
> - } else
> - slopes[V_RIGHT].k = 0;
> -
> - if (!first&& pGC->lineStyle == LineOnOffDash&& pGC->capStyle == CapProjecting) {
> - vertices[V_TOP].x -= rdx;
> - vertices[V_TOP].y -= rdy;
> -
> - vertices[V_LEFT].x -= rdx;
> - vertices[V_LEFT].y -= rdy;
> - slopes[V_LEFT].k = vertices[V_LEFT].x *
> - slopes[V_LEFT].dy - vertices[V_LEFT].y * slopes[V_LEFT].dx;
> - } else
> - slopes[V_LEFT].k += dx * dx + dy * dy;
> -
> -
> - y = miPolyBuildPoly (vertices, slopes, 4, x2, y2, left, right,&nleft,&nright,&h);
> -
> - foreground = (dashIndex& 1) == 0;
> - miFillPolyHelper (pGC, foreground, spanData, y, h, left, right, nleft, nright);
> - if (!first&& pGC->lineStyle == LineOnOffDash&& pGC->capStyle == CapRound) {
> - lcapFace.x = x2;
> - lcapFace.y = y2;
> - if (dx< 0) {
> - lcapFace.xa = -vertices[V_LEFT].x;
> - lcapFace.ya = -vertices[V_LEFT].y;
> - lcapFace.k = slopes[V_LEFT].k;
> - } else {
> - lcapFace.xa = vertices[V_TOP].x;
> - lcapFace.ya = vertices[V_TOP].y;
> - lcapFace.k = -slopes[V_LEFT].k;
> - }
> - miLineArc (pGC, foreground, spanData,
> -&lcapFace, (LineFacePtr) NULL, rcenterx, rcentery, FALSE);
> - }
> - }
> - dashRemain = (int)(((double) dashRemain) - LRemain);
> - if (dashRemain == 0) {
> - dashIndex++;
> - if (dashIndex == pGC->numInDashList)
> - dashIndex = 0;
> - dashRemain = pDash[dashIndex];
> - }
> -
> - leftFace->x = x1;
> - leftFace->y = y1;
> - leftFace->dx = dx;
> - leftFace->dy = dy;
> - leftFace->xa = rdy;
> - leftFace->ya = -rdx;
> - leftFace->k = k;
> -
> - rightFace->x = x2;
> - rightFace->y = y2;
> - rightFace->dx = -dx;
> - rightFace->dy = -dy;
> - rightFace->xa = -rdy;
> - rightFace->ya = rdx;
> - rightFace->k = k;
> -
> - *pDashIndex = dashIndex;
> - *pDashOffset = pDash[dashIndex] - dashRemain;
> -}
> -
> -void
> -miWideDash (GCPtr pGC, int mode, int npt, DDXPointPtr pPts)
> -{
> - int x1, y1, x2, y2;
> - Boolean foreground;
> - Boolean projectLeft, projectRight;
> - LineFaceRec leftFace, rightFace, prevRightFace;
> - LineFaceRec firstFace;
> - int first;
> - int dashIndex, dashOffset;
> - int prevDashIndex;
> - SpanDataRec spanDataRec;
> - SpanDataPtr spanData;
> - Boolean somethingDrawn = FALSE;
> - Boolean selfJoin;
> - Boolean endIsFg = FALSE, startIsFg = FALSE;
> - Boolean firstIsFg = FALSE, prevIsFg = FALSE;
> -
> - if (npt == 0)
> - return;
> - spanData = miSetupSpanData (pGC,&spanDataRec, npt);
> - x2 = pPts->x;
> - y2 = pPts->y;
> - first = TRUE;
> - selfJoin = FALSE;
> - if (mode == CoordModePrevious) {
> - int nptTmp;
> - DDXPointPtr pPtsTmp;
> -
> - x1 = x2;
> - y1 = y2;
> - nptTmp = npt;
> - pPtsTmp = pPts + 1;
> - while (--nptTmp) {
> - x1 += pPtsTmp->x;
> - y1 += pPtsTmp->y;
> - ++pPtsTmp;
> - }
> - if (x2 == x1&& y2 == y1)
> - selfJoin = TRUE;
> - } else if (x2 == pPts[npt - 1].x&& y2 == pPts[npt - 1].y) {
> - selfJoin = TRUE;
> - }
> - projectLeft = pGC->capStyle == CapProjecting&& !selfJoin;
> - projectRight = FALSE;
> - dashIndex = 0;
> - dashOffset = 0;
> - miStepDash ((int) pGC->dashOffset,&dashIndex,
> - pGC->dash, (int) pGC->numInDashList,&dashOffset);
> - while (--npt) {
> - x1 = x2;
> - y1 = y2;
> - ++pPts;
> - x2 = pPts->x;
> - y2 = pPts->y;
> - if (mode == CoordModePrevious) {
> - x2 += x1;
> - y2 += y1;
> - }
> - if (x1 != x2 || y1 != y2) {
> - somethingDrawn = TRUE;
> - if (npt == 1&& pGC->capStyle == CapProjecting&& (!selfJoin || !firstIsFg))
> - projectRight = TRUE;
> - prevDashIndex = dashIndex;
> - miWideDashSegment (pGC, spanData,&dashOffset,&dashIndex,
> - x1, y1, x2, y2, projectLeft, projectRight,&leftFace,&rightFace);
> - startIsFg = !(prevDashIndex& 1);
> - endIsFg = (dashIndex& 1) ^ (dashOffset != 0);
> - if (pGC->lineStyle == LineDoubleDash || startIsFg) {
> - foreground = startIsFg;
> - if (first || (pGC->lineStyle == LineOnOffDash&& !prevIsFg)) {
> - if (first&& selfJoin) {
> - firstFace = leftFace;
> - firstIsFg = startIsFg;
> - } else if (pGC->capStyle == CapRound)
> - miLineArc (pGC, foreground, spanData,
> -&leftFace, (LineFacePtr) NULL, (double) 0.0, (double) 0.0, TRUE);
> - } else {
> - miLineJoin (pGC, foreground, spanData,&leftFace,&prevRightFace);
> - }
> - }
> - prevRightFace = rightFace;
> - prevIsFg = endIsFg;
> - first = FALSE;
> - projectLeft = FALSE;
> - }
> - if (npt == 1&& somethingDrawn) {
> - if (pGC->lineStyle == LineDoubleDash || endIsFg) {
> - foreground = endIsFg;
> - if (selfJoin&& (pGC->lineStyle == LineDoubleDash || firstIsFg)) {
> - miLineJoin (pGC, foreground, spanData,&firstFace,&rightFace);
> - } else {
> - if (pGC->capStyle == CapRound)
> - miLineArc (pGC, foreground, spanData,
> - (LineFacePtr) NULL,&rightFace,
> - (double) 0.0, (double) 0.0, TRUE);
> - }
> - } else {
> - /* glue a cap to the start of the line if
> - * we're OnOffDash and ended on odd dash
> - */
> - if (selfJoin&& firstIsFg) {
> - foreground = TRUE;
> - if (pGC->capStyle == CapProjecting)
> - miLineProjectingCap (pGC, foreground, spanData,
> -&firstFace, TRUE, (double) 0.0, (double) 0.0, TRUE);
> - else if (pGC->capStyle == CapRound)
> - miLineArc (pGC, foreground, spanData,
> -&firstFace, (LineFacePtr) NULL,
> - (double) 0.0, (double) 0.0, TRUE);
> - }
> - }
> - }
> - }
> - /* handle crock where all points are coincident */
> - if (!somethingDrawn&& (pGC->lineStyle == LineDoubleDash || !(dashIndex& 1))) {
> - /* not the same as endIsFg computation above */
> - foreground = (dashIndex& 1) == 0;
> - switch (pGC->capStyle) {
> - case CapRound:
> - miLineArc (pGC, foreground, spanData,
> - (LineFacePtr) NULL, (LineFacePtr) NULL, (double) x2, (double) y2, FALSE);
> - break;
> - case CapProjecting:
> - x1 = pGC->lineWidth;
> - miFillRectPolyHelper (pGC, foreground, spanData,
> - x2 - (x1>> 1), y2 - (x1>> 1), x1, x1);
> - break;
> - }
> - }
> - if (spanData)
> - miCleanupSpanData (pGC, spanData);
> -}
> -
> -#undef ExchangeSpans
> -#define ExchangeSpans(a, b) \
> -{ \
> - DDXPointRec tpt; \
> - int tw; \
> - \
> - tpt = spans[a]; spans[a] = spans[b]; spans[b] = tpt; \
> - tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
> -}
> -
> -static void QuickSortSpans(
> - DDXPointRec spans[],
> - int widths[],
> - int numSpans)
> -{
> - int y;
> - int i, j, m;
> - DDXPointPtr r;
> -
> - /* Always called with numSpans> 1 */
> - /* Sorts only by y, doesn't bother to sort by x */
> -
> - do
> - {
> - if (numSpans< 9)
> - {
> - /* Do insertion sort */
> - int yprev;
> -
> - yprev = spans[0].y;
> - i = 1;
> - do
> - { /* while i != numSpans */
> - y = spans[i].y;
> - if (yprev> y)
> - {
> - /* spans[i] is out of order. Move into proper location. */
> - DDXPointRec tpt;
> - int tw, k;
> -
> - for (j = 0; y>= spans[j].y; j++) {}
> - tpt = spans[i];
> - tw = widths[i];
> - for (k = i; k != j; k--)
> - {
> - spans[k] = spans[k-1];
> - widths[k] = widths[k-1];
> - }
> - spans[j] = tpt;
> - widths[j] = tw;
> - y = spans[i].y;
> - } /* if out of order */
> - yprev = y;
> - i++;
> - } while (i != numSpans);
> - return;
> - }
> -
> - /* Choose partition element, stick in location 0 */
> - m = numSpans / 2;
> - if (spans[m].y> spans[0].y) ExchangeSpans(m, 0);
> - if (spans[m].y> spans[numSpans-1].y) ExchangeSpans(m, numSpans-1);
> - if (spans[m].y> spans[0].y) ExchangeSpans(m, 0);
> - y = spans[0].y;
> -
> - /* Partition array */
> - i = 0;
> - j = numSpans;
> - do
> - {
> - r =&(spans[i]);
> - do
> - {
> - r++;
> - i++;
> - } while (i != numSpans&& r->y< y);
> - r =&(spans[j]);
> - do
> - {
> - r--;
> - j--;
> - } while (y< r->y);
> - if (i< j)
> - ExchangeSpans(i, j);
> - } while (i< j);
> -
> - /* Move partition element back to middle */
> - ExchangeSpans(0, j);
> -
> - /* Recurse */
> - if (numSpans-j-1> 1)
> - QuickSortSpans(&spans[j+1],&widths[j+1], numSpans-j-1);
> - numSpans = j;
> - } while (numSpans> 1);
> -}
> -
> -#define NextBand() \
> -{ \
> - clipy1 = pboxBandStart->y1; \
> - clipy2 = pboxBandStart->y2; \
> - pboxBandEnd = pboxBandStart + 1; \
> - while (pboxBandEnd != pboxLast&& pboxBandEnd->y1 == clipy1) { \
> - pboxBandEnd++; \
> - } \
> - for (; ppt != pptLast&& ppt->y< clipy1; ppt++, pwidth++) {} \
> -}
> -
> -/*
> - Clip a list of scanlines to a region. The caller has allocated the
> - space. FSorted is non-zero if the scanline origins are in ascending
> - order.
> - returns the number of new, clipped scanlines.
> -*/
> -
> -int spice_canvas_clip_spans(pixman_region32_t *prgnDst,
> - DDXPointPtr ppt,
> - int *pwidth,
> - int nspans,
> - DDXPointPtr pptNew,
> - int *pwidthNew,
> - int fSorted)
> -{
> - DDXPointPtr pptLast;
> - int *pwidthNewStart; /* the vengeance of Xerox! */
> - int y, x1, x2;
> - int numRects;
> - pixman_box32_t *pboxBandStart;
> -
> - pptLast = ppt + nspans;
> - pwidthNewStart = pwidthNew;
> -
> - pboxBandStart = pixman_region32_rectangles (prgnDst,&numRects);
> -
> - if (numRects == 1) {
> - /* Do special fast code with clip boundaries in registers(?) */
> - /* It doesn't pay much to make use of fSorted in this case,
> - so we lump everything together. */
> -
> - int clipx1, clipx2, clipy1, clipy2;
> -
> - clipx1 = pboxBandStart->x1;
> - clipy1 = pboxBandStart->y1;
> - clipx2 = pboxBandStart->x2;
> - clipy2 = pboxBandStart->y2;
> -
> - for (; ppt != pptLast; ppt++, pwidth++) {
> - y = ppt->y;
> - x1 = ppt->x;
> - if (clipy1<= y&& y< clipy2) {
> - x2 = x1 + *pwidth;
> - if (x1< clipx1)
> - x1 = clipx1;
> - if (x2> clipx2)
> - x2 = clipx2;
> - if (x1< x2) {
> - /* part of span in clip rectangle */
> - pptNew->x = x1;
> - pptNew->y = y;
> - *pwidthNew = x2 - x1;
> - pptNew++;
> - pwidthNew++;
> - }
> - }
> - } /* end for */
> - } else if (numRects != 0) {
> - /* Have to clip against many boxes */
> - pixman_box32_t *pboxBandEnd, *pbox, *pboxLast;
> - int clipy1, clipy2;
> -
> - /* In this case, taking advantage of sorted spans gains more than
> - the sorting costs. */
> - if ((! fSorted)&& (nspans> 1))
> - QuickSortSpans(ppt, pwidth, nspans);
> -
> - pboxLast = pboxBandStart + numRects;
> -
> - NextBand();
> -
> - for (; ppt != pptLast; ) {
> - y = ppt->y;
> - if (y< clipy2) {
> - /* span is in the current band */
> - pbox = pboxBandStart;
> - x1 = ppt->x;
> - x2 = x1 + *pwidth;
> - do { /* For each box in band */
> - int newx1, newx2;
> -
> - newx1 = x1;
> - newx2 = x2;
> - if (newx1< pbox->x1)
> - newx1 = pbox->x1;
> - if (newx2> pbox->x2)
> - newx2 = pbox->x2;
> - if (newx1< newx2) {
> - /* Part of span in clip rectangle */
> - pptNew->x = newx1;
> - pptNew->y = y;
> - *pwidthNew = newx2 - newx1;
> - pptNew++;
> - pwidthNew++;
> - }
> - pbox++;
> - } while (pbox != pboxBandEnd);
> - ppt++;
> - pwidth++;
> - } else {
> - /* Move to next band, adjust ppt as needed */
> - pboxBandStart = pboxBandEnd;
> - if (pboxBandStart == pboxLast)
> - break; /* We're completely done */
> - NextBand();
> - }
> - }
> - }
> - return (pwidthNew - pwidthNewStart);
> -}
> diff --git a/common/lines.h b/common/lines.h
> deleted file mode 100644
> index 1d092f0..0000000
> --- a/common/lines.h
> +++ /dev/null
> @@ -1,130 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/***********************************************************
> -
> -Copyright 1987, 1998 The Open Group
> -
> -Permission to use, copy, modify, distribute, and sell this software and its
> -documentation for any purpose is hereby granted without fee, provided that
> -the above copyright notice appear in all copies and that both that
> -copyright notice and this permission notice appear in supporting
> -documentation.
> -
> -The above copyright notice and this permission notice shall be included in
> -all copies or substantial portions of the Software.
> -
> -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
> -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> -
> -Except as contained in this notice, the name of The Open Group shall not be
> -used in advertising or otherwise to promote the sale, use or other dealings
> -in this Software without prior written authorization from The Open Group.
> -
> -
> -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
> -
> - All Rights Reserved
> -
> -Permission to use, copy, modify, and distribute this software and its
> -documentation for any purpose and without fee is hereby granted,
> -provided that the above copyright notice appear in all copies and that
> -both that copyright notice and this permission notice appear in
> -supporting documentation, and that the name of Digital not be
> -used in advertising or publicity pertaining to distribution of the
> -software without specific, written prior permission.
> -
> -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
> -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
> -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
> -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
> -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
> -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
> -SOFTWARE.
> -
> -******************************************************************/
> -
> -#ifndef LINES_H
> -#define LINES_H
> -
> -#include<pixman_utils.h>
> -#include<stdlib.h>
> -#include<string.h>
> -#include "draw.h"
> -
> -typedef struct lineGC lineGC;
> -
> -typedef struct {
> - void (*FillSpans)(lineGC * pGC,
> - int num_spans, SpicePoint * points, int *widths,
> - int sorted, int foreground);
> - void (*FillRects)(lineGC * pGC,
> - int nun_rects, pixman_rectangle32_t * rects,
> - int foreground);
> -} lineGCOps;
> -
> -struct lineGC {
> - int width;
> - int height;
> - unsigned char alu;
> - unsigned short lineWidth;
> - unsigned short dashOffset;
> - unsigned short numInDashList;
> - unsigned char *dash;
> - unsigned int lineStyle:2;
> - unsigned int capStyle:2;
> - unsigned int joinStyle:2;
> - lineGCOps *ops;
> -};
> -
> -/* CoordinateMode for drawing routines */
> -
> -#define CoordModeOrigin 0 /* relative to the origin */
> -#define CoordModePrevious 1 /* relative to previous point */
> -
> -/* LineStyle */
> -
> -#define LineSolid 0
> -#define LineOnOffDash 1
> -#define LineDoubleDash 2
> -
> -/* capStyle */
> -
> -#define CapNotLast 0
> -#define CapButt 1
> -#define CapRound 2
> -#define CapProjecting 3
> -
> -/* joinStyle */
> -
> -#define JoinMiter 0
> -#define JoinRound 1
> -#define JoinBevel 2
> -
> -extern void spice_canvas_zero_line(lineGC *pgc,
> - int mode,
> - int num_points,
> - SpicePoint * points);
> -extern void spice_canvas_zero_dash_line(lineGC * pgc,
> - int mode,
> - int n_points,
> - SpicePoint * points);
> -extern void spice_canvas_wide_dash_line(lineGC * pGC,
> - int mode,
> - int num_points,
> - SpicePoint * points);
> -extern void spice_canvas_wide_line(lineGC *pGC,
> - int mode,
> - int num_points,
> - SpicePoint * points);
> -extern int spice_canvas_clip_spans(pixman_region32_t *clip_region,
> - SpicePoint *points,
> - int *widths,
> - int num_spans,
> - SpicePoint *new_points,
> - int *new_widths,
> - int sorted);
> -
> -#endif /* LINES_H */
> diff --git a/common/lz.c b/common/lz.c
> deleted file mode 100644
> index d0d9511..0000000
> --- a/common/lz.c
> +++ /dev/null
> @@ -1,738 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -
> - Copyright 2009 Red Hat, Inc. and/or its affiliates.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -
> - This file incorporates work covered by the following copyright and
> - permission notice:
> - Copyright (C) 2007 Ariya Hidayat (ariya at kde.org)
> - Copyright (C) 2006 Ariya Hidayat (ariya at kde.org)
> - Copyright (C) 2005 Ariya Hidayat (ariya at kde.org)
> -
> - Permission is hereby granted, free of charge, to any person
> - obtaining a copy of this software and associated documentation
> - files (the "Software"), to deal in the Software without
> - restriction, including without limitation the rights to use, copy,
> - modify, merge, publish, distribute, sublicense, and/or sell copies
> - of the Software, and to permit persons to whom the Software is
> - furnished to do so, subject to the following conditions:
> -
> - The above copyright notice and this permission notice shall be
> - included in all copies or substantial portions of the Software.
> -
> - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> - SOFTWARE.
> -
> -*/
> -
> -#include "lz.h"
> -
> -#define DEBUG
> -
> -#ifdef DEBUG
> -
> -#define ASSERT(usr, x) \
> - if (!(x)) (usr)->error(usr, "%s: ASSERT %s failed\n", __FUNCTION__, #x);
> -
> -#else
> -
> -#define ASSERT(usr, x)
> -
> -#endif
> -
> -#define HASH_LOG 13
> -#define HASH_SIZE (1<< HASH_LOG)
> -#define HASH_MASK (HASH_SIZE - 1)
> -
> -
> -typedef struct LzImageSegment LzImageSegment;
> -struct LzImageSegment {
> - uint8_t *lines;
> - uint8_t *lines_end;
> - unsigned int size_delta; // total size of the previous segments in units of
> - // pixels for rgb and bytes for plt.
> - LzImageSegment *next;
> -};
> -
> -// TODO: pack?
> -typedef struct HashEntry {
> - LzImageSegment *image_seg;
> - uint8_t *ref;
> -} HashEntry;
> -
> -typedef struct Encoder {
> - LzUsrContext *usr;
> -
> - LzImageType type;
> - const SpicePalette *palette; // for decoding images with palettes to rgb
> - int stride; // stride is in bytes. For rgb must be equal to
> - // width*bytes_per_pix.
> - // For palettes stride can be bigger than width/pixels_per_byte by 1 only if
> - // width%pixels_per_byte != 0.
> - int height;
> - int width; // the original width (in pixels)
> -
> - LzImageSegment *head_image_segs;
> - LzImageSegment *tail_image_segs;
> - LzImageSegment *free_image_segs;
> -
> - // the dictionary hash table is composed (1) a pointer to the segment the word was found in
> - // (2) a pointer to the first byte in the segment that matches the word
> - HashEntry htab[HASH_SIZE];
> -
> - uint8_t *io_start;
> - uint8_t *io_now;
> - uint8_t *io_end;
> - size_t io_bytes_count;
> -
> - uint8_t *io_last_copy; // pointer to the last byte in which copy count was written
> -} Encoder;
> -
> -/****************************************************/
> -/* functions for managing the pool of image segments*/
> -/****************************************************/
> -static INLINE LzImageSegment *lz_alloc_image_seg(Encoder *encoder);
> -static void lz_reset_image_seg(Encoder *encoder);
> -static int lz_read_image_segments(Encoder *encoder, uint8_t *first_lines,
> - unsigned int num_first_lines);
> -
> -
> -// return a free image segment if one exists. Make allocation if needed. adds it to the
> -// tail of the image segments lists
> -static INLINE LzImageSegment *lz_alloc_image_seg(Encoder *encoder)
> -{
> - LzImageSegment *ret;
> -
> - if (encoder->free_image_segs) {
> - ret = encoder->free_image_segs;
> - encoder->free_image_segs = ret->next;
> - } else {
> - if (!(ret = (LzImageSegment *)encoder->usr->malloc(encoder->usr, sizeof(*ret)))) {
> - return NULL;
> - }
> - }
> -
> - ret->next = NULL;
> - if (encoder->tail_image_segs) {
> - encoder->tail_image_segs->next = ret;
> - }
> - encoder->tail_image_segs = ret;
> -
> - if (!encoder->head_image_segs) {
> - encoder->head_image_segs = ret;
> - }
> -
> - return ret;
> -}
> -
> -// adding seg to the head of free segments (lz_reset_image_seg removes it from used ones)
> -static INLINE void __lz_free_image_seg(Encoder *encoder, LzImageSegment *seg)
> -{
> - seg->next = encoder->free_image_segs;
> - encoder->free_image_segs = seg;
> -}
> -
> -// moves all the used image segments to the free pool
> -static void lz_reset_image_seg(Encoder *encoder)
> -{
> - while (encoder->head_image_segs) {
> - LzImageSegment *seg = encoder->head_image_segs;
> - encoder->head_image_segs = seg->next;
> - __lz_free_image_seg(encoder, seg);
> - }
> - encoder->tail_image_segs = NULL;
> -}
> -
> -static void lz_dealloc_free_segments(Encoder *encoder)
> -{
> - while (encoder->free_image_segs) {
> - LzImageSegment *seg = encoder->free_image_segs;
> - encoder->free_image_segs = seg->next;
> - encoder->usr->free(encoder->usr, seg);
> - }
> -}
> -
> -// return FALSE when operation fails (due to failure in allocation)
> -static int lz_read_image_segments(Encoder *encoder, uint8_t *first_lines,
> - unsigned int num_first_lines)
> -{
> - LzImageSegment *image_seg;
> - uint32_t size_delta = 0;
> - unsigned int num_lines = num_first_lines;
> - uint8_t* lines = first_lines;
> - int row;
> -
> - ASSERT(encoder->usr, !encoder->head_image_segs);
> -
> - image_seg = lz_alloc_image_seg(encoder);
> - if (!image_seg) {
> - goto error_1;
> - }
> -
> - image_seg->lines = lines;
> - image_seg->lines_end = lines + num_lines * encoder->stride;
> - image_seg->size_delta = size_delta;
> -
> - size_delta += num_lines * encoder->stride / RGB_BYTES_PER_PIXEL[encoder->type];
> -
> - for (row = num_first_lines; row< encoder->height; row += num_lines) {
> - num_lines = encoder->usr->more_lines(encoder->usr,&lines);
> - if (num_lines<= 0) {
> - encoder->usr->error(encoder->usr, "more lines failed\n");
> - }
> - image_seg = lz_alloc_image_seg(encoder);
> -
> - if (!image_seg) {
> - goto error_1;
> - }
> -
> - image_seg->lines = lines;
> - image_seg->lines_end = lines + num_lines * encoder->stride;
> - image_seg->size_delta = size_delta;
> -
> - size_delta += num_lines * encoder->stride / RGB_BYTES_PER_PIXEL[encoder->type];
> - }
> -
> - return TRUE;
> -error_1:
> - lz_reset_image_seg(encoder);
> - return FALSE;
> -}
> -
> -/**************************************************************************
> -* Handling encoding and decoding of a byte
> -***************************************************************************/
> -static INLINE int more_io_bytes(Encoder *encoder)
> -{
> - uint8_t *io_ptr;
> - int num_io_bytes = encoder->usr->more_space(encoder->usr,&io_ptr);
> - encoder->io_bytes_count += num_io_bytes;
> - encoder->io_now = io_ptr;
> - encoder->io_end = encoder->io_now + num_io_bytes;
> - return num_io_bytes;
> -}
> -
> -static INLINE void encode(Encoder *encoder, uint8_t byte)
> -{
> - if (encoder->io_now == encoder->io_end) {
> - if (more_io_bytes(encoder)<= 0) {
> - encoder->usr->error(encoder->usr, "%s: no more bytes\n", __FUNCTION__);
> - }
> - ASSERT(encoder->usr, encoder->io_now);
> - }
> -
> - ASSERT(encoder->usr, encoder->io_now< encoder->io_end);
> - *(encoder->io_now++) = byte;
> -}
> -
> -static INLINE void encode_32(Encoder *encoder, unsigned int word)
> -{
> - encode(encoder, (uint8_t)(word>> 24));
> - encode(encoder, (uint8_t)(word>> 16)& 0x0000ff);
> - encode(encoder, (uint8_t)(word>> 8)& 0x0000ff);
> - encode(encoder, (uint8_t)(word& 0x0000ff));
> -}
> -
> -static INLINE void encode_copy_count(Encoder *encoder, uint8_t copy_count)
> -{
> - encode(encoder, copy_count);
> - encoder->io_last_copy = encoder->io_now - 1; // io_now cannot be the first byte of the buffer
> -}
> -
> -static INLINE void update_copy_count(Encoder *encoder, uint8_t copy_count)
> -{
> - ASSERT(encoder->usr, encoder->io_last_copy);
> - *(encoder->io_last_copy) = copy_count;
> -}
> -
> -static INLINE void encode_level(Encoder *encoder, uint8_t level_code)
> -{
> - *(encoder->io_start) |= level_code;
> -}
> -
> -// decrease the io ptr by 1
> -static INLINE void compress_output_prev(Encoder *encoder)
> -{
> - // io_now cannot be the first byte of the buffer
> - encoder->io_now--;
> - // the function should be called only when copy count is written unnecessarily by lz_compress
> - ASSERT(encoder->usr, encoder->io_now == encoder->io_last_copy)
> -}
> -
> -static int encoder_reset(Encoder *encoder, uint8_t *io_ptr, uint8_t *io_ptr_end)
> -{
> - ASSERT(encoder->usr, io_ptr<= io_ptr_end);
> - encoder->io_bytes_count = io_ptr_end - io_ptr;
> - encoder->io_start = io_ptr;
> - encoder->io_now = io_ptr;
> - encoder->io_end = io_ptr_end;
> - encoder->io_last_copy = NULL;
> -
> - return TRUE;
> -}
> -
> -static INLINE uint8_t decode(Encoder *encoder)
> -{
> - if (encoder->io_now == encoder->io_end) {
> - int num_io_bytes = more_io_bytes(encoder);
> - if (num_io_bytes<= 0) {
> - encoder->usr->error(encoder->usr, "%s: no more bytes\n", __FUNCTION__);
> - }
> - ASSERT(encoder->usr, encoder->io_now);
> - }
> - ASSERT(encoder->usr, encoder->io_now< encoder->io_end);
> - return *(encoder->io_now++);
> -}
> -
> -static INLINE uint32_t decode_32(Encoder *encoder)
> -{
> - uint32_t word = 0;
> - word |= decode(encoder);
> - word<<= 8;
> - word |= decode(encoder);
> - word<<= 8;
> - word |= decode(encoder);
> - word<<= 8;
> - word |= decode(encoder);
> - return word;
> -}
> -
> -static INLINE int is_io_to_decode_end(Encoder *encoder)
> -{
> - if (encoder->io_now != encoder->io_end) {
> - return FALSE;
> - } else {
> - int num_io_bytes = more_io_bytes(encoder); //disable inline optimizations
> - return (num_io_bytes<= 0);
> - }
> -}
> -
> -/*******************************************************************
> -* intialization and finalization of lz
> -********************************************************************/
> -static int init_encoder(Encoder *encoder, LzUsrContext *usr)
> -{
> - encoder->usr = usr;
> - encoder->free_image_segs = NULL;
> - encoder->head_image_segs = NULL;
> - encoder->tail_image_segs = NULL;
> - return TRUE;
> -}
> -
> -LzContext *lz_create(LzUsrContext *usr)
> -{
> - Encoder *encoder;
> -
> - if (!usr || !usr->error || !usr->warn || !usr->info || !usr->malloc ||
> - !usr->free || !usr->more_space || !usr->more_lines) {
> - return NULL;
> - }
> -
> - if (!(encoder = (Encoder *)usr->malloc(usr, sizeof(Encoder)))) {
> - return NULL;
> - }
> -
> - if (!init_encoder(encoder, usr)) {
> - usr->free(usr, encoder);
> - return NULL;
> - }
> - return (LzContext *)encoder;
> -}
> -
> -void lz_destroy(LzContext *lz)
> -{
> - Encoder *encoder = (Encoder *)lz;
> -
> - if (!lz) {
> - return;
> - }
> -
> - if (encoder->head_image_segs) {
> - encoder->usr->error(encoder->usr, "%s: used_image_segments not empty\n", __FUNCTION__);
> - lz_reset_image_seg(encoder);
> - }
> - lz_dealloc_free_segments(encoder);
> -
> - encoder->usr->free(encoder->usr, encoder);
> -}
> -
> -/*******************************************************************
> -* encoding and decoding the image
> -********************************************************************/
> -/*
> - * Give hints to the compiler for branch prediction optimization.
> - */
> -#if defined(__GNUC__)&& (__GNUC__> 2)
> -#define LZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
> -#define LZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
> -#else
> -#define LZ_EXPECT_CONDITIONAL(c) (c)
> -#define LZ_UNEXPECT_CONDITIONAL(c) (c)
> -#endif
> -
> -
> -#ifdef __GNUC__
> -#define ATTR_PACKED __attribute__ ((__packed__))
> -#else
> -#define ATTR_PACKED
> -#pragma pack(push)
> -#pragma pack(1)
> -#endif
> -
> -
> -/* the palette images will be treated as one byte pixels. Their width should be transformed
> - accordingly.
> -*/
> -typedef struct ATTR_PACKED one_byte_pixel_t {
> - uint8_t a;
> -} one_byte_pixel_t;
> -
> -typedef struct ATTR_PACKED rgb32_pixel_t {
> - uint8_t b;
> - uint8_t g;
> - uint8_t r;
> - uint8_t pad;
> -} rgb32_pixel_t;
> -
> -typedef struct ATTR_PACKED rgb24_pixel_t {
> - uint8_t b;
> - uint8_t g;
> - uint8_t r;
> -} rgb24_pixel_t;
> -
> -typedef uint16_t rgb16_pixel_t;
> -
> -#ifndef __GNUC__
> -#pragma pack(pop)
> -#endif
> -
> -#undef ATTR_PACKED
> -
> -
> -#define MAX_COPY 32
> -#define MAX_LEN 264 /* 256 + 8 */
> -#define BOUND_OFFSET 2
> -#define LIMIT_OFFSET 6
> -#define MIN_FILE_SIZE 4
> -#define COMP_LEVEL_SIZE_LIMIT 65536
> -
> -// TODO: implemented lz2. should lz1 be an option (no RLE + distance limitation of MAX_DISTANCE)
> -// TODO: I think MAX_FARDISTANCE can be changed easily to 2^29
> -// (and maybe even more when pixel> byte).
> -// i.e. we can support 512M Bytes/Pixels distance instead of only ~68K.
> -#define MAX_DISTANCE 8191 // 2^13
> -#define MAX_FARDISTANCE (65535 + MAX_DISTANCE - 1) // ~2^16+2^13
> -
> -
> -#define LZ_PLT
> -#include "lz_compress_tmpl.c"
> -#define LZ_PLT
> -#include "lz_decompress_tmpl.c"
> -
> -#define LZ_PLT
> -#define PLT8
> -#define TO_RGB32
> -#include "lz_decompress_tmpl.c"
> -
> -#define LZ_PLT
> -#define PLT4_BE
> -#define TO_RGB32
> -#include "lz_decompress_tmpl.c"
> -
> -#define LZ_PLT
> -#define PLT4_LE
> -#define TO_RGB32
> -#include "lz_decompress_tmpl.c"
> -
> -#define LZ_PLT
> -#define PLT1_BE
> -#define TO_RGB32
> -#include "lz_decompress_tmpl.c"
> -
> -#define LZ_PLT
> -#define PLT1_LE
> -#define TO_RGB32
> -#include "lz_decompress_tmpl.c"
> -
> -
> -#define LZ_RGB16
> -#include "lz_compress_tmpl.c"
> -#define LZ_RGB16
> -#include "lz_decompress_tmpl.c"
> -#define LZ_RGB16
> -#define TO_RGB32
> -#include "lz_decompress_tmpl.c"
> -
> -#define LZ_RGB24
> -#include "lz_compress_tmpl.c"
> -#define LZ_RGB24
> -#include "lz_decompress_tmpl.c"
> -
> -
> -#define LZ_RGB32
> -#include "lz_compress_tmpl.c"
> -#define LZ_RGB32
> -#include "lz_decompress_tmpl.c"
> -
> -#define LZ_RGB_ALPHA
> -#include "lz_compress_tmpl.c"
> -#define LZ_RGB_ALPHA
> -#include "lz_decompress_tmpl.c"
> -
> -#undef LZ_UNEXPECT_CONDITIONAL
> -#undef LZ_EXPECT_CONDITIONAL
> -
> -int lz_encode(LzContext *lz, LzImageType type, int width, int height, int top_down,
> - uint8_t *lines, unsigned int num_lines, int stride,
> - uint8_t *io_ptr, unsigned int num_io_bytes)
> -{
> - Encoder *encoder = (Encoder *)lz;
> - uint8_t *io_ptr_end = io_ptr + num_io_bytes;
> -
> - encoder->type = type;
> - encoder->width = width;
> - encoder->height = height;
> - encoder->stride = stride;
> -
> - if (IS_IMAGE_TYPE_PLT[encoder->type]) {
> - if (encoder->stride> (width / PLT_PIXELS_PER_BYTE[encoder->type])) {
> - if (((width % PLT_PIXELS_PER_BYTE[encoder->type]) == 0) || (
> - (encoder->stride - (width / PLT_PIXELS_PER_BYTE[encoder->type]))> 1)) {
> - encoder->usr->error(encoder->usr, "stride overflows (plt)\n");
> - }
> - }
> - } else {
> - if (encoder->stride != width * RGB_BYTES_PER_PIXEL[encoder->type]) {
> - encoder->usr->error(encoder->usr, "stride != width*bytes_per_pixel (rgb)\n");
> - }
> - }
> -
> - // assign the output buffer
> - if (!encoder_reset(encoder, io_ptr, io_ptr_end)) {
> - encoder->usr->error(encoder->usr, "lz encoder io reset failed\n");
> - }
> -
> - // first read the list of the image segments
> - if (!lz_read_image_segments(encoder, lines, num_lines)) {
> - encoder->usr->error(encoder->usr, "lz encoder reading image segments failed\n");
> - }
> -
> - encode_32(encoder, LZ_MAGIC);
> - encode_32(encoder, LZ_VERSION);
> - encode_32(encoder, type);
> - encode_32(encoder, width);
> - encode_32(encoder, height);
> - encode_32(encoder, stride);
> - encode_32(encoder, top_down); // TODO: maybe compress type and top_down to one byte
> -
> - switch (encoder->type) {
> - case LZ_IMAGE_TYPE_PLT1_BE:
> - case LZ_IMAGE_TYPE_PLT1_LE:
> - case LZ_IMAGE_TYPE_PLT4_BE:
> - case LZ_IMAGE_TYPE_PLT4_LE:
> - case LZ_IMAGE_TYPE_PLT8:
> - lz_plt_compress(encoder);
> - break;
> - case LZ_IMAGE_TYPE_RGB16:
> - lz_rgb16_compress(encoder);
> - break;
> - case LZ_IMAGE_TYPE_RGB24:
> - lz_rgb24_compress(encoder);
> - break;
> - case LZ_IMAGE_TYPE_RGB32:
> - lz_rgb32_compress(encoder);
> - break;
> - case LZ_IMAGE_TYPE_RGBA:
> - lz_rgb32_compress(encoder);
> - lz_rgb_alpha_compress(encoder);
> - break;
> - case LZ_IMAGE_TYPE_XXXA:
> - lz_rgb_alpha_compress(encoder);
> - break;
> - case LZ_IMAGE_TYPE_INVALID:
> - default:
> - encoder->usr->error(encoder->usr, "bad image type\n");
> - }
> -
> - // move all the used segments to the free ones
> - lz_reset_image_seg(encoder);
> -
> - encoder->io_bytes_count -= (encoder->io_end - encoder->io_now);
> -
> - return encoder->io_bytes_count;
> -}
> -
> -/*
> - initialize and read lz magic
> -*/
> -void lz_decode_begin(LzContext *lz, uint8_t *io_ptr, unsigned int num_io_bytes,
> - LzImageType *out_type, int *out_width, int *out_height,
> - int *out_n_pixels, int *out_top_down, const SpicePalette *palette)
> -{
> - Encoder *encoder = (Encoder *)lz;
> - uint8_t *io_ptr_end = io_ptr + num_io_bytes;
> - uint32_t magic;
> - uint32_t version;
> -
> - if (!encoder_reset(encoder, io_ptr, io_ptr_end)) {
> - encoder->usr->error(encoder->usr, "io reset failed");
> - }
> -
> - magic = decode_32(encoder);
> - if (magic != LZ_MAGIC) {
> - encoder->usr->error(encoder->usr, "bad magic\n");
> - }
> -
> - version = decode_32(encoder);
> - if (version != LZ_VERSION) {
> - encoder->usr->error(encoder->usr, "bad version\n");
> - }
> -
> - encoder->type = (LzImageType)decode_32(encoder);
> - encoder->width = decode_32(encoder);
> - encoder->height = decode_32(encoder);
> - encoder->stride = decode_32(encoder);
> - *out_top_down = decode_32(encoder);
> -
> - *out_width = encoder->width;
> - *out_height = encoder->height;
> -// *out_stride = encoder->stride;
> - *out_type = encoder->type;
> -
> - // TODO: maybe instead of stride we can encode out_n_pixels
> - // (if stride is not necessary in decoding).
> - if (IS_IMAGE_TYPE_PLT[encoder->type]) {
> - encoder->palette = palette;
> - *out_n_pixels = encoder->stride * PLT_PIXELS_PER_BYTE[encoder->type] * encoder->height;
> - } else {
> - *out_n_pixels = encoder->width * encoder->height;
> - }
> -}
> -
> -void lz_decode(LzContext *lz, LzImageType to_type, uint8_t *buf)
> -{
> - Encoder *encoder = (Encoder *)lz;
> - size_t out_size = 0;
> - size_t alpha_size = 0;
> - size_t size = 0;
> - if (IS_IMAGE_TYPE_PLT[encoder->type]) {
> - if (to_type == encoder->type) {
> - size = encoder->height * encoder->stride;
> - out_size = lz_plt_decompress(encoder, (one_byte_pixel_t *)buf, size);
> - } else if (to_type == LZ_IMAGE_TYPE_RGB32) {
> - size = encoder->height * encoder->stride * PLT_PIXELS_PER_BYTE[encoder->type];
> - if (!encoder->palette) {
> - encoder->usr->error(encoder->usr,
> - "a palette is missing (for bpp to rgb decoding)\n");
> - }
> - switch (encoder->type) {
> - case LZ_IMAGE_TYPE_PLT1_BE:
> - out_size = lz_plt1_be_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
> - break;
> - case LZ_IMAGE_TYPE_PLT1_LE:
> - out_size = lz_plt1_le_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
> - break;
> - case LZ_IMAGE_TYPE_PLT4_BE:
> - out_size = lz_plt4_be_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
> - break;
> - case LZ_IMAGE_TYPE_PLT4_LE:
> - out_size = lz_plt4_le_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
> - break;
> - case LZ_IMAGE_TYPE_PLT8:
> - out_size = lz_plt8_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
> - break;
> - case LZ_IMAGE_TYPE_RGB16:
> - case LZ_IMAGE_TYPE_RGB24:
> - case LZ_IMAGE_TYPE_RGB32:
> - case LZ_IMAGE_TYPE_RGBA:
> - case LZ_IMAGE_TYPE_XXXA:
> - case LZ_IMAGE_TYPE_INVALID:
> - default:
> - encoder->usr->error(encoder->usr, "bad image type\n");
> - }
> - } else {
> - encoder->usr->error(encoder->usr, "unsupported output format\n");
> - }
> - } else {
> - size = encoder->height * encoder->width;
> - switch (encoder->type) {
> - case LZ_IMAGE_TYPE_RGB16:
> - if (encoder->type == to_type) {
> - out_size = lz_rgb16_decompress(encoder, (rgb16_pixel_t *)buf, size);
> - } else if (to_type == LZ_IMAGE_TYPE_RGB32) {
> - out_size = lz_rgb16_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
> - } else {
> - encoder->usr->error(encoder->usr, "unsupported output format\n");
> - }
> - break;
> - case LZ_IMAGE_TYPE_RGB24:
> - if (encoder->type == to_type) {
> - out_size = lz_rgb24_decompress(encoder, (rgb24_pixel_t *)buf, size);
> - } else if (to_type == LZ_IMAGE_TYPE_RGB32) {
> - out_size = lz_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
> - } else {
> - encoder->usr->error(encoder->usr, "unsupported output format\n");
> - }
> - break;
> - case LZ_IMAGE_TYPE_RGB32:
> - if (encoder->type == to_type) {
> - out_size = lz_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
> - } else {
> - encoder->usr->error(encoder->usr, "unsupported output format\n");
> - }
> - break;
> - case LZ_IMAGE_TYPE_RGBA:
> - if (encoder->type == to_type) {
> - out_size = lz_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
> - alpha_size = lz_rgb_alpha_decompress(encoder, (rgb32_pixel_t *)buf, size);
> - ASSERT(encoder->usr, alpha_size == size);
> - } else {
> - encoder->usr->error(encoder->usr, "unsupported output format\n");
> - }
> - break;
> - case LZ_IMAGE_TYPE_XXXA:
> - if (encoder->type == to_type) {
> - alpha_size = lz_rgb_alpha_decompress(encoder, (rgb32_pixel_t *)buf, size);
> - out_size = alpha_size;
> - } else {
> - encoder->usr->error(encoder->usr, "unsupported output format\n");
> - }
> - break;
> - case LZ_IMAGE_TYPE_PLT1_LE:
> - case LZ_IMAGE_TYPE_PLT1_BE:
> - case LZ_IMAGE_TYPE_PLT4_LE:
> - case LZ_IMAGE_TYPE_PLT4_BE:
> - case LZ_IMAGE_TYPE_PLT8:
> - case LZ_IMAGE_TYPE_INVALID:
> - default:
> - encoder->usr->error(encoder->usr, "bad image type\n");
> - }
> - }
> -
> - ASSERT(encoder->usr, is_io_to_decode_end(encoder));
> - ASSERT(encoder->usr, out_size == size);
> -
> - if (out_size != size) {
> - encoder->usr->error(encoder->usr, "bad decode size\n");
> - }
> -}
> -
> diff --git a/common/lz.h b/common/lz.h
> deleted file mode 100644
> index a51ccc0..0000000
> --- a/common/lz.h
> +++ /dev/null
> @@ -1,76 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - dictionary compression for images based on fastlz (http://www.fastlz.org/)
> - (Distributed under MIT license).
> -*/
> -#ifndef __LZ_H
> -#define __LZ_H
> -
> -#include "lz_common.h"
> -#include "lz_config.h"
> -#include "draw.h"
> -#include "macros.h"
> -
> -typedef void *LzContext;
> -
> -typedef struct LzUsrContext LzUsrContext;
> -struct LzUsrContext {
> - ATTR_PRINTF(2, 3) void (*error)(LzUsrContext *usr, const char *fmt, ...);
> - ATTR_PRINTF(2, 3) void (*warn)(LzUsrContext *usr, const char *fmt, ...);
> - ATTR_PRINTF(2, 3) void (*info)(LzUsrContext *usr, const char *fmt, ...);
> - void *(*malloc)(LzUsrContext *usr, int size);
> - void (*free)(LzUsrContext *usr, void *ptr);
> - int (*more_space)(LzUsrContext *usr, uint8_t **io_ptr); // get the next chunk of the
> - // compressed buffer. return
> - // number of bytes in the chunk.
> - int (*more_lines)(LzUsrContext *usr, uint8_t **lines); // get the next chunk of the
> - // original image. If the image
> - // is down to top, return it from
> - // the last line to the first one
> - // (stride should always be
> - // positive)
> -};
> -
> -/*
> - assumes width is in pixels and stride is in bytes
> - return: the number of bytes in the compressed data
> -
> - TODO : determine size limit for the first segment and each chunk. check validity
> - of the segment or go to literal copy.
> - TODO : currently support only rgb images in which width*bytes_per_pixel = stride OR
> - palette images in which stride equals the min number of bytes to
> - hold a line. stride is not necessary for now. just for sanity check.
> - stride should be> 0
> -*/
> -int lz_encode(LzContext *lz, LzImageType type, int width, int height, int top_down,
> - uint8_t *lines, unsigned int num_lines, int stride,
> - uint8_t *io_ptr, unsigned int num_io_bytes);
> -
> -/*
> - prepare encoder and read lz magic.
> - out_n_pixels number of compressed pixels. May differ from Width*height in plt1/4.
> - Use it for allocation the decompressed buffer.
> -
> -*/
> -void lz_decode_begin(LzContext *lz, uint8_t *io_ptr, unsigned int num_io_bytes,
> - LzImageType *out_type, int *out_width, int *out_height,
> - int *out_n_pixels, int *out_top_down, const SpicePalette *palette);
> -
> -/*
> - to_type = the image output type.
> - We assume the buffer is consecutive. i.e. width = stride
> -
> - Important: if the image is plt1/4 and to_type is rgb32, the image
> - will decompressed including the last bits in each line. This means buffer should be
> - larger than width*height if needed and you should use stride to fix it.
> - Note: If the image is down to top, set the stride in the sw surface to negative.
> - use alloc_lz_image_surface create the surface.
> -*/
> -void lz_decode(LzContext *lz, LzImageType to_type, uint8_t *buf);
> -
> -LzContext *lz_create(LzUsrContext *usr);
> -
> -void lz_destroy(LzContext *lz);
> -
> -
> -#endif // __LZ_H
> diff --git a/common/lz_common.h b/common/lz_common.h
> deleted file mode 100644
> index 34276af..0000000
> --- a/common/lz_common.h
> +++ /dev/null
> @@ -1,62 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, write to the Free Software
> -
> - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> -*/
> -
> -/*common header for encoder and decoder*/
> -
> -#ifndef _LZ_COMMON_H
> -#define _LZ_COMMON_H
> -
> -//#define DEBUG
> -
> -/* change the max window size will require change in the encoding format*/
> -#define LZ_MAX_WINDOW_SIZE (1<< 25)
> -#define MAX_COPY 32
> -
> -typedef enum {
> - LZ_IMAGE_TYPE_INVALID,
> - LZ_IMAGE_TYPE_PLT1_LE,
> - LZ_IMAGE_TYPE_PLT1_BE, // PLT stands for palette
> - LZ_IMAGE_TYPE_PLT4_LE,
> - LZ_IMAGE_TYPE_PLT4_BE,
> - LZ_IMAGE_TYPE_PLT8,
> - LZ_IMAGE_TYPE_RGB16,
> - LZ_IMAGE_TYPE_RGB24,
> - LZ_IMAGE_TYPE_RGB32,
> - LZ_IMAGE_TYPE_RGBA,
> - LZ_IMAGE_TYPE_XXXA
> -} LzImageType;
> -
> -#define LZ_IMAGE_TYPE_MASK 0x0f
> -#define LZ_IMAGE_TYPE_LOG 4 // number of bits required for coding the image type
> -
> -/* access to the arrays is based on the image types */
> -static const int IS_IMAGE_TYPE_PLT[] = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
> -static const int IS_IMAGE_TYPE_RGB[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
> -static const int PLT_PIXELS_PER_BYTE[] = {0, 8, 8, 2, 2, 1};
> -static const int RGB_BYTES_PER_PIXEL[] = {0, 1, 1, 1, 1, 1, 2, 3, 4, 4, 4};
> -
> -
> -#define LZ_MAGIC (*(uint32_t *)"LZ ")
> -#define LZ_VERSION_MAJOR 1U
> -#define LZ_VERSION_MINOR 1U
> -#define LZ_VERSION ((LZ_VERSION_MAJOR<< 16) | (LZ_VERSION_MINOR& 0xffff))
> -
> -
> -#endif // _LZ_COMMON_H
> diff --git a/common/lz_compress_tmpl.c b/common/lz_compress_tmpl.c
> deleted file mode 100644
> index 18d6697..0000000
> --- a/common/lz_compress_tmpl.c
> +++ /dev/null
> @@ -1,526 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -
> - Copyright 2009 Red Hat, Inc. and/or its affiliates.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - This file incorporates work covered by the following copyright and
> - permission notice:
> - Copyright (C) 2007 Ariya Hidayat (ariya at kde.org)
> - Copyright (C) 2006 Ariya Hidayat (ariya at kde.org)
> - Copyright (C) 2005 Ariya Hidayat (ariya at kde.org)
> -
> - Permission is hereby granted, free of charge, to any person
> - obtaining a copy of this software and associated documentation
> - files (the "Software"), to deal in the Software without
> - restriction, including without limitation the rights to use, copy,
> - modify, merge, publish, distribute, sublicense, and/or sell copies
> - of the Software, and to permit persons to whom the Software is
> - furnished to do so, subject to the following conditions:
> -
> - The above copyright notice and this permission notice shall be
> - included in all copies or substantial portions of the Software.
> -
> - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> - SOFTWARE.
> -
> -*/
> -
> -#define DJB2_START 5381;
> -#define DJB2_HASH(hash, c) (hash = ((hash<< 5) + hash) ^ (c)) //|{hash = ((hash<< 5) + hash) + c;}
> -
> -/*
> - For each pixel type the following macros are defined:
> - PIXEL : input type
> - FNAME(name)
> - ENCODE_PIXEL(encoder, pixel) : writing a pixel to the compressed buffer (byte by byte)
> - SAME_PIXEL(pix1, pix2) : comparing two pixels
> - HASH_FUNC(value, pix_ptr) : hash func of 3 consecutive pixels
> -*/
> -
> -#ifdef LZ_PLT
> -#define PIXEL one_byte_pixel_t
> -#define FNAME(name) lz_plt_##name
> -#define ENCODE_PIXEL(e, pix) encode(e, (pix).a) // gets the pixel and write only the needed bytes
> - // from the pixel
> -#define SAME_PIXEL(pix1, pix2) ((pix1).a == (pix2).a)
> -#define HASH_FUNC(v, p) { \
> - v = DJB2_START; \
> - DJB2_HASH(v, p[0].a); \
> - DJB2_HASH(v, p[1].a); \
> - DJB2_HASH(v, p[2].a); \
> - v&= HASH_MASK; \
> - }
> -#endif
> -
> -#ifdef LZ_RGB_ALPHA
> -//#undef LZ_RGB_ALPHA
> -#define PIXEL rgb32_pixel_t
> -#define FNAME(name) lz_rgb_alpha_##name
> -#define ENCODE_PIXEL(e, pix) {encode(e, (pix).pad);}
> -#define SAME_PIXEL(pix1, pix2) ((pix1).pad == (pix2).pad)
> -#define HASH_FUNC(v, p) { \
> - v = DJB2_START; \
> - DJB2_HASH(v, p[0].pad); \
> - DJB2_HASH(v, p[1].pad); \
> - DJB2_HASH(v, p[2].pad); \
> - v&= HASH_MASK; \
> - }
> -#endif
> -
> -
> -#ifdef LZ_RGB16
> -#define PIXEL rgb16_pixel_t
> -#define FNAME(name) lz_rgb16_##name
> -#define GET_r(pix) (((pix)>> 10)& 0x1f)
> -#define GET_g(pix) (((pix)>> 5)& 0x1f)
> -#define GET_b(pix) ((pix)& 0x1f)
> -#define ENCODE_PIXEL(e, pix) {encode(e, (pix)>> 8); encode(e, (pix)& 0xff);}
> -
> -#define HASH_FUNC(v, p) { \
> - v = DJB2_START; \
> - DJB2_HASH(v, p[0]& (0x00ff)); \
> - DJB2_HASH(v, (p[0]>> 8)& (0x007f)); \
> - DJB2_HASH(v, p[1]&(0x00ff)); \
> - DJB2_HASH(v, (p[1]>> 8)& (0x007f)); \
> - DJB2_HASH(v, p[2]& (0x00ff)); \
> - DJB2_HASH(v, (p[2]>> 8)& (0x007f)); \
> - v&= HASH_MASK; \
> -}
> -#endif
> -
> -#ifdef LZ_RGB24
> -#define PIXEL rgb24_pixel_t
> -#define FNAME(name) lz_rgb24_##name
> -#define ENCODE_PIXEL(e, pix) {encode(e, (pix).b); encode(e, (pix).g); encode(e, (pix).r);}
> -#endif
> -
> -#ifdef LZ_RGB32
> -#define PIXEL rgb32_pixel_t
> -#define FNAME(name) lz_rgb32_##name
> -#define ENCODE_PIXEL(e, pix) {encode(e, (pix).b); encode(e, (pix).g); encode(e, (pix).r);}
> -#endif
> -
> -
> -#if defined(LZ_RGB24) || defined(LZ_RGB32)
> -#define GET_r(pix) ((pix).r)
> -#define GET_g(pix) ((pix).g)
> -#define GET_b(pix) ((pix).b)
> -#define HASH_FUNC(v, p) { \
> - v = DJB2_START; \
> - DJB2_HASH(v, p[0].r); \
> - DJB2_HASH(v, p[0].g); \
> - DJB2_HASH(v, p[0].b); \
> - DJB2_HASH(v, p[1].r); \
> - DJB2_HASH(v, p[1].g); \
> - DJB2_HASH(v, p[1].b); \
> - DJB2_HASH(v, p[2].r); \
> - DJB2_HASH(v, p[2].g); \
> - DJB2_HASH(v, p[2].b); \
> - v&= HASH_MASK; \
> - }
> -#endif
> -
> -#if defined(LZ_RGB16) || defined(LZ_RGB24) || defined(LZ_RGB32)
> -#define SAME_PIXEL(p1, p2) (GET_r(p1) == GET_r(p2)&& GET_g(p1) == GET_g(p2)&& \
> - GET_b(p1) == GET_b(p2))
> -
> -#endif
> -
> -#define PIXEL_ID(pix_ptr, seg_ptr) (pix_ptr - ((PIXEL *)seg_ptr->lines) + seg_ptr->size_delta)
> -
> -// when encoding, the ref can be in previous segment, and we should check that it doesn't
> -// exceeds its bounds.
> -// TODO: optimization: when only one chunk exists or when the reference is in the same segment,
> -// don't make checks if we reach end of segments
> -// TODO: optimize to continue match between segments?
> -// TODO: check hash function
> -// TODO: check times
> -
> -/* compresses one segment starting from 'from'.*/
> -static void FNAME(compress_seg)(Encoder *encoder, LzImageSegment *seg, PIXEL *from, int copied)
> -{
> - const PIXEL *ip = from;
> - const PIXEL *ip_bound = (PIXEL *)(seg->lines_end) - BOUND_OFFSET;
> - const PIXEL *ip_limit = (PIXEL *)(seg->lines_end) - LIMIT_OFFSET;
> - HashEntry *hslot;
> - int hval;
> - int copy = copied;
> -
> - if (copy == 0) {
> - encode_copy_count(encoder, MAX_COPY - 1);
> - }
> -
> -
> - while (LZ_EXPECT_CONDITIONAL(ip< ip_limit)) { // TODO: maybe change ip_limit and enabling
> - // moving to the next seg
> - const PIXEL *ref;
> - const PIXEL *ref_limit;
> - size_t distance;
> -
> - /* minimum match length */
> -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
> - size_t len = 3;
> -#elif defined(LZ_RGB16)
> - size_t len = 2;
> -#else
> - size_t len = 1;
> -#endif
> - /* comparison starting-point */
> - const PIXEL *anchor = ip;
> -
> -
> -
> - // TODO: RLE without checking if not first byte.
> - // TODO: optimize comparisons
> -
> - /* check for a run */ // TODO for RGB we can use less pixels
> - if (LZ_EXPECT_CONDITIONAL(ip> (PIXEL *)(seg->lines))) {
> - if (SAME_PIXEL(ip[-1], ip[0])&& SAME_PIXEL(ip[0], ip[1])&& SAME_PIXEL(ip[1], ip[2])) {
> - distance = 1;
> - ip += 3;
> - ref = anchor + 2;
> - ref_limit = (PIXEL *)(seg->lines_end);
> -#if defined(LZ_RGB16) || defined(LZ_RGB24) || defined(LZ_RGB32)
> - len = 3;
> -#endif
> - goto match;
> - }
> - }
> -
> - /* find potential match */
> - HASH_FUNC(hval, ip);
> - hslot = encoder->htab + hval;
> - ref = (PIXEL *)(hslot->ref);
> - ref_limit = (PIXEL *)(hslot->image_seg->lines_end);
> -
> - /* calculate distance to the match */
> - distance = PIXEL_ID(anchor, seg) - PIXEL_ID(ref, hslot->image_seg);
> -
> - /* update hash table */
> - hslot->image_seg = seg;
> - hslot->ref = (uint8_t *)anchor;
> -
> - /* is this a match? check the first 3 pixels */
> - if (distance == 0 || (distance>= MAX_FARDISTANCE)) {
> - goto literal;
> - }
> - /* check if the hval key identical*/
> - // no need to check ref limit here because the word size in the htab is 3 pixels
> - if (!SAME_PIXEL(*ref, *ip)) {
> - ref++;
> - ip++;
> - goto literal;
> - }
> - ref++;
> - ip++;
> -
> - /* minimum match length for rgb16 is 2 and for plt and alpha is 3 */
> -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_RGB16)
> - if (!SAME_PIXEL(*ref, *ip)) {
> - ref++;
> - ip++;
> - goto literal;
> - }
> - ref++;
> - ip++;
> -#endif
> -
> -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
> - if (!SAME_PIXEL(*ref, *ip)) {
> - ref++;
> - ip++;
> - goto literal;
> - }
> - ref++;
> - ip++;
> -#endif
> - /* far, needs at least 5-byte match */
> - if (distance>= MAX_DISTANCE) {
> -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
> - if (ref>= (ref_limit - 1)) {
> - goto literal;
> - }
> -#else
> - if (ref> (ref_limit - 1)) {
> - goto literal;
> - }
> -#endif
> - if (!SAME_PIXEL(*ref, *ip)) {
> - ref++;
> - ip++;
> - goto literal;
> - }
> - ref++;
> - ip++;
> - len++;
> -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
> - if (!SAME_PIXEL(*ref, *ip)) {
> - ref++;
> - ip++;
> - goto literal;
> - }
> - ref++;
> - ip++;
> - len++;
> -#endif
> - }
> -match: // RLE or dictionary (both are encoded by distance from ref (-1) and length)
> -
> - /* distance is biased */
> - distance--;
> -
> - // ip is located now at the position of the second mismatch.
> - // later it will be subtracted by 3
> -
> - if (!distance) {
> - /* zero distance means a run */
> - PIXEL x = *ref;
> - while ((ip< ip_bound)&& (ref< ref_limit)) { // TODO: maybe separate a run from
> - // the same seg or from different
> - // ones in order to spare
> - // ref< ref_limit
> - if (!SAME_PIXEL(*ref, x)) {
> - ref++;
> - break;
> - } else {
> - ref++;
> - ip++;
> - }
> - }
> - } else {
> - // TODO: maybe separate a run from the same seg or from different ones in order
> - // to spare ref< ref_limit and that way we can also perform 8 calls of
> - // (ref++ != ip++) outside a loop
> - for (;;) {
> - while ((ip< ip_bound)&& (ref< ref_limit)) {
> - if (!SAME_PIXEL(*ref, *ip)) {
> - ref++;
> - ip++;
> - break;
> - } else {
> - ref++;
> - ip++;
> - }
> - }
> - break;
> - }
> - }
> -
> - /* if we have copied something, adjust the copy count */
> - if (copy) {
> - /* copy is biased, '0' means 1 byte copy */
> - update_copy_count(encoder, copy - 1);
> - } else {
> - /* back, to overwrite the copy count */
> - compress_output_prev(encoder);
> - }
> -
> - /* reset literal counter */
> - copy = 0;
> -
> - /* length is biased, '1' means a match of 3 pixels for PLT and alpha*/
> - /* for RGB 16 1 means 2 */
> - /* for RGB24/32 1 means 1...*/
> - ip -= 3;
> - len = ip - anchor;
> -#if defined(LZ_RGB16)
> - len++;
> -#elif defined(LZ_RGB24) || defined(LZ_RGB32)
> - len += 2;
> -#endif
> - /* encode the match (like fastlz level 2)*/
> - if (distance< MAX_DISTANCE) { // MAX_DISTANCE is 2^13 - 1
> - // when copy is performed, the byte that holds the copy count is smaller than 32.
> - // When there is a reference, the first byte is always larger then 32
> -
> - // 3 bits = length, 5 bits = 5 MSB of distance, 8 bits = 8 LSB of distance
> - if (len< 7) {
> - encode(encoder, (uint8_t)((len<< 5) + (distance>> 8)));
> - encode(encoder, (uint8_t)(distance& 255));
> - } else { // more than 3 bits are needed for length
> - // 3 bits 7, 5 bits = 5 MSB of distance, next bytes are 255 till we
> - // receive a smaller number, last byte = 8 LSB of distance
> - encode(encoder, (uint8_t)((7<< 5) + (distance>> 8)));
> - for (len -= 7; len>= 255; len -= 255) {
> - encode(encoder, 255);
> - }
> - encode(encoder, (uint8_t)len);
> - encode(encoder, (uint8_t)(distance& 255));
> - }
> - } else {
> - /* far away */
> - if (len< 7) { // the max_far_distance is ~2^16+2^13 so two more bytes are needed
> - // 3 bits = length, 5 bits = 5 MSB of MAX_DISTANCE, 8 bits = 8 LSB of MAX_DISTANCE,
> - // 8 bits = 8 MSB distance-MAX_distance (smaller than 2^16),8 bits=8 LSB of
> - // distance-MAX_distance
> - distance -= MAX_DISTANCE;
> - encode(encoder, (uint8_t)((len<< 5) + 31));
> - encode(encoder, (uint8_t)255);
> - encode(encoder, (uint8_t)(distance>> 8));
> - encode(encoder, (uint8_t)(distance& 255));
> - } else {
> - // same as before, but the first byte is followed by the left overs of len
> - distance -= MAX_DISTANCE;
> - encode(encoder, (uint8_t)((7<< 5) + 31));
> - for (len -= 7; len>= 255; len -= 255) {
> - encode(encoder, 255);
> - }
> - encode(encoder, (uint8_t)len);
> - encode(encoder, 255);
> - encode(encoder, (uint8_t)(distance>> 8));
> - encode(encoder, (uint8_t)(distance& 255));
> - }
> - }
> -
> - /* update the hash at match boundary */
> -#if defined(LZ_RGB16) || defined(LZ_RGB24) || defined(LZ_RGB32)
> - if (ip> anchor) {
> -#endif
> - HASH_FUNC(hval, ip);
> - encoder->htab[hval].ref = (uint8_t *)ip;
> - ip++;
> - encoder->htab[hval].image_seg = seg;
> -#if defined(LZ_RGB16) || defined(LZ_RGB24) || defined(LZ_RGB32)
> - } else {ip++;
> - }
> -#endif
> -#if defined(LZ_RGB24) || defined(LZ_RGB32)
> - if (ip> anchor) {
> -#endif
> - HASH_FUNC(hval, ip);
> - encoder->htab[hval].ref = (uint8_t *)ip;
> - ip++;
> - encoder->htab[hval].image_seg = seg;
> -#if defined(LZ_RGB24) || defined(LZ_RGB32)
> - } else {ip++;
> - }
> -#endif
> - /* assuming literal copy */
> - encode_copy_count(encoder, MAX_COPY - 1);
> - continue;
> -
> -literal:
> - ENCODE_PIXEL(encoder, *anchor);
> - anchor++;
> - ip = anchor;
> - copy++;
> -
> - if (LZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY)) {
> - copy = 0;
> - encode_copy_count(encoder, MAX_COPY - 1);
> - }
> - } // END LOOP (ip< ip_limit)
> -
> -
> - /* left-over as literal copy */
> - ip_bound++;
> - while (ip<= ip_bound) {
> - ENCODE_PIXEL(encoder, *ip);
> - ip++;
> - copy++;
> - if (copy == MAX_COPY) {
> - copy = 0;
> - encode_copy_count(encoder, MAX_COPY - 1);
> - }
> - }
> -
> - /* if we have copied something, adjust the copy length */
> - if (copy) {
> - update_copy_count(encoder, copy - 1);
> - } else {
> - compress_output_prev(encoder); // in case we created a new buffer for copy, check that
> - // red_worker could handle size that do not contain the
> - // ne buffer
> - }
> -}
> -
> -
> -/* initializes the hash table. if the file is very small, copies it.
> - copies the first two pixels of the first segment, and sends the segments
> - one by one to compress_seg.
> - the number of bytes compressed are stored inside encoder.
> - */
> -static void FNAME(compress)(Encoder *encoder)
> -{
> - LzImageSegment *cur_seg = encoder->head_image_segs;
> - HashEntry *hslot;
> - PIXEL *ip;
> -
> - // fetch the first image segment that is not too small
> - while (cur_seg&& ((((PIXEL *)cur_seg->lines_end) - ((PIXEL *)cur_seg->lines))< 4)) {
> - // coping the segment
> - if (cur_seg->lines != cur_seg->lines_end) {
> - ip = (PIXEL *)cur_seg->lines;
> - // Note: we assume MAX_COPY> 3
> - encode_copy_count(encoder, (uint8_t)(
> - (((PIXEL *)cur_seg->lines_end) - ((PIXEL *)cur_seg->lines)) - 1));
> - while (ip< (PIXEL *)cur_seg->lines_end) {
> - ENCODE_PIXEL(encoder, *ip);
> - ip++;
> - }
> - }
> - cur_seg = cur_seg->next;
> - }
> -
> - if (!cur_seg) {
> - return;
> - }
> -
> - ip = (PIXEL *)cur_seg->lines;
> -
> - /* initialize hash table */
> - for (hslot = encoder->htab; hslot< encoder->htab + HASH_SIZE; hslot++) {
> - hslot->ref = (uint8_t*)ip;
> - hslot->image_seg = cur_seg;
> - }
> -
> - encode_copy_count(encoder, MAX_COPY - 1);
> - ENCODE_PIXEL(encoder, *ip);
> - ip++;
> - ENCODE_PIXEL(encoder, *ip);
> - ip++;
> -
> - // compressing the first segment
> - FNAME(compress_seg)(encoder, cur_seg, ip, 2);
> -
> - // compressing the next segments
> - for (cur_seg = cur_seg->next; cur_seg; cur_seg = cur_seg->next) {
> - FNAME(compress_seg)(encoder, cur_seg, (PIXEL *)cur_seg->lines, 0);
> - }
> -}
> -
> -#undef FNAME
> -#undef PIXEL_ID
> -#undef PIXEL
> -#undef ENCODE_PIXEL
> -#undef SAME_PIXEL
> -#undef LZ_READU16
> -#undef HASH_FUNC
> -#undef BYTES_TO_16
> -#undef HASH_FUNC_16
> -#undef GET_r
> -#undef GET_g
> -#undef GET_b
> -#undef GET_CODE
> -#undef LZ_PLT
> -#undef LZ_RGB_ALPHA
> -#undef LZ_RGB16
> -#undef LZ_RGB24
> -#undef LZ_RGB32
> -#undef HASH_FUNC2
> diff --git a/common/lz_config.h b/common/lz_config.h
> deleted file mode 100644
> index 439f413..0000000
> --- a/common/lz_config.h
> +++ /dev/null
> @@ -1,48 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, write to the Free Software
> -
> - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> -*/
> -
> -#ifndef __LZ_CONFIG_H
> -#define __LZ_CONFIG_H
> -
> -#include<spice/types.h>
> -#include<spice/macros.h>
> -
> -#ifdef __GNUC__
> -
> -#include<string.h>
> -
> -#define INLINE inline
> -
> -#else
> -
> -#ifdef QXLDD
> -#include<windef.h>
> -#include "os_dep.h"
> -#define INLINE _inline
> -
> -#else
> -#include<stddef.h>
> -#include<string.h>
> -
> -#define INLINE inline
> -#endif // QXLDD
> -
> -#endif //__GNUC__
> -#endif //__LZ_CONFIG_H
> diff --git a/common/lz_decompress_tmpl.c b/common/lz_decompress_tmpl.c
> deleted file mode 100644
> index aa403f6..0000000
> --- a/common/lz_decompress_tmpl.c
> +++ /dev/null
> @@ -1,323 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -
> - Copyright 2009 Red Hat, Inc. and/or its affiliates.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -
> - This file incorporates work covered by the following copyright and
> - permission notice:
> - Copyright (C) 2007 Ariya Hidayat (ariya at kde.org)
> - Copyright (C) 2006 Ariya Hidayat (ariya at kde.org)
> - Copyright (C) 2005 Ariya Hidayat (ariya at kde.org)
> -
> - Permission is hereby granted, free of charge, to any person
> - obtaining a copy of this software and associated documentation
> - files (the "Software"), to deal in the Software without
> - restriction, including without limitation the rights to use, copy,
> - modify, merge, publish, distribute, sublicense, and/or sell copies
> - of the Software, and to permit persons to whom the Software is
> - furnished to do so, subject to the following conditions:
> -
> - The above copyright notice and this permission notice shall be
> - included in all copies or substantial portions of the Software.
> -
> - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> - SOFTWARE.
> -
> -*/
> -
> -// External defines: PLT, RGBX/PLTXX/ALPHA, TO_RGB32.
> -// If PLT4/1 and TO_RGB32 are defined, we need CAST_PLT_DISTANCE (because then the number of
> -// pixels differ from the units used in the compression)
> -
> -/*
> - For each output pixel type the following macros are defined:
> - OUT_PIXEL - the output pixel type
> - COPY_PIXEL(p, out) - assigns the pixel to the place pointed by out and increases
> - out. Used in RLE. Need special handling because in alpha we
> - copy only the pad byte.
> - COPY_REF_PIXEL(ref, out) - copies the pixel pointed by ref to the pixel pointed by out.
> - Increases ref and out.
> - COPY_COMP_PIXEL(encoder, out) - copies pixel from the compressed buffer to the decompressed
> - buffer. Increases out.
> -*/
> -#if !defined(LZ_RGB_ALPHA)
> -#define COPY_PIXEL(p, out) (*out++ = p)
> -#define COPY_REF_PIXEL(ref, out) (*out++ = *ref++)
> -#endif
> -
> -
> -// decompressing plt to plt
> -#ifdef LZ_PLT
> -#ifndef TO_RGB32
> -#define OUT_PIXEL one_byte_pixel_t
> -#define FNAME(name) lz_plt_##name
> -#define COPY_COMP_PIXEL(encoder, out) {out->a = decode(encoder); out++;}
> -#else // TO_RGB32
> -#define OUT_PIXEL rgb32_pixel_t
> -#define COPY_PLT_ENTRY(ent, out) { \
> - (out)->b = ent; \
> - (out)->g = (ent>> 8); \
> - (out)->r = (ent>> 16); \
> - (out)->pad = 0; \
> -}
> -#ifdef PLT8
> -#define FNAME(name) lz_plt8_to_rgb32_##name
> -#define COPY_COMP_PIXEL(encoder, out) { \
> - uint32_t rgb = encoder->palette->ents[decode(encoder)]; \
> - COPY_PLT_ENTRY(rgb, out); \
> - out++;}
> -#elif defined(PLT4_BE)
> -#define FNAME(name) lz_plt4_be_to_rgb32_##name
> -#define COPY_COMP_PIXEL(encoder, out){ \
> - uint8_t byte = decode(encoder); \
> - uint32_t rgb = encoder->palette->ents[((byte>> 4)& 0x0f) % (encoder->palette->num_ents)]; \
> - COPY_PLT_ENTRY(rgb, out); \
> - out++; \
> - rgb = encoder->palette->ents[(byte& 0x0f) % (encoder->palette->num_ents)]; \
> - COPY_PLT_ENTRY(rgb, out); \
> - out++; \
> -}
> -#define CAST_PLT_DISTANCE(dist) (dist*2)
> -#elif defined(PLT4_LE)
> -#define FNAME(name) lz_plt4_le_to_rgb32_##name
> -#define COPY_COMP_PIXEL(encoder, out){ \
> - uint8_t byte = decode(encoder); \
> - uint32_t rgb = encoder->palette->ents[(byte& 0x0f) % (encoder->palette->num_ents)]; \
> - COPY_PLT_ENTRY(rgb, out); \
> - out++; \
> - rgb = encoder->palette->ents[((byte>> 4)& 0x0f) % (encoder->palette->num_ents)]; \
> - COPY_PLT_ENTRY(rgb, out); \
> - out++; \
> -}
> -#define CAST_PLT_DISTANCE(dist) (dist*2)
> -#elif defined(PLT1_BE) // TODO store palette entries for direct access
> -#define FNAME(name) lz_plt1_be_to_rgb32_##name
> -#define COPY_COMP_PIXEL(encoder, out){ \
> - uint8_t byte = decode(encoder); \
> - int i; \
> - uint32_t fore = encoder->palette->ents[1]; \
> - uint32_t back = encoder->palette->ents[0]; \
> - for (i = 7; i>= 0; i--) \
> - { \
> - if ((byte>> i)& 1) { \
> - COPY_PLT_ENTRY(fore, out); \
> - } else { \
> - COPY_PLT_ENTRY(back, out); \
> - } \
> - out++; \
> - } \
> -}
> -#define CAST_PLT_DISTANCE(dist) (dist*8)
> -#elif defined(PLT1_LE)
> -#define FNAME(name) lz_plt1_le_to_rgb32_##name
> -#define COPY_COMP_PIXEL(encoder, out){ \
> - uint8_t byte = decode(encoder); \
> - int i; \
> - uint32_t fore = encoder->palette->ents[1]; \
> - uint32_t back = encoder->palette->ents[0]; \
> - for (i = 0; i< 8; i++) \
> - { \
> - if ((byte>> i)& 1) { \
> - COPY_PLT_ENTRY(fore, out); \
> - } else { \
> - COPY_PLT_ENTRY(back, out); \
> - } \
> - out++; \
> - } \
> -}
> -#define CAST_PLT_DISTANCE(dist) (dist*8)
> -#endif // PLT Type
> -#endif // TO_RGB32
> -#endif
> -
> -#ifdef LZ_RGB16
> -#ifndef TO_RGB32
> -#define OUT_PIXEL rgb16_pixel_t
> -#define FNAME(name) lz_rgb16_##name
> -#define COPY_COMP_PIXEL(e, out) {*out = ((decode(e)<< 8) | decode(e)); out++;}
> -#else
> -#define OUT_PIXEL rgb32_pixel_t
> -#define FNAME(name) lz_rgb16_to_rgb32_##name
> -#define COPY_COMP_PIXEL(e, out) { \
> - out->r = decode(e); \
> - out->b = decode(e); \
> - out->g = (((out->r)<< 6) | ((out->b)>> 2))& ~0x07; \
> - out->g |= (out->g>> 5); \
> - out->r = ((out->r<< 1)& ~0x07)| ((out->r>> 4)& 0x07); \
> - out->b = (out->b<< 3) | ((out->b>> 2)& 0x07); \
> - out->pad = 0; \
> - out++; \
> -}
> -#endif
> -#endif
> -
> -#ifdef LZ_RGB24
> -#define OUT_PIXEL rgb24_pixel_t
> -#define FNAME(name) lz_rgb24_##name
> -#define COPY_COMP_PIXEL(e, out) {out->b = decode(e); out->g = decode(e); out->r = decode(e); out++;}
> -#endif
> -
> -#ifdef LZ_RGB32
> -#define OUT_PIXEL rgb32_pixel_t
> -#define FNAME(name) lz_rgb32_##name
> -#define COPY_COMP_PIXEL(e, out) { \
> - out->b = decode(e); \
> - out->g = decode(e); \
> - out->r = decode(e); \
> - out->pad = 0; \
> - out++; \
> -}
> -#endif
> -
> -#ifdef LZ_RGB_ALPHA
> -#define OUT_PIXEL rgb32_pixel_t
> -#define FNAME(name) lz_rgb_alpha_##name
> -#define COPY_PIXEL(p, out) {out->pad = p.pad; out++;}
> -#define COPY_REF_PIXEL(ref, out) {out->pad = ref->pad; out++; ref++;}
> -#define COPY_COMP_PIXEL(e, out) {out->pad = decode(e); out++;}
> -#endif
> -
> -// return num of bytes in out_buf
> -static size_t FNAME(decompress)(Encoder *encoder, OUT_PIXEL *out_buf, int size)
> -{
> - OUT_PIXEL *op = out_buf;
> - OUT_PIXEL *op_limit = out_buf + size;
> - uint32_t ctrl = decode(encoder);
> - int loop = TRUE;
> -
> - do {
> - const OUT_PIXEL *ref = op;
> - uint32_t len = ctrl>> 5;
> - uint32_t ofs = (ctrl& 31)<< 8; // 5 MSb of distance
> -
> - if (ctrl>= MAX_COPY) { // reference (dictionary/RLE)
> - /* retrieving the reference and the match length */
> -
> - uint8_t code;
> - len--;
> - //ref -= ofs;
> - if (len == 7 - 1) { // match length is bigger than 7
> - do {
> - code = decode(encoder);
> - len += code;
> - } while (code == 255); // remaining of len
> - }
> - code = decode(encoder);
> - ofs += code;
> -
> - /* match from 16-bit distance */
> - if (LZ_UNEXPECT_CONDITIONAL(code == 255)) {
> - if (LZ_EXPECT_CONDITIONAL((ofs - code) == (31<< 8))) {
> - ofs = decode(encoder)<< 8;
> - ofs += decode(encoder);
> - ofs += MAX_DISTANCE;
> - }
> - }
> -
> -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
> - len += 3; // length is biased by 2 + 1 (fixing bias)
> -#elif defined(LZ_RGB16)
> - len += 2; // length is biased by 1 + 1 (fixing bias)
> -#else
> - len += 1;
> -#endif
> - ofs += 1; // offset is biased by 1 (fixing bias)
> -
> -#if defined(TO_RGB32)
> -#if defined(PLT4_BE) || defined(PLT4_LE) || defined(PLT1_BE) || defined(PLT1_LE)
> - ofs = CAST_PLT_DISTANCE(ofs);
> - len = CAST_PLT_DISTANCE(len);
> -#endif
> -#endif
> - ref -= ofs;
> -
> - ASSERT(encoder->usr, op + len<= op_limit);
> - ASSERT(encoder->usr, ref + len<= op_limit);
> - ASSERT(encoder->usr, ref>= out_buf);
> -
> - // TODO: optimize by not calling loop at least 3 times when not PLT_TO_RGB32 (len is
> - // always>=3). in PLT_TO_RGB32 len>= 3*number_of_pixels_per_byte
> -
> - /* copying the match*/
> -
> - if (ref == (op - 1)) { // run // TODO: this will never be called in PLT4/1_TO_RGB
> - // because the number of pixel copied is larger
> - // then one...
> - /* optimize copy for a run */
> - OUT_PIXEL b = *ref;
> - for (; len; --len) {
> - COPY_PIXEL(b, op);
> - ASSERT(encoder->usr, op<= op_limit);
> - }
> - } else {
> - for (; len; --len) {
> - COPY_REF_PIXEL(ref, op);
> - ASSERT(encoder->usr, op<= op_limit);
> - }
> - }
> - } else { // copy
> - ctrl++; // copy count is biased by 1
> -#if defined(TO_RGB32)&& (defined(PLT4_BE) || defined(PLT4_LE) || defined(PLT1_BE) || \
> - defined(PLT1_LE))
> - ASSERT(encoder->usr, op + CAST_PLT_DISTANCE(ctrl)<= op_limit);
> -#else
> - ASSERT(encoder->usr, op + ctrl<= op_limit);
> -#endif
> - COPY_COMP_PIXEL(encoder, op);
> -
> - ASSERT(encoder->usr, op<= op_limit);
> -
> - for (--ctrl; ctrl; ctrl--) {
> - COPY_COMP_PIXEL(encoder, op);
> - ASSERT(encoder->usr, op<= op_limit);
> - }
> - }
> -
> - if (LZ_EXPECT_CONDITIONAL(op< op_limit)) {
> - ctrl = decode(encoder);
> - } else {
> - loop = FALSE;
> - }
> - } while (LZ_EXPECT_CONDITIONAL(loop));
> -
> - return (op - out_buf);
> -}
> -
> -#undef LZ_PLT
> -#undef PLT8
> -#undef PLT4_BE
> -#undef PLT4_LE
> -#undef PLT1_BE
> -#undef PLT1_LE
> -#undef LZ_RGB16
> -#undef LZ_RGB24
> -#undef LZ_RGB32
> -#undef LZ_RGB_ALPHA
> -#undef TO_RGB32
> -#undef OUT_PIXEL
> -#undef FNAME
> -#undef COPY_PIXEL
> -#undef COPY_REF_PIXEL
> -#undef COPY_COMP_PIXEL
> -#undef COPY_PLT_ENTRY
> -#undef CAST_PLT_DISTANCE
> -
> diff --git a/common/macros.h b/common/macros.h
> deleted file mode 100644
> index 44a37e4..0000000
> --- a/common/macros.h
> +++ /dev/null
> @@ -1,30 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef __MACROS_H
> -#define __MACROS_H
> -
> -#if __GNUC__> 4 || (__GNUC__ == 4&& __GNUC_MINOR__>= 5)
> -#define ATTR_PRINTF(a,b) \
> - __attribute__((format(printf,a,b)))
> -#else
> -#define ATTR_PRINTF(a,b)
> -#endif /* __GNUC__ */
> -
> -
> -#endif /* __MACROS_H */
> diff --git a/common/marshaller.c b/common/marshaller.c
> deleted file mode 100644
> index 57ca32e..0000000
> --- a/common/marshaller.c
> +++ /dev/null
> @@ -1,614 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2010 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include "config.h"
> -
> -#include "marshaller.h"
> -#include "mem.h"
> -#include<string.h>
> -#include<stdlib.h>
> -#include<assert.h>
> -
> -#ifdef WORDS_BIGENDIAN
> -#define write_int8(ptr,v) (*((int8_t *)(ptr)) = v)
> -#define write_uint8(ptr,v) (*((uint8_t *)(ptr)) = v)
> -#define write_int16(ptr,v) (*((int16_t *)(ptr)) = SPICE_BYTESWAP16((uint16_t)(v)))
> -#define write_uint16(ptr,v) (*((uint16_t *)(ptr)) = SPICE_BYTESWAP16((uint16_t)(v)))
> -#define write_int32(ptr,v) (*((int32_t *)(ptr)) = SPICE_BYTESWAP32((uint32_t)(v)))
> -#define write_uint32(ptr,v) (*((uint32_t *)(ptr)) = SPICE_BYTESWAP32((uint32_t)(v)))
> -#define write_int64(ptr,v) (*((int64_t *)(ptr)) = SPICE_BYTESWAP64((uint64_t)(v)))
> -#define write_uint64(ptr,v) (*((uint64_t *)(ptr)) = SPICE_BYTESWAP64((uint64_t)(v)))
> -#else
> -#define write_int8(ptr,v) (*((int8_t *)(ptr)) = v)
> -#define write_uint8(ptr,v) (*((uint8_t *)(ptr)) = v)
> -#define write_int16(ptr,v) (*((int16_t *)(ptr)) = v)
> -#define write_uint16(ptr,v) (*((uint16_t *)(ptr)) = v)
> -#define write_int32(ptr,v) (*((int32_t *)(ptr)) = v)
> -#define write_uint32(ptr,v) (*((uint32_t *)(ptr)) = v)
> -#define write_int64(ptr,v) (*((int64_t *)(ptr)) = v)
> -#define write_uint64(ptr,v) (*((uint64_t *)(ptr)) = v)
> -#endif
> -
> -typedef struct {
> - uint8_t *data;
> - size_t len;
> - spice_marshaller_item_free_func free_data;
> - void *opaque;
> -} MarshallerItem;
> -
> -/* Try to fit in 4k page with 2*pointer-size overhead (next ptr and malloc size) */
> -#define MARSHALLER_BUFFER_SIZE (4096 - sizeof(void *) * 2)
> -
> -typedef struct MarshallerBuffer MarshallerBuffer;
> -struct MarshallerBuffer {
> - MarshallerBuffer *next;
> - uint8_t data[MARSHALLER_BUFFER_SIZE];
> -};
> -
> -#define N_STATIC_ITEMS 4
> -
> -typedef struct SpiceMarshallerData SpiceMarshallerData;
> -
> -typedef struct {
> - SpiceMarshaller *marshaller;
> - int item_nr;
> - int is_64bit;
> - size_t offset;
> -} MarshallerRef;
> -
> -struct SpiceMarshaller {
> - size_t total_size;
> - SpiceMarshallerData *data;
> - SpiceMarshaller *next;
> -
> - MarshallerRef pointer_ref;
> -
> - int n_items;
> - int items_size; /* number of items availible in items */
> - MarshallerItem *items;
> -
> - MarshallerItem static_items[N_STATIC_ITEMS];
> -};
> -
> -struct SpiceMarshallerData {
> - size_t total_size;
> - size_t base;
> - SpiceMarshaller *marshallers;
> - SpiceMarshaller *last_marshaller;
> -
> - size_t current_buffer_position;
> - MarshallerBuffer *current_buffer;
> - MarshallerItem *current_buffer_item;
> - MarshallerBuffer *buffers;
> -
> - SpiceMarshaller static_marshaller;
> - MarshallerBuffer static_buffer;
> -};
> -
> -static void spice_marshaller_init(SpiceMarshaller *m,
> - SpiceMarshallerData *data)
> -{
> - m->data = data;
> - m->next = NULL;
> - m->total_size = 0;
> - m->pointer_ref.marshaller = NULL;
> - m->n_items = 0;
> - m->items_size = N_STATIC_ITEMS;
> - m->items = m->static_items;
> -}
> -
> -SpiceMarshaller *spice_marshaller_new(void)
> -{
> - SpiceMarshallerData *d;
> - SpiceMarshaller *m;
> -
> - d = spice_new(SpiceMarshallerData, 1);
> -
> - d->last_marshaller = d->marshallers =&d->static_marshaller;
> - d->total_size = 0;
> - d->base = 0;
> - d->buffers =&d->static_buffer;
> - d->buffers->next = NULL;
> - d->current_buffer = d->buffers;
> - d->current_buffer_position = 0;
> - d->current_buffer_item = NULL;
> -
> - m =&d->static_marshaller;
> - spice_marshaller_init(m, d);
> -
> - return m;
> -}
> -
> -static void free_item_data(SpiceMarshaller *m)
> -{
> - MarshallerItem *item;
> - int i;
> -
> - /* Free all user data */
> - for (i = 0; i< m->n_items; i++) {
> - item =&m->items[i];
> - if (item->free_data != NULL) {
> - item->free_data(item->data, item->opaque);
> - }
> - }
> -}
> -
> -static void free_items(SpiceMarshaller *m)
> -{
> - if (m->items != m->static_items) {
> - free(m->items);
> - }
> -}
> -
> -void spice_marshaller_reset(SpiceMarshaller *m)
> -{
> - SpiceMarshaller *m2, *next;
> - SpiceMarshallerData *d;
> -
> - /* Only supported for root marshaller */
> - assert(m->data->marshallers == m);
> -
> - for (m2 = m; m2 != NULL; m2 = next) {
> - next = m2->next;
> - free_item_data(m2);
> -
> - /* Free non-root marshallers */
> - if (m2 != m) {
> - free_items(m2);
> - free(m2);
> - }
> - }
> -
> - m->next = NULL;
> - m->n_items = 0;
> - m->total_size = 0;
> -
> - d = m->data;
> - d->last_marshaller = d->marshallers;
> - d->total_size = 0;
> - d->base = 0;
> - d->current_buffer_item = NULL;
> - d->current_buffer = d->buffers;
> - d->current_buffer_position = 0;
> -}
> -
> -void spice_marshaller_destroy(SpiceMarshaller *m)
> -{
> - MarshallerBuffer *buf, *next;
> - SpiceMarshallerData *d;
> -
> - /* Only supported for root marshaller */
> - assert(m->data->marshallers == m);
> -
> - spice_marshaller_reset(m);
> -
> - free_items(m);
> -
> - d = m->data;
> -
> - buf = d->buffers->next;
> - while (buf != NULL) {
> - next = buf->next;
> - free(buf);
> - buf = next;
> - }
> -
> - free(d);
> -}
> -
> -static MarshallerItem *spice_marshaller_add_item(SpiceMarshaller *m)
> -{
> - MarshallerItem *item;
> -
> - if (m->n_items == m->items_size) {
> - int items_size = m->items_size * 2;
> -
> - if (m->items == m->static_items) {
> - m->items = spice_new(MarshallerItem, items_size);
> - memcpy(m->items, m->static_items, sizeof(MarshallerItem) * m->n_items);
> - } else {
> - m->items = spice_renew(MarshallerItem, m->items, items_size);
> - }
> - m->items_size = items_size;
> - }
> - item =&m->items[m->n_items++];
> - item->free_data = NULL;
> -
> - return item;
> -}
> -
> -static size_t remaining_buffer_size(SpiceMarshallerData *d)
> -{
> - return MARSHALLER_BUFFER_SIZE - d->current_buffer_position;
> -}
> -
> -uint8_t *spice_marshaller_reserve_space(SpiceMarshaller *m, size_t size)
> -{
> - MarshallerItem *item;
> - SpiceMarshallerData *d;
> - uint8_t *res;
> -
> - if (size == 0) {
> - return NULL;
> - }
> -
> - d = m->data;
> -
> - /* Check current item */
> - item =&m->items[m->n_items - 1];
> - if (item == d->current_buffer_item&&
> - remaining_buffer_size(d)>= size) {
> - assert(m->n_items>= 1);
> - /* We can piggy back on existing item+buffer */
> - res = item->data + item->len;
> - item->len += size;
> - d->current_buffer_position += size;
> - d->total_size += size;
> - m->total_size += size;
> - return res;
> - }
> -
> - item = spice_marshaller_add_item(m);
> -
> - if (remaining_buffer_size(d)>= size) {
> - /* Fits in current buffer */
> - item->data = d->current_buffer->data + d->current_buffer_position;
> - item->len = size;
> - d->current_buffer_position += size;
> - d->current_buffer_item = item;
> - } else if (size> MARSHALLER_BUFFER_SIZE / 2) {
> - /* Large item, allocate by itself */
> - item->data = (uint8_t *)spice_malloc(size);
> - item->len = size;
> - item->free_data = (spice_marshaller_item_free_func)free;
> - item->opaque = NULL;
> - } else {
> - /* Use next buffer */
> - if (d->current_buffer->next == NULL) {
> - d->current_buffer->next = spice_new(MarshallerBuffer, 1);
> - d->current_buffer->next->next = NULL;
> - }
> - d->current_buffer = d->current_buffer->next;
> - d->current_buffer_position = size;
> - d->current_buffer_item = item;
> - item->data = d->current_buffer->data;
> - item->len = size;
> - }
> -
> - d->total_size += size;
> - m->total_size += size;
> - return item->data;
> -}
> -
> -void spice_marshaller_unreserve_space(SpiceMarshaller *m, size_t size)
> -{
> - MarshallerItem *item;
> -
> - if (size == 0) {
> - return;
> - }
> -
> - item =&m->items[m->n_items - 1];
> -
> - assert(item->len>= size);
> - item->len -= size;
> -}
> -
> -uint8_t *spice_marshaller_add_ref_full(SpiceMarshaller *m, uint8_t *data, size_t size,
> - spice_marshaller_item_free_func free_data, void *opaque)
> -{
> - MarshallerItem *item;
> - SpiceMarshallerData *d;
> -
> - if (data == NULL || size == 0) {
> - return NULL;
> - }
> -
> - item = spice_marshaller_add_item(m);
> - item->data = data;
> - item->len = size;
> - item->free_data = free_data;
> - item->opaque = opaque;
> -
> - d = m->data;
> - m->total_size += size;
> - d->total_size += size;
> -
> - return data;
> -}
> -
> -uint8_t *spice_marshaller_add(SpiceMarshaller *m, const uint8_t *data, size_t size)
> -{
> - uint8_t *ptr;
> -
> - ptr = spice_marshaller_reserve_space(m, size);
> - memcpy(ptr, data, size);
> - return ptr;
> -}
> -
> -uint8_t *spice_marshaller_add_ref(SpiceMarshaller *m, uint8_t *data, size_t size)
> -{
> - return spice_marshaller_add_ref_full(m, data, size, NULL, NULL);
> -}
> -
> -void spice_marshaller_add_ref_chunks(SpiceMarshaller *m, SpiceChunks *chunks)
> -{
> - unsigned int i;
> -
> - for (i = 0; i< chunks->num_chunks; i++) {
> - spice_marshaller_add_ref(m, chunks->chunk[i].data,
> - chunks->chunk[i].len);
> - }
> -}
> -
> -SpiceMarshaller *spice_marshaller_get_submarshaller(SpiceMarshaller *m)
> -{
> - SpiceMarshallerData *d;
> - SpiceMarshaller *m2;
> -
> - d = m->data;
> -
> - m2 = spice_new(SpiceMarshaller, 1);
> - spice_marshaller_init(m2, d);
> -
> - d->last_marshaller->next = m2;
> - d->last_marshaller = m2;
> -
> - return m2;
> -}
> -
> -SpiceMarshaller *spice_marshaller_get_ptr_submarshaller(SpiceMarshaller *m, int is_64bit)
> -{
> - SpiceMarshaller *m2;
> - uint8_t *p;
> - int size;
> -
> - size = is_64bit ? 8 : 4;
> -
> - p = spice_marshaller_reserve_space(m, size);
> - memset(p, 0, size);
> - m2 = spice_marshaller_get_submarshaller(m);
> - m2->pointer_ref.marshaller = m;
> - m2->pointer_ref.item_nr = m->n_items - 1;
> - m2->pointer_ref.offset = m->items[m->n_items - 1].len - size;
> - m2->pointer_ref.is_64bit = is_64bit;
> -
> - return m2;
> -}
> -
> -static uint8_t *lookup_ref(MarshallerRef *ref)
> -{
> - MarshallerItem *item;
> -
> - item =&ref->marshaller->items[ref->item_nr];
> - return item->data + ref->offset;
> -}
> -
> -
> -void spice_marshaller_set_base(SpiceMarshaller *m, size_t base)
> -{
> - /* Only supported for root marshaller */
> - assert(m->data->marshallers == m);
> -
> - m->data->base = base;
> -}
> -
> -uint8_t *spice_marshaller_linearize(SpiceMarshaller *m, size_t skip_bytes,
> - size_t *len, int *free_res)
> -{
> - MarshallerItem *item;
> - uint8_t *res, *p;
> - int i;
> -
> - /* Only supported for root marshaller */
> - assert(m->data->marshallers == m);
> -
> - if (m->n_items == 1) {
> - *free_res = FALSE;
> - if (m->items[0].len<= skip_bytes) {
> - *len = 0;
> - return NULL;
> - }
> - *len = m->items[0].len - skip_bytes;
> - return m->items[0].data + skip_bytes;
> - }
> -
> - *free_res = TRUE;
> - res = (uint8_t *)spice_malloc(m->data->total_size - skip_bytes);
> - *len = m->data->total_size - skip_bytes;
> - p = res;
> -
> - do {
> - for (i = 0; i< m->n_items; i++) {
> - item =&m->items[i];
> -
> - if (item->len<= skip_bytes) {
> - skip_bytes -= item->len;
> - continue;
> - }
> - memcpy(p, item->data + skip_bytes, item->len - skip_bytes);
> - p += item->len - skip_bytes;
> - skip_bytes = 0;
> - }
> - m = m->next;
> - } while (m != NULL);
> -
> - return res;
> -}
> -
> -uint8_t *spice_marshaller_get_ptr(SpiceMarshaller *m)
> -{
> - return m->items[0].data;
> -}
> -
> -size_t spice_marshaller_get_offset(SpiceMarshaller *m)
> -{
> - SpiceMarshaller *m2;
> - size_t offset;
> -
> - offset = 0;
> - m2 = m->data->marshallers;
> - while (m2 != m) {
> - offset += m2->total_size;
> - m2 = m2->next;
> - }
> - return offset - m->data->base;
> -}
> -
> -size_t spice_marshaller_get_size(SpiceMarshaller *m)
> -{
> - return m->total_size;
> -}
> -
> -size_t spice_marshaller_get_total_size(SpiceMarshaller *m)
> -{
> - return m->data->total_size;
> -}
> -
> -void spice_marshaller_flush(SpiceMarshaller *m)
> -{
> - SpiceMarshaller *m2;
> - uint8_t *ptr_pos;
> -
> - /* Only supported for root marshaller */
> - assert(m->data->marshallers == m);
> -
> - for (m2 = m; m2 != NULL; m2 = m2->next) {
> - if (m2->pointer_ref.marshaller != NULL&& m2->total_size> 0) {
> - ptr_pos = lookup_ref(&m2->pointer_ref);
> - if (m2->pointer_ref.is_64bit) {
> - write_uint64(ptr_pos,
> - spice_marshaller_get_offset(m2));
> - } else {
> - write_uint32(ptr_pos,
> - spice_marshaller_get_offset(m2));
> - }
> - }
> - }
> -}
> -
> -#ifndef WIN32
> -int spice_marshaller_fill_iovec(SpiceMarshaller *m, struct iovec *vec,
> - int n_vec, size_t skip_bytes)
> -{
> - MarshallerItem *item;
> - int v, i;
> -
> - /* Only supported for root marshaller */
> - assert(m->data->marshallers == m);
> -
> - v = 0;
> - do {
> - for (i = 0; i< m->n_items; i++) {
> - item =&m->items[i];
> -
> - if (item->len<= skip_bytes) {
> - skip_bytes -= item->len;
> - continue;
> - }
> - if (v == n_vec) {
> - return v; /* Not enough space in vec */
> - }
> - vec[v].iov_base = item->data + skip_bytes;
> - vec[v].iov_len = item->len - skip_bytes;
> - skip_bytes = 0;
> - v++;
> - }
> - m = m->next;
> - } while (m != NULL);
> -
> - return v;
> -}
> -#endif
> -
> -void *spice_marshaller_add_uint64(SpiceMarshaller *m, uint64_t v)
> -{
> - uint8_t *ptr;
> -
> - ptr = spice_marshaller_reserve_space(m, sizeof(uint64_t));
> - write_uint64(ptr, v);
> - return (void *)ptr;
> -}
> -
> -void *spice_marshaller_add_int64(SpiceMarshaller *m, int64_t v)
> -{
> - uint8_t *ptr;
> -
> - ptr = spice_marshaller_reserve_space(m, sizeof(int64_t));
> - write_int64(ptr, v);
> - return (void *)ptr;
> -}
> -
> -void *spice_marshaller_add_uint32(SpiceMarshaller *m, uint32_t v)
> -{
> - uint8_t *ptr;
> -
> - ptr = spice_marshaller_reserve_space(m, sizeof(uint32_t));
> - write_uint32(ptr, v);
> - return (void *)ptr;
> -}
> -
> -void spice_marshaller_set_uint32(SpiceMarshaller *m, void *ref, uint32_t v)
> -{
> - write_uint32((uint8_t *)ref, v);
> -}
> -
> -void *spice_marshaller_add_int32(SpiceMarshaller *m, int32_t v)
> -{
> - uint8_t *ptr;
> -
> - ptr = spice_marshaller_reserve_space(m, sizeof(int32_t));
> - write_int32(ptr, v);
> - return (void *)ptr;
> -}
> -
> -void *spice_marshaller_add_uint16(SpiceMarshaller *m, uint16_t v)
> -{
> - uint8_t *ptr;
> -
> - ptr = spice_marshaller_reserve_space(m, sizeof(uint16_t));
> - write_uint16(ptr, v);
> - return (void *)ptr;
> -}
> -
> -void *spice_marshaller_add_int16(SpiceMarshaller *m, int16_t v)
> -{
> - uint8_t *ptr;
> -
> - ptr = spice_marshaller_reserve_space(m, sizeof(int16_t));
> - write_int16(ptr, v);
> - return (void *)ptr;
> -}
> -
> -void *spice_marshaller_add_uint8(SpiceMarshaller *m, uint8_t v)
> -{
> - uint8_t *ptr;
> -
> - ptr = spice_marshaller_reserve_space(m, sizeof(uint8_t));
> - write_uint8(ptr, v);
> - return (void *)ptr;
> -}
> -
> -void *spice_marshaller_add_int8(SpiceMarshaller *m, int8_t v)
> -{
> - uint8_t *ptr;
> -
> - ptr = spice_marshaller_reserve_space(m, sizeof(int8_t));
> - write_int8(ptr, v);
> - return (void *)ptr;
> -}
> diff --git a/common/marshaller.h b/common/marshaller.h
> deleted file mode 100644
> index ae68e85..0000000
> --- a/common/marshaller.h
> +++ /dev/null
> @@ -1,66 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2010 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H_MARSHALLER
> -#define _H_MARSHALLER
> -
> -#include<spice/types.h>
> -#include "mem.h"
> -#ifndef WIN32
> -#include<sys/uio.h>
> -#endif
> -
> -typedef struct SpiceMarshaller SpiceMarshaller;
> -typedef void (*spice_marshaller_item_free_func)(uint8_t *data, void *opaque);
> -
> -SpiceMarshaller *spice_marshaller_new(void);
> -void spice_marshaller_reset(SpiceMarshaller *m);
> -void spice_marshaller_destroy(SpiceMarshaller *m);
> -uint8_t *spice_marshaller_reserve_space(SpiceMarshaller *m, size_t size);
> -void spice_marshaller_unreserve_space(SpiceMarshaller *m, size_t size);
> -uint8_t *spice_marshaller_add(SpiceMarshaller *m, const uint8_t *data, size_t size);
> -uint8_t *spice_marshaller_add_ref(SpiceMarshaller *m, uint8_t *data, size_t size);
> -uint8_t *spice_marshaller_add_ref_full(SpiceMarshaller *m, uint8_t *data, size_t size,
> - spice_marshaller_item_free_func free_data, void *opaque);
> -void spice_marshaller_add_ref_chunks(SpiceMarshaller *m, SpiceChunks *chunks);
> -void spice_marshaller_flush(SpiceMarshaller *m);
> -void spice_marshaller_set_base(SpiceMarshaller *m, size_t base);
> -uint8_t *spice_marshaller_linearize(SpiceMarshaller *m, size_t skip,
> - size_t *len, int *free_res);
> -uint8_t *spice_marshaller_get_ptr(SpiceMarshaller *m);
> -size_t spice_marshaller_get_offset(SpiceMarshaller *m);
> -size_t spice_marshaller_get_size(SpiceMarshaller *m);
> -size_t spice_marshaller_get_total_size(SpiceMarshaller *m);
> -SpiceMarshaller *spice_marshaller_get_submarshaller(SpiceMarshaller *m);
> -SpiceMarshaller *spice_marshaller_get_ptr_submarshaller(SpiceMarshaller *m, int is_64bit);
> -#ifndef WIN32
> -int spice_marshaller_fill_iovec(SpiceMarshaller *m, struct iovec *vec,
> - int n_vec, size_t skip_bytes);
> -#endif
> -void *spice_marshaller_add_uint64(SpiceMarshaller *m, uint64_t v);
> -void *spice_marshaller_add_int64(SpiceMarshaller *m, int64_t v);
> -void *spice_marshaller_add_uint32(SpiceMarshaller *m, uint32_t v);
> -void *spice_marshaller_add_int32(SpiceMarshaller *m, int32_t v);
> -void *spice_marshaller_add_uint16(SpiceMarshaller *m, uint16_t v);
> -void *spice_marshaller_add_int16(SpiceMarshaller *m, int16_t v);
> -void *spice_marshaller_add_uint8(SpiceMarshaller *m, uint8_t v);
> -void *spice_marshaller_add_int8(SpiceMarshaller *m, int8_t v);
> -
> -void spice_marshaller_set_uint32(SpiceMarshaller *m, void *ref, uint32_t v);
> -
> -#endif
> diff --git a/common/marshallers.h b/common/marshallers.h
> deleted file mode 100644
> index c192d5b..0000000
> --- a/common/marshallers.h
> +++ /dev/null
> @@ -1,74 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2010 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H_MARSHALLERS
> -#define _H_MARSHALLERS
> -
> -#ifdef HAVE_CONFIG_H
> -# include "config.h"
> -#endif
> -
> -#include<spice/protocol.h>
> -#include<marshaller.h>
> -#include<messages.h>
> -
> -typedef struct {
> - void (*msg_SpiceMsgEmpty)(SpiceMarshaller *m, SpiceMsgEmpty *msg);
> - void (*msg_SpiceMsgData)(SpiceMarshaller *m, SpiceMsgData *msg);
> - void (*msg_SpiceMsgAudioVolume)(SpiceMarshaller *m, SpiceMsgAudioVolume *msg);
> - void (*msg_SpiceMsgAudioMute)(SpiceMarshaller *m, SpiceMsgAudioMute *msg);
> - void (*msgc_ack_sync)(SpiceMarshaller *m, SpiceMsgcAckSync *msg);
> - void (*msgc_pong)(SpiceMarshaller *m, SpiceMsgPing *msg);
> - void (*msgc_disconnecting)(SpiceMarshaller *m, SpiceMsgDisconnect *msg);
> - void (*msgc_main_client_info)(SpiceMarshaller *m, SpiceMsgcClientInfo *msg);
> - void (*msgc_main_mouse_mode_request)(SpiceMarshaller *m, SpiceMsgcMainMouseModeRequest *msg);
> - void (*msgc_main_agent_start)(SpiceMarshaller *m, SpiceMsgcMainAgentStart *msg);
> - void (*msgc_main_agent_token)(SpiceMarshaller *m, SpiceMsgcMainAgentTokens *msg);
> - void (*msgc_display_init)(SpiceMarshaller *m, SpiceMsgcDisplayInit *msg);
> - void (*msgc_inputs_key_down)(SpiceMarshaller *m, SpiceMsgcKeyDown *msg);
> - void (*msgc_inputs_key_up)(SpiceMarshaller *m, SpiceMsgcKeyUp *msg);
> - void (*msgc_inputs_key_modifiers)(SpiceMarshaller *m, SpiceMsgcKeyModifiers *msg);
> - void (*msgc_inputs_mouse_motion)(SpiceMarshaller *m, SpiceMsgcMouseMotion *msg);
> - void (*msgc_inputs_mouse_position)(SpiceMarshaller *m, SpiceMsgcMousePosition *msg);
> - void (*msgc_inputs_mouse_press)(SpiceMarshaller *m, SpiceMsgcMousePress *msg);
> - void (*msgc_inputs_mouse_release)(SpiceMarshaller *m, SpiceMsgcMouseRelease *msg);
> - void (*msgc_record_data)(SpiceMarshaller *m, SpiceMsgcRecordPacket *msg);
> - void (*msgc_record_mode)(SpiceMarshaller *m, SpiceMsgcRecordMode *msg);
> - void (*msgc_record_start_mark)(SpiceMarshaller *m, SpiceMsgcRecordStartMark *msg);
> - void (*msgc_tunnel_service_add)(SpiceMarshaller *m, SpiceMsgcTunnelAddGenericService *msg, SpiceMarshaller **name_out, SpiceMarshaller **description_out);
> - void (*msgc_tunnel_service_remove)(SpiceMarshaller *m, SpiceMsgcTunnelRemoveService *msg);
> - void (*msgc_tunnel_socket_open_ack)(SpiceMarshaller *m, SpiceMsgcTunnelSocketOpenAck *msg);
> - void (*msgc_tunnel_socket_open_nack)(SpiceMarshaller *m, SpiceMsgcTunnelSocketOpenNack *msg);
> - void (*msgc_tunnel_socket_fin)(SpiceMarshaller *m, SpiceMsgcTunnelSocketFin *msg);
> - void (*msgc_tunnel_socket_closed)(SpiceMarshaller *m, SpiceMsgcTunnelSocketClosed *msg);
> - void (*msgc_tunnel_socket_closed_ack)(SpiceMarshaller *m, SpiceMsgcTunnelSocketClosedAck *msg);
> - void (*msgc_tunnel_socket_data)(SpiceMarshaller *m, SpiceMsgcTunnelSocketData *msg);
> - void (*msgc_tunnel_socket_token)(SpiceMarshaller *m, SpiceMsgcTunnelSocketTokens *msg);
> -#ifdef USE_SMARTCARD
> - void (*msgc_smartcard_atr)(SpiceMarshaller *m, VSCMsgATR *msg);
> - void (*msgc_smartcard_error)(SpiceMarshaller *m, VSCMsgError *msg);
> - void (*msgc_smartcard_header)(SpiceMarshaller *m, VSCMsgHeader *msg);
> - void (*msgc_smartcard_msg)(SpiceMarshaller *m, SpiceMsgcSmartcard *msg, SpiceMarshaller **reader_name_out);
> - void (*msgc_smartcard_reader_add)(SpiceMarshaller *m, VSCMsgReaderAdd *msg);
> -#endif
> -} SpiceMessageMarshallers;
> -
> -SpiceMessageMarshallers *spice_message_marshallers_get(void);
> -SpiceMessageMarshallers *spice_message_marshallers_get1(void);
> -
> -#endif
> diff --git a/common/mem.c b/common/mem.c
> deleted file mode 100644
> index 4db8a2c..0000000
> --- a/common/mem.c
> +++ /dev/null
> @@ -1,243 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2010 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include "mem.h"
> -#include<stdlib.h>
> -#include<stdio.h>
> -#include<string.h>
> -
> -#ifndef MALLOC_ERROR
> -#define MALLOC_ERROR(format, ...) { \
> - printf(format "\n", ## __VA_ARGS__); \
> - abort(); \
> -}
> -#endif
> -
> -size_t spice_strnlen(const char *str, size_t max_len)
> -{
> - size_t len = 0;
> -
> - while (len< max_len&& *str != 0) {
> - len++;
> - str++;
> - }
> -
> - return len;
> -}
> -
> -char *spice_strdup(const char *str)
> -{
> - char *copy;
> -
> - if (str == NULL) {
> - return NULL;
> - }
> -
> - copy = (char *)spice_malloc(strlen(str) + 1);
> - strcpy(copy, str);
> - return copy;
> -}
> -
> -char *spice_strndup(const char *str, size_t n_bytes)
> -{
> - char *copy;
> -
> - if (str == NULL) {
> - return NULL;
> - }
> -
> - copy = (char *)spice_malloc(n_bytes + 1);
> - strncpy(copy, str, n_bytes);
> - copy[n_bytes] = 0;
> - return copy;
> -}
> -
> -void *spice_memdup(const void *mem, size_t n_bytes)
> -{
> - void *copy;
> -
> - if (mem == NULL) {
> - return NULL;
> - }
> -
> - copy = spice_malloc(n_bytes);
> - memcpy(copy, mem, n_bytes);
> - return copy;
> -}
> -
> -void *spice_malloc(size_t n_bytes)
> -{
> - void *mem;
> -
> - if (SPICE_LIKELY(n_bytes)) {
> - mem = malloc(n_bytes);
> -
> - if (SPICE_LIKELY(mem != NULL)) {
> - return mem;
> - }
> -
> - MALLOC_ERROR("spice_malloc: panic: unable to allocate %lu bytes\n",
> - (unsigned long)n_bytes);
> - }
> - return NULL;
> -}
> -
> -void *spice_malloc0(size_t n_bytes)
> -{
> - void *mem;
> -
> - if (SPICE_LIKELY(n_bytes)) {
> - mem = calloc(1, n_bytes);
> -
> - if (SPICE_LIKELY(mem != NULL)) {
> - return mem;
> - }
> -
> - MALLOC_ERROR("spice_malloc0: panic: unable to allocate %lu bytes\n",
> - (unsigned long)n_bytes);
> - }
> - return NULL;
> -}
> -
> -void *spice_realloc(void *mem, size_t n_bytes)
> -{
> - if (SPICE_LIKELY(n_bytes)) {
> - mem = realloc(mem, n_bytes);
> -
> - if (SPICE_LIKELY(mem != NULL)) {
> - return mem;
> - }
> -
> - MALLOC_ERROR("spice_realloc: panic: unable to allocate %lu bytes\n",
> - (unsigned long)n_bytes);
> - }
> -
> - if (mem) {
> - free(mem);
> - }
> -
> - return NULL;
> -}
> -
> -#define SIZE_OVERFLOWS(a,b) (SPICE_UNLIKELY ((a)> SIZE_MAX / (b)))
> -
> -void *spice_malloc_n(size_t n_blocks, size_t n_block_bytes)
> -{
> - if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) {
> - MALLOC_ERROR("spice_malloc_n: overflow allocating %lu*%lu bytes",
> - (unsigned long)n_blocks, (unsigned long)n_block_bytes);
> - }
> -
> - return spice_malloc(n_blocks * n_block_bytes);
> -}
> -
> -void *spice_malloc_n_m(size_t n_blocks, size_t n_block_bytes, size_t extra_size)
> -{
> - size_t size1, size2;
> - if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) {
> - MALLOC_ERROR("spice_malloc_n: overflow allocating %lu*%lu + %lubytes",
> - (unsigned long)n_blocks, (unsigned long)n_block_bytes, (unsigned long)extra_size);
> - }
> - size1 = n_blocks * n_block_bytes;
> - size2 = size1 + extra_size;
> - if (size2< size1) {
> - MALLOC_ERROR("spice_malloc_n: overflow allocating %lu*%lu + %lubytes",
> - (unsigned long)n_blocks, (unsigned long)n_block_bytes, (unsigned long)extra_size);
> - }
> - return spice_malloc(size2);
> -}
> -
> -
> -void *spice_malloc0_n(size_t n_blocks, size_t n_block_bytes)
> -{
> - if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) {
> - MALLOC_ERROR("spice_malloc0_n: overflow allocating %lu*%lu bytes",
> - (unsigned long)n_blocks, (unsigned long)n_block_bytes);
> - }
> -
> - return spice_malloc0 (n_blocks * n_block_bytes);
> -}
> -
> -void *spice_realloc_n(void *mem, size_t n_blocks, size_t n_block_bytes)
> -{
> - if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) {
> - MALLOC_ERROR("spice_realloc_n: overflow allocating %lu*%lu bytes",
> - (unsigned long)n_blocks, (unsigned long)n_block_bytes);
> - }
> -
> - return spice_realloc(mem, n_blocks * n_block_bytes);
> -}
> -
> -SpiceChunks *spice_chunks_new(uint32_t count)
> -{
> - SpiceChunks *chunks;
> -
> - chunks = (SpiceChunks *)spice_malloc_n_m(count, sizeof(SpiceChunk), sizeof(SpiceChunks));
> - chunks->flags = 0;
> - chunks->num_chunks = count;
> -
> - return chunks;
> -}
> -
> -SpiceChunks *spice_chunks_new_linear(uint8_t *data, uint32_t len)
> -{
> - SpiceChunks *chunks;
> -
> - chunks = spice_chunks_new(1);
> - chunks->data_size = chunks->chunk[0].len = len;
> - chunks->chunk[0].data = data;
> - return chunks;
> -}
> -
> -void spice_chunks_destroy(SpiceChunks *chunks)
> -{
> - unsigned int i;
> -
> - if (chunks->flags& SPICE_CHUNKS_FLAGS_FREE) {
> - for (i = 0; i< chunks->num_chunks; i++) {
> - free(chunks->chunk[i].data);
> - }
> - }
> -
> - free(chunks);
> -}
> -
> -void spice_chunks_linearize(SpiceChunks *chunks)
> -{
> - uint8_t *data, *p;
> - unsigned int i;
> -
> - if (chunks->num_chunks> 1) {
> - data = (uint8_t*)spice_malloc(chunks->data_size);
> - for (p = data, i = 0; i< chunks->num_chunks; i++) {
> - memcpy(p, chunks->chunk[i].data,
> - chunks->chunk[i].len);
> - p += chunks->chunk[i].len;
> - }
> - if (chunks->flags& SPICE_CHUNKS_FLAGS_FREE) {
> - for (i = 0; i< chunks->num_chunks; i++) {
> - free(chunks->chunk[i].data);
> - }
> - }
> - chunks->num_chunks = 1;
> - chunks->flags |= SPICE_CHUNKS_FLAGS_FREE;
> - chunks->flags&= ~SPICE_CHUNKS_FLAGS_UNSTABLE;
> - chunks->chunk[0].data = data;
> - chunks->chunk[0].len = chunks->data_size;
> - }
> -}
> diff --git a/common/mem.h b/common/mem.h
> deleted file mode 100644
> index 6863953..0000000
> --- a/common/mem.h
> +++ /dev/null
> @@ -1,129 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2010 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H_MEM
> -#define _H_MEM
> -
> -#include<stdlib.h>
> -#include<spice/macros.h>
> -
> -/* alloca definition from glib/galloca.h */
> -#ifdef __GNUC__
> -/* GCC does the right thing */
> -# undef alloca
> -# define alloca(size) __builtin_alloca (size)
> -#elif defined (GLIB_HAVE_ALLOCA_H)
> -/* a native and working alloca.h is there */
> -# include<alloca.h>
> -#else /* !__GNUC__&& !GLIB_HAVE_ALLOCA_H */
> -# if defined(_MSC_VER) || defined(__DMC__)
> -# include<malloc.h>
> -# define alloca _alloca
> -# else /* !_MSC_VER&& !__DMC__ */
> -# ifdef _AIX
> -# pragma alloca
> -# else /* !_AIX */
> -# ifndef alloca /* predefined by HP cc +Olibcalls */
> -char *alloca ();
> -# endif /* !alloca */
> -# endif /* !_AIX */
> -# endif /* !_MSC_VER&& !__DMC__ */
> -#endif /* !__GNUC__&& !GLIB_HAVE_ALLOCA_H */
> -
> -typedef struct SpiceChunk {
> - uint8_t *data;
> - uint32_t len;
> -} SpiceChunk;
> -
> -enum {
> - SPICE_CHUNKS_FLAGS_UNSTABLE = (1<<0),
> - SPICE_CHUNKS_FLAGS_FREE = (1<<1)
> -};
> -
> -typedef struct SpiceChunks {
> - uint32_t data_size;
> - uint32_t num_chunks;
> - uint32_t flags;
> - SpiceChunk chunk[0];
> -} SpiceChunks;
> -
> -char *spice_strdup(const char *str) SPICE_GNUC_MALLOC;
> -char *spice_strndup(const char *str, size_t n_bytes) SPICE_GNUC_MALLOC;
> -void *spice_memdup(const void *mem, size_t n_bytes) SPICE_GNUC_MALLOC;
> -void *spice_malloc(size_t n_bytes) SPICE_GNUC_MALLOC SPICE_GNUC_ALLOC_SIZE(1);
> -void *spice_malloc0(size_t n_bytes) SPICE_GNUC_MALLOC SPICE_GNUC_ALLOC_SIZE(1);
> -void *spice_realloc(void *mem, size_t n_bytes) SPICE_GNUC_WARN_UNUSED_RESULT;
> -void *spice_malloc_n(size_t n_blocks, size_t n_block_bytes) SPICE_GNUC_MALLOC SPICE_GNUC_ALLOC_SIZE2(1,2);
> -void *spice_malloc_n_m(size_t n_blocks, size_t n_block_bytes, size_t extra_size) SPICE_GNUC_MALLOC;
> -void *spice_malloc0_n(size_t n_blocks, size_t n_block_bytes) SPICE_GNUC_MALLOC SPICE_GNUC_ALLOC_SIZE2(1,2);
> -void *spice_realloc_n(void *mem, size_t n_blocks, size_t n_block_bytes) SPICE_GNUC_WARN_UNUSED_RESULT;
> -SpiceChunks *spice_chunks_new(uint32_t count) SPICE_GNUC_MALLOC;
> -SpiceChunks *spice_chunks_new_linear(uint8_t *data, uint32_t len) SPICE_GNUC_MALLOC;
> -void spice_chunks_destroy(SpiceChunks *chunks);
> -void spice_chunks_linearize(SpiceChunks *chunks);
> -
> -size_t spice_strnlen(const char *str, size_t max_len);
> -
> -/* Optimize: avoid the call to the (slower) _n function if we can
> - * determine at compile-time that no overflow happens.
> - */
> -#if defined (__GNUC__)&& (__GNUC__>= 2)&& defined (__OPTIMIZE__)
> -# define _SPICE_NEW(struct_type, n_structs, func) \
> - (struct_type *) (__extension__ ({ \
> - size_t __n = (size_t) (n_structs); \
> - size_t __s = sizeof (struct_type); \
> - void *__p; \
> - if (__s == 1) \
> - __p = spice_##func (__n); \
> - else if (__builtin_constant_p (__n)&& \
> - __n<= SIZE_MAX / __s) \
> - __p = spice_##func (__n * __s); \
> - else \
> - __p = spice_##func##_n (__n, __s); \
> - __p; \
> - }))
> -# define _SPICE_RENEW(struct_type, mem, n_structs, func) \
> - (struct_type *) (__extension__ ({ \
> - size_t __n = (size_t) (n_structs); \
> - size_t __s = sizeof (struct_type); \
> - void *__p = (void *) (mem); \
> - if (__s == 1) \
> - __p = spice_##func (__p, __n); \
> - else if (__builtin_constant_p (__n)&& \
> - __n<= SIZE_MAX / __s) \
> - __p = spice_##func (__p, __n * __s); \
> - else \
> - __p = spice_##func##_n (__p, __n, __s); \
> - __p; \
> - }))
> -#else
> -
> -/* Unoptimized version: always call the _n() function. */
> -
> -#define _SPICE_NEW(struct_type, n_structs, func) \
> - ((struct_type *) spice_##func##_n ((n_structs), sizeof (struct_type)))
> -#define _SPICE_RENEW(struct_type, mem, n_structs, func) \
> - ((struct_type *) spice_##func##_n (mem, (n_structs), sizeof (struct_type)))
> -
> -#endif
> -
> -#define spice_new(struct_type, n_structs) _SPICE_NEW(struct_type, n_structs, malloc)
> -#define spice_new0(struct_type, n_structs) _SPICE_NEW(struct_type, n_structs, malloc0)
> -#define spice_renew(struct_type, mem, n_structs) _SPICE_RENEW(struct_type, mem, n_structs, realloc)
> -
> -#endif
> diff --git a/common/messages.h b/common/messages.h
> deleted file mode 100644
> index 01689cd..0000000
> --- a/common/messages.h
> +++ /dev/null
> @@ -1,550 +0,0 @@
> -/*
> - Copyright (C) 2009-2010 Red Hat, Inc.
> -
> - Redistribution and use in source and binary forms, with or without
> - modification, are permitted provided that the following conditions are
> - met:
> -
> - * Redistributions of source code must retain the above copyright
> - notice, this list of conditions and the following disclaimer.
> - * Redistributions in binary form must reproduce the above copyright
> - notice, this list of conditions and the following disclaimer in
> - the documentation and/or other materials provided with the
> - distribution.
> - * Neither the name of the copyright holder nor the names of its
> - contributors may be used to endorse or promote products derived
> - from this software without specific prior written permission.
> -
> - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
> - IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
> - TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> -*/
> -
> -#ifndef _H_MESSAGES
> -#define _H_MESSAGES
> -
> -#ifdef HAVE_CONFIG_H
> -# include "config.h"
> -#endif
> -
> -#include<spice/protocol.h>
> -#ifdef USE_SMARTCARD
> -#include<vscard_common.h>
> -#endif
> -#include "draw.h"
> -
> -#ifdef __cplusplus
> -extern "C" {
> -#endif
> -
> -typedef struct SpiceMsgData {
> - uint32_t data_size;
> - uint8_t data[0];
> -} SpiceMsgData;
> -
> -typedef struct SpiceMsgEmpty {
> -} SpiceMsgEmpty;
> -
> -typedef struct SpiceMsgInputsInit {
> - uint32_t keyboard_modifiers;
> -} SpiceMsgInputsInit;
> -
> -typedef struct SpiceMsgInputsKeyModifiers {
> - uint32_t modifiers;
> -} SpiceMsgInputsKeyModifiers;
> -
> -typedef struct SpiceMsgMainMultiMediaTime {
> - uint32_t time;
> -} SpiceMsgMainMultiMediaTime;
> -
> -typedef struct SpiceMsgMainMigrationBegin {
> - uint16_t port;
> - uint16_t sport;
> - uint32_t host_size;
> - uint8_t *host_data;
> - uint16_t pub_key_type;
> - uint32_t pub_key_size;
> - uint8_t *pub_key_data;
> - uint32_t cert_subject_size;
> - uint8_t *cert_subject_data;
> -} SpiceMsgMainMigrationBegin;
> -
> -typedef struct SpiceMsgMainMigrationSwitchHost {
> - uint16_t port;
> - uint16_t sport;
> - uint32_t host_size;
> - uint8_t *host_data;
> - uint32_t cert_subject_size;
> - uint8_t *cert_subject_data;
> -} SpiceMsgMainMigrationSwitchHost;
> -
> -
> -typedef struct SpiceMsgMigrate {
> - uint32_t flags;
> -} SpiceMsgMigrate;
> -
> -typedef struct SpiceResourceID {
> - uint8_t type;
> - uint64_t id;
> -} SpiceResourceID;
> -
> -typedef struct SpiceResourceList {
> - uint16_t count;
> - SpiceResourceID resources[0];
> -} SpiceResourceList;
> -
> -typedef struct SpiceMsgSetAck {
> - uint32_t generation;
> - uint32_t window;
> -} SpiceMsgSetAck;
> -
> -typedef struct SpiceMsgcAckSync {
> - uint32_t generation;
> -} SpiceMsgcAckSync;
> -
> -typedef struct SpiceWaitForChannel {
> - uint8_t channel_type;
> - uint8_t channel_id;
> - uint64_t message_serial;
> -} SpiceWaitForChannel;
> -
> -typedef struct SpiceMsgWaitForChannels {
> - uint8_t wait_count;
> - SpiceWaitForChannel wait_list[0];
> -} SpiceMsgWaitForChannels;
> -
> -typedef struct SpiceChannelId {
> - uint8_t type;
> - uint8_t id;
> -} SpiceChannelId;
> -
> -typedef struct SpiceMsgMainInit {
> - uint32_t session_id;
> - uint32_t display_channels_hint;
> - uint32_t supported_mouse_modes;
> - uint32_t current_mouse_mode;
> - uint32_t agent_connected;
> - uint32_t agent_tokens;
> - uint32_t multi_media_time;
> - uint32_t ram_hint;
> -} SpiceMsgMainInit;
> -
> -typedef struct SpiceMsgDisconnect {
> - uint64_t time_stamp;
> - uint32_t reason; // SPICE_ERR_?
> -} SpiceMsgDisconnect;
> -
> -typedef struct SpiceMsgNotify {
> - uint64_t time_stamp;
> - uint32_t severity;
> - uint32_t visibilty;
> - uint32_t what;
> - uint32_t message_len;
> - uint8_t message[0];
> -} SpiceMsgNotify;
> -
> -typedef struct SpiceMsgChannels {
> - uint32_t num_of_channels;
> - SpiceChannelId channels[0];
> -} SpiceMsgChannels;
> -
> -typedef struct SpiceMsgMainName {
> - uint32_t name_len;
> - uint8_t name[0];
> -} SpiceMsgMainName;
> -
> -typedef struct SpiceMsgMainUuid {
> - uint8_t uuid[16];
> -} SpiceMsgMainUuid;
> -
> -typedef struct SpiceMsgMainMouseMode {
> - uint32_t supported_modes;
> - uint32_t current_mode;
> -} SpiceMsgMainMouseMode;
> -
> -typedef struct SpiceMsgPing {
> - uint32_t id;
> - uint64_t timestamp;
> - void *data;
> - uint32_t data_len;
> -} SpiceMsgPing;
> -
> -typedef struct SpiceMsgMainAgentDisconnect {
> - uint32_t error_code; // SPICE_ERR_?
> -} SpiceMsgMainAgentDisconnect;
> -
> -#define SPICE_AGENT_MAX_DATA_SIZE 2048
> -
> -typedef struct SpiceMsgMainAgentTokens {
> - uint32_t num_tokens;
> -} SpiceMsgMainAgentTokens, SpiceMsgcMainAgentTokens, SpiceMsgcMainAgentStart;
> -
> -typedef struct SpiceMsgcClientInfo {
> - uint64_t cache_size;
> -} SpiceMsgcClientInfo;
> -
> -typedef struct SpiceMsgcMainMouseModeRequest {
> - uint32_t mode;
> -} SpiceMsgcMainMouseModeRequest;
> -
> -typedef struct SpiceCursor {
> - uint32_t flags;
> - SpiceCursorHeader header;
> - uint32_t data_size;
> - uint8_t *data;
> -} SpiceCursor;
> -
> -typedef struct SpiceMsgDisplayMode {
> - uint32_t x_res;
> - uint32_t y_res;
> - uint32_t bits;
> -} SpiceMsgDisplayMode;
> -
> -typedef struct SpiceMsgSurfaceCreate {
> - uint32_t surface_id;
> - uint32_t width;
> - uint32_t height;
> - uint32_t format;
> - uint32_t flags;
> -} SpiceMsgSurfaceCreate;
> -
> -typedef struct SpiceMsgSurfaceDestroy {
> - uint32_t surface_id;
> -} SpiceMsgSurfaceDestroy;
> -
> -typedef struct SpiceMsgDisplayBase {
> - uint32_t surface_id;
> - SpiceRect box;
> - SpiceClip clip;
> -} SpiceMsgDisplayBase;
> -
> -typedef struct SpiceMsgDisplayDrawFill {
> - SpiceMsgDisplayBase base;
> - SpiceFill data;
> -} SpiceMsgDisplayDrawFill;
> -
> -typedef struct SpiceMsgDisplayDrawOpaque {
> - SpiceMsgDisplayBase base;
> - SpiceOpaque data;
> -} SpiceMsgDisplayDrawOpaque;
> -
> -typedef struct SpiceMsgDisplayDrawCopy {
> - SpiceMsgDisplayBase base;
> - SpiceCopy data;
> -} SpiceMsgDisplayDrawCopy;
> -
> -typedef struct SpiceMsgDisplayDrawTransparent {
> - SpiceMsgDisplayBase base;
> - SpiceTransparent data;
> -} SpiceMsgDisplayDrawTransparent;
> -
> -typedef struct SpiceMsgDisplayDrawAlphaBlend {
> - SpiceMsgDisplayBase base;
> - SpiceAlphaBlend data;
> -} SpiceMsgDisplayDrawAlphaBlend;
> -
> -typedef struct SpiceMsgDisplayCopyBits {
> - SpiceMsgDisplayBase base;
> - SpicePoint src_pos;
> -} SpiceMsgDisplayCopyBits;
> -
> -typedef SpiceMsgDisplayDrawCopy SpiceMsgDisplayDrawBlend;
> -
> -typedef struct SpiceMsgDisplayDrawRop3 {
> - SpiceMsgDisplayBase base;
> - SpiceRop3 data;
> -} SpiceMsgDisplayDrawRop3;
> -
> -typedef struct SpiceMsgDisplayDrawBlackness {
> - SpiceMsgDisplayBase base;
> - SpiceBlackness data;
> -} SpiceMsgDisplayDrawBlackness;
> -
> -typedef struct SpiceMsgDisplayDrawWhiteness {
> - SpiceMsgDisplayBase base;
> - SpiceWhiteness data;
> -} SpiceMsgDisplayDrawWhiteness;
> -
> -typedef struct SpiceMsgDisplayDrawInvers {
> - SpiceMsgDisplayBase base;
> - SpiceInvers data;
> -} SpiceMsgDisplayDrawInvers;
> -
> -typedef struct SpiceMsgDisplayDrawStroke {
> - SpiceMsgDisplayBase base;
> - SpiceStroke data;
> -} SpiceMsgDisplayDrawStroke;
> -
> -typedef struct SpiceMsgDisplayDrawText {
> - SpiceMsgDisplayBase base;
> - SpiceText data;
> -} SpiceMsgDisplayDrawText;
> -
> -typedef struct SpiceMsgDisplayInvalOne {
> - uint64_t id;
> -} SpiceMsgDisplayInvalOne;
> -
> -typedef struct SpiceMsgDisplayStreamCreate {
> - uint32_t surface_id;
> - uint32_t id;
> - uint32_t flags;
> - uint32_t codec_type;
> - uint64_t stamp;
> - uint32_t stream_width;
> - uint32_t stream_height;
> - uint32_t src_width;
> - uint32_t src_height;
> - SpiceRect dest;
> - SpiceClip clip;
> -} SpiceMsgDisplayStreamCreate;
> -
> -typedef struct SpiceMsgDisplayStreamData {
> - uint32_t id;
> - uint32_t multi_media_time;
> - uint32_t data_size;
> - uint8_t data[0];
> -} SpiceMsgDisplayStreamData;
> -
> -typedef struct SpiceMsgDisplayStreamClip {
> - uint32_t id;
> - SpiceClip clip;
> -} SpiceMsgDisplayStreamClip;
> -
> -typedef struct SpiceMsgDisplayStreamDestroy {
> - uint32_t id;
> -} SpiceMsgDisplayStreamDestroy;
> -
> -typedef struct SpiceMsgCursorInit {
> - SpicePoint16 position;
> - uint16_t trail_length;
> - uint16_t trail_frequency;
> - uint8_t visible;
> - SpiceCursor cursor;
> -} SpiceMsgCursorInit;
> -
> -typedef struct SpiceMsgCursorSet {
> - SpicePoint16 position;
> - uint8_t visible;
> - SpiceCursor cursor;
> -} SpiceMsgCursorSet;
> -
> -typedef struct SpiceMsgCursorMove {
> - SpicePoint16 position;
> -} SpiceMsgCursorMove;
> -
> -typedef struct SpiceMsgCursorTrail {
> - uint16_t length;
> - uint16_t frequency;
> -} SpiceMsgCursorTrail;
> -
> -typedef struct SpiceMsgcDisplayInit {
> - uint8_t pixmap_cache_id;
> - int64_t pixmap_cache_size; //in pixels
> - uint8_t glz_dictionary_id;
> - int32_t glz_dictionary_window_size; // in pixels
> -} SpiceMsgcDisplayInit;
> -
> -typedef struct SpiceMsgcKeyDown {
> - uint32_t code;
> -} SpiceMsgcKeyDown;
> -
> -typedef struct SpiceMsgcKeyUp {
> - uint32_t code;
> -} SpiceMsgcKeyUp;
> -
> -typedef struct SpiceMsgcKeyModifiers {
> - uint32_t modifiers;
> -} SpiceMsgcKeyModifiers;
> -
> -typedef struct SpiceMsgcMouseMotion {
> - int32_t dx;
> - int32_t dy;
> - uint32_t buttons_state;
> -} SpiceMsgcMouseMotion;
> -
> -typedef struct SpiceMsgcMousePosition {
> - uint32_t x;
> - uint32_t y;
> - uint32_t buttons_state;
> - uint8_t display_id;
> -} SpiceMsgcMousePosition;
> -
> -typedef struct SpiceMsgcMousePress {
> - int32_t button;
> - int32_t buttons_state;
> -} SpiceMsgcMousePress;
> -
> -typedef struct SpiceMsgcMouseRelease {
> - int32_t button;
> - int32_t buttons_state;
> -} SpiceMsgcMouseRelease;
> -
> -typedef struct SpiceMsgAudioVolume {
> - uint8_t nchannels;
> - uint16_t volume[0];
> -} SpiceMsgAudioVolume;
> -
> -typedef struct SpiceMsgAudioMute {
> - uint8_t mute;
> -} SpiceMsgAudioMute;
> -
> -typedef struct SpiceMsgPlaybackMode {
> - uint32_t time;
> - uint32_t mode; //SPICE_AUDIO_DATA_MODE_?
> - uint8_t *data;
> - uint32_t data_size;
> -} SpiceMsgPlaybackMode, SpiceMsgcRecordMode;
> -
> -typedef struct SpiceMsgPlaybackStart {
> - uint32_t channels;
> - uint32_t format; //SPICE_AUDIO_FMT_?
> - uint32_t frequency;
> - uint32_t time;
> -} SpiceMsgPlaybackStart;
> -
> -typedef struct SpiceMsgPlaybackPacket {
> - uint32_t time;
> - uint8_t *data;
> - uint32_t data_size;
> -} SpiceMsgPlaybackPacket, SpiceMsgcRecordPacket;
> -
> -typedef struct SpiceMsgRecordStart {
> - uint32_t channels;
> - uint32_t format; //SPICE_AUDIO_FMT_?
> - uint32_t frequency;
> -} SpiceMsgRecordStart;
> -
> -typedef struct SpiceMsgcRecordStartMark {
> - uint32_t time;
> -} SpiceMsgcRecordStartMark;
> -
> -typedef struct SpiceMsgTunnelInit {
> - uint16_t max_num_of_sockets;
> - uint32_t max_socket_data_size;
> -} SpiceMsgTunnelInit;
> -
> -typedef uint8_t SpiceTunnelIPv4[4];
> -
> -typedef struct SpiceMsgTunnelIpInfo {
> - uint16_t type;
> - union {
> - SpiceTunnelIPv4 ipv4;
> - } u;
> - uint8_t data[0];
> -} SpiceMsgTunnelIpInfo;
> -
> -typedef struct SpiceMsgTunnelServiceIpMap {
> - uint32_t service_id;
> - SpiceMsgTunnelIpInfo virtual_ip;
> -} SpiceMsgTunnelServiceIpMap;
> -
> -typedef struct SpiceMsgTunnelSocketOpen {
> - uint16_t connection_id;
> - uint32_t service_id;
> - uint32_t tokens;
> -} SpiceMsgTunnelSocketOpen;
> -
> -/* connection id must be the first field in msgs directed to a specific connection */
> -
> -typedef struct SpiceMsgTunnelSocketFin {
> - uint16_t connection_id;
> -} SpiceMsgTunnelSocketFin;
> -
> -typedef struct SpiceMsgTunnelSocketClose {
> - uint16_t connection_id;
> -} SpiceMsgTunnelSocketClose;
> -
> -typedef struct SpiceMsgTunnelSocketData {
> - uint16_t connection_id;
> - uint8_t data[0];
> -} SpiceMsgTunnelSocketData;
> -
> -typedef struct SpiceMsgTunnelSocketTokens {
> - uint16_t connection_id;
> - uint32_t num_tokens;
> -} SpiceMsgTunnelSocketTokens;
> -
> -typedef struct SpiceMsgTunnelSocketClosedAck {
> - uint16_t connection_id;
> -} SpiceMsgTunnelSocketClosedAck;
> -
> -typedef struct SpiceMsgcTunnelAddGenericService {
> - uint32_t type;
> - uint32_t id;
> - uint32_t group;
> - uint32_t port;
> - uint64_t name;
> - uint64_t description;
> - union {
> - SpiceMsgTunnelIpInfo ip;
> - } u;
> -} SpiceMsgcTunnelAddGenericService;
> -
> -typedef struct SpiceMsgcTunnelRemoveService {
> - uint32_t id;
> -} SpiceMsgcTunnelRemoveService;
> -
> -/* connection id must be the first field in msgs directed to a specific connection */
> -
> -typedef struct SpiceMsgcTunnelSocketOpenAck {
> - uint16_t connection_id;
> - uint32_t tokens;
> -} SpiceMsgcTunnelSocketOpenAck;
> -
> -typedef struct SpiceMsgcTunnelSocketOpenNack {
> - uint16_t connection_id;
> -} SpiceMsgcTunnelSocketOpenNack;
> -
> -typedef struct SpiceMsgcTunnelSocketData {
> - uint16_t connection_id;
> - uint8_t data[0];
> -} SpiceMsgcTunnelSocketData;
> -
> -typedef struct SpiceMsgcTunnelSocketFin {
> - uint16_t connection_id;
> -} SpiceMsgcTunnelSocketFin;
> -
> -typedef struct SpiceMsgcTunnelSocketClosed {
> - uint16_t connection_id;
> -} SpiceMsgcTunnelSocketClosed;
> -
> -typedef struct SpiceMsgcTunnelSocketClosedAck {
> - uint16_t connection_id;
> -} SpiceMsgcTunnelSocketClosedAck;
> -
> -typedef struct SpiceMsgcTunnelSocketTokens {
> - uint16_t connection_id;
> - uint32_t num_tokens;
> -} SpiceMsgcTunnelSocketTokens;
> -
> -#ifdef USE_SMARTCARD
> -typedef struct SpiceMsgSmartcard {
> - VSCMsgType type;
> - uint32_t length;
> - uint32_t reader_id;
> - uint8_t data[0];
> -} SpiceMsgSmartcard;
> -
> -typedef struct SpiceMsgcSmartcard {
> - VSCMsgHeader header;
> - union {
> - VSCMsgError error;
> - VSCMsgATR atr_data;
> - VSCMsgReaderAdd add;
> - };
> -} SpiceMsgcSmartcard;
> -#endif
> -
> -#ifdef __cplusplus
> -}
> -#endif
> -
> -#endif /* _H_SPICE_PROTOCOL */
> diff --git a/common/mutex.h b/common/mutex.h
> deleted file mode 100644
> index a2d35de..0000000
> --- a/common/mutex.h
> +++ /dev/null
> @@ -1,35 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H_MUTEX
> -#define _H_MUTEX
> -#ifdef _WIN32
> -#include<windows.h>
> -typedef CRITICAL_SECTION mutex_t;
> -#define MUTEX_INIT(mutex) InitializeCriticalSection(&mutex)
> -#define MUTEX_LOCK(mutex) EnterCriticalSection(&mutex)
> -#define MUTEX_UNLOCK(mutex) LeaveCriticalSection(&mutex)
> -#else
> -#include<pthread.h>
> -typedef pthread_mutex_t mutex_t;
> -#define MUTEX_INIT(mutex) pthread_mutex_init(&mutex, NULL);
> -#define MUTEX_LOCK(mutex) pthread_mutex_lock(&mutex)
> -#define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(&mutex)
> -#endif
> -
> -#endif // _H_MUTEX
> diff --git a/common/ogl_ctx.c b/common/ogl_ctx.c
> deleted file mode 100644
> index ae25c2d..0000000
> --- a/common/ogl_ctx.c
> +++ /dev/null
> @@ -1,254 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include<stdlib.h>
> -#include<stdio.h>
> -#include<X11/Xlib.h>
> -#include<GL/glx.h>
> -
> -#include "ogl_ctx.h"
> -
> -
> -#define PANIC(str) { \
> - printf("%s: panic: %s", __FUNCTION__, str); \
> - abort(); \
> -}
> -
> -enum {
> - OGLCTX_TYPE_PBUF,
> - OGLCTX_TYPE_PIXMAP,
> -};
> -
> -struct OGLCtx {
> - int type;
> - Display *x_display;
> - GLXContext glx_context;
> - GLXDrawable drawable;
> -};
> -
> -typedef struct OGLPixmapCtx {
> - OGLCtx base;
> - Pixmap pixmap;
> -} OGLPixmapCtx;
> -
> -
> -
> -const char *oglctx_type_str(OGLCtx *ctx)
> -{
> - static const char *pbuf_str = "pbuf";
> - static const char *pixmap_str = "pixmap";
> - static const char *invalid_str = "invalid";
> -
> - switch (ctx->type) {
> - case OGLCTX_TYPE_PBUF:
> - return pbuf_str;
> - case OGLCTX_TYPE_PIXMAP:
> - return pixmap_str;
> - default:
> - return invalid_str;
> - }
> -}
> -
> -void oglctx_make_current(OGLCtx *ctx)
> -{
> - if (!glXMakeCurrent(ctx->x_display, ctx->drawable, ctx->glx_context)) {
> - printf("%s: failed\n", __FUNCTION__);
> - }
> -}
> -
> -OGLCtx *pbuf_create(int width, int heigth)
> -{
> - OGLCtx *ctx;
> - Display *x_display;
> - int num_configs;
> - GLXFBConfig *fb_config;
> - GLXPbuffer glx_pbuf;
> - GLXContext glx_context;
> -
> - const int glx_attributes[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT,
> - GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
> - GLX_RED_SIZE, 8,
> - GLX_GREEN_SIZE, 8,
> - GLX_BLUE_SIZE, 8,
> - GLX_ALPHA_SIZE, 8,
> - GLX_STENCIL_SIZE, 4,
> - 0 };
> -
> - int pbuf_attrib[] = { GLX_PRESERVED_CONTENTS, True,
> - GLX_PBUFFER_WIDTH, width,
> - GLX_PBUFFER_HEIGHT, heigth,
> - GLX_LARGEST_PBUFFER, False,
> - 0, 0 };
> -
> - if (!(ctx = calloc(1, sizeof(*ctx)))) {
> - printf("%s: alloc pbuf failed\n", __FUNCTION__);
> - return NULL;
> - }
> -
> - if (!(x_display = XOpenDisplay(NULL))) {
> - printf("%s: open display failed\n", __FUNCTION__);
> - goto error_1;
> - }
> -
> - if (!(fb_config = glXChooseFBConfig(x_display, 0, glx_attributes,&num_configs)) ||
> - !num_configs) {
> - printf("%s: choose fb config failed\n", __FUNCTION__);
> - goto error_2;
> - }
> -
> - if (!(glx_pbuf = glXCreatePbuffer(x_display, fb_config[0], pbuf_attrib))) {
> - goto error_3;
> - }
> -
> - if (!(glx_context = glXCreateNewContext(x_display, fb_config[0], GLX_RGBA_TYPE, NULL, True))) {
> - printf("%s: create context failed\n", __FUNCTION__);
> - goto error_4;
> - }
> -
> - XFree(fb_config);
> -
> - ctx->type = OGLCTX_TYPE_PBUF;
> - ctx->drawable = glx_pbuf;
> - ctx->glx_context = glx_context;
> - ctx->x_display = x_display;
> -
> - return ctx;
> -
> -error_4:
> - glXDestroyPbuffer(x_display, glx_pbuf);
> -
> -error_3:
> - XFree(fb_config);
> -
> -error_2:
> - XCloseDisplay(x_display);
> -
> -error_1:
> - free(ctx);
> -
> - return NULL;
> -}
> -
> -OGLCtx *pixmap_create(int width, int heigth)
> -{
> - Display *x_display;
> - int num_configs;
> - GLXFBConfig *fb_config;
> - GLXPixmap glx_pixmap;
> - GLXContext glx_context;
> - Pixmap pixmap;
> - int screen;
> - Window root_window;
> - OGLPixmapCtx *pix;
> -
> - const int glx_attributes[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT,
> - GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
> - GLX_RED_SIZE, 8,
> - GLX_GREEN_SIZE, 8,
> - GLX_BLUE_SIZE, 8,
> - GLX_ALPHA_SIZE, 8,
> - GLX_STENCIL_SIZE, 4,
> - 0 };
> -
> - if (!(pix = calloc(1, sizeof(*pix)))) {
> - printf("%s: alloc pix failed\n", __FUNCTION__);
> - return NULL;
> - }
> -
> - if (!(x_display = XOpenDisplay(NULL))) {
> - printf("%s: open display failed\n", __FUNCTION__);
> - goto error_1;
> - }
> -
> - screen = DefaultScreen(x_display);
> - root_window = RootWindow(x_display, screen);
> -
> - if (!(fb_config = glXChooseFBConfig(x_display, 0, glx_attributes,&num_configs)) ||
> - !num_configs) {
> - printf("%s: choose fb config failed\n", __FUNCTION__);
> - goto error_2;
> - }
> -
> - if (!(pixmap = XCreatePixmap(x_display, root_window, width, heigth, 32 /*use fb config*/))) {
> - printf("%s: create x pixmap failed\n", __FUNCTION__);
> - goto error_3;
> - }
> -
> - if (!(glx_pixmap = glXCreatePixmap(x_display, fb_config[0], pixmap, NULL))) {
> - printf("%s: create glx pixmap failed\n", __FUNCTION__);
> - goto error_4;
> - }
> -
> -
> - if (!(glx_context = glXCreateNewContext(x_display, fb_config[0], GLX_RGBA_TYPE, NULL, True))) {
> - printf("%s: create context failed\n", __FUNCTION__);
> - goto error_5;
> - }
> -
> - XFree(fb_config);
> -
> - pix->base.type = OGLCTX_TYPE_PIXMAP;
> - pix->base.x_display = x_display;
> - pix->base.drawable = glx_pixmap;
> - pix->base.glx_context = glx_context;
> - pix->pixmap = pixmap;
> -
> - return&pix->base;
> -
> -error_5:
> - glXDestroyPixmap(x_display, glx_pixmap);
> -
> -error_4:
> - XFreePixmap(x_display, pixmap);
> -
> -error_3:
> - XFree(fb_config);
> -
> -error_2:
> - XCloseDisplay(x_display);
> -
> -error_1:
> - free(pix);
> -
> - return NULL;
> -}
> -
> -void oglctx_destroy(OGLCtx *ctx)
> -{
> - if (!ctx) {
> - return;
> - }
> - // test is current ?
> -
> - glXDestroyContext(ctx->x_display, ctx->glx_context);
> - switch (ctx->type) {
> - case OGLCTX_TYPE_PBUF:
> - glXDestroyPbuffer(ctx->x_display, ctx->drawable);
> - break;
> - case OGLCTX_TYPE_PIXMAP:
> - glXDestroyPixmap(ctx->x_display, ctx->drawable);
> - XFreePixmap(ctx->x_display, ((OGLPixmapCtx *)ctx)->pixmap);
> - break;
> - default:
> - PANIC("invalid ogl ctx type");
> - }
> -
> - XCloseDisplay(ctx->x_display);
> - free(ctx);
> -}
> -
> diff --git a/common/ogl_ctx.h b/common/ogl_ctx.h
> deleted file mode 100644
> index 3abe6d7..0000000
> --- a/common/ogl_ctx.h
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H_GLCTX
> -#define _H_GLCTX
> -
> -typedef struct OGLCtx OGLCtx;
> -
> -const char *oglctx_type_str(OGLCtx *ctx);
> -void oglctx_make_current(OGLCtx *ctx);
> -OGLCtx *pbuf_create(int width, int heigth);
> -OGLCtx *pixmap_create(int width, int heigth);
> -void oglctx_destroy(OGLCtx *ctx);
> -
> -#endif
> -
> diff --git a/common/pixman_utils.c b/common/pixman_utils.c
> deleted file mode 100644
> index 914c97e..0000000
> --- a/common/pixman_utils.c
> +++ /dev/null
> @@ -1,1614 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include<config.h>
> -#include "pixman_utils.h"
> -#include<spice/macros.h>
> -
> -#include<stdlib.h>
> -#include<string.h>
> -#include<stdio.h>
> -#include "mem.h"
> -
> -#ifndef ASSERT
> -#define ASSERT(x) if (!(x)) { \
> - printf("%s: ASSERT %s failed\n", __FUNCTION__, #x); \
> - abort(); \
> -}
> -#endif
> -
> -#ifndef PANIC
> -#define PANIC(str) { \
> - printf("%s: panic: %s", __FUNCTION__, str); \
> - abort(); \
> -}
> -#endif
> -
> -#define SOLID_RASTER_OP(_name, _size, _type, _equation) \
> -static void \
> -solid_rop_ ## _name ## _ ## _size (_type *ptr, int len, _type src) \
> -{ \
> - while (len--) { \
> - _type dst = *ptr; \
> - if (dst) /* avoid unused warning */{}; \
> - *ptr = (_type)(_equation); \
> - ptr++; \
> - } \
> -} \
> -
> -#define TILED_RASTER_OP(_name, _size, _type, _equation) \
> -static void \
> -tiled_rop_ ## _name ## _ ## _size (_type *ptr, int len, _type *tile, _type *tile_end, int tile_width) \
> -{ \
> - while (len--) { \
> - _type src = *tile; \
> - _type dst = *ptr; \
> - if (src) /* avoid unused warning */{}; \
> - if (dst) /* avoid unused warning */{}; \
> - *ptr = (_type)(_equation); \
> - ptr++; \
> - tile++; \
> - if (tile == tile_end) \
> - tile -= tile_width; \
> - } \
> -} \
> -
> -#define COPY_RASTER_OP(_name, _size, _type, _equation) \
> -static void \
> - copy_rop_ ## _name ## _ ## _size (_type *ptr, _type *src_line, int len) \
> -{ \
> - while (len--) { \
> - _type src = *src_line; \
> - _type dst = *ptr; \
> - if (src) /* avoid unused warning */ {}; \
> - if (dst) /* avoid unused warning */{}; \
> - *ptr = (_type)(_equation); \
> - ptr++; \
> - src_line++; \
> - } \
> -} \
> -
> -#define RASTER_OP(name, equation) \
> - SOLID_RASTER_OP(name, 8, uint8_t, equation) \
> - SOLID_RASTER_OP(name, 16, uint16_t, equation) \
> - SOLID_RASTER_OP(name, 32, uint32_t, equation) \
> - TILED_RASTER_OP(name, 8, uint8_t, equation) \
> - TILED_RASTER_OP(name, 16, uint16_t, equation) \
> - TILED_RASTER_OP(name, 32, uint32_t, equation) \
> - COPY_RASTER_OP(name, 8, uint8_t, equation) \
> - COPY_RASTER_OP(name, 16, uint16_t, equation) \
> - COPY_RASTER_OP(name, 32, uint32_t, equation)
> -
> -RASTER_OP(clear, 0x0)
> -RASTER_OP(and, src& dst)
> -RASTER_OP(and_reverse, src& ~dst)
> -RASTER_OP(copy, src)
> -RASTER_OP(and_inverted, ~src& dst)
> -RASTER_OP(noop, dst)
> -RASTER_OP(xor, src ^ dst)
> -RASTER_OP(or, src | dst)
> -RASTER_OP(nor, ~src& ~dst)
> -RASTER_OP(equiv, ~src ^ dst)
> -RASTER_OP(invert, ~dst)
> -RASTER_OP(or_reverse, src | ~dst)
> -RASTER_OP(copy_inverted, ~src)
> -RASTER_OP(or_inverted, ~src | dst)
> -RASTER_OP(nand, ~src | ~dst)
> -RASTER_OP(set, 0xffffffff)
> -
> -typedef void (*solid_rop_8_func_t)(uint8_t *ptr, int len, uint8_t src);
> -typedef void (*solid_rop_16_func_t)(uint16_t *ptr, int len, uint16_t src);
> -typedef void (*solid_rop_32_func_t)(uint32_t *ptr, int len, uint32_t src);
> -typedef void (*tiled_rop_8_func_t)(uint8_t *ptr, int len,
> - uint8_t *tile, uint8_t *tile_end, int tile_width);
> -typedef void (*tiled_rop_16_func_t)(uint16_t *ptr, int len,
> - uint16_t *tile, uint16_t *tile_end, int tile_width);
> -typedef void (*tiled_rop_32_func_t)(uint32_t *ptr, int len,
> - uint32_t *tile, uint32_t *tile_end, int tile_width);
> -typedef void (*copy_rop_8_func_t)(uint8_t *ptr, uint8_t *src, int len);
> -typedef void (*copy_rop_16_func_t)(uint16_t *ptr, uint16_t *src, int len);
> -typedef void (*copy_rop_32_func_t)(uint32_t *ptr, uint32_t *src, int len);
> -
> -#define ROP_TABLE(_type, _size) \
> -static void (*solid_rops_ ## _size[16]) (_type *ptr, int len, _type src) = { \
> - solid_rop_clear_ ## _size, \
> - solid_rop_and_ ## _size, \
> - solid_rop_and_reverse_ ## _size, \
> - solid_rop_copy_ ## _size, \
> - solid_rop_and_inverted_ ## _size, \
> - solid_rop_noop_ ## _size, \
> - solid_rop_xor_ ## _size, \
> - solid_rop_or_ ## _size, \
> - solid_rop_nor_ ## _size, \
> - solid_rop_equiv_ ## _size, \
> - solid_rop_invert_ ## _size, \
> - solid_rop_or_reverse_ ## _size, \
> - solid_rop_copy_inverted_ ## _size, \
> - solid_rop_or_inverted_ ## _size, \
> - solid_rop_nand_ ## _size, \
> - solid_rop_set_ ## _size \
> -}; \
> -static void (*tiled_rops_ ## _size[16]) (_type *ptr, int len, _type *tile, _type *tile_end, int tile_width) = { \
> - tiled_rop_clear_ ## _size, \
> - tiled_rop_and_ ## _size, \
> - tiled_rop_and_reverse_ ## _size, \
> - tiled_rop_copy_ ## _size, \
> - tiled_rop_and_inverted_ ## _size, \
> - tiled_rop_noop_ ## _size, \
> - tiled_rop_xor_ ## _size, \
> - tiled_rop_or_ ## _size, \
> - tiled_rop_nor_ ## _size, \
> - tiled_rop_equiv_ ## _size, \
> - tiled_rop_invert_ ## _size, \
> - tiled_rop_or_reverse_ ## _size, \
> - tiled_rop_copy_inverted_ ## _size, \
> - tiled_rop_or_inverted_ ## _size, \
> - tiled_rop_nand_ ## _size, \
> - tiled_rop_set_ ## _size \
> -}; \
> -static void (*copy_rops_ ## _size[16]) (_type *ptr, _type *tile, int len) = { \
> - copy_rop_clear_ ## _size, \
> - copy_rop_and_ ## _size, \
> - copy_rop_and_reverse_ ## _size, \
> - copy_rop_copy_ ## _size, \
> - copy_rop_and_inverted_ ## _size, \
> - copy_rop_noop_ ## _size, \
> - copy_rop_xor_ ## _size, \
> - copy_rop_or_ ## _size, \
> - copy_rop_nor_ ## _size, \
> - copy_rop_equiv_ ## _size, \
> - copy_rop_invert_ ## _size, \
> - copy_rop_or_reverse_ ## _size, \
> - copy_rop_copy_inverted_ ## _size, \
> - copy_rop_or_inverted_ ## _size, \
> - copy_rop_nand_ ## _size, \
> - copy_rop_set_ ## _size \
> -};
> -
> -ROP_TABLE(uint8_t, 8)
> -ROP_TABLE(uint16_t, 16)
> -ROP_TABLE(uint32_t, 32)
> -
> -/* We can't get the real bits per pixel info from pixman_image_t,
> - only the DEPTH which is the sum of all a+r+g+b bits, which
> - is e.g. 24 for 32bit xRGB. We really want the bpp, so
> - we have this ugly conversion thing */
> -int spice_pixman_image_get_bpp(pixman_image_t *image)
> -{
> - int depth;
> -
> - depth = pixman_image_get_depth(image);
> - if (depth == 24) {
> - return 32;
> - }
> - if (depth == 15) {
> - return 16;
> - }
> - return depth;
> -}
> -
> -void spice_pixman_fill_rect(pixman_image_t *dest,
> - int x, int y,
> - int width, int height,
> - uint32_t value)
> -{
> - uint32_t *bits;
> - int stride, depth;
> - uint32_t byte_width;
> - uint8_t *byte_line;
> -
> - bits = pixman_image_get_data(dest);
> - stride = pixman_image_get_stride(dest);
> - depth = spice_pixman_image_get_bpp(dest);
> - /* stride is in bytes, depth in bits */
> -
> - ASSERT(x>= 0);
> - ASSERT(y>= 0);
> - ASSERT(width> 0);
> - ASSERT(height> 0);
> - ASSERT(x + width<= pixman_image_get_width(dest));
> - ASSERT(y + height<= pixman_image_get_height(dest));
> -
> - if (pixman_fill(bits,
> - stride / 4,
> - depth,
> - x, y,
> - width, height,
> - value)) {
> - return;
> - }
> -
> - if (depth == 8) {
> - byte_line = ((uint8_t *)bits) + stride * y + x;
> - byte_width = width;
> - value = (value& 0xff) * 0x01010101;
> - } else if (depth == 16) {
> - byte_line = ((uint8_t *)bits) + stride * y + x * 2;
> - byte_width = 2 * width;
> - value = (value& 0xffff) * 0x00010001;
> - } else {
> - ASSERT (depth == 32)
> - byte_line = ((uint8_t *)bits) + stride * y + x * 4;
> - byte_width = 4 * width;
> - }
> -
> - while (height--) {
> - int w;
> - uint8_t *d = byte_line;
> -
> - byte_line += stride;
> - w = byte_width;
> -
> - while (w>= 1&& ((uintptr_t)d& 1)) {
> - *(uint8_t *)d = (value& 0xff);
> - w--;
> - d++;
> - }
> -
> - while (w>= 2&& ((uintptr_t)d& 3)) {
> - *(uint16_t *)d = value;
> - w -= 2;
> - d += 2;
> - }
> -
> - while (w>= 4&& ((uintptr_t)d& 7)) {
> - *(uint32_t *)d = value;
> -
> - w -= 4;
> - d += 4;
> - }
> -
> - while (w>= 4) {
> - *(uint32_t *)d = value;
> -
> - w -= 4;
> - d += 4;
> - }
> -
> - while (w>= 2) {
> - *(uint16_t *)d = value;
> - w -= 2;
> - d += 2;
> - }
> -
> - while (w>= 1) {
> - *(uint8_t *)d = (value& 0xff);
> - w--;
> - d++;
> - }
> - }
> -}
> -
> -void spice_pixman_fill_rect_rop(pixman_image_t *dest,
> - int x, int y,
> - int width, int height,
> - uint32_t value,
> - SpiceROP rop)
> -{
> - uint32_t *bits;
> - int stride, depth;
> - uint8_t *byte_line;
> -
> - bits = pixman_image_get_data(dest);
> - stride = pixman_image_get_stride(dest);
> - depth = spice_pixman_image_get_bpp(dest);
> - /* stride is in bytes, depth in bits */
> -
> - ASSERT(x>= 0);
> - ASSERT(y>= 0);
> - ASSERT(width> 0);
> - ASSERT(height> 0);
> - ASSERT(x + width<= pixman_image_get_width(dest));
> - ASSERT(y + height<= pixman_image_get_height(dest));
> - ASSERT(rop< 16);
> -
> - if (depth == 8) {
> - solid_rop_8_func_t rop_func = solid_rops_8[rop];
> -
> - byte_line = ((uint8_t *)bits) + stride * y + x;
> - while (height--) {
> - rop_func((uint8_t *)byte_line, width, (uint8_t)value);
> - byte_line += stride;
> - }
> -
> - } else if (depth == 16) {
> - solid_rop_16_func_t rop_func = solid_rops_16[rop];
> -
> - byte_line = ((uint8_t *)bits) + stride * y + x * 2;
> - while (height--) {
> - rop_func((uint16_t *)byte_line, width, (uint16_t)value);
> - byte_line += stride;
> - }
> - } else {
> - solid_rop_32_func_t rop_func = solid_rops_32[rop];
> -
> - byte_line = ((uint8_t *)bits) + stride * y + x * 4;
> - while (height--) {
> - rop_func((uint32_t *)byte_line, width, (uint32_t)value);
> - byte_line += stride;
> - }
> - }
> -}
> -
> -void spice_pixman_tile_rect(pixman_image_t *dest,
> - int x, int y,
> - int width, int height,
> - pixman_image_t *tile,
> - int offset_x,
> - int offset_y)
> -{
> - uint32_t *bits, *tile_bits;
> - int stride, depth;
> - int tile_width, tile_height, tile_stride;
> - uint8_t *byte_line;
> - uint8_t *tile_line;
> - int tile_start_x, tile_start_y, tile_end_dx;
> -
> - bits = pixman_image_get_data(dest);
> - stride = pixman_image_get_stride(dest);
> - depth = spice_pixman_image_get_bpp(dest);
> - /* stride is in bytes, depth in bits */
> -
> - tile_bits = pixman_image_get_data(tile);
> - tile_stride = pixman_image_get_stride(tile);
> - tile_width = pixman_image_get_width(tile);
> - tile_height = pixman_image_get_height(tile);
> -
> - ASSERT(x>= 0);
> - ASSERT(y>= 0);
> - ASSERT(width> 0);
> - ASSERT(height> 0);
> - ASSERT(x + width<= pixman_image_get_width(dest));
> - ASSERT(y + height<= pixman_image_get_height(dest));
> - ASSERT(depth == spice_pixman_image_get_bpp(tile));
> -
> - tile_start_x = (x - offset_x) % tile_width;
> - if (tile_start_x< 0) {
> - tile_start_x += tile_width;
> - }
> - tile_start_y = (y - offset_y) % tile_height;
> - if (tile_start_y< 0) {
> - tile_start_y += tile_height;
> - }
> - tile_end_dx = tile_width - tile_start_x;
> -
> - if (depth == 8) {
> - byte_line = ((uint8_t *)bits) + stride * y + x;
> - tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x;
> - while (height--) {
> - tiled_rop_copy_8((uint8_t *)byte_line, width,
> - (uint8_t *)tile_line, (uint8_t *)tile_line + tile_end_dx,
> - tile_width);
> - byte_line += stride;
> - tile_line += tile_stride;
> - if (++tile_start_y == tile_height) {
> - tile_line -= tile_height * tile_stride;
> - tile_start_y = 0;
> - }
> - }
> -
> - } else if (depth == 16) {
> - byte_line = ((uint8_t *)bits) + stride * y + x * 2;
> - tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 2;
> - while (height--) {
> - tiled_rop_copy_16((uint16_t *)byte_line, width,
> - (uint16_t *)tile_line, (uint16_t *)tile_line + tile_end_dx,
> - tile_width);
> - byte_line += stride;
> - tile_line += tile_stride;
> - if (++tile_start_y == tile_height) {
> - tile_line -= tile_height * tile_stride;
> - tile_start_y = 0;
> - }
> - }
> - } else {
> - ASSERT (depth == 32);
> -
> - byte_line = ((uint8_t *)bits) + stride * y + x * 4;
> - tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 4;
> - while (height--) {
> - tiled_rop_copy_32((uint32_t *)byte_line, width,
> - (uint32_t *)tile_line, (uint32_t *)tile_line + tile_end_dx,
> - tile_width);
> - byte_line += stride;
> - tile_line += tile_stride;
> - if (++tile_start_y == tile_height) {
> - tile_line -= tile_height * tile_stride;
> - tile_start_y = 0;
> - }
> - }
> - }
> -}
> -
> -void spice_pixman_tile_rect_rop(pixman_image_t *dest,
> - int x, int y,
> - int width, int height,
> - pixman_image_t *tile,
> - int offset_x,
> - int offset_y,
> - SpiceROP rop)
> -{
> - uint32_t *bits, *tile_bits;
> - int stride, depth;
> - int tile_width, tile_height, tile_stride;
> - uint8_t *byte_line;
> - uint8_t *tile_line;
> - int tile_start_x, tile_start_y, tile_end_dx;
> -
> - bits = pixman_image_get_data(dest);
> - stride = pixman_image_get_stride(dest);
> - depth = spice_pixman_image_get_bpp(dest);
> - /* stride is in bytes, depth in bits */
> -
> - tile_bits = pixman_image_get_data(tile);
> - tile_stride = pixman_image_get_stride(tile);
> - tile_width = pixman_image_get_width(tile);
> - tile_height = pixman_image_get_height(tile);
> -
> - ASSERT(x>= 0);
> - ASSERT(y>= 0);
> - ASSERT(width> 0);
> - ASSERT(height> 0);
> - ASSERT(x + width<= pixman_image_get_width(dest));
> - ASSERT(y + height<= pixman_image_get_height(dest));
> - ASSERT(rop< 16);
> - ASSERT(depth == spice_pixman_image_get_bpp(tile));
> -
> - tile_start_x = (x - offset_x) % tile_width;
> - if (tile_start_x< 0) {
> - tile_start_x += tile_width;
> - }
> - tile_start_y = (y - offset_y) % tile_height;
> - if (tile_start_y< 0) {
> - tile_start_y += tile_height;
> - }
> - tile_end_dx = tile_width - tile_start_x;
> -
> - if (depth == 8) {
> - tiled_rop_8_func_t rop_func = tiled_rops_8[rop];
> -
> - byte_line = ((uint8_t *)bits) + stride * y + x;
> - tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x;
> - while (height--) {
> - rop_func((uint8_t *)byte_line, width,
> - (uint8_t *)tile_line, (uint8_t *)tile_line + tile_end_dx,
> - tile_width);
> - byte_line += stride;
> - tile_line += tile_stride;
> - if (++tile_start_y == tile_height) {
> - tile_line -= tile_height * tile_stride;
> - tile_start_y = 0;
> - }
> - }
> -
> - } else if (depth == 16) {
> - tiled_rop_16_func_t rop_func = tiled_rops_16[rop];
> -
> - byte_line = ((uint8_t *)bits) + stride * y + x * 2;
> - tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 2;
> - while (height--) {
> - rop_func((uint16_t *)byte_line, width,
> - (uint16_t *)tile_line, (uint16_t *)tile_line + tile_end_dx,
> - tile_width);
> - byte_line += stride;
> - tile_line += tile_stride;
> - if (++tile_start_y == tile_height) {
> - tile_line -= tile_height * tile_stride;
> - tile_start_y = 0;
> - }
> - }
> - } else {
> - tiled_rop_32_func_t rop_func = tiled_rops_32[rop];
> -
> - ASSERT (depth == 32);
> -
> - byte_line = ((uint8_t *)bits) + stride * y + x * 4;
> - tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 4;
> - while (height--) {
> - rop_func((uint32_t *)byte_line, width,
> - (uint32_t *)tile_line, (uint32_t *)tile_line + tile_end_dx,
> - tile_width);
> - byte_line += stride;
> - tile_line += tile_stride;
> - if (++tile_start_y == tile_height) {
> - tile_line -= tile_height * tile_stride;
> - tile_start_y = 0;
> - }
> - }
> - }
> -}
> -
> -
> -void spice_pixman_blit(pixman_image_t *dest,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int dest_x, int dest_y,
> - int width, int height)
> -{
> - uint32_t *bits, *src_bits;
> - int stride, depth, src_depth;
> - int src_width, src_height, src_stride;
> - uint8_t *byte_line;
> - uint8_t *src_line;
> - int byte_width;
> -
> - if (!src) {
> - fprintf(stderr, "missing src!");
> - return;
> - }
> -
> - bits = pixman_image_get_data(dest);
> - stride = pixman_image_get_stride(dest);
> - depth = spice_pixman_image_get_bpp(dest);
> - /* stride is in bytes, depth in bits */
> -
> - src_bits = pixman_image_get_data(src);
> - src_stride = pixman_image_get_stride(src);
> - src_width = pixman_image_get_width(src);
> - src_height = pixman_image_get_height(src);
> - src_depth = spice_pixman_image_get_bpp(src);
> -
> - /* Clip source */
> - if (src_x< 0) {
> - width += src_x;
> - dest_x -= src_x;
> - src_x = 0;
> - }
> - if (src_y< 0) {
> - height += src_y;
> - dest_y -= src_y;
> - src_y = 0;
> - }
> - if (src_x + width> src_width) {
> - width = src_width - src_x;
> - }
> - if (src_y + height> src_height) {
> - height = src_height - src_y;
> - }
> -
> - if (width<= 0 || height<= 0) {
> - return;
> - }
> -
> - ASSERT(src_x>= 0);
> - ASSERT(src_y>= 0);
> - ASSERT(dest_x>= 0);
> - ASSERT(dest_y>= 0);
> - ASSERT(width> 0);
> - ASSERT(height> 0);
> - ASSERT(dest_x + width<= pixman_image_get_width(dest));
> - ASSERT(dest_y + height<= pixman_image_get_height(dest));
> - ASSERT(src_x + width<= pixman_image_get_width(src));
> - ASSERT(src_y + height<= pixman_image_get_height(src));
> - ASSERT(depth == src_depth);
> -
> - if (pixman_blt(src_bits,
> - bits,
> - src_stride / 4,
> - stride / 4,
> - depth, depth,
> - src_x, src_y,
> - dest_x, dest_y,
> - width, height)) {
> - return;
> - }
> -
> - if (depth == 8) {
> - byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x;
> - byte_width = width;
> - src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x;
> - } else if (depth == 16) {
> - byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 2;
> - byte_width = width * 2;
> - src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 2;
> - } else {
> - ASSERT (depth == 32);
> - byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 4;
> - byte_width = width * 4;
> - src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 4;
> - }
> -
> - while (height--) {
> - memcpy(byte_line, src_line, byte_width);
> - byte_line += stride;
> - src_line += src_stride;
> - }
> -}
> -
> -void spice_pixman_blit_rop (pixman_image_t *dest,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int dest_x, int dest_y,
> - int width, int height,
> - SpiceROP rop)
> -{
> - uint32_t *bits, *src_bits;
> - int stride, depth, src_depth;
> - int src_width, src_height, src_stride;
> - uint8_t *byte_line;
> - uint8_t *src_line;
> -
> - bits = pixman_image_get_data(dest);
> - stride = pixman_image_get_stride(dest);
> - depth = spice_pixman_image_get_bpp(dest);
> - /* stride is in bytes, depth in bits */
> -
> - src_bits = pixman_image_get_data(src);
> - src_stride = pixman_image_get_stride(src);
> - src_width = pixman_image_get_width(src);
> - src_height = pixman_image_get_height(src);
> - src_depth = spice_pixman_image_get_bpp(src);
> -
> - /* Clip source */
> - if (src_x< 0) {
> - width += src_x;
> - dest_x -= src_x;
> - src_x = 0;
> - }
> - if (src_y< 0) {
> - height += src_y;
> - dest_y -= src_y;
> - src_y = 0;
> - }
> - if (src_x + width> src_width) {
> - width = src_width - src_x;
> - }
> - if (src_y + height> src_height) {
> - height = src_height - src_y;
> - }
> -
> - if (width<= 0 || height<= 0) {
> - return;
> - }
> -
> - ASSERT(src_x>= 0);
> - ASSERT(src_y>= 0);
> - ASSERT(dest_x>= 0);
> - ASSERT(dest_y>= 0);
> - ASSERT(width> 0);
> - ASSERT(height> 0);
> - ASSERT(dest_x + width<= pixman_image_get_width(dest));
> - ASSERT(dest_y + height<= pixman_image_get_height(dest));
> - ASSERT(src_x + width<= pixman_image_get_width(src));
> - ASSERT(src_y + height<= pixman_image_get_height(src));
> - ASSERT(depth == src_depth);
> -
> - if (depth == 8) {
> - copy_rop_8_func_t rop_func = copy_rops_8[rop];
> -
> - byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x;
> - src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x;
> -
> - while (height--) {
> - rop_func((uint8_t *)byte_line, (uint8_t *)src_line, width);
> - byte_line += stride;
> - src_line += src_stride;
> - }
> - } else if (depth == 16) {
> - copy_rop_16_func_t rop_func = copy_rops_16[rop];
> -
> - byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 2;
> - src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 2;
> -
> - while (height--) {
> - rop_func((uint16_t *)byte_line, (uint16_t *)src_line, width);
> - byte_line += stride;
> - src_line += src_stride;
> - }
> - } else {
> - copy_rop_32_func_t rop_func = copy_rops_32[rop];
> -
> - ASSERT (depth == 32);
> - byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 4;
> - src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 4;
> -
> - while (height--) {
> - rop_func((uint32_t *)byte_line, (uint32_t *)src_line, width);
> - byte_line += stride;
> - src_line += src_stride;
> - }
> - }
> -
> -}
> -
> -void spice_pixman_blit_colorkey (pixman_image_t *dest,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int dest_x, int dest_y,
> - int width, int height,
> - uint32_t transparent_color)
> -{
> - uint32_t *bits, *src_bits;
> - int stride, depth;
> - int src_width, src_height, src_stride;
> - uint8_t *byte_line;
> - uint8_t *src_line;
> - int x;
> -
> - bits = pixman_image_get_data(dest);
> - stride = pixman_image_get_stride(dest);
> - depth = spice_pixman_image_get_bpp(dest);
> - /* stride is in bytes, depth in bits */
> -
> - src_bits = pixman_image_get_data(src);
> - src_stride = pixman_image_get_stride(src);
> - src_width = pixman_image_get_width(src);
> - src_height = pixman_image_get_height(src);
> -
> - /* Clip source */
> - if (src_x< 0) {
> - width += src_x;
> - dest_x -= src_x;
> - src_x = 0;
> - }
> - if (src_y< 0) {
> - height += src_y;
> - dest_y -= src_y;
> - src_y = 0;
> - }
> - if (src_x + width> src_width) {
> - width = src_width - src_x;
> - }
> - if (src_y + height> src_height) {
> - height = src_height - src_y;
> - }
> -
> - if (width<= 0 || height<= 0) {
> - return;
> - }
> -
> - ASSERT(src_x>= 0);
> - ASSERT(src_y>= 0);
> - ASSERT(dest_x>= 0);
> - ASSERT(dest_y>= 0);
> - ASSERT(width> 0);
> - ASSERT(height> 0);
> - ASSERT(dest_x + width<= pixman_image_get_width(dest));
> - ASSERT(dest_y + height<= pixman_image_get_height(dest));
> - ASSERT(src_x + width<= pixman_image_get_width(src));
> - ASSERT(src_y + height<= pixman_image_get_height(src));
> - ASSERT(depth == spice_pixman_image_get_bpp(src));
> -
> - if (depth == 8) {
> - byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x;
> - src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x;
> -
> - while (height--) {
> - uint8_t *d = (uint8_t *)byte_line;
> - uint8_t *s = (uint8_t *)byte_line;
> -
> - s = (uint8_t *)src_line;
> - for (x = 0; x< width; x++) {
> - uint8_t val = *s;
> - if (val != (uint8_t)transparent_color) {
> - *d = val;
> - }
> - s++; d++;
> - }
> -
> - byte_line += stride;
> - src_line += src_stride;
> - }
> - } else if (depth == 16) {
> - byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 2;
> - src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 2;
> -
> - while (height--) {
> - uint16_t *d = (uint16_t *)byte_line;
> - uint16_t *s = (uint16_t *)byte_line;
> -
> - s = (uint16_t *)src_line;
> - for (x = 0; x< width; x++) {
> - uint16_t val = *s;
> - if (val != (uint16_t)transparent_color) {
> - *d = val;
> - }
> - s++; d++;
> - }
> -
> - byte_line += stride;
> - src_line += src_stride;
> - }
> - } else {
> - ASSERT (depth == 32);
> - byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 4;
> - src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 4;
> -
> - while (height--) {
> - uint32_t *d = (uint32_t *)byte_line;
> - uint32_t *s = (uint32_t *)byte_line;
> -
> - transparent_color&= 0xffffff;
> - s = (uint32_t *)src_line;
> - for (x = 0; x< width; x++) {
> - uint32_t val = *s;
> - if ((0xffffff& val) != transparent_color) {
> - *d = val;
> - }
> - s++; d++;
> - }
> -
> - byte_line += stride;
> - src_line += src_stride;
> - }
> - }
> -}
> -
> -static void copy_bits_up(uint8_t *data, const int stride, int bpp,
> - const int src_x, const int src_y,
> - const int width, const int height,
> - const int dest_x, const int dest_y)
> -{
> - uint8_t *src = data + src_y * stride + src_x * bpp;
> - uint8_t *dest = data + dest_y * stride + dest_x * bpp;
> - uint8_t *end = dest + height * stride;
> - for (; dest != end; dest += stride, src += stride) {
> - memcpy(dest, src, width * bpp);
> - }
> -}
> -
> -static void copy_bits_down(uint8_t *data, const int stride, int bpp,
> - const int src_x, const int src_y,
> - const int width, const int height,
> - const int dest_x, const int dest_y)
> -{
> - uint8_t *src = data + (src_y + height - 1) * stride + src_x * bpp;
> - uint8_t *end = data + (dest_y - 1) * stride + dest_x * bpp;
> - uint8_t *dest = end + height * stride;
> -
> - for (; dest != end; dest -= stride, src -= stride) {
> - memcpy(dest, src, width * bpp);
> - }
> -}
> -
> -static void copy_bits_same_line(uint8_t *data, const int stride, int bpp,
> - const int src_x, const int src_y,
> - const int width, const int height,
> - const int dest_x, const int dest_y)
> -{
> - uint8_t *src = data + src_y * stride + src_x * bpp;
> - uint8_t *dest = data + dest_y * stride + dest_x * bpp;
> - uint8_t *end = dest + height * stride;
> - for (; dest != end; dest += stride, src += stride) {
> - memmove(dest, src, width * bpp);
> - }
> -}
> -
> -void spice_pixman_copy_rect (pixman_image_t *image,
> - int src_x, int src_y,
> - int width, int height,
> - int dest_x, int dest_y)
> -{
> - uint8_t *data;
> - int stride;
> - int bpp;
> -
> - data = (uint8_t *)pixman_image_get_data(image);
> - stride = pixman_image_get_stride(image);
> - bpp = spice_pixman_image_get_bpp(image) / 8;
> -
> - if (dest_y> src_y) {
> - copy_bits_down(data, stride, bpp,
> - src_x, src_y,
> - width, height,
> - dest_x, dest_y);
> - } else if (dest_y< src_y) {
> - copy_bits_up(data, stride, bpp,
> - src_x, src_y,
> - width, height,
> - dest_x, dest_y);
> - } else {
> - copy_bits_same_line(data, stride, bpp,
> - src_x, src_y,
> - width, height,
> - dest_x, dest_y);
> - }
> -}
> -
> -pixman_bool_t spice_pixman_region32_init_rects (pixman_region32_t *region,
> - const SpiceRect *rects,
> - int count)
> -{
> - /* These types are compatible, so just cast */
> - return pixman_region32_init_rects(region, (pixman_box32_t *)rects, count);
> -}
> -
> -pixman_format_code_t spice_surface_format_to_pixman(uint32_t surface_format)
> -{
> - switch (surface_format) {
> - case SPICE_SURFACE_FMT_1_A:
> - return PIXMAN_a1;
> - case SPICE_SURFACE_FMT_8_A:
> - return PIXMAN_a8;
> - case SPICE_SURFACE_FMT_16_555:
> - return PIXMAN_x1r5g5b5;
> - case SPICE_SURFACE_FMT_16_565:
> - return PIXMAN_r5g6b5;
> - case SPICE_SURFACE_FMT_32_xRGB:
> - return PIXMAN_x8r8g8b8;
> - case SPICE_SURFACE_FMT_32_ARGB:
> - return PIXMAN_a8r8g8b8;
> - default:
> - printf("Unknown surface format %d\n", surface_format);
> - abort();
> - break;
> - }
> - return (pixman_format_code_t)0; /* Not reached */
> -}
> -
> -/* Returns the "spice native" pixman version of a specific bitmap format.
> - * This isn't bitwise the same as the bitmap format, for instance we
> - * typically convert indexed to real color modes and use the standard
> - * surface modes rather than weird things like 24bit
> - */
> -pixman_format_code_t spice_bitmap_format_to_pixman(int bitmap_format,
> - uint32_t palette_surface_format)
> -{
> - switch (bitmap_format) {
> - case SPICE_BITMAP_FMT_1BIT_LE:
> - case SPICE_BITMAP_FMT_1BIT_BE:
> - case SPICE_BITMAP_FMT_4BIT_LE:
> - case SPICE_BITMAP_FMT_4BIT_BE:
> - case SPICE_BITMAP_FMT_8BIT:
> - /* Indexed mode palettes are the same as their destination canvas format */
> - return spice_surface_format_to_pixman(palette_surface_format);
> -
> - case SPICE_BITMAP_FMT_16BIT:
> - return PIXMAN_x1r5g5b5;
> -
> - case SPICE_BITMAP_FMT_24BIT:
> - case SPICE_BITMAP_FMT_32BIT:
> - return PIXMAN_x8r8g8b8;
> -
> - case SPICE_BITMAP_FMT_RGBA:
> - return PIXMAN_a8r8g8b8;
> -
> - case SPICE_BITMAP_FMT_INVALID:
> - default:
> - printf("Unknown bitmap format %d\n", bitmap_format);
> - abort();
> - return PIXMAN_a8r8g8b8;
> - }
> -}
> -
> -/* Tries to view a spice bitmap as a pixman_image_t without copying,
> - * will often fail due to unhandled formats or strides.
> - */
> -pixman_image_t *spice_bitmap_try_as_pixman(int src_format,
> - int flags,
> - int width,
> - int height,
> - uint8_t *data,
> - int stride)
> -{
> - pixman_format_code_t pixman_format;
> -
> - /* Pixman stride must be multiple of 4 */
> - if (stride % 4 != 0) {
> - return NULL;
> - }
> -
> - switch (src_format) {
> - case SPICE_BITMAP_FMT_32BIT:
> -#ifdef WORDS_BIGENDIAN
> - pixman_format = PIXMAN_b8g8r8x8;
> -#else
> - pixman_format = PIXMAN_x8r8g8b8;
> -#endif
> - break;
> - case SPICE_BITMAP_FMT_RGBA:
> -#ifdef WORDS_BIGENDIAN
> - pixman_format = PIXMAN_b8g8r8a8;
> -#else
> - pixman_format = PIXMAN_a8r8g8b8;
> -#endif
> - break;
> - case SPICE_BITMAP_FMT_24BIT:
> -#ifdef WORDS_BIGENDIAN
> - pixman_format = PIXMAN_b8g8r8;
> -#else
> - pixman_format = PIXMAN_r8g8b8;
> -#endif
> - break;
> - case SPICE_BITMAP_FMT_16BIT:
> -#ifdef WORDS_BIGENDIAN
> - return NULL;
> -#else
> - pixman_format = PIXMAN_x1r5g5b5;
> -#endif
> - break;
> -
> - default:
> - return NULL;
> - }
> -
> - if (!(flags& SPICE_BITMAP_FLAGS_TOP_DOWN)) {
> - data += stride * (height - 1);
> - stride = -stride;
> - }
> -
> - return pixman_image_create_bits (pixman_format,
> - width,
> - height,
> - (uint32_t *)data,
> - stride);
> -}
> -
> -#ifdef WORDS_BIGENDIAN
> -#define UINT16_FROM_LE(x) SPICE_BYTESWAP16(x)
> -#define UINT32_FROM_LE(x) SPICE_BYTESWAP32(x)
> -#else
> -#define UINT16_FROM_LE(x) (x)
> -#define UINT32_FROM_LE(x) (x)
> -#endif
> -
> -static inline uint32_t rgb_16_555_to_32(uint16_t color)
> -{
> - uint32_t ret;
> -
> - ret = ((color& 0x001f)<< 3) | ((color& 0x001c)>> 2);
> - ret |= ((color& 0x03e0)<< 6) | ((color& 0x0380)<< 1);
> - ret |= ((color& 0x7c00)<< 9) | ((color& 0x7000)<< 4);
> -
> - return ret;
> -}
> -
> -static inline uint16_t rgb_32_to_16_555(uint32_t color)
> -{
> - return
> - (((color)>> 3)& 0x001f) |
> - (((color)>> 6)& 0x03e0) |
> - (((color)>> 9)& 0x7c00);
> -}
> -
> -
> -static void bitmap_32_to_32(uint8_t* dest, int dest_stride,
> - uint8_t* src, int src_stride,
> - int width, uint8_t* end)
> -{
> -#ifdef WORDS_BIGENDIAN
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - uint32_t* src_line = (uint32_t *)src;
> - uint32_t* src_line_end = src_line + width;
> - uint32_t* dest_line = (uint32_t *)dest;
> -
> - for (; src_line< src_line_end; ++dest_line, ++src_line) {
> - *dest_line = UINT32_FROM_LE(*src_line);
> - }
> - }
> -#else
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - memcpy(dest, src, width * 4);
> - }
> -#endif
> -}
> -
> -static void bitmap_24_to_32(uint8_t* dest, int dest_stride,
> - uint8_t* src, int src_stride,
> - int width, uint8_t* end)
> -{
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - uint8_t* src_line = src;
> - uint8_t* src_line_end = src_line + width * 3;
> - uint32_t* dest_line = (uint32_t *)dest;
> -
> - for (; src_line< src_line_end; ++dest_line) {
> - uint32_t r, g, b;
> - b = *(src_line++);
> - g = *(src_line++);
> - r = *(src_line++);
> - *dest_line = (r<< 16) | (g<< 8) | (b);
> - }
> - }
> -}
> -
> -static void bitmap_16_to_16_555(uint8_t* dest, int dest_stride,
> - uint8_t* src, int src_stride,
> - int width, uint8_t* end)
> -{
> -#ifdef WORDS_BIGENDIAN
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - uint16_t* src_line = (uint16_t *)src;
> - uint16_t* src_line_end = src_line + width;
> - uint16_t* dest_line = (uint16_t *)dest;
> -
> - for (; src_line< src_line_end; ++dest_line, ++src_line) {
> - *dest_line = UINT16_FROM_LE(*src_line);
> - }
> - }
> -#else
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - memcpy(dest, src, width * 2);
> - }
> -#endif
> -}
> -
> -static void bitmap_8_32_to_32(uint8_t *dest, int dest_stride,
> - uint8_t *src, int src_stride,
> - int width, uint8_t *end,
> - SpicePalette *palette)
> -{
> - uint32_t local_ents[256];
> - uint32_t *ents;
> - int n_ents;
> -#ifdef WORDS_BIGENDIAN
> - int i;
> -#endif
> -
> - if (!palette) {
> - PANIC("No palette");
> - return;
> - }
> -
> - n_ents = MIN(palette->num_ents, 256);
> - ents = palette->ents;
> -
> - if (n_ents< 255
> -#ifdef WORDS_BIGENDIAN
> - || TRUE
> -#endif
> - ) {
> - memcpy(local_ents, ents, n_ents*4);
> - ents = local_ents;
> -
> -#ifdef WORDS_BIGENDIAN
> - for (i = 0; i< n_ents; i++) {
> - ents[i] = UINT32_FROM_LE(ents[i]);
> - }
> -#endif
> - }
> -
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - uint32_t *dest_line = (uint32_t*)dest;
> - uint8_t *src_line = src;
> - uint8_t *src_line_end = src_line + width;
> -
> - while (src_line< src_line_end) {
> - *(dest_line++) = ents[*(src_line++)];
> - }
> - }
> -}
> -
> -static void bitmap_8_16_to_16_555(uint8_t *dest, int dest_stride,
> - uint8_t *src, int src_stride,
> - int width, uint8_t *end,
> - SpicePalette *palette)
> -{
> - uint32_t local_ents[256];
> - uint32_t *ents;
> - int n_ents;
> -#ifdef WORDS_BIGENDIAN
> - int i;
> -#endif
> -
> - if (!palette) {
> - PANIC("No palette");
> - return;
> - }
> -
> - n_ents = MIN(palette->num_ents, 256);
> - ents = palette->ents;
> -
> - if (n_ents< 255
> -#ifdef WORDS_BIGENDIAN
> - || TRUE
> -#endif
> - ) {
> - memcpy(local_ents, ents, n_ents*4);
> - ents = local_ents;
> -
> -#ifdef WORDS_BIGENDIAN
> - for (i = 0; i< n_ents; i++) {
> - ents[i] = UINT32_FROM_LE(ents[i]);
> - }
> -#endif
> - }
> -
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - uint16_t *dest_line = (uint16_t*)dest;
> - uint8_t *src_line = src;
> - uint8_t *src_line_end = src_line + width;
> -
> - while (src_line< src_line_end) {
> - *(dest_line++) = ents[*(src_line++)];
> - }
> - }
> -}
> -
> -static void bitmap_4be_32_to_32(uint8_t* dest, int dest_stride,
> - uint8_t* src, int src_stride,
> - int width, uint8_t* end,
> - SpicePalette *palette)
> -{
> - uint32_t local_ents[16];
> - uint32_t *ents;
> - int n_ents;
> -#ifdef WORDS_BIGENDIAN
> - int i;
> -#endif
> -
> - if (!palette) {
> - PANIC("No palette");
> - return;
> - }
> -
> - n_ents = MIN(palette->num_ents, 16);
> - ents = palette->ents;
> -
> - if (n_ents< 16
> -#ifdef WORDS_BIGENDIAN
> - || TRUE
> -#endif
> - ) {
> - memcpy(local_ents, ents, n_ents*4);
> - ents = local_ents;
> -
> -#ifdef WORDS_BIGENDIAN
> - for (i = 0; i< n_ents; i++) {
> - ents[i] = UINT32_FROM_LE(ents[i]);
> - }
> -#endif
> - }
> -
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - uint32_t *dest_line = (uint32_t *)dest;
> - uint8_t *row = src;
> - int i;
> -
> - for (i = 0; i< (width>> 1); i++) {
> - *(dest_line++) = ents[(*row>> 4)& 0x0f];
> - *(dest_line++) = ents[*(row++)& 0x0f];
> - }
> - if (width& 1) {
> - *(dest_line) = ents[(*row>> 4)& 0x0f];
> - }
> - }
> -}
> -
> -static void bitmap_4be_16_to_16_555(uint8_t* dest, int dest_stride,
> - uint8_t* src, int src_stride,
> - int width, uint8_t* end,
> - SpicePalette *palette)
> -{
> - uint32_t local_ents[16];
> - uint32_t *ents;
> - int n_ents;
> -#ifdef WORDS_BIGENDIAN
> - int i;
> -#endif
> -
> - if (!palette) {
> - PANIC("No palette");
> - return;
> - }
> -
> - n_ents = MIN(palette->num_ents, 16);
> - ents = palette->ents;
> -
> - if (n_ents< 16
> -#ifdef WORDS_BIGENDIAN
> - || TRUE
> -#endif
> - ) {
> - memcpy(local_ents, ents, n_ents*4);
> - ents = local_ents;
> -
> -#ifdef WORDS_BIGENDIAN
> - for (i = 0; i< n_ents; i++) {
> - ents[i] = UINT32_FROM_LE(ents[i]);
> - }
> -#endif
> - }
> -
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - uint16_t *dest_line = (uint16_t *)dest;
> - uint8_t *row = src;
> - int i;
> -
> - for (i = 0; i< (width>> 1); i++) {
> - *(dest_line++) = ents[(*row>> 4)& 0x0f];
> - *(dest_line++) = ents[*(row++)& 0x0f];
> - }
> - if (width& 1) {
> - *(dest_line) = ents[(*row>> 4)& 0x0f];
> - }
> - }
> -}
> -
> -static inline int test_bit_be(void* addr, int bit)
> -{
> - return !!(((uint8_t*)addr)[bit>> 3]& (0x80>> (bit& 0x07)));
> -}
> -
> -static void bitmap_1be_32_to_32(uint8_t* dest, int dest_stride,
> - uint8_t* src, int src_stride,
> - int width, uint8_t* end,
> - SpicePalette *palette)
> -{
> - uint32_t fore_color;
> - uint32_t back_color;
> -
> - ASSERT(palette != NULL);
> -
> - if (!palette) {
> - return;
> - }
> -
> - fore_color = UINT32_FROM_LE(palette->ents[1]);
> - back_color = UINT32_FROM_LE(palette->ents[0]);
> -
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - uint32_t* dest_line = (uint32_t*)dest;
> - int i;
> -
> - for (i = 0; i< width; i++) {
> - if (test_bit_be(src, i)) {
> - *(dest_line++) = fore_color;
> - } else {
> - *(dest_line++) = back_color;
> - }
> - }
> - }
> -}
> -
> -
> -static void bitmap_1be_16_to_16_555(uint8_t* dest, int dest_stride,
> - uint8_t* src, int src_stride,
> - int width, uint8_t* end,
> - SpicePalette *palette)
> -{
> - uint16_t fore_color;
> - uint16_t back_color;
> -
> - ASSERT(palette != NULL);
> -
> - if (!palette) {
> - return;
> - }
> -
> - fore_color = (uint16_t) UINT32_FROM_LE(palette->ents[1]);
> - back_color = (uint16_t) UINT32_FROM_LE(palette->ents[0]);
> -
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - uint16_t* dest_line = (uint16_t*)dest;
> - int i;
> -
> - for (i = 0; i< width; i++) {
> - if (test_bit_be(src, i)) {
> - *(dest_line++) = fore_color;
> - } else {
> - *(dest_line++) = back_color;
> - }
> - }
> - }
> -}
> -
> -#ifdef NOT_USED_ATM
> -
> -static void bitmap_16_to_32(uint8_t* dest, int dest_stride,
> - uint8_t* src, int src_stride,
> - int width, uint8_t* end)
> -{
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - uint16_t* src_line = (uint16_t*)src;
> - uint16_t* src_line_end = src_line + width;
> - uint32_t* dest_line = (uint32_t*)dest;
> -
> - for (; src_line< src_line_end; ++dest_line, src_line++) {
> - *dest_line = rgb_16_555_to_32(UINT16_FROM_LE(*src_line));
> - }
> - }
> -}
> -
> -static void bitmap_32_to_16_555(uint8_t* dest, int dest_stride,
> - uint8_t* src, int src_stride,
> - int width, uint8_t* end)
> -{
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - uint32_t* src_line = (uint32_t *)src;
> - uint32_t* src_line_end = src_line + width;
> - uint16_t* dest_line = (uint16_t *)dest;
> -
> - for (; src_line< src_line_end; ++dest_line, ++src_line) {
> - *dest_line = rgb_32_to_16_555(UINT16_FROM_LE(*src_line));
> - }
> - }
> -}
> -
> -
> -static void bitmap_24_to_16_555(uint8_t* dest, int dest_stride,
> - uint8_t* src, int src_stride,
> - int width, uint8_t* end)
> -{
> - for (; src != end; src += src_stride, dest += dest_stride) {
> - uint8_t* src_line = src;
> - uint8_t* src_line_end = src_line + width * 3;
> - uint16_t* dest_line = (uint16_t *)dest;
> -
> - for (; src_line< src_line_end; ++dest_line) {
> - uint8_t r, g, b;
> - b = *(src_line++);
> - g = *(src_line++);
> - r = *(src_line++);
> - *dest_line = rgb_32_to_16_555(r<< 24 | g<< 16 | b);
> - }
> - }
> -}
> -
> -#endif
> -
> -/* This assumes that the dest, if set is the same format as
> - spice_bitmap_format_to_pixman would have picked */
> -pixman_image_t *spice_bitmap_to_pixman(pixman_image_t *dest_image,
> - int src_format,
> - int flags,
> - int width,
> - int height,
> - uint8_t *src,
> - int src_stride,
> - uint32_t palette_surface_format,
> - SpicePalette *palette)
> -{
> - uint8_t* dest;
> - int dest_stride;
> - uint8_t* end;
> -
> - if (dest_image == NULL) {
> - pixman_format_code_t dest_format;
> -
> - dest_format = spice_bitmap_format_to_pixman(src_format,
> - palette_surface_format);
> - dest_image = pixman_image_create_bits (dest_format,
> - width, height,
> - NULL, 0);
> - }
> -
> - dest = (uint8_t *)pixman_image_get_data(dest_image);
> - dest_stride = pixman_image_get_stride(dest_image);
> - if (!(flags& SPICE_BITMAP_FLAGS_TOP_DOWN)) {
> - ASSERT(height> 0);
> - dest += dest_stride * (height - 1);
> - dest_stride = -dest_stride;
> - }
> - end = src + (height * src_stride);
> -
> - switch (src_format) {
> - case SPICE_BITMAP_FMT_32BIT:
> - case SPICE_BITMAP_FMT_RGBA:
> - bitmap_32_to_32(dest, dest_stride, src, src_stride, width, end);
> - break;
> - case SPICE_BITMAP_FMT_24BIT:
> - bitmap_24_to_32(dest, dest_stride, src, src_stride, width, end);
> - break;
> - case SPICE_BITMAP_FMT_16BIT:
> - bitmap_16_to_16_555(dest, dest_stride, src, src_stride, width, end);
> - break;
> - case SPICE_BITMAP_FMT_8BIT:
> - if (palette_surface_format == SPICE_SURFACE_FMT_32_ARGB ||
> - palette_surface_format == SPICE_SURFACE_FMT_32_xRGB) {
> - bitmap_8_32_to_32(dest, dest_stride, src, src_stride, width, end, palette);
> - } else if (palette_surface_format == SPICE_SURFACE_FMT_16_555) {
> - bitmap_8_16_to_16_555(dest, dest_stride, src, src_stride, width, end, palette);
> - } else {
> - PANIC("Unsupported palette format");
> - }
> - break;
> - case SPICE_BITMAP_FMT_4BIT_BE:
> - if (palette_surface_format == SPICE_SURFACE_FMT_32_ARGB ||
> - palette_surface_format == SPICE_SURFACE_FMT_32_xRGB) {
> - bitmap_4be_32_to_32(dest, dest_stride, src, src_stride, width, end, palette);
> - } else if (palette_surface_format == SPICE_SURFACE_FMT_16_555) {
> - bitmap_4be_16_to_16_555(dest, dest_stride, src, src_stride, width, end, palette);
> - } else {
> - PANIC("Unsupported palette format");
> - }
> - break;
> - case SPICE_BITMAP_FMT_1BIT_BE:
> - if (palette_surface_format == SPICE_SURFACE_FMT_32_ARGB ||
> - palette_surface_format == SPICE_SURFACE_FMT_32_xRGB) {
> - bitmap_1be_32_to_32(dest, dest_stride, src, src_stride, width, end, palette);
> - } else if (palette_surface_format == SPICE_SURFACE_FMT_16_555) {
> - bitmap_1be_16_to_16_555(dest, dest_stride, src, src_stride, width, end, palette);
> - } else {
> - PANIC("Unsupported palette format");
> - }
> - break;
> - default:
> - PANIC("Unsupported bitmap format");
> - break;
> - }
> -
> - return dest_image;
> -}
> -
> -static int pixman_format_compatible (pixman_format_code_t dest_format,
> - pixman_format_code_t src_format)
> -{
> - if (dest_format == src_format) {
> - return TRUE;
> - }
> -
> - if (src_format == PIXMAN_a8r8g8b8&&
> - dest_format == PIXMAN_x8r8g8b8) {
> - /* This is the same, we just ignore the alphas */
> - return TRUE;
> - }
> -
> - return FALSE;
> -}
> -
> -pixman_image_t *spice_bitmap_convert_to_pixman(pixman_format_code_t dest_format,
> - pixman_image_t *dest_image,
> - int src_format,
> - int flags,
> - int width,
> - int height,
> - uint8_t *src,
> - int src_stride,
> - uint32_t palette_surface_format,
> - SpicePalette *palette)
> -{
> - pixman_image_t *src_image;
> - pixman_format_code_t native_format;
> -
> - if (dest_image == NULL) {
> - dest_image = pixman_image_create_bits (dest_format,
> - width, height,
> - NULL, 0);
> - }
> -
> - native_format =
> - spice_bitmap_format_to_pixman(src_format, palette_surface_format);
> -
> - if (pixman_format_compatible (dest_format, native_format)) {
> - return spice_bitmap_to_pixman(dest_image,
> - src_format,
> - flags, width,height,
> - src, src_stride,
> - palette_surface_format, palette);
> - }
> -
> - src_image = spice_bitmap_try_as_pixman(src_format,
> - flags, width,height,
> - src, src_stride);
> -
> - /* Can't convert directly, need a temporary copy
> - * Hopefully most bitmap reads should not need conversion (i.e.
> - * hit the spice_bitmap_to_pixmap case above) or work with the
> - * try_as_pixmap case, but in case some specific combination
> - * shows up here commonly we might want to add non-temporary
> - * conversion special casing here */
> - if (src_image == NULL) {
> - src_image = spice_bitmap_to_pixman(NULL,
> - src_format,
> - flags, width,height,
> - src, src_stride,
> - palette_surface_format, palette);
> - }
> -
> - pixman_image_composite32 (PIXMAN_OP_SRC,
> - src_image, NULL, dest_image,
> - 0, 0,
> - 0, 0,
> - 0, 0,
> - width, height);
> -
> - pixman_image_unref (src_image);
> -
> - return dest_image;
> -}
> diff --git a/common/pixman_utils.h b/common/pixman_utils.h
> deleted file mode 100644
> index e15b682..0000000
> --- a/common/pixman_utils.h
> +++ /dev/null
> @@ -1,128 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H__PIXMAN_UTILS
> -#define _H__PIXMAN_UTILS
> -
> -#include<spice/types.h>
> -#include<stdlib.h>
> -#define PIXMAN_DONT_DEFINE_STDINT
> -#include<pixman.h>
> -
> -#include "draw.h"
> -
> -/* This lists all possible 2 argument binary raster ops.
> - * This enum has the same values as the X11 GXcopy type
> - * and same as the GL constants (GL_AND etc) if you
> - * or it with 0x1500. However it is not exactly the
> - * same as the win32 ROP2 type (they use another order).
> - */
> -typedef enum {
> - SPICE_ROP_CLEAR, /* 0x0 0 */
> - SPICE_ROP_AND, /* 0x1 src AND dst */
> - SPICE_ROP_AND_REVERSE, /* 0x2 src AND NOT dst */
> - SPICE_ROP_COPY, /* 0x3 src */
> - SPICE_ROP_AND_INVERTED, /* 0x4 (NOT src) AND dst */
> - SPICE_ROP_NOOP, /* 0x5 dst */
> - SPICE_ROP_XOR, /* 0x6 src XOR dst */
> - SPICE_ROP_OR, /* 0x7 src OR dst */
> - SPICE_ROP_NOR, /* 0x8 (NOT src) AND (NOT dst) */
> - SPICE_ROP_EQUIV, /* 0x9 (NOT src) XOR dst */
> - SPICE_ROP_INVERT, /* 0xa NOT dst */
> - SPICE_ROP_OR_REVERSE, /* 0xb src OR (NOT dst) */
> - SPICE_ROP_COPY_INVERTED, /* 0xc NOT src */
> - SPICE_ROP_OR_INVERTED, /* 0xd (NOT src) OR dst */
> - SPICE_ROP_NAND, /* 0xe (NOT src) OR (NOT dst) */
> - SPICE_ROP_SET /* 0xf 1 */
> -} SpiceROP;
> -
> -
> -int spice_pixman_image_get_bpp(pixman_image_t *image);
> -
> -pixman_format_code_t spice_surface_format_to_pixman(uint32_t surface_format);
> -pixman_format_code_t spice_bitmap_format_to_pixman(int bitmap_format,
> - uint32_t palette_surface_format);
> -pixman_image_t *spice_bitmap_try_as_pixman(int src_format, int flags,
> - int width, int height,
> - uint8_t *data, int stride);
> -pixman_image_t *spice_bitmap_to_pixman(pixman_image_t *dest_image,
> - int src_format, int flags,
> - int width, int height,
> - uint8_t *src, int src_stride,
> - uint32_t palette_surface_format,
> - SpicePalette *palette);
> -pixman_image_t *spice_bitmap_convert_to_pixman(pixman_format_code_t dest_format,
> - pixman_image_t *dest_image,
> - int src_format, int flags,
> - int width, int height,
> - uint8_t *src, int src_stride,
> - uint32_t palette_surface_format,
> - SpicePalette *palette);
> -
> -void spice_pixman_region32_init_from_bitmap(pixman_region32_t *region,
> - uint32_t *data,
> - int width, int height,
> - int stride);
> -pixman_bool_t spice_pixman_region32_init_rects(pixman_region32_t *region,
> - const SpiceRect *rects,
> - int count);
> -void spice_pixman_fill_rect(pixman_image_t *dest,
> - int x, int y,
> - int w, int h,
> - uint32_t value);
> -void spice_pixman_fill_rect_rop(pixman_image_t *dest,
> - int x, int y,
> - int w, int h,
> - uint32_t value,
> - SpiceROP rop);
> -void spice_pixman_tile_rect(pixman_image_t *dest,
> - int x, int y,
> - int w, int h,
> - pixman_image_t *tile,
> - int offset_x,
> - int offset_y);
> -void spice_pixman_tile_rect_rop(pixman_image_t *dest,
> - int x, int y,
> - int w, int h,
> - pixman_image_t *tile,
> - int offset_x,
> - int offset_y,
> - SpiceROP rop);
> -void spice_pixman_blit(pixman_image_t *dest,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int dest_x, int dest_y,
> - int w, int h);
> -void spice_pixman_blit_rop(pixman_image_t *dest,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int dest_x, int dest_y,
> - int w, int h,
> - SpiceROP rop);
> -void spice_pixman_blit_colorkey(pixman_image_t *dest,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int dest_x, int dest_y,
> - int width, int height,
> - uint32_t transparent_color);
> -void spice_pixman_copy_rect(pixman_image_t *image,
> - int src_x, int src_y,
> - int w, int h,
> - int dest_x, int dest_y);
> -
> -#endif /* _H__PIXMAN_UTILS */
> diff --git a/common/quic.c b/common/quic.c
> deleted file mode 100644
> index 9f2c978..0000000
> --- a/common/quic.c
> +++ /dev/null
> @@ -1,1706 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -// Red Hat image compression based on SFALIC by Roman Starosolski
> -// http://sun.iinf.polsl.gliwice.pl/~rstaros/sfalic/index.html
> -
> -#include "quic.h"
> -#include<spice/macros.h>
> -
> -//#define DEBUG
> -
> -#define RLE
> -#define RLE_STAT
> -#define PRED_1
> -//#define RLE_PRED_1
> -#define RLE_PRED_2
> -//#define RLE_PRED_3
> -#define QUIC_RGB
> -
> -#define QUIC_MAGIC (*(uint32_t *)"QUIC")
> -#define QUIC_VERSION_MAJOR 0U
> -#define QUIC_VERSION_MINOR 1U
> -#define QUIC_VERSION ((QUIC_VERSION_MAJOR<< 16) | (QUIC_VERSION_MAJOR& 0xffff))
> -
> -#ifdef DEBUG
> -
> -#define ASSERT(usr, x) \
> - if (!(x)) (usr)->error(usr, "%s: ASSERT %s failed\n", __FUNCTION__, #x);
> -
> -#else
> -
> -#define ASSERT(usr, x)
> -
> -#endif
> -
> -typedef uint8_t BYTE;
> -
> -/* maximum number of codes in family */
> -#define MAXNUMCODES 8
> -
> -/* model evolution, warning: only 1,3 and 5 allowed */
> -#define DEFevol 3
> -#define MINevol 0
> -#define MAXevol 5
> -
> -/* starting wait mask index */
> -#define DEFwmistart 0
> -#define MINwmistart 0
> -
> -/* codeword length limit */
> -#define DEFmaxclen 26
> -
> -/* target wait mask index */
> -#define DEFwmimax 6
> -
> -/* number of symbols to encode before increasing wait mask index */
> -#define DEFwminext 2048
> -#define MINwminext 1
> -#define MAXwminext 100000000
> -
> -typedef struct QuicFamily {
> - unsigned int nGRcodewords[MAXNUMCODES]; /* indexed by code number, contains number of
> - unmodified GR codewords in the code */
> - unsigned int notGRcwlen[MAXNUMCODES]; /* indexed by code number, contains codeword
> - length of the not-GR codeword */
> - unsigned int notGRprefixmask[MAXNUMCODES]; /* indexed by code number, contains mask to
> - determine if the codeword is GR or not-GR */
> - unsigned int notGRsuffixlen[MAXNUMCODES]; /* indexed by code number, contains suffix
> - length of the not-GR codeword */
> -
> - /* array for translating distribution U to L for depths up to 8 bpp,
> - initialized by decorelateinit() */
> - BYTE xlatU2L[256];
> -
> - /* array for translating distribution L to U for depths up to 8 bpp,
> - initialized by corelateinit() */
> - unsigned int xlatL2U[256];
> -} QuicFamily;
> -
> -static QuicFamily family_8bpc;
> -static QuicFamily family_5bpc;
> -
> -typedef unsigned COUNTER; /* counter in the array of counters in bucket of the data model */
> -
> -typedef struct s_bucket {
> - COUNTER *pcounters; /* pointer to array of counters */
> - unsigned int bestcode; /* best code so far */
> -} s_bucket;
> -
> -typedef struct Encoder Encoder;
> -
> -typedef struct CommonState {
> - Encoder *encoder;
> -
> - unsigned int waitcnt;
> - unsigned int tabrand_seed;
> - unsigned int wm_trigger;
> - unsigned int wmidx;
> - unsigned int wmileft;
> -
> -#ifdef RLE_STAT
> - int melcstate; /* index to the state array */
> -
> - int melclen; /* contents of the state array location
> - indexed by melcstate: the "expected"
> - run length is 2^melclen, shorter runs are
> - encoded by a 1 followed by the run length
> - in binary representation, wit a fixed length
> - of melclen bits */
> -
> - unsigned long melcorder; /* 2^ melclen */
> -#endif
> -} CommonState;
> -
> -
> -#define MAX_CHANNELS 4
> -
> -typedef struct FamilyStat {
> - s_bucket **buckets_ptrs;
> - s_bucket *buckets_buf;
> - COUNTER *counters;
> -} FamilyStat;
> -
> -typedef struct Channel {
> - Encoder *encoder;
> -
> - int correlate_row_width;
> - BYTE *correlate_row;
> -
> - s_bucket **_buckets_ptrs;
> -
> - FamilyStat family_stat_8bpc;
> - FamilyStat family_stat_5bpc;
> -
> - CommonState state;
> -} Channel;
> -
> -struct Encoder {
> - QuicUsrContext *usr;
> - QuicImageType type;
> - unsigned int width;
> - unsigned int height;
> - unsigned int num_channels;
> -
> - unsigned int n_buckets_8bpc;
> - unsigned int n_buckets_5bpc;
> -
> - unsigned int io_available_bits;
> - uint32_t io_word;
> - uint32_t io_next_word;
> - uint32_t *io_now;
> - uint32_t *io_end;
> - uint32_t io_words_count;
> -
> - int rows_completed;
> -
> - Channel channels[MAX_CHANNELS];
> -
> - CommonState rgb_state;
> -};
> -
> -/* target wait mask index */
> -static int wmimax = DEFwmimax;
> -
> -/* number of symbols to encode before increasing wait mask index */
> -static int wminext = DEFwminext;
> -
> -/* model evolution mode */
> -static int evol = DEFevol;
> -
> -/* bppmask[i] contains i ones as lsb-s */
> -static const unsigned long int bppmask[33] = {
> - 0x00000000, /* [0] */
> - 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
> - 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
> - 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
> - 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
> - 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
> - 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
> - 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
> - 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff /* [32] */
> -};
> -
> -static const unsigned int bitat[32] = {
> - 0x00000001, 0x00000002, 0x00000004, 0x00000008,
> - 0x00000010, 0x00000020, 0x00000040, 0x00000080,
> - 0x00000100, 0x00000200, 0x00000400, 0x00000800,
> - 0x00001000, 0x00002000, 0x00004000, 0x00008000,
> - 0x00010000, 0x00020000, 0x00040000, 0x00080000,
> - 0x00100000, 0x00200000, 0x00400000, 0x00800000,
> - 0x01000000, 0x02000000, 0x04000000, 0x08000000,
> - 0x10000000, 0x20000000, 0x40000000, 0x80000000 /* [31]*/
> -};
> -
> -
> -#define TABRAND_TABSIZE 256
> -#define TABRAND_SEEDMASK 0x0ff
> -
> -static const unsigned int tabrand_chaos[TABRAND_TABSIZE] = {
> - 0x02c57542, 0x35427717, 0x2f5a2153, 0x9244f155, 0x7bd26d07, 0x354c6052, 0x57329b28, 0x2993868e,
> - 0x6cd8808c, 0x147b46e0, 0x99db66af, 0xe32b4cac, 0x1b671264, 0x9d433486, 0x62a4c192, 0x06089a4b,
> - 0x9e3dce44, 0xdaabee13, 0x222425ea, 0xa46f331d, 0xcd589250, 0x8bb81d7f, 0xc8b736b9, 0x35948d33,
> - 0xd7ac7fd0, 0x5fbe2803, 0x2cfbc105, 0x013dbc4e, 0x7a37820f, 0x39f88e9e, 0xedd58794, 0xc5076689,
> - 0xfcada5a4, 0x64c2f46d, 0xb3ba3243, 0x8974b4f9, 0x5a05aebd, 0x20afcd00, 0x39e2b008, 0x88a18a45,
> - 0x600bde29, 0xf3971ace, 0xf37b0a6b, 0x7041495b, 0x70b707ab, 0x06beffbb, 0x4206051f, 0xe13c4ee3,
> - 0xc1a78327, 0x91aa067c, 0x8295f72a, 0x732917a6, 0x1d871b4d, 0x4048f136, 0xf1840e7e, 0x6a6048c1,
> - 0x696cb71a, 0x7ff501c3, 0x0fc6310b, 0x57e0f83d, 0x8cc26e74, 0x11a525a2, 0x946934c7, 0x7cd888f0,
> - 0x8f9d8604, 0x4f86e73b, 0x04520316, 0xdeeea20c, 0xf1def496, 0x67687288, 0xf540c5b2, 0x22401484,
> - 0x3478658a, 0xc2385746, 0x01979c2c, 0x5dad73c8, 0x0321f58b, 0xf0fedbee, 0x92826ddf, 0x284bec73,
> - 0x5b1a1975, 0x03df1e11, 0x20963e01, 0xa17cf12b, 0x740d776e, 0xa7a6bf3c, 0x01b5cce4, 0x1118aa76,
> - 0xfc6fac0a, 0xce927e9b, 0x00bf2567, 0x806f216c, 0xbca69056, 0x795bd3e9, 0xc9dc4557, 0x8929b6c2,
> - 0x789d52ec, 0x3f3fbf40, 0xb9197368, 0xa38c15b5, 0xc3b44fa8, 0xca8333b0, 0xb7e8d590, 0xbe807feb,
> - 0xbf5f8360, 0xd99e2f5c, 0x372928e1, 0x7c757c4c, 0x0db5b154, 0xc01ede02, 0x1fc86e78, 0x1f3985be,
> - 0xb4805c77, 0x00c880fa, 0x974c1b12, 0x35ab0214, 0xb2dc840d, 0x5b00ae37, 0xd313b026, 0xb260969d,
> - 0x7f4c8879, 0x1734c4d3, 0x49068631, 0xb9f6a021, 0x6b863e6f, 0xcee5debf, 0x29f8c9fb, 0x53dd6880,
> - 0x72b61223, 0x1f67a9fd, 0x0a0f6993, 0x13e59119, 0x11cca12e, 0xfe6b6766, 0x16b6effc, 0x97918fc4,
> - 0xc2b8a563, 0x94f2f741, 0x0bfa8c9a, 0xd1537ae8, 0xc1da349c, 0x873c60ca, 0x95005b85, 0x9b5c080e,
> - 0xbc8abbd9, 0xe1eab1d2, 0x6dac9070, 0x4ea9ebf1, 0xe0cf30d4, 0x1ef5bd7b, 0xd161043e, 0x5d2fa2e2,
> - 0xff5d3cae, 0x86ed9f87, 0x2aa1daa1, 0xbd731a34, 0x9e8f4b22, 0xb1c2c67a, 0xc21758c9, 0xa182215d,
> - 0xccb01948, 0x8d168df7, 0x04238cfe, 0x368c3dbc, 0x0aeadca5, 0xbad21c24, 0x0a71fee5, 0x9fc5d872,
> - 0x54c152c6, 0xfc329483, 0x6783384a, 0xeddb3e1c, 0x65f90e30, 0x884ad098, 0xce81675a, 0x4b372f7d,
> - 0x68bf9a39, 0x43445f1e, 0x40f8d8cb, 0x90d5acb6, 0x4cd07282, 0x349eeb06, 0x0c9d5332, 0x520b24ef,
> - 0x80020447, 0x67976491, 0x2f931ca3, 0xfe9b0535, 0xfcd30220, 0x61a9e6cc, 0xa487d8d7, 0x3f7c5dd1,
> - 0x7d0127c5, 0x48f51d15, 0x60dea871, 0xc9a91cb7, 0x58b53bb3, 0x9d5e0b2d, 0x624a78b4, 0x30dbee1b,
> - 0x9bdf22e7, 0x1df5c299, 0x2d5643a7, 0xf4dd35ff, 0x03ca8fd6, 0x53b47ed8, 0x6f2c19aa, 0xfeb0c1f4,
> - 0x49e54438, 0x2f2577e6, 0xbf876969, 0x72440ea9, 0xfa0bafb8, 0x74f5b3a0, 0x7dd357cd, 0x89ce1358,
> - 0x6ef2cdda, 0x1e7767f3, 0xa6be9fdb, 0x4f5f88f8, 0xba994a3a, 0x08ca6b65, 0xe0893818, 0x9e00a16a,
> - 0xf42bfc8f, 0x9972eedc, 0x749c8b51, 0x32c05f5e, 0xd706805f, 0x6bfbb7cf, 0xd9210a10, 0x31a1db97,
> - 0x923a9559, 0x37a7a1f6, 0x059f8861, 0xca493e62, 0x65157e81, 0x8f6467dd, 0xab85ff9f, 0x9331aff2,
> - 0x8616b9f5, 0xedbd5695, 0xee7e29b1, 0x313ac44f, 0xb903112f, 0x432ef649, 0xdc0a36c0, 0x61cf2bba,
> - 0x81474925, 0xa8b6c7ad, 0xee5931de, 0xb2f8158d, 0x59fb7409, 0x2e3dfaed, 0x9af25a3f, 0xe1fed4d5,
> -};
> -
> -static unsigned int stabrand(void)
> -{
> - //ASSERT( !(TABRAND_SEEDMASK& TABRAND_TABSIZE));
> - //ASSERT( TABRAND_SEEDMASK + 1 == TABRAND_TABSIZE );
> -
> - return TABRAND_SEEDMASK;
> -}
> -
> -static unsigned int tabrand(unsigned int *tabrand_seed)
> -{
> - return tabrand_chaos[++*tabrand_seed& TABRAND_SEEDMASK];
> -}
> -
> -static const unsigned short besttrigtab[3][11] = { /* array of wm_trigger for waitmask and evol,
> - used by set_wm_trigger() */
> - /* 1 */ { 550, 900, 800, 700, 500, 350, 300, 200, 180, 180, 160},
> - /* 3 */ { 110, 550, 900, 800, 550, 400, 350, 250, 140, 160, 140},
> - /* 5 */ { 100, 120, 550, 900, 700, 500, 400, 300, 220, 250, 160}
> -};
> -
> -/* set wm_trigger knowing waitmask (param) and evol (glob)*/
> -static void set_wm_trigger(CommonState *state)
> -{
> - unsigned int wm = state->wmidx;
> - if (wm> 10) {
> - wm = 10;
> - }
> -
> - ASSERT(state->encoder->usr, evol< 6);
> -
> - state->wm_trigger = besttrigtab[evol / 2][wm];
> -
> - ASSERT(state->encoder->usr, state->wm_trigger<= 2000);
> - ASSERT(state->encoder->usr, state->wm_trigger>= 1);
> -}
> -
> -static int ceil_log_2(int val) /* ceil(log_2(val)) */
> -{
> - int result;
> -
> - //ASSERT(val>0);
> -
> - if (val == 1) {
> - return 0;
> - }
> -
> - result = 1;
> - val -= 1;
> - while (val>>= 1) {
> - result++;
> - }
> -
> - return result;
> -}
> -
> -/* number of leading zeroes in the byte, used by cntlzeroes(uint)*/
> -static const BYTE lzeroes[256] = {
> - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
> - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
> -};
> -
> -/* count leading zeroes */
> -static unsigned int cnt_l_zeroes(const unsigned int bits)
> -{
> - if (bits& 0xff800000) {
> - return lzeroes[bits>> 24];
> - } else if (bits& 0xffff8000) {
> - return 8 + lzeroes[(bits>> 16)& 0x000000ff];
> - } else if (bits& 0xffffff80) {
> - return 16 + lzeroes[(bits>> 8)& 0x000000ff];
> - } else {
> - return 24 + lzeroes[bits& 0x000000ff];
> - }
> -}
> -
> -#define QUIC_FAMILY_8BPC
> -#include "quic_family_tmpl.c"
> -
> -#ifdef QUIC_RGB
> -#define QUIC_FAMILY_5BPC
> -#include "quic_family_tmpl.c"
> -#endif
> -
> -static void decorelate_init(QuicFamily *family, int bpc)
> -{
> - const unsigned int pixelbitmask = bppmask[bpc];
> - const unsigned int pixelbitmaskshr = pixelbitmask>> 1;
> - unsigned int s;
> -
> - //ASSERT(bpc<= 8);
> -
> - for (s = 0; s<= pixelbitmask; s++) {
> - if (s<= pixelbitmaskshr) {
> - family->xlatU2L[s] = s<< 1;
> - } else {
> - family->xlatU2L[s] = ((pixelbitmask - s)<< 1) + 1;
> - }
> - }
> -}
> -
> -static void corelate_init(QuicFamily *family, int bpc)
> -{
> - const unsigned long int pixelbitmask = bppmask[bpc];
> - unsigned long int s;
> -
> - //ASSERT(bpc<= 8);
> -
> - for (s = 0; s<= pixelbitmask; s++) {
> - if (s& 0x01) {
> - family->xlatL2U[s] = pixelbitmask - (s>> 1);
> - } else {
> - family->xlatL2U[s] = (s>> 1);
> - }
> - }
> -}
> -
> -static void family_init(QuicFamily *family, int bpc, int limit)
> -{
> - int l;
> -
> - for (l = 0; l< bpc; l++) { /* fill arrays indexed by code number */
> - int altprefixlen, altcodewords;
> -
> - altprefixlen = limit - bpc;
> - if (altprefixlen> (int)(bppmask[bpc - l])) {
> - altprefixlen = bppmask[bpc - l];
> - }
> -
> - altcodewords = bppmask[bpc] + 1 - (altprefixlen<< l);
> -
> - family->nGRcodewords[l] = (altprefixlen<< l);
> - family->notGRcwlen[l] = altprefixlen + ceil_log_2(altcodewords);
> - family->notGRprefixmask[l] = bppmask[32 - altprefixlen]; /* needed for decoding only */
> - family->notGRsuffixlen[l] = ceil_log_2(altcodewords); /* needed for decoding only */
> - }
> -
> - decorelate_init(family, bpc);
> - corelate_init(family, bpc);
> -}
> -
> -static void more_io_words(Encoder *encoder)
> -{
> - uint32_t *io_ptr;
> - int num_io_words = encoder->usr->more_space(encoder->usr,&io_ptr, encoder->rows_completed);
> - if (num_io_words<= 0) {
> - encoder->usr->error(encoder->usr, "%s: no more words\n", __FUNCTION__);
> - }
> - ASSERT(encoder->usr, io_ptr);
> - encoder->io_words_count += num_io_words;
> - encoder->io_now = io_ptr;
> - encoder->io_end = encoder->io_now + num_io_words;
> -}
> -
> -static void __write_io_word(Encoder *encoder)
> -{
> - more_io_words(encoder);
> - *(encoder->io_now++) = encoder->io_word;
> -}
> -
> -static void (*__write_io_word_ptr)(Encoder *encoder) = __write_io_word;
> -
> -static INLINE void write_io_word(Encoder *encoder)
> -{
> - if (encoder->io_now == encoder->io_end) {
> - __write_io_word_ptr(encoder); //disable inline optimizations
> - return;
> - }
> - *(encoder->io_now++) = encoder->io_word;
> -}
> -
> -static INLINE void encode(Encoder *encoder, unsigned int word, unsigned int len)
> -{
> - int delta;
> -
> - ASSERT(encoder->usr, len> 0&& len< 32);
> - ASSERT(encoder->usr, !(word& ~bppmask[len]));
> - if ((delta = ((int)encoder->io_available_bits - len))>= 0) {
> - encoder->io_available_bits = delta;
> - encoder->io_word |= word<< encoder->io_available_bits;
> - return;
> - }
> - delta = -delta;
> - encoder->io_word |= word>> delta;
> - write_io_word(encoder);
> - encoder->io_available_bits = 32 - delta;
> - encoder->io_word = word<< encoder->io_available_bits;
> -
> - ASSERT(encoder->usr, encoder->io_available_bits< 32);
> - ASSERT(encoder->usr, (encoder->io_word& bppmask[encoder->io_available_bits]) == 0);
> -}
> -
> -static INLINE void encode_32(Encoder *encoder, unsigned int word)
> -{
> - encode(encoder, word>> 16, 16);
> - encode(encoder, word& 0x0000ffff, 16);
> -}
> -
> -static INLINE void flush(Encoder *encoder)
> -{
> - if (encoder->io_available_bits> 0&& encoder->io_available_bits != 32) {
> - encode(encoder, 0, encoder->io_available_bits);
> - }
> - encode_32(encoder, 0);
> - encode(encoder, 0, 1);
> -}
> -
> -static void __read_io_word(Encoder *encoder)
> -{
> - more_io_words(encoder);
> - encoder->io_next_word = *(encoder->io_now++);
> -}
> -
> -static void (*__read_io_word_ptr)(Encoder *encoder) = __read_io_word;
> -
> -
> -static INLINE void read_io_word(Encoder *encoder)
> -{
> - if (encoder->io_now == encoder->io_end) {
> - __read_io_word_ptr(encoder); //disable inline optimizations
> - return;
> - }
> - ASSERT(encoder->usr, encoder->io_now< encoder->io_end);
> - encoder->io_next_word = *(encoder->io_now++);
> -}
> -
> -static INLINE void decode_eatbits(Encoder *encoder, int len)
> -{
> - int delta;
> -
> - ASSERT(encoder->usr, len> 0&& len< 32);
> - encoder->io_word<<= len;
> -
> - if ((delta = ((int)encoder->io_available_bits - len))>= 0) {
> - encoder->io_available_bits = delta;
> - encoder->io_word |= encoder->io_next_word>> encoder->io_available_bits;
> - return;
> - }
> -
> - delta = -delta;
> - encoder->io_word |= encoder->io_next_word<< delta;
> - read_io_word(encoder);
> - encoder->io_available_bits = 32 - delta;
> - encoder->io_word |= (encoder->io_next_word>> encoder->io_available_bits);
> -}
> -
> -static INLINE void decode_eat32bits(Encoder *encoder)
> -{
> - decode_eatbits(encoder, 16);
> - decode_eatbits(encoder, 16);
> -}
> -
> -#ifdef RLE
> -
> -#ifdef RLE_STAT
> -
> -static INLINE void encode_ones(Encoder *encoder, unsigned int n)
> -{
> - unsigned int count;
> -
> - for (count = n>> 5; count; count--) {
> - encode(encoder, ~0U, 32);
> - }
> -
> - if ((n&= 0x1f)) {
> - encode(encoder, (1U<< n) - 1, n);
> - }
> -}
> -
> -#define MELCSTATES 32 /* number of melcode states */
> -
> -static int zeroLUT[256]; /* table to find out number of leading zeros */
> -
> -static int J[MELCSTATES] = {
> - 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7,
> - 7, 8, 9, 10, 11, 12, 13, 14, 15
> -};
> -
> -/* creates the bit counting look-up table. */
> -static void init_zeroLUT(void)
> -{
> - int i, j, k, l;
> -
> - j = k = 1;
> - l = 8;
> - for (i = 0; i< 256; ++i) {
> - zeroLUT[i] = l;
> - --k;
> - if (k == 0) {
> - k = j;
> - --l;
> - j *= 2;
> - }
> - }
> -}
> -
> -static void encoder_init_rle(CommonState *state)
> -{
> - state->melcstate = 0;
> - state->melclen = J[0];
> - state->melcorder = 1<< state->melclen;
> -}
> -
> -#ifdef QUIC_RGB
> -
> -static void encode_run(Encoder *encoder, unsigned int runlen) //todo: try use end of line
> -{
> - int hits = 0;
> -
> - while (runlen>= encoder->rgb_state.melcorder) {
> - hits++;
> - runlen -= encoder->rgb_state.melcorder;
> - if (encoder->rgb_state.melcstate< MELCSTATES) {
> - encoder->rgb_state.melclen = J[++encoder->rgb_state.melcstate];
> - encoder->rgb_state.melcorder = (1L<< encoder->rgb_state.melclen);
> - }
> - }
> -
> - /* send the required number of "hit" bits (one per occurrence
> - of a run of length melcorder). This number is never too big:
> - after 31 such "hit" bits, each "hit" would represent a run of 32K
> - pixels.
> - */
> - encode_ones(encoder, hits);
> -
> - encode(encoder, runlen, encoder->rgb_state.melclen + 1);
> -
> - /* adjust melcoder parameters */
> - if (encoder->rgb_state.melcstate) {
> - encoder->rgb_state.melclen = J[--encoder->rgb_state.melcstate];
> - encoder->rgb_state.melcorder = (1L<< encoder->rgb_state.melclen);
> - }
> -}
> -
> -#endif
> -
> -static void encode_channel_run(Encoder *encoder, Channel *channel, unsigned int runlen)
> -{
> - //todo: try use end of line
> - int hits = 0;
> -
> - while (runlen>= channel->state.melcorder) {
> - hits++;
> - runlen -= channel->state.melcorder;
> - if (channel->state.melcstate< MELCSTATES) {
> - channel->state.melclen = J[++channel->state.melcstate];
> - channel->state.melcorder = (1L<< channel->state.melclen);
> - }
> - }
> -
> - /* send the required number of "hit" bits (one per occurrence
> - of a run of length melcorder). This number is never too big:
> - after 31 such "hit" bits, each "hit" would represent a run of 32K
> - pixels.
> - */
> - encode_ones(encoder, hits);
> -
> - encode(encoder, runlen, channel->state.melclen + 1);
> -
> - /* adjust melcoder parameters */
> - if (channel->state.melcstate) {
> - channel->state.melclen = J[--channel->state.melcstate];
> - channel->state.melcorder = (1L<< channel->state.melclen);
> - }
> -}
> -
> -/* decoding routine: reads bits from the input and returns a run length. */
> -/* argument is the number of pixels left to end-of-line (bound on run length) */
> -
> -#ifdef QUIC_RGB
> -static int decode_run(Encoder *encoder)
> -{
> - int runlen = 0;
> -
> - do {
> - register int temp, hits;
> - temp = zeroLUT[(BYTE)(~(encoder->io_word>> 24))];/* number of leading ones in the
> - input stream, up to 8 */
> - for (hits = 1; hits<= temp; hits++) {
> - runlen += encoder->rgb_state.melcorder;
> -
> - if (encoder->rgb_state.melcstate< MELCSTATES) {
> - encoder->rgb_state.melclen = J[++encoder->rgb_state.melcstate];
> - encoder->rgb_state.melcorder = (1U<< encoder->rgb_state.melclen);
> - }
> - }
> - if (temp != 8) {
> - decode_eatbits(encoder, temp + 1); /* consume the leading
> - 0 of the remainder encoding */
> - break;
> - }
> - decode_eatbits(encoder, 8);
> - } while (1);
> -
> - /* read the length of the remainder */
> - if (encoder->rgb_state.melclen) {
> - runlen += encoder->io_word>> (32 - encoder->rgb_state.melclen);
> - decode_eatbits(encoder, encoder->rgb_state.melclen);
> - }
> -
> - /* adjust melcoder parameters */
> - if (encoder->rgb_state.melcstate) {
> - encoder->rgb_state.melclen = J[--encoder->rgb_state.melcstate];
> - encoder->rgb_state.melcorder = (1U<< encoder->rgb_state.melclen);
> - }
> -
> - return runlen;
> -}
> -
> -#endif
> -
> -static int decode_channel_run(Encoder *encoder, Channel *channel)
> -{
> - int runlen = 0;
> -
> - do {
> - register int temp, hits;
> - temp = zeroLUT[(BYTE)(~(encoder->io_word>> 24))];/* number of leading ones in the
> - input stream, up to 8 */
> - for (hits = 1; hits<= temp; hits++) {
> - runlen += channel->state.melcorder;
> -
> - if (channel->state.melcstate< MELCSTATES) {
> - channel->state.melclen = J[++channel->state.melcstate];
> - channel->state.melcorder = (1U<< channel->state.melclen);
> - }
> - }
> - if (temp != 8) {
> - decode_eatbits(encoder, temp + 1); /* consume the leading
> - 0 of the remainder encoding */
> - break;
> - }
> - decode_eatbits(encoder, 8);
> - } while (1);
> -
> - /* read the length of the remainder */
> - if (channel->state.melclen) {
> - runlen += encoder->io_word>> (32 - channel->state.melclen);
> - decode_eatbits(encoder, channel->state.melclen);
> - }
> -
> - /* adjust melcoder parameters */
> - if (channel->state.melcstate) {
> - channel->state.melclen = J[--channel->state.melcstate];
> - channel->state.melcorder = (1U<< channel->state.melclen);
> - }
> -
> - return runlen;
> -}
> -
> -#else
> -
> -static INLINE int find_msb(int x)
> -{
> - int r;
> -
> - __asm__("bsrl %1,%0\n\t"
> - "jnz 1f\n\t"
> - "movl $-1,%0\n"
> - "1:" : "=r" (r) : "rm" (x));
> - return r + 1;
> -}
> -
> -static INLINE void encode_run(Encoder *encoder, unsigned int len)
> -{
> - int odd = len& 1U;
> - int msb;
> -
> - len&= ~1U;
> -
> - while ((msb = find_msb(len))) {
> - len&= ~(1<< (msb - 1));
> - ASSERT(encoder->usr, msb< 32);
> - encode(encoder, (1<< (msb)) - 1, msb);
> - encode(encoder, 0, 1);
> - }
> -
> - if (odd) {
> - encode(encoder, 2, 2);
> - } else {
> - encode(encoder, 0, 1);
> - }
> -}
> -
> -static INLINE unsigned int decode_run(Encoder *encoder)
> -{
> - unsigned int len = 0;
> - int count;
> -
> - do {
> - count = 0;
> - while (encoder->io_word& (1U<< 31)) {
> - decode_eatbits(encoder, 1);
> - count++;
> - ASSERT(encoder->usr, count< 32);
> - }
> - decode_eatbits(encoder, 1);
> - len += (1U<< count)>> 1;
> - } while (count> 1);
> -
> - return len;
> -}
> -
> -#endif
> -#endif
> -
> -static INLINE void init_decode_io(Encoder *encoder)
> -{
> - encoder->io_next_word = encoder->io_word = *(encoder->io_now++);
> - encoder->io_available_bits = 0;
> -}
> -
> -#ifdef __GNUC__
> -#define ATTR_PACKED __attribute__ ((__packed__))
> -#else
> -#define ATTR_PACKED
> -#pragma pack(push)
> -#pragma pack(1)
> -#endif
> -
> -typedef struct ATTR_PACKED one_byte_pixel_t {
> - BYTE a;
> -} one_byte_t;
> -
> -typedef struct ATTR_PACKED three_bytes_pixel_t {
> - BYTE a;
> - BYTE b;
> - BYTE c;
> -} three_bytes_t;
> -
> -typedef struct ATTR_PACKED four_bytes_pixel_t {
> - BYTE a;
> - BYTE b;
> - BYTE c;
> - BYTE d;
> -} four_bytes_t;
> -
> -typedef struct ATTR_PACKED rgb32_pixel_t {
> - BYTE b;
> - BYTE g;
> - BYTE r;
> - BYTE pad;
> -} rgb32_pixel_t;
> -
> -typedef struct ATTR_PACKED rgb24_pixel_t {
> - BYTE b;
> - BYTE g;
> - BYTE r;
> -} rgb24_pixel_t;
> -
> -typedef uint16_t rgb16_pixel_t;
> -
> -#ifndef __GNUC__
> -#pragma pack(pop)
> -#endif
> -
> -#undef ATTR_PACKED
> -
> -#define ONE_BYTE
> -#include "quic_tmpl.c"
> -
> -#define FOUR_BYTE
> -#include "quic_tmpl.c"
> -
> -#ifdef QUIC_RGB
> -
> -#define QUIC_RGB32
> -#include "quic_rgb_tmpl.c"
> -
> -#define QUIC_RGB24
> -#include "quic_rgb_tmpl.c"
> -
> -#define QUIC_RGB16
> -#include "quic_rgb_tmpl.c"
> -
> -#define QUIC_RGB16_TO_32
> -#include "quic_rgb_tmpl.c"
> -
> -#else
> -
> -#define THREE_BYTE
> -#include "quic_tmpl.c"
> -
> -#endif
> -
> -static void fill_model_structures(Encoder *encoder, FamilyStat *family_stat,
> - unsigned int rep_first, unsigned int first_size,
> - unsigned int rep_next, unsigned int mul_size,
> - unsigned int levels, unsigned int ncounters,
> - unsigned int nbuckets, unsigned int n_buckets_ptrs)
> -{
> - unsigned int
> - bsize,
> - bstart,
> - bend = 0,
> - repcntr,
> - bnumber;
> -
> - COUNTER * free_counter = family_stat->counters;/* first free location in the array of
> - counters */
> -
> - bnumber = 0;
> -
> - repcntr = rep_first + 1; /* first bucket */
> - bsize = first_size;
> -
> - do { /* others */
> - if (bnumber) {
> - bstart = bend + 1;
> - } else {
> - bstart = 0;
> - }
> -
> - if (!--repcntr) {
> - repcntr = rep_next;
> - bsize *= mul_size;
> - }
> -
> - bend = bstart + bsize - 1;
> - if (bend + bsize>= levels) {
> - bend = levels - 1;
> - }
> -
> - family_stat->buckets_buf[bnumber].pcounters = free_counter;
> - free_counter += ncounters;
> -
> - ASSERT(encoder->usr, bstart< n_buckets_ptrs);
> - {
> - unsigned int i;
> - ASSERT(encoder->usr, bend< n_buckets_ptrs);
> - for (i = bstart; i<= bend; i++) {
> - family_stat->buckets_ptrs[i] = family_stat->buckets_buf + bnumber;
> - }
> - }
> -
> - bnumber++;
> - } while (bend< levels - 1);
> -
> - ASSERT(encoder->usr, free_counter - family_stat->counters == nbuckets * ncounters);
> -}
> -
> -static void find_model_params(Encoder *encoder,
> - const int bpc,
> - unsigned int *ncounters,
> - unsigned int *levels,
> - unsigned int *n_buckets_ptrs,
> - unsigned int *repfirst,
> - unsigned int *firstsize,
> - unsigned int *repnext,
> - unsigned int *mulsize,
> - unsigned int *nbuckets)
> -{
> - unsigned int bsize; /* bucket size */
> - unsigned int bstart, bend = 0; /* bucket start and end, range : 0 to levels-1*/
> - unsigned int repcntr; /* helper */
> -
> - ASSERT(encoder->usr, bpc<= 8&& bpc> 0);
> -
> -
> - *ncounters = 8;
> -
> - *levels = 0x1<< bpc;
> -
> - *n_buckets_ptrs = 0; /* ==0 means: not set yet */
> -
> - switch (evol) { /* set repfirst firstsize repnext mulsize */
> - case 1: /* buckets contain following numbers of contexts: 1 1 1 2 2 4 4 8 8 ... */
> - *repfirst = 3;
> - *firstsize = 1;
> - *repnext = 2;
> - *mulsize = 2;
> - break;
> - case 3: /* 1 2 4 8 16 32 64 ... */
> - *repfirst = 1;
> - *firstsize = 1;
> - *repnext = 1;
> - *mulsize = 2;
> - break;
> - case 5: /* 1 4 16 64 256 1024 4096 16384 65536 */
> - *repfirst = 1;
> - *firstsize = 1;
> - *repnext = 1;
> - *mulsize = 4;
> - break;
> - case 0: /* obsolete */
> - case 2: /* obsolete */
> - case 4: /* obsolete */
> - encoder->usr->error(encoder->usr, "findmodelparams(): evol value obsolete!!!\n");
> - default:
> - encoder->usr->error(encoder->usr, "findmodelparams(): evol out of range!!!\n");
> - }
> -
> - *nbuckets = 0;
> - repcntr = *repfirst + 1; /* first bucket */
> - bsize = *firstsize;
> -
> - do { /* other buckets */
> - if (nbuckets) { /* bucket start */
> - bstart = bend + 1;
> - } else {
> - bstart = 0;
> - }
> -
> - if (!--repcntr) { /* bucket size */
> - repcntr = *repnext;
> - bsize *= *mulsize;
> - }
> -
> - bend = bstart + bsize - 1; /* bucket end */
> - if (bend + bsize>= *levels) { /* if following bucked was bigger than current one */
> - bend = *levels - 1; /* concatenate them */
> - }
> -
> - if (!*n_buckets_ptrs) { /* array size not set yet? */
> - *n_buckets_ptrs = *levels;
> - #if 0
> - if (bend == *levels - 1) { /* this bucket is last - all in the first array */
> - *n_buckets_ptrs = *levels;
> - } else if (bsize>= 256) { /* this bucket is allowed to reside in the 2nd table */
> - b_lo_ptrs = bstart;
> - assert(bstart); /* previous bucket exists */
> - }
> - #endif
> - }
> -
> - (*nbuckets)++;
> - } while (bend< *levels - 1);
> -}
> -
> -static int init_model_structures(Encoder *encoder, FamilyStat *family_stat,
> - unsigned int rep_first, unsigned int first_size,
> - unsigned int rep_next, unsigned int mul_size,
> - unsigned int levels, unsigned int ncounters,
> - unsigned int n_buckets_ptrs, unsigned int n_buckets)
> -{
> - family_stat->buckets_ptrs = (s_bucket **)encoder->usr->malloc(encoder->usr,
> - n_buckets_ptrs *
> - sizeof(s_bucket *));
> - if (!family_stat->buckets_ptrs) {
> - return FALSE;
> - }
> -
> - family_stat->counters = (COUNTER *)encoder->usr->malloc(encoder->usr,
> - n_buckets * sizeof(COUNTER) *
> - MAXNUMCODES);
> - if (!family_stat->counters) {
> - goto error_1;
> - }
> -
> - family_stat->buckets_buf = (s_bucket *)encoder->usr->malloc(encoder->usr,
> - n_buckets * sizeof(s_bucket));
> - if (!family_stat->buckets_buf) {
> - goto error_2;
> - }
> -
> - fill_model_structures(encoder, family_stat, rep_first, first_size, rep_next, mul_size, levels,
> - ncounters, n_buckets, n_buckets_ptrs);
> -
> - return TRUE;
> -
> -error_2:
> - encoder->usr->free(encoder->usr, family_stat->counters);
> -
> -error_1:
> - encoder->usr->free(encoder->usr, family_stat->buckets_ptrs);
> -
> - return FALSE;
> -}
> -
> -static void free_family_stat(QuicUsrContext *usr, FamilyStat *family_stat)
> -{
> - usr->free(usr, family_stat->buckets_ptrs);
> - usr->free(usr, family_stat->counters);
> - usr->free(usr, family_stat->buckets_buf);
> -}
> -
> -static int init_channel(Encoder *encoder, Channel *channel)
> -{
> - unsigned int ncounters;
> - unsigned int levels;
> - unsigned int rep_first;
> - unsigned int first_size;
> - unsigned int rep_next;
> - unsigned int mul_size;
> - unsigned int n_buckets;
> - unsigned int n_buckets_ptrs;
> -
> - channel->encoder = encoder;
> - channel->state.encoder = encoder;
> - channel->correlate_row_width = 0;
> - channel->correlate_row = NULL;
> -
> - find_model_params(encoder, 8,&ncounters,&levels,&n_buckets_ptrs,&rep_first,
> -&first_size,&rep_next,&mul_size,&n_buckets);
> - encoder->n_buckets_8bpc = n_buckets;
> - if (!init_model_structures(encoder,&channel->family_stat_8bpc, rep_first, first_size,
> - rep_next, mul_size, levels, ncounters, n_buckets_ptrs,
> - n_buckets)) {
> - return FALSE;
> - }
> -
> - find_model_params(encoder, 5,&ncounters,&levels,&n_buckets_ptrs,&rep_first,
> -&first_size,&rep_next,&mul_size,&n_buckets);
> - encoder->n_buckets_5bpc = n_buckets;
> - if (!init_model_structures(encoder,&channel->family_stat_5bpc, rep_first, first_size,
> - rep_next, mul_size, levels, ncounters, n_buckets_ptrs,
> - n_buckets)) {
> - free_family_stat(encoder->usr,&channel->family_stat_8bpc);
> - return FALSE;
> - }
> -
> - return TRUE;
> -}
> -
> -static void destroy_channel(Channel *channel)
> -{
> - QuicUsrContext *usr = channel->encoder->usr;
> - if (channel->correlate_row) {
> - usr->free(usr, channel->correlate_row - 1);
> - }
> - free_family_stat(usr,&channel->family_stat_8bpc);
> - free_family_stat(usr,&channel->family_stat_5bpc);
> -}
> -
> -static int init_encoder(Encoder *encoder, QuicUsrContext *usr)
> -{
> - int i;
> -
> - encoder->usr = usr;
> - encoder->rgb_state.encoder = encoder;
> -
> - for (i = 0; i< MAX_CHANNELS; i++) {
> - if (!init_channel(encoder,&encoder->channels[i])) {
> - for (--i; i>= 0; i--) {
> - destroy_channel(&encoder->channels[i]);
> - }
> - return FALSE;
> - }
> - }
> - return TRUE;
> -}
> -
> -static int encoder_reste(Encoder *encoder, uint32_t *io_ptr, uint32_t *io_ptr_end)
> -{
> - ASSERT(encoder->usr, ((unsigned long)io_ptr % 4) == ((unsigned long)io_ptr_end % 4));
> - ASSERT(encoder->usr, io_ptr<= io_ptr_end);
> -
> - encoder->rgb_state.waitcnt = 0;
> - encoder->rgb_state.tabrand_seed = stabrand();
> - encoder->rgb_state.wmidx = DEFwmistart;
> - encoder->rgb_state.wmileft = wminext;
> - set_wm_trigger(&encoder->rgb_state);
> -
> -#if defined(RLE)&& defined(RLE_STAT)
> - encoder_init_rle(&encoder->rgb_state);
> -#endif
> -
> - encoder->io_words_count = io_ptr_end - io_ptr;
> - encoder->io_now = io_ptr;
> - encoder->io_end = io_ptr_end;
> - encoder->rows_completed = 0;
> -
> - return TRUE;
> -}
> -
> -static int encoder_reste_channels(Encoder *encoder, int channels, int width, int bpc)
> -{
> - int i;
> -
> - encoder->num_channels = channels;
> -
> - for (i = 0; i< channels; i++) {
> - s_bucket *bucket;
> - s_bucket *end_bucket;
> -
> - if (encoder->channels[i].correlate_row_width< width) {
> - encoder->channels[i].correlate_row_width = 0;
> - if (encoder->channels[i].correlate_row) {
> - encoder->usr->free(encoder->usr, encoder->channels[i].correlate_row - 1);
> - }
> - if (!(encoder->channels[i].correlate_row = (BYTE *)encoder->usr->malloc(encoder->usr,
> - width + 1))) {
> - return FALSE;
> - }
> - encoder->channels[i].correlate_row++;
> - encoder->channels[i].correlate_row_width = width;
> - }
> -
> - if (bpc == 8) {
> - MEMCLEAR(encoder->channels[i].family_stat_8bpc.counters,
> - encoder->n_buckets_8bpc * sizeof(COUNTER) * MAXNUMCODES);
> - bucket = encoder->channels[i].family_stat_8bpc.buckets_buf;
> - end_bucket = bucket + encoder->n_buckets_8bpc;
> - for (; bucket< end_bucket; bucket++) {
> - bucket->bestcode = /*BPC*/ 8 - 1;
> - }
> - encoder->channels[i]._buckets_ptrs = encoder->channels[i].family_stat_8bpc.buckets_ptrs;
> - } else if (bpc == 5) {
> - MEMCLEAR(encoder->channels[i].family_stat_5bpc.counters,
> - encoder->n_buckets_5bpc * sizeof(COUNTER) * MAXNUMCODES);
> - bucket = encoder->channels[i].family_stat_5bpc.buckets_buf;
> - end_bucket = bucket + encoder->n_buckets_5bpc;
> - for (; bucket< end_bucket; bucket++) {
> - bucket->bestcode = /*BPC*/ 5 - 1;
> - }
> - encoder->channels[i]._buckets_ptrs = encoder->channels[i].family_stat_5bpc.buckets_ptrs;
> - } else {
> - encoder->usr->warn(encoder->usr, "%s: bad bpc %d\n", __FUNCTION__, bpc);
> - return FALSE;
> - }
> -
> - encoder->channels[i].state.waitcnt = 0;
> - encoder->channels[i].state.tabrand_seed = stabrand();
> - encoder->channels[i].state.wmidx = DEFwmistart;
> - encoder->channels[i].state.wmileft = wminext;
> - set_wm_trigger(&encoder->channels[i].state);
> -
> -#if defined(RLE)&& defined(RLE_STAT)
> - encoder_init_rle(&encoder->channels[i].state);
> -#endif
> - }
> - return TRUE;
> -}
> -
> -static void quic_image_params(Encoder *encoder, QuicImageType type, int *channels, int *bpc)
> -{
> - ASSERT(encoder->usr, channels&& bpc);
> - switch (type) {
> - case QUIC_IMAGE_TYPE_GRAY:
> - *channels = 1;
> - *bpc = 8;
> - break;
> - case QUIC_IMAGE_TYPE_RGB16:
> - *channels = 3;
> - *bpc = 5;
> -#ifndef QUIC_RGB
> - encoder->usr->error(encoder->usr, "not implemented\n");
> -#endif
> - break;
> - case QUIC_IMAGE_TYPE_RGB24:
> - *channels = 3;
> - *bpc = 8;
> - break;
> - case QUIC_IMAGE_TYPE_RGB32:
> - *channels = 3;
> - *bpc = 8;
> - break;
> - case QUIC_IMAGE_TYPE_RGBA:
> - *channels = 4;
> - *bpc = 8;
> - break;
> - case QUIC_IMAGE_TYPE_INVALID:
> - default:
> - *channels = 0;
> - *bpc = 0;
> - encoder->usr->error(encoder->usr, "bad image type\n");
> - }
> -}
> -
> -#define FILL_LINES() { \
> - if (line == lines_end) { \
> - int n = encoder->usr->more_lines(encoder->usr,&line); \
> - if (n<= 0) { \
> - encoder->usr->error(encoder->usr, "more lines failed\n"); \
> - } \
> - lines_end = line + n * stride; \
> - } \
> -}
> -
> -#define NEXT_LINE() { \
> - line += stride; \
> - FILL_LINES(); \
> -}
> -
> -#define QUIC_COMPRESS_RGB(bits) \
> - encoder->channels[0].correlate_row[-1] = 0; \
> - encoder->channels[1].correlate_row[-1] = 0; \
> - encoder->channels[2].correlate_row[-1] = 0; \
> - quic_rgb##bits##_compress_row0(encoder, (rgb##bits##_pixel_t *)(line), width); \
> - encoder->rows_completed++; \
> - for (row = 1; row< height; row++) { \
> - prev = line; \
> - NEXT_LINE(); \
> - encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0]; \
> - encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0]; \
> - encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0]; \
> - quic_rgb##bits##_compress_row(encoder, (rgb##bits##_pixel_t *)prev, \
> - (rgb##bits##_pixel_t *)line, width); \
> - encoder->rows_completed++; \
> - }
> -
> -int quic_encode(QuicContext *quic, QuicImageType type, int width, int height,
> - uint8_t *line, unsigned int num_lines, int stride,
> - uint32_t *io_ptr, unsigned int num_io_words)
> -{
> - Encoder *encoder = (Encoder *)quic;
> - uint32_t *io_ptr_end = io_ptr + num_io_words;
> - uint8_t *lines_end;
> - int row;
> - uint8_t *prev;
> - int channels;
> - int bpc;
> -#ifndef QUIC_RGB
> - int i;
> -#endif
> -
> - ASSERT(encoder->usr, line);
> - lines_end = line + num_lines * stride;
> -
> - quic_image_params(encoder, type,&channels,&bpc);
> -
> - if (!encoder_reste(encoder, io_ptr, io_ptr_end) ||
> - !encoder_reste_channels(encoder, channels, width, bpc)) {
> - return QUIC_ERROR;
> - }
> -
> - encoder->io_word = 0;
> - encoder->io_available_bits = 32;
> -
> - encode_32(encoder, QUIC_MAGIC);
> - encode_32(encoder, QUIC_VERSION);
> - encode_32(encoder, type);
> - encode_32(encoder, width);
> - encode_32(encoder, height);
> -
> - FILL_LINES();
> -
> - switch (type) {
> -#ifdef QUIC_RGB
> - case QUIC_IMAGE_TYPE_RGB32:
> - ASSERT(encoder->usr, ABS(stride)>= width * 4);
> - QUIC_COMPRESS_RGB(32);
> - break;
> - case QUIC_IMAGE_TYPE_RGB24:
> - ASSERT(encoder->usr, ABS(stride)>= width * 3);
> - QUIC_COMPRESS_RGB(24);
> - break;
> - case QUIC_IMAGE_TYPE_RGB16:
> - ASSERT(encoder->usr, ABS(stride)>= width * 2);
> - QUIC_COMPRESS_RGB(16);
> - break;
> - case QUIC_IMAGE_TYPE_RGBA:
> - ASSERT(encoder->usr, ABS(stride)>= width * 4);
> -
> - encoder->channels[0].correlate_row[-1] = 0;
> - encoder->channels[1].correlate_row[-1] = 0;
> - encoder->channels[2].correlate_row[-1] = 0;
> - quic_rgb32_compress_row0(encoder, (rgb32_pixel_t *)(line), width);
> -
> - encoder->channels[3].correlate_row[-1] = 0;
> - quic_four_compress_row0(encoder,&encoder->channels[3], (four_bytes_t *)(line + 3), width);
> -
> - encoder->rows_completed++;
> -
> - for (row = 1; row< height; row++) {
> - prev = line;
> - NEXT_LINE();
> - encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
> - encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];
> - encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];
> - quic_rgb32_compress_row(encoder, (rgb32_pixel_t *)prev, (rgb32_pixel_t *)line, width);
> -
> - encoder->channels[3].correlate_row[-1] = encoder->channels[3].correlate_row[0];
> - quic_four_compress_row(encoder,&encoder->channels[3], (four_bytes_t *)(prev + 3),
> - (four_bytes_t *)(line + 3), width);
> - encoder->rows_completed++;
> - }
> - break;
> -#else
> - case QUIC_IMAGE_TYPE_RGB24:
> - ASSERT(encoder->usr, ABS(stride)>= width * 3);
> - for (i = 0; i< 3; i++) {
> - encoder->channels[i].correlate_row[-1] = 0;
> - quic_three_compress_row0(encoder,&encoder->channels[i], (three_bytes_t *)(line + i),
> - width);
> - }
> - encoder->rows_completed++;
> - for (row = 1; row< height; row++) {
> - prev = line;
> - NEXT_LINE();
> - for (i = 0; i< 3; i++) {
> - encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
> - quic_three_compress_row(encoder,&encoder->channels[i], (three_bytes_t *)(prev + i),
> - (three_bytes_t *)(line + i), width);
> - }
> - encoder->rows_completed++;
> - }
> - break;
> - case QUIC_IMAGE_TYPE_RGB32:
> - case QUIC_IMAGE_TYPE_RGBA:
> - ASSERT(encoder->usr, ABS(stride)>= width * 4);
> - for (i = 0; i< channels; i++) {
> - encoder->channels[i].correlate_row[-1] = 0;
> - quic_four_compress_row0(encoder,&encoder->channels[i], (four_bytes_t *)(line + i),
> - width);
> - }
> - encoder->rows_completed++;
> - for (row = 1; row< height; row++) {
> - prev = line;
> - NEXT_LINE();
> - for (i = 0; i< channels; i++) {
> - encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
> - quic_four_compress_row(encoder,&encoder->channels[i], (four_bytes_t *)(prev + i),
> - (four_bytes_t *)(line + i), width);
> - }
> - encoder->rows_completed++;
> - }
> - break;
> -#endif
> - case QUIC_IMAGE_TYPE_GRAY:
> - ASSERT(encoder->usr, ABS(stride)>= width);
> - encoder->channels[0].correlate_row[-1] = 0;
> - quic_one_compress_row0(encoder,&encoder->channels[0], (one_byte_t *)line, width);
> - encoder->rows_completed++;
> - for (row = 1; row< height; row++) {
> - prev = line;
> - NEXT_LINE();
> - encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
> - quic_one_compress_row(encoder,&encoder->channels[0], (one_byte_t *)prev,
> - (one_byte_t *)line, width);
> - encoder->rows_completed++;
> - }
> - break;
> - case QUIC_IMAGE_TYPE_INVALID:
> - default:
> - encoder->usr->error(encoder->usr, "bad image type\n");
> - }
> -
> - flush(encoder);
> - encoder->io_words_count -= (encoder->io_end - encoder->io_now);
> -
> - return encoder->io_words_count;
> -}
> -
> -int quic_decode_begin(QuicContext *quic, uint32_t *io_ptr, unsigned int num_io_words,
> - QuicImageType *out_type, int *out_width, int *out_height)
> -{
> - Encoder *encoder = (Encoder *)quic;
> - uint32_t *io_ptr_end = io_ptr + num_io_words;
> - QuicImageType type;
> - int width;
> - int height;
> - uint32_t magic;
> - uint32_t version;
> - int channels;
> - int bpc;
> -
> - if (!encoder_reste(encoder, io_ptr, io_ptr_end)) {
> - return QUIC_ERROR;
> - }
> -
> - init_decode_io(encoder);
> -
> - magic = encoder->io_word;
> - decode_eat32bits(encoder);
> - if (magic != QUIC_MAGIC) {
> - encoder->usr->warn(encoder->usr, "bad magic\n");
> - return QUIC_ERROR;
> - }
> -
> - version = encoder->io_word;
> - decode_eat32bits(encoder);
> - if (version != QUIC_VERSION) {
> - encoder->usr->warn(encoder->usr, "bad version\n");
> - return QUIC_ERROR;
> - }
> -
> - type = (QuicImageType)encoder->io_word;
> - decode_eat32bits(encoder);
> -
> - width = encoder->io_word;
> - decode_eat32bits(encoder);
> -
> - height = encoder->io_word;
> - decode_eat32bits(encoder);
> -
> - quic_image_params(encoder, type,&channels,&bpc);
> -
> - if (!encoder_reste_channels(encoder, channels, width, bpc)) {
> - return QUIC_ERROR;
> - }
> -
> - *out_width = encoder->width = width;
> - *out_height = encoder->height = height;
> - *out_type = encoder->type = type;
> - return QUIC_OK;
> -}
> -
> -#ifndef QUIC_RGB
> -static void clear_row(four_bytes_t *row, int width)
> -{
> - four_bytes_t *end;
> - for (end = row + width; row< end; row++) {
> - row->a = 0;
> - }
> -}
> -
> -#endif
> -
> -#ifdef QUIC_RGB
> -
> -static void uncompress_rgba(Encoder *encoder, uint8_t *buf, int stride)
> -{
> - unsigned int row;
> - uint8_t *prev;
> -
> - encoder->channels[0].correlate_row[-1] = 0;
> - encoder->channels[1].correlate_row[-1] = 0;
> - encoder->channels[2].correlate_row[-1] = 0;
> - quic_rgb32_uncompress_row0(encoder, (rgb32_pixel_t *)buf, encoder->width);
> -
> - encoder->channels[3].correlate_row[-1] = 0;
> - quic_four_uncompress_row0(encoder,&encoder->channels[3], (four_bytes_t *)(buf + 3),
> - encoder->width);
> -
> - encoder->rows_completed++;
> - for (row = 1; row< encoder->height; row++) {
> - prev = buf;
> - buf += stride;
> -
> - encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
> - encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];
> - encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];
> - quic_rgb32_uncompress_row(encoder, (rgb32_pixel_t *)prev, (rgb32_pixel_t *)buf,
> - encoder->width);
> -
> - encoder->channels[3].correlate_row[-1] = encoder->channels[3].correlate_row[0];
> - quic_four_uncompress_row(encoder,&encoder->channels[3], (four_bytes_t *)(prev + 3),
> - (four_bytes_t *)(buf + 3), encoder->width);
> -
> - encoder->rows_completed++;
> - }
> -}
> -
> -#endif
> -
> -static void uncompress_gray(Encoder *encoder, uint8_t *buf, int stride)
> -{
> - unsigned int row;
> - uint8_t *prev;
> -
> - encoder->channels[0].correlate_row[-1] = 0;
> - quic_one_uncompress_row0(encoder,&encoder->channels[0], (one_byte_t *)buf, encoder->width);
> - encoder->rows_completed++;
> - for (row = 1; row< encoder->height; row++) {
> - prev = buf;
> - buf += stride;
> - encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
> - quic_one_uncompress_row(encoder,&encoder->channels[0], (one_byte_t *)prev,
> - (one_byte_t *)buf, encoder->width);
> - encoder->rows_completed++;
> - }
> -}
> -
> -#define QUIC_UNCOMPRESS_RGB(prefix, type) \
> - encoder->channels[0].correlate_row[-1] = 0; \
> - encoder->channels[1].correlate_row[-1] = 0; \
> - encoder->channels[2].correlate_row[-1] = 0; \
> - quic_rgb##prefix##_uncompress_row0(encoder, (type *)buf, encoder->width); \
> - encoder->rows_completed++; \
> - for (row = 1; row< encoder->height; row++) { \
> - prev = buf; \
> - buf += stride; \
> - encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0]; \
> - encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0]; \
> - encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0]; \
> - quic_rgb##prefix##_uncompress_row(encoder, (type *)prev, (type *)buf, \
> - encoder->width); \
> - encoder->rows_completed++; \
> - }
> -
> -int quic_decode(QuicContext *quic, QuicImageType type, uint8_t *buf, int stride)
> -{
> - Encoder *encoder = (Encoder *)quic;
> - unsigned int row;
> - uint8_t *prev;
> -#ifndef QUIC_RGB
> - int i;
> -#endif
> -
> - ASSERT(encoder->usr, buf);
> -
> - switch (encoder->type) {
> -#ifdef QUIC_RGB
> - case QUIC_IMAGE_TYPE_RGB32:
> - case QUIC_IMAGE_TYPE_RGB24:
> - if (type == QUIC_IMAGE_TYPE_RGB32) {
> - ASSERT(encoder->usr, ABS(stride)>= (int)encoder->width * 4);
> - QUIC_UNCOMPRESS_RGB(32, rgb32_pixel_t);
> - break;
> - } else if (type == QUIC_IMAGE_TYPE_RGB24) {
> - ASSERT(encoder->usr, ABS(stride)>= (int)encoder->width * 3);
> - QUIC_UNCOMPRESS_RGB(24, rgb24_pixel_t);
> - break;
> - }
> - encoder->usr->warn(encoder->usr, "unsupported output format\n");
> - return QUIC_ERROR;
> - case QUIC_IMAGE_TYPE_RGB16:
> - if (type == QUIC_IMAGE_TYPE_RGB16) {
> - ASSERT(encoder->usr, ABS(stride)>= (int)encoder->width * 2);
> - QUIC_UNCOMPRESS_RGB(16, rgb16_pixel_t);
> - } else if (type == QUIC_IMAGE_TYPE_RGB32) {
> - ASSERT(encoder->usr, ABS(stride)>= (int)encoder->width * 4);
> - QUIC_UNCOMPRESS_RGB(16_to_32, rgb32_pixel_t);
> - } else {
> - encoder->usr->warn(encoder->usr, "unsupported output format\n");
> - return QUIC_ERROR;
> - }
> -
> - break;
> - case QUIC_IMAGE_TYPE_RGBA:
> -
> - if (type != QUIC_IMAGE_TYPE_RGBA) {
> - encoder->usr->warn(encoder->usr, "unsupported output format\n");
> - return QUIC_ERROR;
> - }
> - ASSERT(encoder->usr, ABS(stride)>= (int)encoder->width * 4);
> - uncompress_rgba(encoder, buf, stride);
> - break;
> -#else
> - case QUIC_IMAGE_TYPE_RGB24:
> - ASSERT(encoder->usr, ABS(stride)>= (int)encoder->width * 3);
> - for (i = 0; i< 3; i++) {
> - encoder->channels[i].correlate_row[-1] = 0;
> - quic_three_uncompress_row0(encoder,&encoder->channels[i], (three_bytes_t *)(buf + i),
> - encoder->width);
> - }
> - encoder->rows_completed++;
> - for (row = 1; row< encoder->height; row++) {
> - prev = buf;
> - buf += stride;
> - for (i = 0; i< 3; i++) {
> - encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
> - quic_three_uncompress_row(encoder,&encoder->channels[i],
> - (three_bytes_t *)(prev + i),
> - (three_bytes_t *)(buf + i),
> - encoder->width);
> - }
> - encoder->rows_completed++;
> - }
> - break;
> - case QUIC_IMAGE_TYPE_RGB32:
> - ASSERT(encoder->usr, ABS(stride)>= encoder->width * 4);
> - for (i = 0; i< 3; i++) {
> - encoder->channels[i].correlate_row[-1] = 0;
> - quic_four_uncompress_row0(encoder,&encoder->channels[i], (four_bytes_t *)(buf + i),
> - encoder->width);
> - }
> - clear_row((four_bytes_t *)(buf + 3), encoder->width);
> - encoder->rows_completed++;
> - for (row = 1; row< encoder->height; row++) {
> - prev = buf;
> - buf += stride;
> - for (i = 0; i< 3; i++) {
> - encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
> - quic_four_uncompress_row(encoder,&encoder->channels[i],
> - (four_bytes_t *)(prev + i),
> - (four_bytes_t *)(buf + i),
> - encoder->width);
> - }
> - clear_row((four_bytes_t *)(buf + 3), encoder->width);
> - encoder->rows_completed++;
> - }
> - break;
> - case QUIC_IMAGE_TYPE_RGBA:
> - ASSERT(encoder->usr, ABS(stride)>= encoder->width * 4);
> - for (i = 0; i< 4; i++) {
> - encoder->channels[i].correlate_row[-1] = 0;
> - quic_four_uncompress_row0(encoder,&encoder->channels[i], (four_bytes_t *)(buf + i),
> - encoder->width);
> - }
> - encoder->rows_completed++;
> - for (row = 1; row< encoder->height; row++) {
> - prev = buf;
> - buf += stride;
> - for (i = 0; i< 4; i++) {
> - encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
> - quic_four_uncompress_row(encoder,&encoder->channels[i],
> - (four_bytes_t *)(prev + i),
> - (four_bytes_t *)(buf + i),
> - encoder->width);
> - }
> - encoder->rows_completed++;
> - }
> - break;
> -#endif
> - case QUIC_IMAGE_TYPE_GRAY:
> -
> - if (type != QUIC_IMAGE_TYPE_GRAY) {
> - encoder->usr->warn(encoder->usr, "unsupported output format\n");
> - return QUIC_ERROR;
> - }
> - ASSERT(encoder->usr, ABS(stride)>= (int)encoder->width);
> - uncompress_gray(encoder, buf, stride);
> - break;
> - case QUIC_IMAGE_TYPE_INVALID:
> - default:
> - encoder->usr->error(encoder->usr, "bad image type\n");
> - }
> - return QUIC_OK;
> -}
> -
> -static int need_init = TRUE;
> -
> -QuicContext *quic_create(QuicUsrContext *usr)
> -{
> - Encoder *encoder;
> -
> - if (!usr || need_init || !usr->error || !usr->warn || !usr->info || !usr->malloc ||
> - !usr->free || !usr->more_space || !usr->more_lines) {
> - return NULL;
> - }
> -
> - if (!(encoder = (Encoder *)usr->malloc(usr, sizeof(Encoder)))) {
> - return NULL;
> - }
> -
> - if (!init_encoder(encoder, usr)) {
> - usr->free(usr, encoder);
> - return NULL;
> - }
> - return (QuicContext *)encoder;
> -}
> -
> -void quic_destroy(QuicContext *quic)
> -{
> - Encoder *encoder = (Encoder *)quic;
> - int i;
> -
> - if (!quic) {
> - return;
> - }
> -
> - for (i = 0; i< MAX_CHANNELS; i++) {
> - destroy_channel(&encoder->channels[i]);
> - }
> - encoder->usr->free(encoder->usr, encoder);
> -}
> -
> -void quic_init(void)
> -{
> - if (!need_init) {
> - return;
> - }
> - need_init = FALSE;
> -
> - family_init(&family_8bpc, 8, DEFmaxclen);
> - family_init(&family_5bpc, 5, DEFmaxclen);
> -#if defined(RLE)&& defined(RLE_STAT)
> - init_zeroLUT();
> -#endif
> -}
> -
> diff --git a/common/quic.h b/common/quic.h
> deleted file mode 100644
> index 35683d2..0000000
> --- a/common/quic.h
> +++ /dev/null
> @@ -1,66 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef __QUIC_H
> -#define __QUIC_H
> -
> -#include "quic_config.h"
> -#include "macros.h"
> -
> -typedef enum {
> - QUIC_IMAGE_TYPE_INVALID,
> - QUIC_IMAGE_TYPE_GRAY,
> - QUIC_IMAGE_TYPE_RGB16,
> - QUIC_IMAGE_TYPE_RGB24,
> - QUIC_IMAGE_TYPE_RGB32,
> - QUIC_IMAGE_TYPE_RGBA
> -} QuicImageType;
> -
> -#define QUIC_ERROR -1
> -#define QUIC_OK 0
> -
> -typedef void *QuicContext;
> -
> -typedef struct QuicUsrContext QuicUsrContext;
> -struct QuicUsrContext {
> - ATTR_PRINTF(2, 3) void (*error)(QuicUsrContext *usr, const char *fmt, ...);
> - ATTR_PRINTF(2, 3) void (*warn)(QuicUsrContext *usr, const char *fmt, ...);
> - ATTR_PRINTF(2, 3) void (*info)(QuicUsrContext *usr, const char *fmt, ...);
> - void *(*malloc)(QuicUsrContext *usr, int size);
> - void (*free)(QuicUsrContext *usr, void *ptr);
> - int (*more_space)(QuicUsrContext *usr, uint32_t **io_ptr, int rows_completed);
> - int (*more_lines)(QuicUsrContext *usr, uint8_t **lines); // on return the last line of previous
> - // lines bunch must still be valid
> -};
> -
> -int quic_encode(QuicContext *quic, QuicImageType type, int width, int height,
> - uint8_t *lines, unsigned int num_lines, int stride,
> - uint32_t *io_ptr, unsigned int num_io_words);
> -
> -int quic_decode_begin(QuicContext *quic, uint32_t *io_ptr, unsigned int num_io_words,
> - QuicImageType *type, int *width, int *height);
> -int quic_decode(QuicContext *quic, QuicImageType type, uint8_t *buf, int stride);
> -
> -
> -QuicContext *quic_create(QuicUsrContext *usr);
> -void quic_destroy(QuicContext *quic);
> -
> -void quic_init(void);
> -
> -#endif
> -
> diff --git a/common/quic_config.h b/common/quic_config.h
> deleted file mode 100644
> index 1273dbc..0000000
> --- a/common/quic_config.h
> +++ /dev/null
> @@ -1,51 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef __QUIC_CONFIG_H
> -#define __QUIC_CONFIG_H
> -
> -#include<spice/types.h>
> -
> -#ifdef __GNUC__
> -
> -#include<string.h>
> -
> -#define INLINE inline
> -
> -#define MEMCLEAR(ptr, size) memset(ptr, 0, size)
> -
> -#else
> -
> -#ifdef QXLDD
> -#include<windef.h>
> -#include "os_dep.h"
> -#define INLINE _inline
> -#define MEMCLEAR(ptr, size) RtlZeroMemory(ptr, size)
> -#else
> -#include<stddef.h>
> -#include<string.h>
> -
> -#define INLINE inline
> -#define MEMCLEAR(ptr, size) memset(ptr, 0, size)
> -#endif
> -
> -
> -#endif
> -
> -#endif
> -
> diff --git a/common/quic_family_tmpl.c b/common/quic_family_tmpl.c
> deleted file mode 100644
> index e07596b..0000000
> --- a/common/quic_family_tmpl.c
> +++ /dev/null
> @@ -1,115 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifdef QUIC_FAMILY_8BPC
> -#undef QUIC_FAMILY_8BPC
> -#define FNAME(name) name##_8bpc
> -#define VNAME(name) name##_8bpc
> -#define BPC 8
> -#endif
> -
> -
> -#ifdef QUIC_FAMILY_5BPC
> -#undef QUIC_FAMILY_5BPC
> -#define FNAME(name) name##_5bpc
> -#define VNAME(name) name##_5bpc
> -#define BPC 5
> -#endif
> -
> -
> -static unsigned int FNAME(golomb_code_len)(const BYTE n, const unsigned int l)
> -{
> - if (n< VNAME(family).nGRcodewords[l]) {
> - return (n>> l) + 1 + l;
> - } else {
> - return VNAME(family).notGRcwlen[l];
> - }
> -}
> -
> -static void FNAME(golomb_coding)(const BYTE n, const unsigned int l, unsigned int * const codeword,
> - unsigned int * const codewordlen)
> -{
> - if (n< VNAME(family).nGRcodewords[l]) {
> - (*codeword) = bitat[l] | (n& bppmask[l]);
> - (*codewordlen) = (n>> l) + l + 1;
> - } else {
> - (*codeword) = n - VNAME(family).nGRcodewords[l];
> - (*codewordlen) = VNAME(family).notGRcwlen[l];
> - }
> -}
> -
> -static unsigned int FNAME(golomb_decoding)(const unsigned int l, const unsigned int bits,
> - unsigned int * const codewordlen)
> -{
> - if (bits> VNAME(family).notGRprefixmask[l]) { /*GR*/
> - const unsigned int zeroprefix = cnt_l_zeroes(bits); /* leading zeroes in codeword */
> - const unsigned int cwlen = zeroprefix + 1 + l; /* codeword length */
> - (*codewordlen) = cwlen;
> - return (zeroprefix<< l) | ((bits>> (32 - cwlen))& bppmask[l]);
> - } else { /* not-GR */
> - const unsigned int cwlen = VNAME(family).notGRcwlen[l];
> - (*codewordlen) = cwlen;
> - return VNAME(family).nGRcodewords[l] + ((bits)>> (32 - cwlen)&
> - bppmask[VNAME(family).notGRsuffixlen[l]]);
> - }
> -}
> -
> -/* update the bucket using just encoded curval */
> -static void FNAME(update_model)(CommonState *state, s_bucket * const bucket,
> - const BYTE curval, unsigned int bpp)
> -{
> - COUNTER * const pcounters = bucket->pcounters;
> - unsigned int i;
> - unsigned int bestcode;
> - unsigned int bestcodelen;
> - //unsigned int bpp = encoder->bpp;
> -
> - /* update counters, find minimum */
> -
> - bestcode = bpp - 1;
> - bestcodelen = (pcounters[bestcode] += FNAME(golomb_code_len)(curval, bestcode));
> -
> - for (i = bpp - 2; i< bpp; i--) { /* NOTE: expression i<bpp for signed int i would be: i>=0 */
> - const unsigned int ithcodelen = (pcounters[i] += FNAME(golomb_code_len)(curval, i));
> -
> - if (ithcodelen< bestcodelen) {
> - bestcode = i;
> - bestcodelen = ithcodelen;
> - }
> - }
> -
> - bucket->bestcode = bestcode; /* store the found minimum */
> -
> - if (bestcodelen> state->wm_trigger) { /* halving counters? */
> - for (i = 0; i< bpp; i++) {
> - pcounters[i]>>= 1;
> - }
> - }
> -}
> -
> -static s_bucket *FNAME(find_bucket)(Channel *channel, const unsigned int val)
> -{
> - ASSERT(channel->encoder->usr, val< (0x1U<< BPC));
> -
> - return channel->_buckets_ptrs[val];
> -}
> -
> -#undef FNAME
> -#undef VNAME
> -#undef BPC
> -
> diff --git a/common/quic_rgb_tmpl.c b/common/quic_rgb_tmpl.c
> deleted file mode 100644
> index 681493a..0000000
> --- a/common/quic_rgb_tmpl.c
> +++ /dev/null
> @@ -1,763 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifdef QUIC_RGB32
> -#undef QUIC_RGB32
> -#define PIXEL rgb32_pixel_t
> -#define FNAME(name) quic_rgb32_##name
> -#define golomb_coding golomb_coding_8bpc
> -#define golomb_decoding golomb_decoding_8bpc
> -#define update_model update_model_8bpc
> -#define find_bucket find_bucket_8bpc
> -#define family family_8bpc
> -#define BPC 8
> -#define BPC_MASK 0xffU
> -#define COMPRESS_IMP
> -#define SET_r(pix, val) ((pix)->r = val)
> -#define GET_r(pix) ((pix)->r)
> -#define SET_g(pix, val) ((pix)->g = val)
> -#define GET_g(pix) ((pix)->g)
> -#define SET_b(pix, val) ((pix)->b = val)
> -#define GET_b(pix) ((pix)->b)
> -#define UNCOMPRESS_PIX_START(pix) ((pix)->pad = 0)
> -#endif
> -
> -#ifdef QUIC_RGB24
> -#undef QUIC_RGB24
> -#define PIXEL rgb24_pixel_t
> -#define FNAME(name) quic_rgb24_##name
> -#define golomb_coding golomb_coding_8bpc
> -#define golomb_decoding golomb_decoding_8bpc
> -#define update_model update_model_8bpc
> -#define find_bucket find_bucket_8bpc
> -#define family family_8bpc
> -#define BPC 8
> -#define BPC_MASK 0xffU
> -#define COMPRESS_IMP
> -#define SET_r(pix, val) ((pix)->r = val)
> -#define GET_r(pix) ((pix)->r)
> -#define SET_g(pix, val) ((pix)->g = val)
> -#define GET_g(pix) ((pix)->g)
> -#define SET_b(pix, val) ((pix)->b = val)
> -#define GET_b(pix) ((pix)->b)
> -#define UNCOMPRESS_PIX_START(pix)
> -#endif
> -
> -#ifdef QUIC_RGB16
> -#undef QUIC_RGB16
> -#define PIXEL rgb16_pixel_t
> -#define FNAME(name) quic_rgb16_##name
> -#define golomb_coding golomb_coding_5bpc
> -#define golomb_decoding golomb_decoding_5bpc
> -#define update_model update_model_5bpc
> -#define find_bucket find_bucket_5bpc
> -#define family family_5bpc
> -#define BPC 5
> -#define BPC_MASK 0x1fU
> -#define COMPRESS_IMP
> -#define SET_r(pix, val) (*(pix) = (*(pix)& ~(0x1f<< 10)) | ((val)<< 10))
> -#define GET_r(pix) ((*(pix)>> 10)& 0x1f)
> -#define SET_g(pix, val) (*(pix) = (*(pix)& ~(0x1f<< 5)) | ((val)<< 5))
> -#define GET_g(pix) ((*(pix)>> 5)& 0x1f)
> -#define SET_b(pix, val) (*(pix) = (*(pix)& ~0x1f) | (val))
> -#define GET_b(pix) (*(pix)& 0x1f)
> -#define UNCOMPRESS_PIX_START(pix) (*(pix) = 0)
> -#endif
> -
> -#ifdef QUIC_RGB16_TO_32
> -#undef QUIC_RGB16_TO_32
> -#define PIXEL rgb32_pixel_t
> -#define FNAME(name) quic_rgb16_to_32_##name
> -#define golomb_coding golomb_coding_5bpc
> -#define golomb_decoding golomb_decoding_5bpc
> -#define update_model update_model_5bpc
> -#define find_bucket find_bucket_5bpc
> -#define family family_5bpc
> -#define BPC 5
> -#define BPC_MASK 0x1fU
> -
> -#define SET_r(pix, val) ((pix)->r = ((val)<< 3) | (((val)& 0x1f)>> 2))
> -#define GET_r(pix) ((pix)->r>> 3)
> -#define SET_g(pix, val) ((pix)->g = ((val)<< 3) | (((val)& 0x1f)>> 2))
> -#define GET_g(pix) ((pix)->g>> 3)
> -#define SET_b(pix, val) ((pix)->b = ((val)<< 3) | (((val)& 0x1f)>> 2))
> -#define GET_b(pix) ((pix)->b>> 3)
> -#define UNCOMPRESS_PIX_START(pix) ((pix)->pad = 0)
> -#endif
> -
> -#define SAME_PIXEL(p1, p2) \
> - (GET_r(p1) == GET_r(p2)&& GET_g(p1) == GET_g(p2)&& \
> - GET_b(p1) == GET_b(p2))
> -
> -
> -#define _PIXEL_A(channel, curr) ((unsigned int)GET_##channel((curr) - 1))
> -#define _PIXEL_B(channel, prev) ((unsigned int)GET_##channel(prev))
> -#define _PIXEL_C(channel, prev) ((unsigned int)GET_##channel((prev) - 1))
> -
> -/* a */
> -
> -#define DECORELATE_0(channel, curr, bpc_mask)\
> - family.xlatU2L[(unsigned)((int)GET_##channel(curr) - (int)_PIXEL_A(channel, curr))& bpc_mask]
> -
> -#define CORELATE_0(channel, curr, correlate, bpc_mask)\
> - ((family.xlatL2U[correlate] + _PIXEL_A(channel, curr))& bpc_mask)
> -
> -#ifdef PRED_1
> -
> -/* (a+b)/2 */
> -#define DECORELATE(channel, prev, curr, bpc_mask, r) \
> - r = family.xlatU2L[(unsigned)((int)GET_##channel(curr) - (int)((_PIXEL_A(channel, curr) + \
> - _PIXEL_B(channel, prev))>> 1))& bpc_mask]
> -
> -#define CORELATE(channel, prev, curr, correlate, bpc_mask, r) \
> - SET_##channel(r, ((family.xlatL2U[correlate] + \
> - (int)((_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev))>> 1))& bpc_mask))
> -#endif
> -
> -#ifdef PRED_2
> -
> -/* .75a+.75b-.5c */
> -#define DECORELATE(channel, prev, curr, bpc_mask, r) { \
> - int p = ((int)(3 * (_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev))) - \
> - (int)(_PIXEL_C(channel, prev)<< 1))>> 2; \
> - if (p< 0) { \
> - p = 0; \
> - } else if ((unsigned)p> bpc_mask) { \
> - p = bpc_mask; \
> - } \
> - r = family.xlatU2L[(unsigned)((int)GET_##channel(curr) - p)& bpc_mask]; \
> -}
> -
> -#define CORELATE(channel, prev, curr, correlate, bpc_mask, r) { \
> - const int p = ((int)(3 * (_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev))) - \
> - (int)(_PIXEL_C(channel, prev)<< 1) )>> 2; \
> - const unsigned int s = family.xlatL2U[correlate]; \
> - if (!(p& ~bpc_mask)) { \
> - SET_##channel(r, (s + (unsigned)p)& bpc_mask); \
> - } else if (p< 0) { \
> - SET_##channel(r, s); \
> - } else { \
> - SET_##channel(r, (s + bpc_mask)& bpc_mask); \
> - } \
> -}
> -
> -#endif
> -
> -
> -#define COMPRESS_ONE_ROW0_0(channel) \
> - correlate_row_##channel[0] = family.xlatU2L[GET_##channel(cur_row)]; \
> - golomb_coding(correlate_row_##channel[0], find_bucket(channel_##channel, \
> - correlate_row_##channel[-1])->bestcode, \
> -&codeword,&codewordlen); \
> - encode(encoder, codeword, codewordlen);
> -
> -#define COMPRESS_ONE_ROW0(channel, index) \
> - correlate_row_##channel[index] = DECORELATE_0(channel,&cur_row[index], bpc_mask); \
> - golomb_coding(correlate_row_##channel[index], find_bucket(channel_##channel, \
> - correlate_row_##channel[index -1])->bestcode, \
> -&codeword,&codewordlen); \
> - encode(encoder, codeword, codewordlen);
> -
> -#define UPDATE_MODEL(index) \
> - update_model(&encoder->rgb_state, find_bucket(channel_r, correlate_row_r[index - 1]), \
> - correlate_row_r[index], bpc); \
> - update_model(&encoder->rgb_state, find_bucket(channel_g, correlate_row_g[index - 1]), \
> - correlate_row_g[index], bpc); \
> - update_model(&encoder->rgb_state, find_bucket(channel_b, correlate_row_b[index - 1]), \
> - correlate_row_b[index], bpc);
> -
> -
> -#ifdef RLE_PRED_1
> -#define RLE_PRED_1_IMP \
> -if (SAME_PIXEL(&cur_row[i - 1],&prev_row[i])) { \
> - if (run_index != i&& SAME_PIXEL(&prev_row[i - 1],&prev_row[i])&& \
> - i + 1< end&& SAME_PIXEL(&prev_row[i],&prev_row[i + 1])) { \
> - goto do_run; \
> - } \
> -}
> -#else
> -#define RLE_PRED_1_IMP
> -#endif
> -
> -#ifdef RLE_PRED_2
> -#define RLE_PRED_2_IMP \
> -if (SAME_PIXEL(&prev_row[i - 1],&prev_row[i])) { \
> - if (run_index != i&& i> 2&& SAME_PIXEL(&cur_row[i - 1],&cur_row[i - 2])) { \
> - goto do_run; \
> - } \
> -}
> -#else
> -#define RLE_PRED_2_IMP
> -#endif
> -
> -#ifdef RLE_PRED_3
> -#define RLE_PRED_3_IMP \
> -if (i> 1&& SAME_PIXEL(&cur_row[i - 1],&cur_row[i - 2])&& i != run_index) { \
> - goto do_run; \
> -}
> -#else
> -#define RLE_PRED_3_IMP
> -#endif
> -
> -#ifdef COMPRESS_IMP
> -
> -static void FNAME(compress_row0_seg)(Encoder *encoder, int i,
> - const PIXEL * const cur_row,
> - const int end,
> - const unsigned int waitmask,
> - const unsigned int bpc,
> - const unsigned int bpc_mask)
> -{
> - Channel * const channel_r = encoder->channels;
> - Channel * const channel_g = channel_r + 1;
> - Channel * const channel_b = channel_g + 1;
> -
> - BYTE * const correlate_row_r = channel_r->correlate_row;
> - BYTE * const correlate_row_g = channel_g->correlate_row;
> - BYTE * const correlate_row_b = channel_b->correlate_row;
> - int stopidx;
> -
> - ASSERT(encoder->usr, end - i> 0);
> -
> - if (!i) {
> - unsigned int codeword, codewordlen;
> -
> - COMPRESS_ONE_ROW0_0(r);
> - COMPRESS_ONE_ROW0_0(g);
> - COMPRESS_ONE_ROW0_0(b);
> -
> - if (encoder->rgb_state.waitcnt) {
> - encoder->rgb_state.waitcnt--;
> - } else {
> - encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed)& waitmask);
> - UPDATE_MODEL(0);
> - }
> - stopidx = ++i + encoder->rgb_state.waitcnt;
> - } else {
> - stopidx = i + encoder->rgb_state.waitcnt;
> - }
> -
> - while (stopidx< end) {
> - for (; i<= stopidx; i++) {
> - unsigned int codeword, codewordlen;
> - COMPRESS_ONE_ROW0(r, i);
> - COMPRESS_ONE_ROW0(g, i);
> - COMPRESS_ONE_ROW0(b, i);
> - }
> -
> - UPDATE_MODEL(stopidx);
> - stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed)& waitmask);
> - }
> -
> - for (; i< end; i++) {
> - unsigned int codeword, codewordlen;
> -
> - COMPRESS_ONE_ROW0(r, i);
> - COMPRESS_ONE_ROW0(g, i);
> - COMPRESS_ONE_ROW0(b, i);
> - }
> - encoder->rgb_state.waitcnt = stopidx - end;
> -}
> -
> -static void FNAME(compress_row0)(Encoder *encoder, const PIXEL *cur_row,
> - unsigned int width)
> -{
> - const unsigned int bpc = BPC;
> - const unsigned int bpc_mask = BPC_MASK;
> - int pos = 0;
> -
> - while ((wmimax> (int)encoder->rgb_state.wmidx)&& (encoder->rgb_state.wmileft<= width)) {
> - if (encoder->rgb_state.wmileft) {
> - FNAME(compress_row0_seg)(encoder, pos, cur_row, pos + encoder->rgb_state.wmileft,
> - bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask);
> - width -= encoder->rgb_state.wmileft;
> - pos += encoder->rgb_state.wmileft;
> - }
> -
> - encoder->rgb_state.wmidx++;
> - set_wm_trigger(&encoder->rgb_state);
> - encoder->rgb_state.wmileft = wminext;
> - }
> -
> - if (width) {
> - FNAME(compress_row0_seg)(encoder, pos, cur_row, pos + width,
> - bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask);
> - if (wmimax> (int)encoder->rgb_state.wmidx) {
> - encoder->rgb_state.wmileft -= width;
> - }
> - }
> -
> - ASSERT(encoder->usr, (int)encoder->rgb_state.wmidx<= wmimax);
> - ASSERT(encoder->usr, encoder->rgb_state.wmidx<= 32);
> - ASSERT(encoder->usr, wminext> 0);
> -}
> -
> -#define COMPRESS_ONE_0(channel) \
> - correlate_row_##channel[0] = family.xlatU2L[(unsigned)((int)GET_##channel(cur_row) - \
> - (int)GET_##channel(prev_row) )& bpc_mask]; \
> - golomb_coding(correlate_row_##channel[0], \
> - find_bucket(channel_##channel, correlate_row_##channel[-1])->bestcode, \
> -&codeword,&codewordlen); \
> - encode(encoder, codeword, codewordlen);
> -
> -#define COMPRESS_ONE(channel, index) \
> - DECORELATE(channel,&prev_row[index],&cur_row[index],bpc_mask, \
> - correlate_row_##channel[index]); \
> - golomb_coding(correlate_row_##channel[index], \
> - find_bucket(channel_##channel, correlate_row_##channel[index - 1])->bestcode, \
> -&codeword,&codewordlen); \
> - encode(encoder, codeword, codewordlen);
> -
> -static void FNAME(compress_row_seg)(Encoder *encoder, int i,
> - const PIXEL * const prev_row,
> - const PIXEL * const cur_row,
> - const int end,
> - const unsigned int waitmask,
> - const unsigned int bpc,
> - const unsigned int bpc_mask)
> -{
> - Channel * const channel_r = encoder->channels;
> - Channel * const channel_g = channel_r + 1;
> - Channel * const channel_b = channel_g + 1;
> -
> - BYTE * const correlate_row_r = channel_r->correlate_row;
> - BYTE * const correlate_row_g = channel_g->correlate_row;
> - BYTE * const correlate_row_b = channel_b->correlate_row;
> - int stopidx;
> -#ifdef RLE
> - int run_index = 0;
> - int run_size;
> -#endif
> -
> - ASSERT(encoder->usr, end - i> 0);
> -
> - if (!i) {
> - unsigned int codeword, codewordlen;
> -
> - COMPRESS_ONE_0(r);
> - COMPRESS_ONE_0(g);
> - COMPRESS_ONE_0(b);
> -
> - if (encoder->rgb_state.waitcnt) {
> - encoder->rgb_state.waitcnt--;
> - } else {
> - encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed)& waitmask);
> - UPDATE_MODEL(0);
> - }
> - stopidx = ++i + encoder->rgb_state.waitcnt;
> - } else {
> - stopidx = i + encoder->rgb_state.waitcnt;
> - }
> - for (;;) {
> - while (stopidx< end) {
> - for (; i<= stopidx; i++) {
> - unsigned int codeword, codewordlen;
> -#ifdef RLE
> - RLE_PRED_1_IMP;
> - RLE_PRED_2_IMP;
> - RLE_PRED_3_IMP;
> -#endif
> - COMPRESS_ONE(r, i);
> - COMPRESS_ONE(g, i);
> - COMPRESS_ONE(b, i);
> - }
> -
> - UPDATE_MODEL(stopidx);
> - stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed)& waitmask);
> - }
> -
> - for (; i< end; i++) {
> - unsigned int codeword, codewordlen;
> -#ifdef RLE
> - RLE_PRED_1_IMP;
> - RLE_PRED_2_IMP;
> - RLE_PRED_3_IMP;
> -#endif
> - COMPRESS_ONE(r, i);
> - COMPRESS_ONE(g, i);
> - COMPRESS_ONE(b, i);
> - }
> - encoder->rgb_state.waitcnt = stopidx - end;
> -
> - return;
> -
> -#ifdef RLE
> -do_run:
> - run_index = i;
> - encoder->rgb_state.waitcnt = stopidx - i;
> - run_size = 0;
> -
> - while (SAME_PIXEL(&cur_row[i],&cur_row[i - 1])) {
> - run_size++;
> - if (++i == end) {
> - encode_run(encoder, run_size);
> - return;
> - }
> - }
> - encode_run(encoder, run_size);
> - stopidx = i + encoder->rgb_state.waitcnt;
> -#endif
> - }
> -}
> -
> -static void FNAME(compress_row)(Encoder *encoder,
> - const PIXEL * const prev_row,
> - const PIXEL * const cur_row,
> - unsigned int width)
> -
> -{
> - const unsigned int bpc = BPC;
> - const unsigned int bpc_mask = BPC_MASK;
> - unsigned int pos = 0;
> -
> - while ((wmimax> (int)encoder->rgb_state.wmidx)&& (encoder->rgb_state.wmileft<= width)) {
> - if (encoder->rgb_state.wmileft) {
> - FNAME(compress_row_seg)(encoder, pos, prev_row, cur_row,
> - pos + encoder->rgb_state.wmileft,
> - bppmask[encoder->rgb_state.wmidx],
> - bpc, bpc_mask);
> - width -= encoder->rgb_state.wmileft;
> - pos += encoder->rgb_state.wmileft;
> - }
> -
> - encoder->rgb_state.wmidx++;
> - set_wm_trigger(&encoder->rgb_state);
> - encoder->rgb_state.wmileft = wminext;
> - }
> -
> - if (width) {
> - FNAME(compress_row_seg)(encoder, pos, prev_row, cur_row, pos + width,
> - bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask);
> - if (wmimax> (int)encoder->rgb_state.wmidx) {
> - encoder->rgb_state.wmileft -= width;
> - }
> - }
> -
> - ASSERT(encoder->usr, (int)encoder->rgb_state.wmidx<= wmimax);
> - ASSERT(encoder->usr, encoder->rgb_state.wmidx<= 32);
> - ASSERT(encoder->usr, wminext> 0);
> -}
> -
> -#endif
> -
> -#define UNCOMPRESS_ONE_ROW0_0(channel) \
> - correlate_row_##channel[0] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \
> - correlate_row_##channel[-1])->bestcode, \
> - encoder->io_word,&codewordlen); \
> - SET_##channel(&cur_row[0], (BYTE)family.xlatL2U[correlate_row_##channel[0]]); \
> - decode_eatbits(encoder, codewordlen);
> -
> -#define UNCOMPRESS_ONE_ROW0(channel) \
> - correlate_row_##channel[i] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \
> - correlate_row_##channel[i - 1])->bestcode, \
> - encoder->io_word, \
> -&codewordlen); \
> - SET_##channel(&cur_row[i], CORELATE_0(channel,&cur_row[i], correlate_row_##channel[i], \
> - bpc_mask)); \
> - decode_eatbits(encoder, codewordlen);
> -
> -static void FNAME(uncompress_row0_seg)(Encoder *encoder, int i,
> - PIXEL * const cur_row,
> - const int end,
> - const unsigned int waitmask,
> - const unsigned int bpc,
> - const unsigned int bpc_mask)
> -{
> - Channel * const channel_r = encoder->channels;
> - Channel * const channel_g = channel_r + 1;
> - Channel * const channel_b = channel_g + 1;
> -
> - BYTE * const correlate_row_r = channel_r->correlate_row;
> - BYTE * const correlate_row_g = channel_g->correlate_row;
> - BYTE * const correlate_row_b = channel_b->correlate_row;
> - int stopidx;
> -
> - ASSERT(encoder->usr, end - i> 0);
> -
> - if (!i) {
> - unsigned int codewordlen;
> -
> - UNCOMPRESS_PIX_START(&cur_row[i]);
> - UNCOMPRESS_ONE_ROW0_0(r);
> - UNCOMPRESS_ONE_ROW0_0(g);
> - UNCOMPRESS_ONE_ROW0_0(b);
> -
> - if (encoder->rgb_state.waitcnt) {
> - --encoder->rgb_state.waitcnt;
> - } else {
> - encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed)& waitmask);
> - UPDATE_MODEL(0);
> - }
> - stopidx = ++i + encoder->rgb_state.waitcnt;
> - } else {
> - stopidx = i + encoder->rgb_state.waitcnt;
> - }
> -
> - while (stopidx< end) {
> - for (; i<= stopidx; i++) {
> - unsigned int codewordlen;
> -
> - UNCOMPRESS_PIX_START(&cur_row[i]);
> - UNCOMPRESS_ONE_ROW0(r);
> - UNCOMPRESS_ONE_ROW0(g);
> - UNCOMPRESS_ONE_ROW0(b);
> - }
> - UPDATE_MODEL(stopidx);
> - stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed)& waitmask);
> - }
> -
> - for (; i< end; i++) {
> - unsigned int codewordlen;
> -
> - UNCOMPRESS_PIX_START(&cur_row[i]);
> - UNCOMPRESS_ONE_ROW0(r);
> - UNCOMPRESS_ONE_ROW0(g);
> - UNCOMPRESS_ONE_ROW0(b);
> - }
> - encoder->rgb_state.waitcnt = stopidx - end;
> -}
> -
> -static void FNAME(uncompress_row0)(Encoder *encoder,
> - PIXEL * const cur_row,
> - unsigned int width)
> -
> -{
> - const unsigned int bpc = BPC;
> - const unsigned int bpc_mask = BPC_MASK;
> - unsigned int pos = 0;
> -
> - while ((wmimax> (int)encoder->rgb_state.wmidx)&& (encoder->rgb_state.wmileft<= width)) {
> - if (encoder->rgb_state.wmileft) {
> - FNAME(uncompress_row0_seg)(encoder, pos, cur_row,
> - pos + encoder->rgb_state.wmileft,
> - bppmask[encoder->rgb_state.wmidx],
> - bpc, bpc_mask);
> - pos += encoder->rgb_state.wmileft;
> - width -= encoder->rgb_state.wmileft;
> - }
> -
> - encoder->rgb_state.wmidx++;
> - set_wm_trigger(&encoder->rgb_state);
> - encoder->rgb_state.wmileft = wminext;
> - }
> -
> - if (width) {
> - FNAME(uncompress_row0_seg)(encoder, pos, cur_row, pos + width,
> - bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask);
> - if (wmimax> (int)encoder->rgb_state.wmidx) {
> - encoder->rgb_state.wmileft -= width;
> - }
> - }
> -
> - ASSERT(encoder->usr, (int)encoder->rgb_state.wmidx<= wmimax);
> - ASSERT(encoder->usr, encoder->rgb_state.wmidx<= 32);
> - ASSERT(encoder->usr, wminext> 0);
> -}
> -
> -#define UNCOMPRESS_ONE_0(channel) \
> - correlate_row_##channel[0] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \
> - correlate_row_##channel[-1])->bestcode, \
> - encoder->io_word,&codewordlen); \
> - SET_##channel(&cur_row[0], (family.xlatL2U[correlate_row_##channel[0]] + \
> - GET_##channel(prev_row))& bpc_mask); \
> - decode_eatbits(encoder, codewordlen);
> -
> -#define UNCOMPRESS_ONE(channel) \
> - correlate_row_##channel[i] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \
> - correlate_row_##channel[i - 1])->bestcode, \
> - encoder->io_word, \
> -&codewordlen); \
> - CORELATE(channel,&prev_row[i],&cur_row[i], correlate_row_##channel[i], bpc_mask, \
> -&cur_row[i]); \
> - decode_eatbits(encoder, codewordlen);
> -
> -static void FNAME(uncompress_row_seg)(Encoder *encoder,
> - const PIXEL * const prev_row,
> - PIXEL * const cur_row,
> - int i,
> - const int end,
> - const unsigned int bpc,
> - const unsigned int bpc_mask)
> -{
> - Channel * const channel_r = encoder->channels;
> - Channel * const channel_g = channel_r + 1;
> - Channel * const channel_b = channel_g + 1;
> -
> - BYTE * const correlate_row_r = channel_r->correlate_row;
> - BYTE * const correlate_row_g = channel_g->correlate_row;
> - BYTE * const correlate_row_b = channel_b->correlate_row;
> - const unsigned int waitmask = bppmask[encoder->rgb_state.wmidx];
> - int stopidx;
> -#ifdef RLE
> - int run_index = 0;
> - int run_end;
> -#endif
> -
> - ASSERT(encoder->usr, end - i> 0);
> -
> - if (!i) {
> - unsigned int codewordlen;
> -
> - UNCOMPRESS_PIX_START(&cur_row[i]);
> - UNCOMPRESS_ONE_0(r);
> - UNCOMPRESS_ONE_0(g);
> - UNCOMPRESS_ONE_0(b);
> -
> - if (encoder->rgb_state.waitcnt) {
> - --encoder->rgb_state.waitcnt;
> - } else {
> - encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed)& waitmask);
> - UPDATE_MODEL(0);
> - }
> - stopidx = ++i + encoder->rgb_state.waitcnt;
> - } else {
> - stopidx = i + encoder->rgb_state.waitcnt;
> - }
> - for (;;) {
> - while (stopidx< end) {
> - for (; i<= stopidx; i++) {
> - unsigned int codewordlen;
> -#ifdef RLE
> - RLE_PRED_1_IMP;
> - RLE_PRED_2_IMP;
> - RLE_PRED_3_IMP;
> -#endif
> - UNCOMPRESS_PIX_START(&cur_row[i]);
> - UNCOMPRESS_ONE(r);
> - UNCOMPRESS_ONE(g);
> - UNCOMPRESS_ONE(b);
> - }
> -
> - UPDATE_MODEL(stopidx);
> -
> - stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed)& waitmask);
> - }
> -
> - for (; i< end; i++) {
> - unsigned int codewordlen;
> -#ifdef RLE
> - RLE_PRED_1_IMP;
> - RLE_PRED_2_IMP;
> - RLE_PRED_3_IMP;
> -#endif
> - UNCOMPRESS_PIX_START(&cur_row[i]);
> - UNCOMPRESS_ONE(r);
> - UNCOMPRESS_ONE(g);
> - UNCOMPRESS_ONE(b);
> - }
> -
> - encoder->rgb_state.waitcnt = stopidx - end;
> -
> - return;
> -
> -#ifdef RLE
> -do_run:
> - encoder->rgb_state.waitcnt = stopidx - i;
> - run_index = i;
> - run_end = i + decode_run(encoder);
> -
> - for (; i< run_end; i++) {
> - UNCOMPRESS_PIX_START(&cur_row[i]);
> - SET_r(&cur_row[i], GET_r(&cur_row[i - 1]));
> - SET_g(&cur_row[i], GET_g(&cur_row[i - 1]));
> - SET_b(&cur_row[i], GET_b(&cur_row[i - 1]));
> - }
> -
> - if (i == end) {
> - return;
> - }
> -
> - stopidx = i + encoder->rgb_state.waitcnt;
> -#endif
> - }
> -}
> -
> -static void FNAME(uncompress_row)(Encoder *encoder,
> - const PIXEL * const prev_row,
> - PIXEL * const cur_row,
> - unsigned int width)
> -
> -{
> - const unsigned int bpc = BPC;
> - const unsigned int bpc_mask = BPC_MASK;
> - unsigned int pos = 0;
> -
> - while ((wmimax> (int)encoder->rgb_state.wmidx)&& (encoder->rgb_state.wmileft<= width)) {
> - if (encoder->rgb_state.wmileft) {
> - FNAME(uncompress_row_seg)(encoder, prev_row, cur_row, pos,
> - pos + encoder->rgb_state.wmileft, bpc, bpc_mask);
> - pos += encoder->rgb_state.wmileft;
> - width -= encoder->rgb_state.wmileft;
> - }
> -
> - encoder->rgb_state.wmidx++;
> - set_wm_trigger(&encoder->rgb_state);
> - encoder->rgb_state.wmileft = wminext;
> - }
> -
> - if (width) {
> - FNAME(uncompress_row_seg)(encoder, prev_row, cur_row, pos,
> - pos + width, bpc, bpc_mask);
> - if (wmimax> (int)encoder->rgb_state.wmidx) {
> - encoder->rgb_state.wmileft -= width;
> - }
> - }
> -
> - ASSERT(encoder->usr, (int)encoder->rgb_state.wmidx<= wmimax);
> - ASSERT(encoder->usr, encoder->rgb_state.wmidx<= 32);
> - ASSERT(encoder->usr, wminext> 0);
> -}
> -
> -#undef PIXEL
> -#undef FNAME
> -#undef _PIXEL_A
> -#undef _PIXEL_B
> -#undef _PIXEL_C
> -#undef SAME_PIXEL
> -#undef RLE_PRED_1_IMP
> -#undef RLE_PRED_2_IMP
> -#undef RLE_PRED_3_IMP
> -#undef UPDATE_MODEL
> -#undef DECORELATE_0
> -#undef DECORELATE
> -#undef COMPRESS_ONE_ROW0_0
> -#undef COMPRESS_ONE_ROW0
> -#undef COMPRESS_ONE_0
> -#undef COMPRESS_ONE
> -#undef CORELATE_0
> -#undef CORELATE
> -#undef UNCOMPRESS_ONE_ROW0_0
> -#undef UNCOMPRESS_ONE_ROW0
> -#undef UNCOMPRESS_ONE_0
> -#undef UNCOMPRESS_ONE
> -#undef golomb_coding
> -#undef golomb_decoding
> -#undef update_model
> -#undef find_bucket
> -#undef family
> -#undef BPC
> -#undef BPC_MASK
> -#undef COMPRESS_IMP
> -#undef SET_r
> -#undef GET_r
> -#undef SET_g
> -#undef GET_g
> -#undef SET_b
> -#undef GET_b
> -#undef UNCOMPRESS_PIX_START
> -
> diff --git a/common/quic_tmpl.c b/common/quic_tmpl.c
> deleted file mode 100644
> index 47a6a23..0000000
> --- a/common/quic_tmpl.c
> +++ /dev/null
> @@ -1,633 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifdef ONE_BYTE
> -#undef ONE_BYTE
> -#define FNAME(name) quic_one_##name
> -#define PIXEL one_byte_t
> -#endif
> -
> -#ifdef THREE_BYTE
> -#undef THREE_BYTE
> -#define FNAME(name) quic_three_##name
> -#define PIXEL three_bytes_t
> -#endif
> -
> -#ifdef FOUR_BYTE
> -#undef FOUR_BYTE
> -#define FNAME(name) quic_four_##name
> -#define PIXEL four_bytes_t
> -#endif
> -
> -#define golomb_coding golomb_coding_8bpc
> -#define golomb_decoding golomb_decoding_8bpc
> -#define update_model update_model_8bpc
> -#define find_bucket find_bucket_8bpc
> -#define family family_8bpc
> -
> -#define BPC 8
> -#define BPC_MASK 0xffU
> -
> -#define _PIXEL_A ((unsigned int)curr[-1].a)
> -#define _PIXEL_B ((unsigned int)prev[0].a)
> -#define _PIXEL_C ((unsigned int)prev[-1].a)
> -
> -#ifdef RLE_PRED_1
> -#define RLE_PRED_1_IMP \
> -if (cur_row[i - 1].a == prev_row[i].a) { \
> - if (run_index != i&& prev_row[i - 1].a == prev_row[i].a&& \
> - i + 1< end&& prev_row[i].a == prev_row[i + 1].a) { \
> - goto do_run; \
> - } \
> -}
> -#else
> -#define RLE_PRED_1_IMP
> -#endif
> -
> -#ifdef RLE_PRED_2
> -#define RLE_PRED_2_IMP \
> -if (prev_row[i - 1].a == prev_row[i].a) { \
> - if (run_index != i&& i> 2&& cur_row[i - 1].a == cur_row[i - 2].a) { \
> - goto do_run; \
> - } \
> -}
> -#else
> -#define RLE_PRED_2_IMP
> -#endif
> -
> -#ifdef RLE_PRED_3
> -#define RLE_PRED_3_IMP \
> -if (i> 1&& cur_row[i - 1].a == cur_row[i - 2].a&& i != run_index) { \
> - goto do_run; \
> -}
> -#else
> -#define RLE_PRED_3_IMP
> -#endif
> -
> -/* a */
> -static INLINE BYTE FNAME(decorelate_0)(const PIXEL * const curr, const unsigned int bpc_mask)
> -{
> - return family.xlatU2L[(unsigned)((int)curr[0].a - (int)_PIXEL_A)& bpc_mask];
> -}
> -
> -static INLINE void FNAME(corelate_0)(PIXEL *curr, const BYTE corelate,
> - const unsigned int bpc_mask)
> -{
> - curr->a = (family.xlatL2U[corelate] + _PIXEL_A)& bpc_mask;
> -}
> -
> -#ifdef PRED_1
> -
> -/* (a+b)/2 */
> -static INLINE BYTE FNAME(decorelate)(const PIXEL *const prev, const PIXEL * const curr,
> - const unsigned int bpc_mask)
> -{
> - return family.xlatU2L[(unsigned)((int)curr->a - (int)((_PIXEL_A + _PIXEL_B)>> 1))& bpc_mask];
> -}
> -
> -
> -static INLINE void FNAME(corelate)(const PIXEL *prev, PIXEL *curr, const BYTE corelate,
> - const unsigned int bpc_mask)
> -{
> - curr->a = (family.xlatL2U[corelate] + (int)((_PIXEL_A + _PIXEL_B)>> 1))& bpc_mask;
> -}
> -
> -#endif
> -
> -#ifdef PRED_2
> -
> -/* .75a+.75b-.5c */
> -static INLINE BYTE FNAME(decorelate)(const PIXEL *const prev, const PIXEL * const curr,
> - const unsigned int bpc_mask)
> -{
> - int p = ((int)(3 * (_PIXEL_A + _PIXEL_B)) - (int)(_PIXEL_C<< 1))>> 2;
> -
> - if (p< 0) {
> - p = 0;
> - } else if ((unsigned)p> bpc_mask) {
> - p = bpc_mask;
> - }
> -
> - {
> - return family.xlatU2L[(unsigned)((int)curr->a - p)& bpc_mask];
> - }
> -}
> -
> -static INLINE void FNAME(corelate)(const PIXEL *prev, PIXEL *curr, const BYTE corelate,
> - const unsigned int bpc_mask)
> -{
> - const int p = ((int)(3 * (_PIXEL_A + _PIXEL_B)) - (int)(_PIXEL_C<< 1))>> 2;
> - const unsigned int s = family.xlatL2U[corelate];
> -
> - if (!(p& ~bpc_mask)) {
> - curr->a = (s + (unsigned)p)& bpc_mask;
> - } else if (p< 0) {
> - curr->a = s;
> - } else {
> - curr->a = (s + bpc_mask)& bpc_mask;
> - }
> -}
> -
> -#endif
> -
> -static void FNAME(compress_row0_seg)(Encoder *encoder, Channel *channel, int i,
> - const PIXEL * const cur_row,
> - const int end,
> - const unsigned int waitmask,
> - const unsigned int bpc,
> - const unsigned int bpc_mask)
> -{
> - BYTE * const decorelate_drow = channel->correlate_row;
> - int stopidx;
> -
> - ASSERT(encoder->usr, end - i> 0);
> -
> - if (i == 0) {
> - unsigned int codeword, codewordlen;
> -
> - decorelate_drow[0] = family.xlatU2L[cur_row->a];
> - golomb_coding(decorelate_drow[0], find_bucket(channel, decorelate_drow[-1])->bestcode,
> -&codeword,&codewordlen);
> - encode(encoder, codeword, codewordlen);
> -
> - if (channel->state.waitcnt) {
> - channel->state.waitcnt--;
> - } else {
> - channel->state.waitcnt = (tabrand(&channel->state.tabrand_seed)& waitmask);
> - update_model(&channel->state, find_bucket(channel, decorelate_drow[-1]),
> - decorelate_drow[i], bpc);
> - }
> - stopidx = ++i + channel->state.waitcnt;
> - } else {
> - stopidx = i + channel->state.waitcnt;
> - }
> -
> - while (stopidx< end) {
> - for (; i<= stopidx; i++) {
> - unsigned int codeword, codewordlen;
> - decorelate_drow[i] = FNAME(decorelate_0)(&cur_row[i], bpc_mask);
> - golomb_coding(decorelate_drow[i],
> - find_bucket(channel, decorelate_drow[i - 1])->bestcode,&codeword,
> -&codewordlen);
> - encode(encoder, codeword, codewordlen);
> - }
> -
> - update_model(&channel->state, find_bucket(channel, decorelate_drow[stopidx - 1]),
> - decorelate_drow[stopidx], bpc);
> - stopidx = i + (tabrand(&channel->state.tabrand_seed)& waitmask);
> - }
> -
> - for (; i< end; i++) {
> - unsigned int codeword, codewordlen;
> - decorelate_drow[i] = FNAME(decorelate_0)(&cur_row[i], bpc_mask);
> - golomb_coding(decorelate_drow[i], find_bucket(channel, decorelate_drow[i - 1])->bestcode,
> -&codeword,&codewordlen);
> - encode(encoder, codeword, codewordlen);
> - }
> - channel->state.waitcnt = stopidx - end;
> -}
> -
> -static void FNAME(compress_row0)(Encoder *encoder, Channel *channel, const PIXEL *cur_row,
> - unsigned int width)
> -{
> - const unsigned int bpc = BPC;
> - const unsigned int bpc_mask = BPC_MASK;
> - int pos = 0;
> -
> - while ((wmimax> (int)channel->state.wmidx)&& (channel->state.wmileft<= width)) {
> - if (channel->state.wmileft) {
> - FNAME(compress_row0_seg)(encoder, channel, pos, cur_row, pos + channel->state.wmileft,
> - bppmask[channel->state.wmidx], bpc, bpc_mask);
> - width -= channel->state.wmileft;
> - pos += channel->state.wmileft;
> - }
> -
> - channel->state.wmidx++;
> - set_wm_trigger(&channel->state);
> - channel->state.wmileft = wminext;
> - }
> -
> - if (width) {
> - FNAME(compress_row0_seg)(encoder, channel, pos, cur_row, pos + width,
> - bppmask[channel->state.wmidx], bpc, bpc_mask);
> - if (wmimax> (int)channel->state.wmidx) {
> - channel->state.wmileft -= width;
> - }
> - }
> -
> - ASSERT(encoder->usr, (int)channel->state.wmidx<= wmimax);
> - ASSERT(encoder->usr, channel->state.wmidx<= 32);
> - ASSERT(encoder->usr, wminext> 0);
> -}
> -
> -static void FNAME(compress_row_seg)(Encoder *encoder, Channel *channel, int i,
> - const PIXEL * const prev_row,
> - const PIXEL * const cur_row,
> - const int end,
> - const unsigned int waitmask,
> - const unsigned int bpc,
> - const unsigned int bpc_mask)
> -{
> - BYTE * const decorelate_drow = channel->correlate_row;
> - int stopidx;
> -#ifdef RLE
> - int run_index = 0;
> - int run_size;
> -#endif
> -
> - ASSERT(encoder->usr, end - i> 0);
> -
> - if (!i) {
> - unsigned int codeword, codewordlen;
> -
> - decorelate_drow[0] = family.xlatU2L[(unsigned)((int)cur_row->a -
> - (int)prev_row->a)& bpc_mask];
> -
> - golomb_coding(decorelate_drow[0],
> - find_bucket(channel, decorelate_drow[-1])->bestcode,
> -&codeword,
> -&codewordlen);
> - encode(encoder, codeword, codewordlen);
> -
> - if (channel->state.waitcnt) {
> - channel->state.waitcnt--;
> - } else {
> - channel->state.waitcnt = (tabrand(&channel->state.tabrand_seed)& waitmask);
> - update_model(&channel->state, find_bucket(channel, decorelate_drow[-1]),
> - decorelate_drow[0], bpc);
> - }
> - stopidx = ++i + channel->state.waitcnt;
> - } else {
> - stopidx = i + channel->state.waitcnt;
> - }
> - for (;;) {
> - while (stopidx< end) {
> - for (; i<= stopidx; i++) {
> - unsigned int codeword, codewordlen;
> -#ifdef RLE
> - RLE_PRED_1_IMP;
> - RLE_PRED_2_IMP;
> - RLE_PRED_3_IMP;
> -#endif
> - decorelate_drow[i] = FNAME(decorelate)(&prev_row[i],&cur_row[i], bpc_mask);
> - golomb_coding(decorelate_drow[i],
> - find_bucket(channel, decorelate_drow[i - 1])->bestcode,&codeword,
> -&codewordlen);
> - encode(encoder, codeword, codewordlen);
> - }
> -
> - update_model(&channel->state, find_bucket(channel, decorelate_drow[stopidx - 1]),
> - decorelate_drow[stopidx], bpc);
> - stopidx = i + (tabrand(&channel->state.tabrand_seed)& waitmask);
> - }
> -
> - for (; i< end; i++) {
> - unsigned int codeword, codewordlen;
> -#ifdef RLE
> - RLE_PRED_1_IMP;
> - RLE_PRED_2_IMP;
> - RLE_PRED_3_IMP;
> -#endif
> - decorelate_drow[i] = FNAME(decorelate)(&prev_row[i],&cur_row[i], bpc_mask);
> - golomb_coding(decorelate_drow[i], find_bucket(channel,
> - decorelate_drow[i - 1])->bestcode,
> -&codeword,&codewordlen);
> - encode(encoder, codeword, codewordlen);
> - }
> - channel->state.waitcnt = stopidx - end;
> -
> - return;
> -
> -#ifdef RLE
> -do_run:
> - run_index = i;
> - channel->state.waitcnt = stopidx - i;
> - run_size = 0;
> -
> - while (cur_row[i].a == cur_row[i - 1].a) {
> - run_size++;
> - if (++i == end) {
> -#ifdef RLE_STAT
> - encode_channel_run(encoder, channel, run_size);
> -#else
> - encode_run(encoder, run_size);
> -#endif
> - return;
> - }
> - }
> -#ifdef RLE_STAT
> - encode_channel_run(encoder, channel, run_size);
> -#else
> - encode_run(encoder, run_size);
> -#endif
> - stopidx = i + channel->state.waitcnt;
> -#endif
> - }
> -}
> -
> -static void FNAME(compress_row)(Encoder *encoder, Channel *channel,
> - const PIXEL * const prev_row,
> - const PIXEL * const cur_row,
> - unsigned int width)
> -
> -{
> - const unsigned int bpc = BPC;
> - const unsigned int bpc_mask = BPC_MASK;
> - unsigned int pos = 0;
> -
> - while ((wmimax> (int)channel->state.wmidx)&& (channel->state.wmileft<= width)) {
> - if (channel->state.wmileft) {
> - FNAME(compress_row_seg)(encoder, channel, pos, prev_row, cur_row,
> - pos + channel->state.wmileft, bppmask[channel->state.wmidx],
> - bpc, bpc_mask);
> - width -= channel->state.wmileft;
> - pos += channel->state.wmileft;
> - }
> -
> - channel->state.wmidx++;
> - set_wm_trigger(&channel->state);
> - channel->state.wmileft = wminext;
> - }
> -
> - if (width) {
> - FNAME(compress_row_seg)(encoder, channel, pos, prev_row, cur_row, pos + width,
> - bppmask[channel->state.wmidx], bpc, bpc_mask);
> - if (wmimax> (int)channel->state.wmidx) {
> - channel->state.wmileft -= width;
> - }
> - }
> -
> - ASSERT(encoder->usr, (int)channel->state.wmidx<= wmimax);
> - ASSERT(encoder->usr, channel->state.wmidx<= 32);
> - ASSERT(encoder->usr, wminext> 0);
> -}
> -
> -static void FNAME(uncompress_row0_seg)(Encoder *encoder, Channel *channel, int i,
> - BYTE * const correlate_row,
> - PIXEL * const cur_row,
> - const int end,
> - const unsigned int waitmask,
> - const unsigned int bpc,
> - const unsigned int bpc_mask)
> -{
> - int stopidx;
> -
> - ASSERT(encoder->usr, end - i> 0);
> -
> - if (i == 0) {
> - unsigned int codewordlen;
> -
> - correlate_row[0] = (BYTE)golomb_decoding(find_bucket(channel,
> - correlate_row[-1])->bestcode,
> - encoder->io_word,&codewordlen);
> - cur_row[0].a = (BYTE)family.xlatL2U[correlate_row[0]];
> - decode_eatbits(encoder, codewordlen);
> -
> - if (channel->state.waitcnt) {
> - --channel->state.waitcnt;
> - } else {
> - channel->state.waitcnt = (tabrand(&channel->state.tabrand_seed)& waitmask);
> - update_model(&channel->state, find_bucket(channel, correlate_row[-1]),
> - correlate_row[0], bpc);
> - }
> - stopidx = ++i + channel->state.waitcnt;
> - } else {
> - stopidx = i + channel->state.waitcnt;
> - }
> -
> - while (stopidx< end) {
> - struct s_bucket * pbucket = NULL;
> -
> - for (; i<= stopidx; i++) {
> - unsigned int codewordlen;
> -
> - pbucket = find_bucket(channel, correlate_row[i - 1]);
> - correlate_row[i] = (BYTE)golomb_decoding(pbucket->bestcode, encoder->io_word,
> -&codewordlen);
> - FNAME(corelate_0)(&cur_row[i], correlate_row[i], bpc_mask);
> - decode_eatbits(encoder, codewordlen);
> - }
> -
> - update_model(&channel->state, pbucket, correlate_row[stopidx], bpc);
> -
> - stopidx = i + (tabrand(&channel->state.tabrand_seed)& waitmask);
> - }
> -
> - for (; i< end; i++) {
> - unsigned int codewordlen;
> -
> - correlate_row[i] = (BYTE)golomb_decoding(find_bucket(channel,
> - correlate_row[i - 1])->bestcode,
> - encoder->io_word,&codewordlen);
> - FNAME(corelate_0)(&cur_row[i], correlate_row[i], bpc_mask);
> - decode_eatbits(encoder, codewordlen);
> - }
> - channel->state.waitcnt = stopidx - end;
> -}
> -
> -static void FNAME(uncompress_row0)(Encoder *encoder, Channel *channel,
> - PIXEL * const cur_row,
> - unsigned int width)
> -
> -{
> - const unsigned int bpc = BPC;
> - const unsigned int bpc_mask = BPC_MASK;
> - BYTE * const correlate_row = channel->correlate_row;
> - unsigned int pos = 0;
> -
> - while ((wmimax> (int)channel->state.wmidx)&& (channel->state.wmileft<= width)) {
> - if (channel->state.wmileft) {
> - FNAME(uncompress_row0_seg)(encoder, channel, pos, correlate_row, cur_row,
> - pos + channel->state.wmileft, bppmask[channel->state.wmidx],
> - bpc, bpc_mask);
> - pos += channel->state.wmileft;
> - width -= channel->state.wmileft;
> - }
> -
> - channel->state.wmidx++;
> - set_wm_trigger(&channel->state);
> - channel->state.wmileft = wminext;
> - }
> -
> - if (width) {
> - FNAME(uncompress_row0_seg)(encoder, channel, pos, correlate_row, cur_row, pos + width,
> - bppmask[channel->state.wmidx], bpc, bpc_mask);
> - if (wmimax> (int)channel->state.wmidx) {
> - channel->state.wmileft -= width;
> - }
> - }
> -
> - ASSERT(encoder->usr, (int)channel->state.wmidx<= wmimax);
> - ASSERT(encoder->usr, channel->state.wmidx<= 32);
> - ASSERT(encoder->usr, wminext> 0);
> -}
> -
> -static void FNAME(uncompress_row_seg)(Encoder *encoder, Channel *channel,
> - BYTE *correlate_row,
> - const PIXEL * const prev_row,
> - PIXEL * const cur_row,
> - int i,
> - const int end,
> - const unsigned int bpc,
> - const unsigned int bpc_mask)
> -{
> - const unsigned int waitmask = bppmask[channel->state.wmidx];
> - int stopidx;
> -#ifdef RLE
> - int run_index = 0;
> - int run_end;
> -#endif
> -
> - ASSERT(encoder->usr, end - i> 0);
> -
> - if (i == 0) {
> - unsigned int codewordlen;
> -
> - correlate_row[0] = (BYTE)golomb_decoding(find_bucket(channel, correlate_row[-1])->bestcode,
> - encoder->io_word,&codewordlen);
> - cur_row[0].a = (family.xlatL2U[correlate_row[0]] + prev_row[0].a)& bpc_mask;
> - decode_eatbits(encoder, codewordlen);
> -
> - if (channel->state.waitcnt) {
> - --channel->state.waitcnt;
> - } else {
> - channel->state.waitcnt = (tabrand(&channel->state.tabrand_seed)& waitmask);
> - update_model(&channel->state, find_bucket(channel, correlate_row[-1]),
> - correlate_row[0], bpc);
> - }
> - stopidx = ++i + channel->state.waitcnt;
> - } else {
> - stopidx = i + channel->state.waitcnt;
> - }
> - for (;;) {
> - while (stopidx< end) {
> - struct s_bucket * pbucket = NULL;
> -
> - for (; i<= stopidx; i++) {
> - unsigned int codewordlen;
> -#ifdef RLE
> - RLE_PRED_1_IMP;
> - RLE_PRED_2_IMP;
> - RLE_PRED_3_IMP;
> -#endif
> - pbucket = find_bucket(channel, correlate_row[i - 1]);
> - correlate_row[i] = (BYTE)golomb_decoding(pbucket->bestcode, encoder->io_word,
> -&codewordlen);
> - FNAME(corelate)(&prev_row[i],&cur_row[i], correlate_row[i], bpc_mask);
> - decode_eatbits(encoder, codewordlen);
> - }
> -
> - update_model(&channel->state, pbucket, correlate_row[stopidx], bpc);
> -
> - stopidx = i + (tabrand(&channel->state.tabrand_seed)& waitmask);
> - }
> -
> - for (; i< end; i++) {
> - unsigned int codewordlen;
> -#ifdef RLE
> - RLE_PRED_1_IMP;
> - RLE_PRED_2_IMP;
> - RLE_PRED_3_IMP;
> -#endif
> - correlate_row[i] = (BYTE)golomb_decoding(find_bucket(channel,
> - correlate_row[i - 1])->bestcode,
> - encoder->io_word,&codewordlen);
> - FNAME(corelate)(&prev_row[i],&cur_row[i], correlate_row[i], bpc_mask);
> - decode_eatbits(encoder, codewordlen);
> - }
> -
> - channel->state.waitcnt = stopidx - end;
> -
> - return;
> -
> -#ifdef RLE
> -do_run:
> - channel->state.waitcnt = stopidx - i;
> - run_index = i;
> -#ifdef RLE_STAT
> - run_end = i + decode_channel_run(encoder, channel);
> -#else
> - run_end = i + decode_run(encoder);
> -#endif
> -
> - for (; i< run_end; i++) {
> - cur_row[i].a = cur_row[i - 1].a;
> - }
> -
> - if (i == end) {
> - return;
> - }
> -
> - stopidx = i + channel->state.waitcnt;
> -#endif
> - }
> -}
> -
> -static void FNAME(uncompress_row)(Encoder *encoder, Channel *channel,
> - const PIXEL * const prev_row,
> - PIXEL * const cur_row,
> - unsigned int width)
> -
> -{
> - const unsigned int bpc = BPC;
> - const unsigned int bpc_mask = BPC_MASK;
> - BYTE * const correlate_row = channel->correlate_row;
> - unsigned int pos = 0;
> -
> - while ((wmimax> (int)channel->state.wmidx)&& (channel->state.wmileft<= width)) {
> - if (channel->state.wmileft) {
> - FNAME(uncompress_row_seg)(encoder, channel, correlate_row, prev_row, cur_row, pos,
> - pos + channel->state.wmileft, bpc, bpc_mask);
> - pos += channel->state.wmileft;
> - width -= channel->state.wmileft;
> - }
> -
> - channel->state.wmidx++;
> - set_wm_trigger(&channel->state);
> - channel->state.wmileft = wminext;
> - }
> -
> - if (width) {
> - FNAME(uncompress_row_seg)(encoder, channel, correlate_row, prev_row, cur_row, pos,
> - pos + width, bpc, bpc_mask);
> - if (wmimax> (int)channel->state.wmidx) {
> - channel->state.wmileft -= width;
> - }
> - }
> -
> - ASSERT(encoder->usr, (int)channel->state.wmidx<= wmimax);
> - ASSERT(encoder->usr, channel->state.wmidx<= 32);
> - ASSERT(encoder->usr, wminext> 0);
> -}
> -
> -#undef PIXEL
> -#undef FNAME
> -#undef _PIXEL_A
> -#undef _PIXEL_B
> -#undef _PIXEL_C
> -#undef RLE_PRED_1_IMP
> -#undef RLE_PRED_2_IMP
> -#undef RLE_PRED_3_IMP
> -#undef golomb_coding
> -#undef golomb_deoding
> -#undef update_model
> -#undef find_bucket
> -#undef family
> -#undef BPC
> -#undef BPC_MASK
> -
> diff --git a/common/rect.h b/common/rect.h
> deleted file mode 100644
> index cdd4335..0000000
> --- a/common/rect.h
> +++ /dev/null
> @@ -1,115 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H_RECT
> -#define _H_RECT
> -
> -#include "draw.h"
> -#include<spice/macros.h>
> -
> -static inline void rect_sect(SpiceRect* r, const SpiceRect* bounds)
> -{
> - r->left = MAX(r->left, bounds->left);
> - r->right = MIN(r->right, bounds->right);
> - r->right = MAX(r->left, r->right);
> -
> - r->top = MAX(r->top, bounds->top);
> - r->bottom = MIN(r->bottom, bounds->bottom);
> - r->bottom = MAX(r->top, r->bottom);
> -}
> -
> -static inline void rect_offset(SpiceRect* r, int dx, int dy)
> -{
> - r->left += dx;
> - r->right += dx;
> - r->top += dy;
> - r->bottom += dy;
> -}
> -
> -static inline int rect_is_empty(const SpiceRect* r)
> -{
> - return r->top == r->bottom || r->left == r->right;
> -}
> -
> -static inline int rect_intersects(const SpiceRect* r1, const SpiceRect* r2)
> -{
> - return r1->left< r2->right&& r1->right> r2->left&&
> - r1->top< r2->bottom&& r1->bottom> r2->top;
> -}
> -
> -static inline int rect_is_equal(const SpiceRect *r1, const SpiceRect *r2)
> -{
> - return r1->top == r2->top&& r1->left == r2->left&&
> - r1->bottom == r2->bottom&& r1->right == r2->right;
> -}
> -
> -static inline void rect_union(SpiceRect *dest, const SpiceRect *r)
> -{
> - dest->top = MIN(dest->top, r->top);
> - dest->left = MIN(dest->left, r->left);
> - dest->bottom = MAX(dest->bottom, r->bottom);
> - dest->right = MAX(dest->right, r->right);
> -}
> -
> -static inline int rect_is_same_size(const SpiceRect *r1, const SpiceRect *r2)
> -{
> - return r1->right - r1->left == r2->right - r2->left&&
> - r1->bottom - r1->top == r2->bottom - r2->top;
> -}
> -
> -#ifdef __cplusplus
> -
> -static inline void rect_sect(SpiceRect& r, const SpiceRect& bounds)
> -{
> - rect_sect(&r,&bounds);
> -}
> -
> -static inline void rect_offset(SpiceRect& r, int dx, int dy)
> -{
> - rect_offset(&r, dx, dy);
> -}
> -
> -static inline int rect_is_empty(const SpiceRect& r)
> -{
> - return rect_is_empty(&r);
> -}
> -
> -static inline int rect_intersects(const SpiceRect& r1, const SpiceRect& r2)
> -{
> - return rect_intersects(&r1,&r2);
> -}
> -
> -static inline int rect_is_equal(const SpiceRect& r1, const SpiceRect& r2)
> -{
> - return rect_is_equal(&r1,&r2);
> -}
> -
> -static inline void rect_union(SpiceRect& dest, const SpiceRect& r)
> -{
> - rect_union(&dest,&r);
> -}
> -
> -static inline int rect_is_same_size(const SpiceRect& r1, const SpiceRect& r2)
> -{
> - return rect_is_same_size(&r1,&r2);
> -}
> -
> -#endif
> -
> -#endif
> -
> diff --git a/common/region.c b/common/region.c
> deleted file mode 100644
> index 3f51f7b..0000000
> --- a/common/region.c
> +++ /dev/null
> @@ -1,893 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include<stdio.h>
> -#include<string.h>
> -#include<stdlib.h>
> -#include<spice/macros.h>
> -
> -#include "region.h"
> -#include "rect.h"
> -#include "mem.h"
> -
> -#define ASSERT(x) if (!(x)) { \
> - printf("%s: ASSERT %s failed\n", __FUNCTION__, #x); \
> - abort(); \
> -}
> -
> -/* true iff two Boxes overlap */
> -#define EXTENTCHECK(r1, r2) \
> - (!( ((r1)->x2<= (r2)->x1) || \
> - ((r1)->x1>= (r2)->x2) || \
> - ((r1)->y2<= (r2)->y1) || \
> - ((r1)->y1>= (r2)->y2) ) )
> -
> -/* true iff Box r1 contains Box r2 */
> -#define SUBSUMES(r1, r2) \
> - ( ((r1)->x1<= (r2)->x1)&& \
> - ((r1)->x2>= (r2)->x2)&& \
> - ((r1)->y1<= (r2)->y1)&& \
> - ((r1)->y2>= (r2)->y2) )
> -
> -
> -void region_init(QRegion *rgn)
> -{
> - pixman_region32_init(rgn);
> -}
> -
> -void region_clear(QRegion *rgn)
> -{
> - pixman_region32_fini(rgn);
> - pixman_region32_init(rgn);
> -}
> -
> -void region_destroy(QRegion *rgn)
> -{
> - pixman_region32_fini(rgn);
> -}
> -
> -void region_clone(QRegion *dest, const QRegion *src)
> -{
> - pixman_region32_init(dest);
> - pixman_region32_copy(dest, (pixman_region32_t *)src);
> -}
> -
> -#define FIND_BAND(r, r_band_end, r_end, ry1) \
> - do { \
> - ry1 = r->y1; \
> - r_band_end = r + 1; \
> - while ((r_band_end != r_end)&& (r_band_end->y1 == ry1)) { \
> - r_band_end++; \
> - } \
> - } while (0)
> -
> -static int test_band(int query,
> - int res,
> - pixman_box32_t *r1,
> - pixman_box32_t *r1_end,
> - pixman_box32_t *r2,
> - pixman_box32_t *r2_end)
> -{
> - int x1;
> - int x2;
> -
> - do {
> - x1 = MAX(r1->x1, r2->x1);
> - x2 = MIN(r1->x2, r2->x2);
> -
> - /*
> - * Is there any overlap between the two rectangles?
> - */
> - if (x1< x2) {
> - res |= REGION_TEST_SHARED;
> -
> - if (r1->x1< r2->x1 || r1->x2> r2->x2) {
> - res |= REGION_TEST_LEFT_EXCLUSIVE;
> - }
> -
> - if (r2->x1< r1->x1 || r2->x2> r1->x2) {
> - res |= REGION_TEST_RIGHT_EXCLUSIVE;
> - }
> - } else {
> - /* No overlap at all, the leftmost is exclusive */
> - if (r1->x1< r2->x1) {
> - res |= REGION_TEST_LEFT_EXCLUSIVE;
> - } else {
> - res |= REGION_TEST_RIGHT_EXCLUSIVE;
> - }
> - }
> -
> - if ((res& query) == query) {
> - return res;
> - }
> -
> - /*
> - * Advance the pointer(s) with the leftmost right side, since the next
> - * rectangle on that list may still overlap the other region's
> - * current rectangle.
> - */
> - if (r1->x2 == x2) {
> - r1++;
> - }
> - if (r2->x2 == x2) {
> - r2++;
> - }
> - } while ((r1 != r1_end)&& (r2 != r2_end));
> -
> - /*
> - * Deal with whichever band (if any) still has rectangles left.
> - */
> - if (r1 != r1_end) {
> - res |= REGION_TEST_LEFT_EXCLUSIVE;
> - } else if (r2 != r2_end) {
> - res |= REGION_TEST_RIGHT_EXCLUSIVE;
> - }
> -
> - return res;
> -}
> -
> -static int test_generic (pixman_region32_t *reg1,
> - pixman_region32_t *reg2,
> - int query)
> -{
> - pixman_box32_t *r1; /* Pointer into first region */
> - pixman_box32_t *r2; /* Pointer into 2d region */
> - pixman_box32_t *r1_end; /* End of 1st region */
> - pixman_box32_t *r2_end; /* End of 2d region */
> - int ybot; /* Bottom of intersection */
> - int ytop; /* Top of intersection */
> - pixman_box32_t * r1_band_end; /* End of current band in r1 */
> - pixman_box32_t * r2_band_end; /* End of current band in r2 */
> - int top; /* Top of non-overlapping band */
> - int bot; /* Bottom of non-overlapping band*/
> - int r1y1; /* Temps for r1->y1 and r2->y1 */
> - int r2y1;
> - int r1_num_rects;
> - int r2_num_rects;
> - int res;
> -
> - r1 = pixman_region32_rectangles(reg1,&r1_num_rects);
> - r1_end = r1 + r1_num_rects;
> -
> - r2 = pixman_region32_rectangles(reg2,&r2_num_rects);
> - r2_end = r2 + r2_num_rects;
> -
> - res = 0;
> -
> - /*
> - * Initialize ybot.
> - * In the upcoming loop, ybot and ytop serve different functions depending
> - * on whether the band being handled is an overlapping or non-overlapping
> - * band.
> - * In the case of a non-overlapping band (only one of the regions
> - * has points in the band), ybot is the bottom of the most recent
> - * intersection and thus clips the top of the rectangles in that band.
> - * ytop is the top of the next intersection between the two regions and
> - * serves to clip the bottom of the rectangles in the current band.
> - * For an overlapping band (where the two regions intersect), ytop clips
> - * the top of the rectangles of both regions and ybot clips the bottoms.
> - */
> -
> - ybot = MIN(r1->y1, r2->y1);
> -
> - do {
> - /*
> - * This algorithm proceeds one source-band (as opposed to a
> - * destination band, which is determined by where the two regions
> - * intersect) at a time. r1_band_end and r2_band_end serve to mark the
> - * rectangle after the last one in the current band for their
> - * respective regions.
> - */
> - FIND_BAND(r1, r1_band_end, r1_end, r1y1);
> - FIND_BAND(r2, r2_band_end, r2_end, r2y1);
> -
> - /*
> - * First handle the band that doesn't intersect, if any.
> - *
> - * Note that attention is restricted to one band in the
> - * non-intersecting region at once, so if a region has n
> - * bands between the current position and the next place it overlaps
> - * the other, this entire loop will be passed through n times.
> - */
> - if (r1y1< r2y1) {
> - top = MAX (r1y1, ybot);
> - bot = MIN (r1->y2, r2y1);
> - if (top != bot) {
> - res |= REGION_TEST_LEFT_EXCLUSIVE;
> -
> - if ((res& query) == query) {
> - return res& query;
> - }
> - }
> -
> - ytop = r2y1;
> - } else if (r2y1< r1y1) {
> - top = MAX (r2y1, ybot);
> - bot = MIN (r2->y2, r1y1);
> -
> - if (top != bot) {
> - res |= REGION_TEST_RIGHT_EXCLUSIVE;
> -
> - if ((res& query) == query) {
> - return res& query;
> - }
> - }
> - ytop = r1y1;
> - } else {
> - ytop = r1y1;
> - }
> -
> - /*
> - * Now see if we've hit an intersecting band. The two bands only
> - * intersect if ybot> ytop
> - */
> - ybot = MIN (r1->y2, r2->y2);
> - if (ybot> ytop) {
> - res = test_band(query, res,
> - r1, r1_band_end,
> - r2, r2_band_end);
> - if ((res& query) == query) {
> - return res& query;
> - }
> - }
> -
> - /*
> - * If we've finished with a band (y2 == ybot) we skip forward
> - * in the region to the next band.
> - */
> - if (r1->y2 == ybot) {
> - r1 = r1_band_end;
> - }
> -
> - if (r2->y2 == ybot) {
> - r2 = r2_band_end;
> - }
> -
> - }
> - while (r1 != r1_end&& r2 != r2_end);
> -
> - /*
> - * Deal with whichever region (if any) still has rectangles left.
> - */
> -
> - if (r1 != r1_end) {
> - res |= REGION_TEST_LEFT_EXCLUSIVE;
> - } else if (r2 != r2_end) {
> - res |= REGION_TEST_RIGHT_EXCLUSIVE;
> - }
> -
> - return res& query;
> -}
> -
> -int region_test(const QRegion *_reg1, const QRegion *_reg2, int query)
> -{
> - int res;
> - pixman_region32_t *reg1 = (pixman_region32_t *)_reg1;
> - pixman_region32_t *reg2 = (pixman_region32_t *)_reg2;
> -
> - query = (query) ? query& REGION_TEST_ALL : REGION_TEST_ALL;
> -
> - res = 0;
> -
> - if (!pixman_region32_not_empty(reg1) || !pixman_region32_not_empty(reg2) ||
> - !EXTENTCHECK (®1->extents,®2->extents)) {
> - /* One or more regions are empty or they are disjoint */
> -
> - if (pixman_region32_not_empty(reg1)) {
> - res |= REGION_TEST_LEFT_EXCLUSIVE;
> - }
> -
> - if (pixman_region32_not_empty(reg2)) {
> - res |= REGION_TEST_RIGHT_EXCLUSIVE;
> - }
> -
> - return res& query;
> - } else if (!reg1->data&& !reg2->data) {
> - /* Just two rectangles that intersect */
> - res |= REGION_TEST_SHARED;
> -
> - if (!SUBSUMES(®1->extents,®2->extents)) {
> - res |= REGION_TEST_RIGHT_EXCLUSIVE;
> - }
> -
> - if (!SUBSUMES(®2->extents,®1->extents)) {
> - res |= REGION_TEST_LEFT_EXCLUSIVE;
> - }
> -
> - return res& query;
> - } else if (!reg2->data&& SUBSUMES (®2->extents,®1->extents)) {
> - /* reg2 is just a rect that contains all of reg1 */
> -
> - res |= REGION_TEST_SHARED; /* some piece must be shared, because reg is not empty */
> - res |= REGION_TEST_RIGHT_EXCLUSIVE; /* reg2 contains all of reg1 and then some */
> -
> - return res& query;
> - } else if (!reg1->data&& SUBSUMES (®1->extents,®2->extents)) {
> - /* reg1 is just a rect that contains all of reg2 */
> -
> - res |= REGION_TEST_SHARED; /* some piece must be shared, because reg is not empty */
> - res |= REGION_TEST_LEFT_EXCLUSIVE; /* reg1 contains all of reg2 and then some */
> -
> - return res& query;
> - } else if (reg1 == reg2) {
> - res |= REGION_TEST_SHARED;
> - return res& query;
> - } else {
> - /* General purpose intersection */
> - return test_generic (reg1, reg2, query);
> - }
> -}
> -
> -int region_is_valid(const QRegion *rgn)
> -{
> - return pixman_region32_selfcheck((pixman_region32_t *)rgn);
> -}
> -
> -int region_is_empty(const QRegion *rgn)
> -{
> - return !pixman_region32_not_empty((pixman_region32_t *)rgn);
> -}
> -
> -SpiceRect *region_dup_rects(const QRegion *rgn, uint32_t *num_rects)
> -{
> - pixman_box32_t *boxes;
> - SpiceRect *rects;
> - int n, i;
> -
> - boxes = pixman_region32_rectangles((pixman_region32_t *)rgn,&n);
> - if (num_rects) {
> - *num_rects = n;
> - }
> - rects = spice_new(SpiceRect, n);
> - for (i = 0; i< n; i++) {
> - rects[i].left = boxes[i].x1;
> - rects[i].top = boxes[i].y1;
> - rects[i].right = boxes[i].x2;
> - rects[i].bottom = boxes[i].y2;
> - }
> - return rects;
> -}
> -
> -void region_ret_rects(const QRegion *rgn, SpiceRect *rects, uint32_t num_rects)
> -{
> - pixman_box32_t *boxes;
> - unsigned int n, i;
> -
> - boxes = pixman_region32_rectangles((pixman_region32_t *)rgn, (int *)&n);
> - for (i = 0; i< n&& i< num_rects; i++) {
> - rects[i].left = boxes[i].x1;
> - rects[i].top = boxes[i].y1;
> - rects[i].right = boxes[i].x2;
> - rects[i].bottom = boxes[i].y2;
> - }
> -
> - if (i&& i != n) {
> - unsigned int x;
> -
> - for (x = 0; x< (n - num_rects); ++x) {
> - rects[i - 1].left = MIN(rects[i - 1].left, boxes[i + x].x1);
> - rects[i - 1].top = MIN(rects[i - 1].top, boxes[i + x].y1);
> - rects[i - 1].right = MAX(rects[i - 1].right, boxes[i + x].x2);
> - rects[i - 1].bottom = MAX(rects[i - 1].bottom, boxes[i + x].y2);
> - }
> - }
> -}
> -
> -
> -int region_is_equal(const QRegion *rgn1, const QRegion *rgn2)
> -{
> - return pixman_region32_equal((pixman_region32_t *)rgn1, (pixman_region32_t *)rgn2);
> -}
> -
> -int region_intersects(const QRegion *rgn1, const QRegion *rgn2)
> -{
> - int test_res;
> -
> - if (!region_bounds_intersects(rgn1, rgn2)) {
> - return FALSE;
> - }
> -
> - test_res = region_test(rgn1, rgn2, REGION_TEST_SHARED);
> - return !!test_res;
> -}
> -
> -int region_bounds_intersects(const QRegion *rgn1, const QRegion *rgn2)
> -{
> - pixman_box32_t *extents1, *extents2;
> -
> - extents1 = pixman_region32_extents((pixman_region32_t *)rgn1);
> - extents2 = pixman_region32_extents((pixman_region32_t *)rgn1);
> -
> - return EXTENTCHECK(extents1, extents2);
> -}
> -
> -int region_contains(const QRegion *rgn, const QRegion *other)
> -{
> - int test_res;
> -
> - test_res = region_test(rgn, other, REGION_TEST_RIGHT_EXCLUSIVE);
> - return !test_res;
> -}
> -
> -int region_contains_point(const QRegion *rgn, int32_t x, int32_t y)
> -{
> - return pixman_region32_contains_point((pixman_region32_t *)rgn, x, y, NULL);
> -}
> -
> -void region_or(QRegion *rgn, const QRegion *other_rgn)
> -{
> - pixman_region32_union(rgn, rgn, (pixman_region32_t *)other_rgn);
> -}
> -
> -void region_and(QRegion *rgn, const QRegion *other_rgn)
> -{
> - pixman_region32_intersect(rgn, rgn, (pixman_region32_t *)other_rgn);
> -}
> -
> -void region_xor(QRegion *rgn, const QRegion *other_rgn)
> -{
> - pixman_region32_t intersection;
> -
> - pixman_region32_copy(&intersection, rgn);
> - pixman_region32_intersect(&intersection,
> -&intersection,
> - (pixman_region32_t *)other_rgn);
> - pixman_region32_union(rgn, rgn, (pixman_region32_t *)other_rgn);
> - pixman_region32_subtract(rgn, rgn,&intersection);
> - pixman_region32_fini(&intersection);
> -}
> -
> -void region_exclude(QRegion *rgn, const QRegion *other_rgn)
> -{
> - pixman_region32_subtract(rgn, rgn, (pixman_region32_t *)other_rgn);
> -}
> -
> -void region_add(QRegion *rgn, const SpiceRect *r)
> -{
> - pixman_region32_union_rect(rgn, rgn, r->left, r->top,
> - r->right - r->left,
> - r->bottom - r->top);
> -}
> -
> -void region_remove(QRegion *rgn, const SpiceRect *r)
> -{
> - pixman_region32_t rg;
> -
> - pixman_region32_init_rect(&rg, r->left, r->top,
> - r->right - r->left,
> - r->bottom - r->top);
> - pixman_region32_subtract(rgn, rgn,&rg);
> - pixman_region32_fini(&rg);
> -}
> -
> -
> -void region_offset(QRegion *rgn, int32_t dx, int32_t dy)
> -{
> - pixman_region32_translate(rgn, dx, dy);
> -}
> -
> -void region_dump(const QRegion *rgn, const char *prefix)
> -{
> - pixman_box32_t *rects, *extents;
> - int n_rects, i;
> -
> - printf("%sREGION: %p, ", prefix, rgn);
> -
> - if (!pixman_region32_not_empty((pixman_region32_t *)rgn)) {
> - printf("EMPTY\n");
> - return;
> - }
> -
> - extents = pixman_region32_extents((pixman_region32_t *)rgn);
> - rects = pixman_region32_rectangles((pixman_region32_t *)rgn,&n_rects);
> - printf("num %u bounds (%d, %d, %d, %d)\n",
> - n_rects,
> - extents->x1,
> - extents->y1,
> - extents->x2,
> - extents->y2);
> -
> -
> - for (i = 0; i< n_rects; i++) {
> - printf("%*s %12d %12d %12d %12d\n",
> - (int)strlen(prefix), "",
> - rects[i].x1,
> - rects[i].y1,
> - rects[i].x2,
> - rects[i].y2);
> - }
> -}
> -
> -#ifdef REGION_TEST
> -
> -static int slow_region_test(const QRegion *rgn, const QRegion *other_rgn, int query)
> -{
> - pixman_region32_t intersection;
> - int res;
> -
> - pixman_region32_init(&intersection);
> - pixman_region32_intersect(&intersection,
> - (pixman_region32_t *)rgn,
> - (pixman_region32_t *)other_rgn);
> -
> - res = 0;
> -
> - if (query& REGION_TEST_SHARED&&
> - pixman_region32_not_empty(&intersection)) {
> - res |= REGION_TEST_SHARED;
> - }
> -
> - if (query& REGION_TEST_LEFT_EXCLUSIVE&&
> - !pixman_region32_equal(&intersection, (pixman_region32_t *)rgn)) {
> - res |= REGION_TEST_LEFT_EXCLUSIVE;
> - }
> -
> - if (query& REGION_TEST_RIGHT_EXCLUSIVE&&
> - !pixman_region32_equal(&intersection, (pixman_region32_t *)other_rgn)) {
> - res |= REGION_TEST_RIGHT_EXCLUSIVE;
> - }
> -
> - pixman_region32_fini(&intersection);
> -
> - return res;
> -}
> -
> -
> -static int rect_is_valid(const SpiceRect *r)
> -{
> - if (r->top> r->bottom || r->left> r->right) {
> - printf("%s: invalid rect\n", __FUNCTION__);
> - return FALSE;
> - }
> - return TRUE;
> -}
> -
> -static void rect_set(SpiceRect *r, int32_t top, int32_t left, int32_t bottom, int32_t right)
> -{
> - r->top = top;
> - r->left = left;
> - r->bottom = bottom;
> - r->right = right;
> - ASSERT(rect_is_valid(r));
> -}
> -
> -static void random_region(QRegion *reg)
> -{
> - int i;
> - int num_rects;
> - int x, y, w, h;
> - SpiceRect _r;
> - SpiceRect *r =&_r;
> -
> - region_clear(reg);
> -
> - num_rects = rand() % 20;
> - for (i = 0; i< num_rects; i++) {
> - x = rand()%100;
> - y = rand()%100;
> - w = rand()%100;
> - h = rand()%100;
> - rect_set(r,
> - x, y,
> - x+w, y+h);
> - region_add(reg, r);
> - }
> -}
> -
> -static void test(const QRegion *r1, const QRegion *r2, int *expected)
> -{
> - printf("r1 is_empty %s [%s]\n",
> - region_is_empty(r1) ? "TRUE" : "FALSE",
> - (region_is_empty(r1) == *(expected++)) ? "OK" : "ERR");
> - printf("r2 is_empty %s [%s]\n",
> - region_is_empty(r2) ? "TRUE" : "FALSE",
> - (region_is_empty(r2) == *(expected++)) ? "OK" : "ERR");
> - printf("is_equal %s [%s]\n",
> - region_is_equal(r1, r2) ? "TRUE" : "FALSE",
> - (region_is_equal(r1, r2) == *(expected++)) ? "OK" : "ERR");
> - printf("intersects %s [%s]\n",
> - region_intersects(r1, r2) ? "TRUE" : "FALSE",
> - (region_intersects(r1, r2) == *(expected++)) ? "OK" : "ERR");
> - printf("contains %s [%s]\n",
> - region_contains(r1, r2) ? "TRUE" : "FALSE",
> - (region_contains(r1, r2) == *(expected++)) ? "OK" : "ERR");
> -}
> -
> -enum {
> - EXPECT_R1_EMPTY,
> - EXPECT_R2_EMPTY,
> - EXPECT_EQUAL,
> - EXPECT_SECT,
> - EXPECT_CONT,
> -};
> -
> -int main(void)
> -{
> - QRegion _r1, _r2, _r3;
> - QRegion *r1 =&_r1;
> - QRegion *r2 =&_r2;
> - QRegion *r3 =&_r3;
> - SpiceRect _r;
> - SpiceRect *r =&_r;
> - int expected[5];
> - int i, j;
> -
> - region_init(r1);
> - region_init(r2);
> -
> - printf("dump r1 empty rgn [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
> - region_dump(r1, "");
> - expected[EXPECT_R1_EMPTY] = TRUE;
> - expected[EXPECT_R2_EMPTY] = TRUE;
> - expected[EXPECT_EQUAL] = TRUE;
> - expected[EXPECT_SECT] = FALSE;
> - expected[EXPECT_CONT] = TRUE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - region_clone(r3, r1);
> - printf("dump r3 clone rgn [%s]\n", region_is_valid(r3) ? "VALID" : "INVALID");
> - region_dump(r3, "");
> - expected[EXPECT_R1_EMPTY] = TRUE;
> - expected[EXPECT_R2_EMPTY] = TRUE;
> - expected[EXPECT_EQUAL] = TRUE;
> - expected[EXPECT_SECT] = FALSE;
> - expected[EXPECT_CONT] = TRUE;
> - test(r1, r3, expected);
> - region_destroy(r3);
> - printf("\n");
> -
> - rect_set(r, 0, 0, 100, 100);
> - region_add(r1, r);
> - printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
> - region_dump(r1, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = TRUE;
> - expected[EXPECT_EQUAL] = FALSE;
> - expected[EXPECT_SECT] = FALSE;
> - expected[EXPECT_CONT] = TRUE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - region_clear(r1);
> - rect_set(r, 0, 0, 0, 0);
> - region_add(r1, r);
> - printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
> - region_dump(r1, "");
> - expected[EXPECT_R1_EMPTY] = TRUE;
> - expected[EXPECT_R2_EMPTY] = TRUE;
> - expected[EXPECT_EQUAL] = TRUE;
> - expected[EXPECT_SECT] = FALSE;
> - expected[EXPECT_CONT] = TRUE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - rect_set(r, -100, -100, 0, 0);
> - region_add(r1, r);
> - printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
> - region_dump(r1, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = TRUE;
> - expected[EXPECT_EQUAL] = FALSE;
> - expected[EXPECT_SECT] = FALSE;
> - expected[EXPECT_CONT] = TRUE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - region_clear(r1);
> - rect_set(r, -100, -100, 100, 100);
> - region_add(r1, r);
> - printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
> - region_dump(r1, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = TRUE;
> - expected[EXPECT_EQUAL] = FALSE;
> - expected[EXPECT_SECT] = FALSE;
> - expected[EXPECT_CONT] = TRUE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> -
> - region_clear(r1);
> - region_clear(r2);
> -
> - rect_set(r, 100, 100, 200, 200);
> - region_add(r1, r);
> - printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
> - region_dump(r1, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = TRUE;
> - expected[EXPECT_EQUAL] = FALSE;
> - expected[EXPECT_SECT] = FALSE;
> - expected[EXPECT_CONT] = TRUE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - rect_set(r, 300, 300, 400, 400);
> - region_add(r1, r);
> - printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
> - region_dump(r1, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = TRUE;
> - expected[EXPECT_EQUAL] = FALSE;
> - expected[EXPECT_SECT] = FALSE;
> - expected[EXPECT_CONT] = TRUE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - rect_set(r, 500, 500, 600, 600);
> - region_add(r2, r);
> - printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
> - region_dump(r2, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = FALSE;
> - expected[EXPECT_EQUAL] = FALSE;
> - expected[EXPECT_SECT] = FALSE;
> - expected[EXPECT_CONT] = FALSE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - region_clear(r2);
> -
> - rect_set(r, 100, 100, 200, 200);
> - region_add(r2, r);
> - rect_set(r, 300, 300, 400, 400);
> - region_add(r2, r);
> - printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
> - region_dump(r2, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = FALSE;
> - expected[EXPECT_EQUAL] = TRUE;
> - expected[EXPECT_SECT] = TRUE;
> - expected[EXPECT_CONT] = TRUE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - region_clear(r2);
> -
> - rect_set(r, 100, 100, 200, 200);
> - region_add(r2, r);
> - printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
> - region_dump(r2, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = FALSE;
> - expected[EXPECT_EQUAL] = FALSE;
> - expected[EXPECT_SECT] = TRUE;
> - expected[EXPECT_CONT] = TRUE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - region_clear(r2);
> -
> - rect_set(r, -2000, -2000, -1000, -1000);
> - region_add(r2, r);
> - printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
> - region_dump(r2, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = FALSE;
> - expected[EXPECT_EQUAL] = FALSE;
> - expected[EXPECT_SECT] = FALSE;
> - expected[EXPECT_CONT] = FALSE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - region_clear(r2);
> -
> - rect_set(r, -2000, -2000, 1000, 1000);
> - region_add(r2, r);
> - printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
> - region_dump(r2, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = FALSE;
> - expected[EXPECT_EQUAL] = FALSE;
> - expected[EXPECT_SECT] = TRUE;
> - expected[EXPECT_CONT] = FALSE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - region_clear(r2);
> -
> - rect_set(r, 150, 150, 175, 175);
> - region_add(r2, r);
> - printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
> - region_dump(r2, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = FALSE;
> - expected[EXPECT_EQUAL] = FALSE;
> - expected[EXPECT_SECT] = TRUE;
> - expected[EXPECT_CONT] = TRUE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - region_clear(r2);
> -
> - rect_set(r, 150, 150, 350, 350);
> - region_add(r2, r);
> - printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
> - region_dump(r2, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = FALSE;
> - expected[EXPECT_EQUAL] = FALSE;
> - expected[EXPECT_SECT] = TRUE;
> - expected[EXPECT_CONT] = FALSE;
> - test(r1, r2, expected);
> - printf("\n");
> -
> - region_and(r2, r1);
> - printf("dump r2 and r1 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
> - region_dump(r2, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = FALSE;
> - expected[EXPECT_EQUAL] = FALSE;
> - expected[EXPECT_SECT] = TRUE;
> - expected[EXPECT_CONT] = FALSE;
> - test(r2, r1, expected);
> - printf("\n");
> -
> -
> - region_clone(r3, r1);
> - printf("dump r3 clone rgn [%s]\n", region_is_valid(r3) ? "VALID" : "INVALID");
> - region_dump(r3, "");
> - expected[EXPECT_R1_EMPTY] = FALSE;
> - expected[EXPECT_R2_EMPTY] = FALSE;
> - expected[EXPECT_EQUAL] = TRUE;
> - expected[EXPECT_SECT] = TRUE;
> - expected[EXPECT_CONT] = TRUE;
> - test(r1, r3, expected);
> - printf("\n");
> -
> - j = 0;
> - for (i = 0; i< 1000000; i++) {
> - int res1, res2, test;
> - int tests[] = {
> - REGION_TEST_LEFT_EXCLUSIVE,
> - REGION_TEST_RIGHT_EXCLUSIVE,
> - REGION_TEST_SHARED,
> - REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_RIGHT_EXCLUSIVE,
> - REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_SHARED,
> - REGION_TEST_RIGHT_EXCLUSIVE | REGION_TEST_SHARED,
> - REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_RIGHT_EXCLUSIVE | REGION_TEST_SHARED
> - };
> -
> - random_region(r1);
> - random_region(r2);
> -
> - for (test = 0; test< 7; test++) {
> - res1 = region_test(r1, r2, tests[test]);
> - res2 = slow_region_test(r1, r2, tests[test]);
> - if (res1 != res2) {
> - printf ("Error in region_test %d, got %d, expected %d, query=%d\n",
> - j, res1, res2, tests[test]);
> - printf ("r1:\n");
> - region_dump(r1, "");
> - printf ("r2:\n");
> - region_dump(r2, "");
> - }
> - j++;
> - }
> - }
> -
> - region_destroy(r3);
> - region_destroy(r1);
> - region_destroy(r2);
> -
> - return 0;
> -}
> -
> -#endif
> -
> diff --git a/common/region.h b/common/region.h
> deleted file mode 100644
> index bad7494..0000000
> --- a/common/region.h
> +++ /dev/null
> @@ -1,63 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H_REGION
> -#define _H_REGION
> -
> -#include<stdint.h>
> -#include "draw.h"
> -#include<pixman_utils.h>
> -
> -typedef pixman_region32_t QRegion;
> -
> -#define REGION_TEST_LEFT_EXCLUSIVE (1<< 0)
> -#define REGION_TEST_RIGHT_EXCLUSIVE (1<< 1)
> -#define REGION_TEST_SHARED (1<< 2)
> -#define REGION_TEST_ALL \
> - (REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_RIGHT_EXCLUSIVE | REGION_TEST_SHARED)
> -
> -void region_init(QRegion *rgn);
> -void region_clear(QRegion *rgn);
> -void region_destroy(QRegion *rgn);
> -void region_clone(QRegion *dest, const QRegion *src);
> -SpiceRect *region_dup_rects(const QRegion *rgn, uint32_t *num_rects);
> -void region_ret_rects(const QRegion *rgn, SpiceRect *rects, uint32_t num_rects);
> -
> -int region_test(const QRegion *rgn, const QRegion *other_rgn, int query);
> -int region_is_valid(const QRegion *rgn);
> -int region_is_empty(const QRegion *rgn);
> -int region_is_equal(const QRegion *rgn1, const QRegion *rgn2);
> -int region_intersects(const QRegion *rgn1, const QRegion *rgn2);
> -int region_bounds_intersects(const QRegion *rgn1, const QRegion *rgn2);
> -int region_contains(const QRegion *rgn, const QRegion *other);
> -int region_contains_point(const QRegion *rgn, int32_t x, int32_t y);
> -
> -void region_or(QRegion *rgn, const QRegion *other_rgn);
> -void region_and(QRegion *rgn, const QRegion *other_rgn);
> -void region_xor(QRegion *rgn, const QRegion *other_rgn);
> -void region_exclude(QRegion *rgn, const QRegion *other_rgn);
> -
> -void region_add(QRegion *rgn, const SpiceRect *r);
> -void region_remove(QRegion *rgn, const SpiceRect *r);
> -
> -void region_offset(QRegion *rgn, int32_t dx, int32_t dy);
> -
> -void region_dump(const QRegion *rgn, const char *prefix);
> -
> -#endif
> -
> diff --git a/common/ring.h b/common/ring.h
> deleted file mode 100644
> index 0194959..0000000
> --- a/common/ring.h
> +++ /dev/null
> @@ -1,153 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H_RING2
> -#define _H_RING2
> -
> -#include<stddef.h>
> -
> -#ifndef ASSERT
> -# include<assert.h>
> -# define ASSERT(X) assert(X)
> -#endif
> -
> -typedef struct Ring RingItem;
> -typedef struct Ring {
> - RingItem *prev;
> - RingItem *next;
> -} Ring;
> -
> -static inline void ring_init(Ring *ring)
> -{
> - ring->next = ring->prev = ring;
> -}
> -
> -static inline void ring_item_init(RingItem *item)
> -{
> - item->next = item->prev = NULL;
> -}
> -
> -static inline int ring_item_is_linked(RingItem *item)
> -{
> - return !!item->next;
> -}
> -
> -static inline int ring_is_empty(Ring *ring)
> -{
> - ASSERT(ring->next != NULL&& ring->prev != NULL);
> - return ring == ring->next;
> -}
> -
> -static inline void ring_add(Ring *ring, RingItem *item)
> -{
> - ASSERT(ring->next != NULL&& ring->prev != NULL);
> - ASSERT(item->next == NULL&& item->prev == NULL);
> -
> - item->next = ring->next;
> - item->prev = ring;
> - ring->next = item->next->prev = item;
> -}
> -
> -static inline void ring_add_after(RingItem *item, RingItem *pos)
> -{
> - ring_add(pos, item);
> -}
> -
> -static inline void ring_add_before(RingItem *item, RingItem *pos)
> -{
> - ring_add(pos->prev, item);
> -}
> -
> -static inline void __ring_remove(RingItem *item)
> -{
> - item->next->prev = item->prev;
> - item->prev->next = item->next;
> - item->prev = item->next = 0;
> -}
> -
> -static inline void ring_remove(RingItem *item)
> -{
> - ASSERT(item->next != NULL&& item->prev != NULL);
> - ASSERT(item->next != item);
> -
> - __ring_remove(item);
> -}
> -
> -static inline RingItem *ring_get_head(Ring *ring)
> -{
> - RingItem *ret;
> -
> - ASSERT(ring->next != NULL&& ring->prev != NULL);
> -
> - if (ring_is_empty(ring)) {
> - return NULL;
> - }
> - ret = ring->next;
> - return ret;
> -}
> -
> -static inline RingItem *ring_get_tail(Ring *ring)
> -{
> - RingItem *ret;
> -
> - ASSERT(ring->next != NULL&& ring->prev != NULL);
> -
> - if (ring_is_empty(ring)) {
> - return NULL;
> - }
> - ret = ring->prev;
> - return ret;
> -}
> -
> -static inline RingItem *ring_next(Ring *ring, RingItem *pos)
> -{
> - RingItem *ret;
> -
> - ASSERT(ring->next != NULL&& ring->prev != NULL);
> - ASSERT(pos);
> - ASSERT(pos->next != NULL&& pos->prev != NULL);
> - ret = pos->next;
> - return (ret == ring) ? NULL : ret;
> -}
> -
> -static inline RingItem *ring_prev(Ring *ring, RingItem *pos)
> -{
> - RingItem *ret;
> -
> - ASSERT(ring->next != NULL&& ring->prev != NULL);
> - ASSERT(pos);
> - ASSERT(pos->next != NULL&& pos->prev != NULL);
> - ret = pos->prev;
> - return (ret == ring) ? NULL : ret;
> -}
> -
> -static inline unsigned int ring_get_length(Ring *ring)
> -{
> - RingItem *i;
> - unsigned int ret = 0;
> -
> - for (i = ring_get_head(ring);
> - i != NULL;
> - i = ring_next(ring, i))
> - ret++;
> -
> - return ret;
> -}
> -
> -#endif
> -
> diff --git a/common/rop3.c b/common/rop3.c
> deleted file mode 100644
> index 15de023..0000000
> --- a/common/rop3.c
> +++ /dev/null
> @@ -1,657 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include<stdio.h>
> -
> -#include "rop3.h"
> -
> -#ifndef ASSERT
> -#define ASSERT(x) if (!(x)) { \
> - printf("%s: ASSERT %s failed\n", __FUNCTION__, #x); \
> - abort(); \
> -}
> -#endif
> -
> -#ifndef WARN
> -#define WARN(x) printf("warning: %s\n", x)
> -#endif
> -
> -typedef void (*rop3_with_pattern_handler_t)(pixman_image_t *d, pixman_image_t *s,
> - SpicePoint *src_pos, pixman_image_t *p,
> - SpicePoint *pat_pos);
> -
> -typedef void (*rop3_with_color_handler_t)(pixman_image_t *d, pixman_image_t *s,
> - SpicePoint *src_pos, uint32_t rgb);
> -
> -typedef void (*rop3_test_handler_t)(void);
> -
> -#define ROP3_NUM_OPS 256
> -
> -static rop3_with_pattern_handler_t rop3_with_pattern_handlers_32[ROP3_NUM_OPS];
> -static rop3_with_pattern_handler_t rop3_with_pattern_handlers_16[ROP3_NUM_OPS];
> -static rop3_with_color_handler_t rop3_with_color_handlers_32[ROP3_NUM_OPS];
> -static rop3_with_color_handler_t rop3_with_color_handlers_16[ROP3_NUM_OPS];
> -static rop3_test_handler_t rop3_test_handlers_32[ROP3_NUM_OPS];
> -static rop3_test_handler_t rop3_test_handlers_16[ROP3_NUM_OPS];
> -
> -
> -static void default_rop3_with_pattern_handler(pixman_image_t *d, pixman_image_t *s,
> - SpicePoint *src_pos, pixman_image_t *p,
> - SpicePoint *pat_pos)
> -{
> - WARN("not implemented 0x%x");
> -}
> -
> -static void default_rop3_withe_color_handler(pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
> - uint32_t rgb)
> -{
> - WARN("not implemented 0x%x");
> -}
> -
> -static void default_rop3_test_handler(void)
> -{
> -}
> -
> -#define ROP3_HANDLERS_DEPTH(name, formula, index, depth) \
> -static void rop3_handle_p##depth##_##name(pixman_image_t *d, pixman_image_t *s, \
> - SpicePoint *src_pos, \
> - pixman_image_t *p, SpicePoint *pat_pos) \
> -{ \
> - int width = pixman_image_get_width(d); \
> - int height = pixman_image_get_height(d); \
> - uint8_t *dest_line = (uint8_t *)pixman_image_get_data(d); \
> - int dest_stride = pixman_image_get_stride(d); \
> - uint8_t *end_line = dest_line + height * dest_stride; \
> - \
> - int pat_width = pixman_image_get_width(p); \
> - int pat_height = pixman_image_get_height(p); \
> - uint8_t *pat_base = (uint8_t *)pixman_image_get_data(p); \
> - int pat_stride = pixman_image_get_stride(p); \
> - int pat_v_offset = pat_pos->y; \
> - \
> - int src_stride = pixman_image_get_stride(s); \
> - uint8_t *src_line; \
> - src_line = (uint8_t *)pixman_image_get_data(s) + src_pos->y * src_stride + (src_pos->x * depth / 8); \
> - \
> - for (; dest_line< end_line; dest_line += dest_stride, src_line += src_stride) { \
> - uint##depth##_t *dest = (uint##depth##_t *)dest_line; \
> - uint##depth##_t *end = dest + width; \
> - uint##depth##_t *src = (uint##depth##_t *)src_line; \
> - \
> - int pat_h_offset = pat_pos->x; \
> - \
> - for (; dest< end; dest++, src++) { \
> - uint##depth##_t *pat; \
> - pat = (uint##depth##_t *) \
> - (pat_base + pat_v_offset * pat_stride + (pat_h_offset * depth / 8)); \
> - *dest = formula; \
> - pat_h_offset = (pat_h_offset + 1) % pat_width; \
> - } \
> - \
> - pat_v_offset = (pat_v_offset + 1) % pat_height; \
> - } \
> -} \
> - \
> -static void rop3_handle_c##depth##_##name(pixman_image_t *d, pixman_image_t *s, \
> - SpicePoint *src_pos, \
> - uint32_t rgb) \
> -{ \
> - int width = pixman_image_get_width(d); \
> - int height = pixman_image_get_height(d); \
> - uint8_t *dest_line = (uint8_t *)pixman_image_get_data(d); \
> - int dest_stride = pixman_image_get_stride(d); \
> - uint8_t *end_line = dest_line + height * dest_stride; \
> - uint##depth##_t _pat = rgb; \
> - uint##depth##_t *pat =&_pat; \
> - \
> - int src_stride = pixman_image_get_stride(s); \
> - uint8_t *src_line; \
> - src_line = (uint8_t *) \
> - pixman_image_get_data(s) + src_pos->y * src_stride + (src_pos->x * depth / 8); \
> - \
> - for (; dest_line< end_line; dest_line += dest_stride, src_line += src_stride) { \
> - uint##depth##_t *dest = (uint##depth##_t *)dest_line; \
> - uint##depth##_t *end = dest + width; \
> - uint##depth##_t *src = (uint##depth##_t *)src_line; \
> - for (; dest< end; dest++, src++) { \
> - *dest = formula; \
> - } \
> - } \
> -} \
> - \
> -static void rop3_test##depth##_##name(void) \
> -{ \
> - uint8_t d = 0xaa; \
> - uint8_t s = 0xcc; \
> - uint8_t p = 0xf0; \
> - uint8_t *pat =&p; \
> - uint8_t *src =&s; \
> - uint8_t *dest =&d; \
> - \
> - d = formula; \
> - if (d != index) { \
> - printf("%s: failed, result is 0x%x expect 0x%x\n", __FUNCTION__, d, index); \
> - } \
> -}
> -
> -#define ROP3_HANDLERS(name, formula, index) \
> - ROP3_HANDLERS_DEPTH(name, formula, index, 32) \
> - ROP3_HANDLERS_DEPTH(name, formula, index, 16)
> -
> -ROP3_HANDLERS(DPSoon, ~(*pat | *src | *dest), 0x01);
> -ROP3_HANDLERS(DPSona, ~(*pat | *src)& *dest, 0x02);
> -ROP3_HANDLERS(SDPona, ~(*pat | *dest)& *src, 0x04);
> -ROP3_HANDLERS(PDSxnon, ~(~(*src ^ *dest) | *pat), 0x06);
> -ROP3_HANDLERS(PDSaon, ~((*src& *dest) | *pat), 0x07);
> -ROP3_HANDLERS(SDPnaa, ~*pat& *dest& *src, 0x08);
> -ROP3_HANDLERS(PDSxon, ~((*src ^ *dest) | *pat), 0x09);
> -ROP3_HANDLERS(PSDnaon, ~((~*dest& *src) | *pat), 0x0b);
> -ROP3_HANDLERS(PDSnaon, ~((~*src& *dest) | *pat), 0x0d);
> -ROP3_HANDLERS(PDSonon, ~(~(*src | *dest) | *pat), 0x0e);
> -ROP3_HANDLERS(PDSona, ~(*src | *dest)& *pat, 0x10);
> -ROP3_HANDLERS(SDPxnon, ~(~(*pat ^ *dest) | *src), 0x12);
> -ROP3_HANDLERS(SDPaon, ~((*pat& *dest) | *src), 0x13);
> -ROP3_HANDLERS(DPSxnon, ~(~(*pat ^ *src) | *dest), 0x14);
> -ROP3_HANDLERS(DPSaon, ~((*pat& *src) | *dest), 0x15);
> -ROP3_HANDLERS(PSDPSanaxx, (~(*pat& *src)& *dest) ^ *src ^ *pat, 0x16);
> -ROP3_HANDLERS(SSPxDSxaxn, ~(((*src ^ *dest)& (*src ^ *pat)) ^ *src), 0x17);
> -ROP3_HANDLERS(SPxPDxa, (*src ^ *pat)& (*pat ^ *dest), 0x18);
> -ROP3_HANDLERS(SDPSanaxn, ~((~(*pat& *src)& *dest) ^ *src), 0x19);
> -ROP3_HANDLERS(PDSPaox, ((*pat& *src) | *dest) ^ *pat, 0x1a);
> -ROP3_HANDLERS(SDPSxaxn, ~(((*pat ^ *src)& *dest) ^ *src), 0x1b);
> -ROP3_HANDLERS(PSDPaox, ((*pat& *dest) | *src) ^ *pat, 0x1c);
> -ROP3_HANDLERS(DSPDxaxn, ~(((*pat ^ *dest)& *src) ^ *dest), 0x1d);
> -ROP3_HANDLERS(PDSox, (*dest | *src) ^ *pat, 0x1e);
> -ROP3_HANDLERS(PDSoan, ~((*src | *dest)& *pat), 0x1f);
> -ROP3_HANDLERS(DPSnaa, ~*src& *pat& *dest, 0x20);
> -ROP3_HANDLERS(SDPxon, ~((*pat ^ *dest) | *src), 0x21);
> -ROP3_HANDLERS(SPDnaon, ~((~*dest& *pat) | *src), 0x23);
> -ROP3_HANDLERS(SPxDSxa, (*src ^ *pat)& (*dest ^ *src), 0x24);
> -ROP3_HANDLERS(PDSPanaxn, ~((~(*src& *pat)& *dest) ^ *pat), 0x25);
> -ROP3_HANDLERS(SDPSaox, ((*src& *pat) | *dest) ^ *src, 0x26);
> -ROP3_HANDLERS(SDPSxnox, (~(*src ^ *pat) | *dest) ^ *src, 0x27);
> -ROP3_HANDLERS(DPSxa, (*pat ^ *src)& *dest, 0x28);
> -ROP3_HANDLERS(PSDPSaoxxn, ~(((*src& *pat) | *dest) ^ *src ^ *pat), 0x29);
> -ROP3_HANDLERS(DPSana, ~(*src& *pat)& *dest, 0x2a);
> -ROP3_HANDLERS(SSPxPDxaxn, ~(((*pat ^ *dest)& (*src ^ *pat)) ^ *src), 0x2b);
> -ROP3_HANDLERS(SPDSoax, ((*src | *dest)& *pat) ^ *src, 0x2c);
> -ROP3_HANDLERS(PSDnox, (~*dest | *src) ^ *pat, 0x2d);
> -ROP3_HANDLERS(PSDPxox, ((*pat ^ *dest) | *src) ^ *pat, 0x2e);
> -ROP3_HANDLERS(PSDnoan, ~((~*dest | *src)& *pat), 0x2f);
> -ROP3_HANDLERS(SDPnaon, ~((~*pat& *dest) | *src), 0x31);
> -ROP3_HANDLERS(SDPSoox, (*src | *pat | *dest) ^ *src, 0x32);
> -ROP3_HANDLERS(SPDSaox, ((*src& *dest) | *pat) ^ *src, 0x34);
> -ROP3_HANDLERS(SPDSxnox, (~(*src ^ *dest) | *pat) ^ *src, 0x35);
> -ROP3_HANDLERS(SDPox, (*pat | *dest) ^ *src, 0x36);
> -ROP3_HANDLERS(SDPoan, ~((*pat | *dest)& *src), 0x37);
> -ROP3_HANDLERS(PSDPoax, ((*pat | *dest)& *src) ^ *pat, 0x38);
> -ROP3_HANDLERS(SPDnox, (~*dest | *pat) ^ *src, 0x39);
> -ROP3_HANDLERS(SPDSxox, ((*src ^ *dest) | *pat) ^ *src, 0x3a);
> -ROP3_HANDLERS(SPDnoan, ~((~*dest | *pat)& *src), 0x3b);
> -ROP3_HANDLERS(SPDSonox, (~(*src | *dest) | *pat) ^ *src, 0x3d);
> -ROP3_HANDLERS(SPDSnaox, ((~*src& *dest) | *pat) ^ *src, 0x3e);
> -ROP3_HANDLERS(PSDnaa, ~*dest& *src& *pat, 0x40);
> -ROP3_HANDLERS(DPSxon, ~((*src ^ *pat) | *dest), 0x41);
> -ROP3_HANDLERS(SDxPDxa, (*src ^ *dest)& (*pat ^ *dest), 0x42);
> -ROP3_HANDLERS(SPDSanaxn, ~((~(*src& *dest)& *pat) ^ *src), 0x43);
> -ROP3_HANDLERS(DPSnaon, ~((~*src& *pat) | *dest), 0x45);
> -ROP3_HANDLERS(DSPDaox, ((*dest& *pat) | *src) ^ *dest, 0x46);
> -ROP3_HANDLERS(PSDPxaxn, ~(((*pat ^ *dest)& *src) ^ *pat), 0x47);
> -ROP3_HANDLERS(SDPxa, (*pat ^ *dest)& *src, 0x48);
> -ROP3_HANDLERS(PDSPDaoxxn, ~(((*dest& *pat) | *src) ^ *dest ^ *pat), 0x49);
> -ROP3_HANDLERS(DPSDoax, ((*dest | *src)& *pat) ^ *dest, 0x4a);
> -ROP3_HANDLERS(PDSnox, (~*src | *dest) ^ *pat, 0x4b);
> -ROP3_HANDLERS(SDPana, ~(*pat& *dest)& *src, 0x4c);
> -ROP3_HANDLERS(SSPxDSxoxn, ~(((*src ^ *dest) | (*src ^ *pat)) ^ *src), 0x4d);
> -ROP3_HANDLERS(PDSPxox, ((*pat ^ *src) | *dest) ^ *pat, 0x4e);
> -ROP3_HANDLERS(PDSnoan, ~((~*src | *dest)& *pat), 0x4f);
> -ROP3_HANDLERS(DSPnaon, ~((~*pat& *src) | *dest), 0x51);
> -ROP3_HANDLERS(DPSDaox, ((*dest& *src) | *pat) ^ *dest, 0x52);
> -ROP3_HANDLERS(SPDSxaxn, ~(((*src ^ *dest)& *pat) ^ *src), 0x53);
> -ROP3_HANDLERS(DPSonon, ~(~(*src | *pat) | *dest), 0x54);
> -ROP3_HANDLERS(DPSox, (*src | *pat) ^ *dest, 0x56);
> -ROP3_HANDLERS(DPSoan, ~((*src | *pat)& *dest), 0x57);
> -ROP3_HANDLERS(PDSPoax, ((*pat | *src)& *dest) ^ *pat, 0x58);
> -ROP3_HANDLERS(DPSnox, (~*src | *pat) ^ *dest, 0x59);
> -ROP3_HANDLERS(DPSDonox, (~(*dest | *src) | *pat) ^ *dest, 0x5b);
> -ROP3_HANDLERS(DPSDxox, ((*dest ^ *src) | *pat) ^ *dest, 0x5c);
> -ROP3_HANDLERS(DPSnoan, ~((~*src | *pat)& *dest), 0x5d);
> -ROP3_HANDLERS(DPSDnaox, ((~*dest& *src) | *pat) ^ *dest, 0x5e);
> -ROP3_HANDLERS(PDSxa, (*src ^ *dest)& *pat, 0x60);
> -ROP3_HANDLERS(DSPDSaoxxn, ~(((*src& *dest) | *pat) ^ *src ^ *dest), 0x61);
> -ROP3_HANDLERS(DSPDoax, ((*dest | *pat)& *src) ^ *dest, 0x62);
> -ROP3_HANDLERS(SDPnox, (~*pat | *dest) ^ *src, 0x63);
> -ROP3_HANDLERS(SDPSoax, ((*src | *pat)& *dest) ^ *src, 0x64);
> -ROP3_HANDLERS(DSPnox, (~*pat | *src) ^ *dest, 0x65);
> -ROP3_HANDLERS(SDPSonox, (~(*src | *pat) | *dest) ^ *src, 0x67);
> -ROP3_HANDLERS(DSPDSonoxxn, ~((~(*src | *dest) | *pat) ^ *src ^ *dest), 0x68);
> -ROP3_HANDLERS(PDSxxn, ~(*src ^ *dest ^ *pat), 0x69);
> -ROP3_HANDLERS(DPSax, (*src& *pat) ^ *dest, 0x6a);
> -ROP3_HANDLERS(PSDPSoaxxn, ~(((*src | *pat)& *dest) ^ *src ^ *pat), 0x6b);
> -ROP3_HANDLERS(SDPax, (*pat& *dest) ^ *src, 0x6c);
> -ROP3_HANDLERS(PDSPDoaxxn, ~(((*dest | *pat)& *src) ^ *dest ^ *pat), 0x6d);
> -ROP3_HANDLERS(SDPSnoax, ((~*src | *pat)& *dest) ^ *src, 0x6e);
> -ROP3_HANDLERS(PDSxnan, ~(~(*src ^ *dest)& *pat), 0x6f);
> -ROP3_HANDLERS(PDSana, ~(*src& *dest)& *pat, 0x70);
> -ROP3_HANDLERS(SSDxPDxaxn, ~(((*dest ^ *pat)& (*src ^ *dest)) ^ *src), 0x71);
> -ROP3_HANDLERS(SDPSxox, ((*src ^ *pat) | *dest) ^ *src, 0x72);
> -ROP3_HANDLERS(SDPnoan, ~((~*pat | *dest)& *src), 0x73);
> -ROP3_HANDLERS(DSPDxox, ((*dest ^ *pat) | *src) ^ *dest, 0x74);
> -ROP3_HANDLERS(DSPnoan, ~((~*pat | *src)& *dest), 0x75);
> -ROP3_HANDLERS(SDPSnaox, ((~*src& *pat) | *dest) ^ *src, 0x76);
> -ROP3_HANDLERS(PDSax, (*src& *dest) ^ *pat, 0x78);
> -ROP3_HANDLERS(DSPDSoaxxn, ~(((*src | *dest)& *pat) ^ *src ^ *dest), 0x79);
> -ROP3_HANDLERS(DPSDnoax, ((~*dest | *src)& *pat) ^ *dest, 0x7a);
> -ROP3_HANDLERS(SDPxnan, ~(~(*pat ^ *dest)& *src), 0x7b);
> -ROP3_HANDLERS(SPDSnoax, ((~*src | *dest)& *pat) ^ *src, 0x7c);
> -ROP3_HANDLERS(DPSxnan, ~(~(*src ^ *pat)& *dest), 0x7d);
> -ROP3_HANDLERS(SPxDSxo, (*src ^ *dest) | (*pat ^ *src), 0x7e);
> -ROP3_HANDLERS(DPSaan, ~(*src& *pat& *dest), 0x7f);
> -ROP3_HANDLERS(DPSaa, *src& *pat& *dest, 0x80);
> -ROP3_HANDLERS(SPxDSxon, ~((*src ^ *dest) | (*pat ^ *src)), 0x81);
> -ROP3_HANDLERS(DPSxna, ~(*src ^ *pat)& *dest, 0x82);
> -ROP3_HANDLERS(SPDSnoaxn, ~(((~*src | *dest)& *pat) ^ *src), 0x83);
> -ROP3_HANDLERS(SDPxna, ~(*pat ^ *dest)& *src, 0x84);
> -ROP3_HANDLERS(PDSPnoaxn, ~(((~*pat | *src)& *dest) ^ *pat), 0x85);
> -ROP3_HANDLERS(DSPDSoaxx, ((*src | *dest)& *pat) ^ *src ^ *dest, 0x86);
> -ROP3_HANDLERS(PDSaxn, ~((*src& *dest) ^ *pat), 0x87);
> -ROP3_HANDLERS(SDPSnaoxn, ~(((~*src& *pat) | *dest) ^ *src), 0x89);
> -ROP3_HANDLERS(DSPnoa, (~*pat | *src)& *dest, 0x8a);
> -ROP3_HANDLERS(DSPDxoxn, ~(((*dest ^ *pat) | *src) ^ *dest), 0x8b);
> -ROP3_HANDLERS(SDPnoa, (~*pat | *dest)& *src, 0x8c);
> -ROP3_HANDLERS(SDPSxoxn, ~(((*src ^ *pat) | *dest) ^ *src), 0x8d);
> -ROP3_HANDLERS(SSDxPDxax, ((*dest ^ *pat)& (*dest ^ *src)) ^ *src, 0x8e);
> -ROP3_HANDLERS(PDSanan, ~(~(*src& *dest)& *pat), 0x8f);
> -ROP3_HANDLERS(PDSxna, ~(*src ^ *dest)& *pat, 0x90);
> -ROP3_HANDLERS(SDPSnoaxn, ~(((~*src | *pat)& *dest) ^ *src), 0x91);
> -ROP3_HANDLERS(DPSDPoaxx, ((*pat | *dest)& *src) ^ *pat ^ *dest, 0x92);
> -ROP3_HANDLERS(SPDaxn, ~((*dest& *pat) ^ *src), 0x93);
> -ROP3_HANDLERS(PSDPSoaxx, ((*src | *pat)& *dest) ^ *src ^ *pat, 0x94);
> -ROP3_HANDLERS(DPSaxn, ~((*src& *pat) ^ *dest), 0x95);
> -ROP3_HANDLERS(DPSxx, *src ^ *pat ^ *dest, 0x96);
> -ROP3_HANDLERS(PSDPSonoxx, (~(*src | *pat) | *dest) ^ *src ^ *pat, 0x97);
> -ROP3_HANDLERS(SDPSonoxn, ~((~(*src | *pat) | *dest) ^ *src), 0x98);
> -ROP3_HANDLERS(DPSnax, (~*src& *pat) ^ *dest, 0x9a);
> -ROP3_HANDLERS(SDPSoaxn, ~(((*src | *pat)& *dest) ^ *src), 0x9b);
> -ROP3_HANDLERS(SPDnax, (~*dest& *pat) ^ *src, 0x9c);
> -ROP3_HANDLERS(DSPDoaxn, ~(((*dest | *pat)& *src) ^ *dest), 0x9d);
> -ROP3_HANDLERS(DSPDSaoxx, ((*src& *dest) | *pat) ^ *src ^ *dest, 0x9e);
> -ROP3_HANDLERS(PDSxan, ~((*src ^ *dest)& *pat), 0x9f);
> -ROP3_HANDLERS(PDSPnaoxn, ~(((~*pat& *src) | *dest) ^ *pat), 0xa1);
> -ROP3_HANDLERS(DPSnoa, (~*src | *pat)& *dest, 0xa2);
> -ROP3_HANDLERS(DPSDxoxn, ~(((*dest ^ *src) | *pat) ^ *dest), 0xa3);
> -ROP3_HANDLERS(PDSPonoxn, ~((~(*pat | *src) | *dest) ^ *pat), 0xa4);
> -ROP3_HANDLERS(DSPnax, (~*pat& *src) ^ *dest, 0xa6);
> -ROP3_HANDLERS(PDSPoaxn, ~(((*pat | *src)& *dest) ^ *pat), 0xa7);
> -ROP3_HANDLERS(DPSoa, (*src | *pat)& *dest, 0xa8);
> -ROP3_HANDLERS(DPSoxn, ~((*src | *pat) ^ *dest), 0xa9);
> -ROP3_HANDLERS(DPSono, ~(*src | *pat) | *dest, 0xab);
> -ROP3_HANDLERS(SPDSxax, ((*src ^ *dest)& *pat) ^ *src, 0xac);
> -ROP3_HANDLERS(DPSDaoxn, ~(((*dest& *src) | *pat) ^ *dest), 0xad);
> -ROP3_HANDLERS(DSPnao, (~*pat& *src) | *dest, 0xae);
> -ROP3_HANDLERS(PDSnoa, (~*src | *dest)& *pat, 0xb0);
> -ROP3_HANDLERS(PDSPxoxn, ~(((*pat ^ *src) | *dest) ^ *pat), 0xb1);
> -ROP3_HANDLERS(SSPxDSxox, ((*src ^ *dest) | (*pat ^ *src)) ^ *src, 0xb2);
> -ROP3_HANDLERS(SDPanan, ~(~(*pat& *dest)& *src), 0xb3);
> -ROP3_HANDLERS(PSDnax, (~*dest& *src) ^ *pat, 0xb4);
> -ROP3_HANDLERS(DPSDoaxn, ~(((*dest | *src)& *pat) ^ *dest), 0xb5);
> -ROP3_HANDLERS(DPSDPaoxx, ((*pat& *dest) | *src) ^ *pat ^ *dest, 0xb6);
> -ROP3_HANDLERS(SDPxan, ~((*pat ^ *dest)& *src), 0xb7);
> -ROP3_HANDLERS(PSDPxax, ((*dest ^ *pat)& *src) ^ *pat, 0xb8);
> -ROP3_HANDLERS(DSPDaoxn, ~(((*dest& *pat) | *src) ^ *dest), 0xb9);
> -ROP3_HANDLERS(DPSnao, (~*src& *pat) | *dest, 0xba);
> -ROP3_HANDLERS(SPDSanax, (~(*src& *dest)& *pat) ^ *src, 0xbc);
> -ROP3_HANDLERS(SDxPDxan, ~((*dest ^ *pat)& (*dest ^ *src)), 0xbd);
> -ROP3_HANDLERS(DPSxo, (*src ^ *pat) | *dest, 0xbe);
> -ROP3_HANDLERS(DPSano, ~(*src& *pat) | *dest, 0xbf);
> -ROP3_HANDLERS(SPDSnaoxn, ~(((~*src& *dest) | *pat) ^ *src), 0xc1);
> -ROP3_HANDLERS(SPDSonoxn, ~((~(*src | *dest) | *pat) ^ *src), 0xc2);
> -ROP3_HANDLERS(SPDnoa, (~*dest | *pat)& *src, 0xc4);
> -ROP3_HANDLERS(SPDSxoxn, ~(((*src ^ *dest) | *pat) ^ *src), 0xc5);
> -ROP3_HANDLERS(SDPnax, (~*pat& *dest) ^ *src, 0xc6);
> -ROP3_HANDLERS(PSDPoaxn, ~(((*pat | *dest)& *src) ^ *pat), 0xc7);
> -ROP3_HANDLERS(SDPoa, (*pat | *dest)& *src, 0xc8);
> -ROP3_HANDLERS(SPDoxn, ~((*dest | *pat) ^ *src), 0xc9);
> -ROP3_HANDLERS(DPSDxax, ((*dest ^ *src)& *pat) ^ *dest, 0xca);
> -ROP3_HANDLERS(SPDSaoxn, ~(((*src& *dest) | *pat) ^ *src), 0xcb);
> -ROP3_HANDLERS(SDPono, ~(*pat | *dest) | *src, 0xcd);
> -ROP3_HANDLERS(SDPnao, (~*pat& *dest) | *src, 0xce);
> -ROP3_HANDLERS(PSDnoa, (~*dest | *src)& *pat, 0xd0);
> -ROP3_HANDLERS(PSDPxoxn, ~(((*pat ^ *dest) | *src) ^ *pat), 0xd1);
> -ROP3_HANDLERS(PDSnax, (~*src& *dest) ^ *pat, 0xd2);
> -ROP3_HANDLERS(SPDSoaxn, ~(((*src | *dest)& *pat) ^ *src), 0xd3);
> -ROP3_HANDLERS(SSPxPDxax, ((*dest ^ *pat)& (*pat ^ *src)) ^ *src, 0xd4);
> -ROP3_HANDLERS(DPSanan, ~(~(*src& *pat)& *dest), 0xd5);
> -ROP3_HANDLERS(PSDPSaoxx, ((*src& *pat) | *dest) ^ *src ^ *pat, 0xd6);
> -ROP3_HANDLERS(DPSxan, ~((*src ^ *pat)& *dest), 0xd7);
> -ROP3_HANDLERS(PDSPxax, ((*pat ^ *src)& *dest) ^ *pat, 0xd8);
> -ROP3_HANDLERS(SDPSaoxn, ~(((*src& *pat) | *dest) ^ *src), 0xd9);
> -ROP3_HANDLERS(DPSDanax, (~(*dest& *src)& *pat) ^ *dest, 0xda);
> -ROP3_HANDLERS(SPxDSxan, ~((*src ^ *dest)& (*pat ^ *src)), 0xdb);
> -ROP3_HANDLERS(SPDnao, (~*dest& *pat) | *src, 0xdc);
> -ROP3_HANDLERS(SDPxo, (*pat ^ *dest) | *src, 0xde);
> -ROP3_HANDLERS(SDPano, ~(*pat& *dest) | *src, 0xdf);
> -ROP3_HANDLERS(PDSoa, (*src | *dest)& *pat, 0xe0);
> -ROP3_HANDLERS(PDSoxn, ~((*src | *dest) ^ *pat), 0xe1);
> -ROP3_HANDLERS(DSPDxax, ((*dest ^ *pat)& *src) ^ *dest, 0xe2);
> -ROP3_HANDLERS(PSDPaoxn, ~(((*pat& *dest) | *src) ^ *pat), 0xe3);
> -ROP3_HANDLERS(SDPSxax, ((*src ^ *pat)& *dest) ^ *src, 0xe4);
> -ROP3_HANDLERS(PDSPaoxn, ~(((*pat& *src) | *dest) ^ *pat), 0xe5);
> -ROP3_HANDLERS(SDPSanax, (~(*src& *pat)& *dest) ^ *src, 0xe6);
> -ROP3_HANDLERS(SPxPDxan, ~((*dest ^ *pat)& (*pat ^ *src)), 0xe7);
> -ROP3_HANDLERS(SSPxDSxax, ((*src ^ *dest)& (*pat ^ *src)) ^ *src, 0xe8);
> -ROP3_HANDLERS(DSPDSanaxxn, ~((~(*src& *dest)& *pat) ^ *src ^ *dest), 0xe9);
> -ROP3_HANDLERS(DPSao, (*src& *pat) | *dest, 0xea);
> -ROP3_HANDLERS(DPSxno, ~(*src ^ *pat) | *dest, 0xeb);
> -ROP3_HANDLERS(SDPao, (*pat& *dest) | *src, 0xec);
> -ROP3_HANDLERS(SDPxno, ~(*pat ^ *dest) | *src, 0xed);
> -ROP3_HANDLERS(SDPnoo, ~*pat | *dest | *src, 0xef);
> -ROP3_HANDLERS(PDSono, ~(*src | *dest) | *pat, 0xf1);
> -ROP3_HANDLERS(PDSnao, (~*src& *dest) | *pat, 0xf2);
> -ROP3_HANDLERS(PSDnao, (~*dest& *src) | *pat, 0xf4);
> -ROP3_HANDLERS(PDSxo, (*src ^ *dest) | *pat, 0xf6);
> -ROP3_HANDLERS(PDSano, ~(*src& *dest) | *pat, 0xf7);
> -ROP3_HANDLERS(PDSao, (*src& *dest) | *pat, 0xf8);
> -ROP3_HANDLERS(PDSxno, ~(*src ^ *dest) | *pat, 0xf9);
> -ROP3_HANDLERS(DPSnoo, ~*src | *pat | *dest, 0xfb);
> -ROP3_HANDLERS(PSDnoo, ~*dest | *src | *pat, 0xfd);
> -ROP3_HANDLERS(DPSoo, *src | *pat | *dest, 0xfe);
> -
> -
> -#define ROP3_FILL_HANDLERS(op, index) \
> - rop3_with_pattern_handlers_32[index] = rop3_handle_p32_##op; \
> - rop3_with_pattern_handlers_16[index] = rop3_handle_p16_##op; \
> - rop3_with_color_handlers_32[index] = rop3_handle_c32_##op; \
> - rop3_with_color_handlers_16[index] = rop3_handle_c16_##op; \
> - rop3_test_handlers_32[index] = rop3_test32_##op; \
> - rop3_test_handlers_16[index] = rop3_test16_##op;
> -
> -void rop3_init(void)
> -{
> - static int need_init = 1;
> - int i;
> -
> - if (!need_init) {
> - return;
> - }
> - need_init = 0;
> -
> - for (i = 0; i< ROP3_NUM_OPS; i++) {
> - rop3_with_pattern_handlers_32[i] = default_rop3_with_pattern_handler;
> - rop3_with_pattern_handlers_16[i] = default_rop3_with_pattern_handler;
> - rop3_with_color_handlers_32[i] = default_rop3_withe_color_handler;
> - rop3_with_color_handlers_16[i] = default_rop3_withe_color_handler;
> - rop3_test_handlers_32[i] = default_rop3_test_handler;
> - rop3_test_handlers_16[i] = default_rop3_test_handler;
> - }
> -
> - ROP3_FILL_HANDLERS(DPSoon, 0x01);
> - ROP3_FILL_HANDLERS(DPSona, 0x02);
> - ROP3_FILL_HANDLERS(SDPona, 0x04);
> - ROP3_FILL_HANDLERS(PDSxnon, 0x06);
> - ROP3_FILL_HANDLERS(PDSaon, 0x07);
> - ROP3_FILL_HANDLERS(SDPnaa, 0x08);
> - ROP3_FILL_HANDLERS(PDSxon, 0x09);
> - ROP3_FILL_HANDLERS(PSDnaon, 0x0b);
> - ROP3_FILL_HANDLERS(PDSnaon, 0x0d);
> - ROP3_FILL_HANDLERS(PDSonon, 0x0e);
> - ROP3_FILL_HANDLERS(PDSona, 0x10);
> - ROP3_FILL_HANDLERS(SDPxnon, 0x12);
> - ROP3_FILL_HANDLERS(SDPaon, 0x13);
> - ROP3_FILL_HANDLERS(DPSxnon, 0x14);
> - ROP3_FILL_HANDLERS(DPSaon, 0x15);
> - ROP3_FILL_HANDLERS(PSDPSanaxx, 0x16);
> - ROP3_FILL_HANDLERS(SSPxDSxaxn, 0x17);
> - ROP3_FILL_HANDLERS(SPxPDxa, 0x18);
> - ROP3_FILL_HANDLERS(SDPSanaxn, 0x19);
> - ROP3_FILL_HANDLERS(PDSPaox, 0x1a);
> - ROP3_FILL_HANDLERS(SDPSxaxn, 0x1b);
> - ROP3_FILL_HANDLERS(PSDPaox, 0x1c);
> - ROP3_FILL_HANDLERS(DSPDxaxn, 0x1d);
> - ROP3_FILL_HANDLERS(PDSox, 0x1e);
> - ROP3_FILL_HANDLERS(PDSoan, 0x1f);
> - ROP3_FILL_HANDLERS(DPSnaa, 0x20);
> - ROP3_FILL_HANDLERS(SDPxon, 0x21);
> - ROP3_FILL_HANDLERS(SPDnaon, 0x23);
> - ROP3_FILL_HANDLERS(SPxDSxa, 0x24);
> - ROP3_FILL_HANDLERS(PDSPanaxn, 0x25);
> - ROP3_FILL_HANDLERS(SDPSaox, 0x26);
> - ROP3_FILL_HANDLERS(SDPSxnox, 0x27);
> - ROP3_FILL_HANDLERS(DPSxa, 0x28);
> - ROP3_FILL_HANDLERS(PSDPSaoxxn, 0x29);
> - ROP3_FILL_HANDLERS(DPSana, 0x2a);
> - ROP3_FILL_HANDLERS(SSPxPDxaxn, 0x2b);
> - ROP3_FILL_HANDLERS(SPDSoax, 0x2c);
> - ROP3_FILL_HANDLERS(PSDnox, 0x2d);
> - ROP3_FILL_HANDLERS(PSDPxox, 0x2e);
> - ROP3_FILL_HANDLERS(PSDnoan, 0x2f);
> - ROP3_FILL_HANDLERS(SDPnaon, 0x31);
> - ROP3_FILL_HANDLERS(SDPSoox, 0x32);
> - ROP3_FILL_HANDLERS(SPDSaox, 0x34);
> - ROP3_FILL_HANDLERS(SPDSxnox, 0x35);
> - ROP3_FILL_HANDLERS(SDPox, 0x36);
> - ROP3_FILL_HANDLERS(SDPoan, 0x37);
> - ROP3_FILL_HANDLERS(PSDPoax, 0x38);
> - ROP3_FILL_HANDLERS(SPDnox, 0x39);
> - ROP3_FILL_HANDLERS(SPDSxox, 0x3a);
> - ROP3_FILL_HANDLERS(SPDnoan, 0x3b);
> - ROP3_FILL_HANDLERS(SPDSonox, 0x3d);
> - ROP3_FILL_HANDLERS(SPDSnaox, 0x3e);
> - ROP3_FILL_HANDLERS(PSDnaa, 0x40);
> - ROP3_FILL_HANDLERS(DPSxon, 0x41);
> - ROP3_FILL_HANDLERS(SDxPDxa, 0x42);
> - ROP3_FILL_HANDLERS(SPDSanaxn, 0x43);
> - ROP3_FILL_HANDLERS(DPSnaon, 0x45);
> - ROP3_FILL_HANDLERS(DSPDaox, 0x46);
> - ROP3_FILL_HANDLERS(PSDPxaxn, 0x47);
> - ROP3_FILL_HANDLERS(SDPxa, 0x48);
> - ROP3_FILL_HANDLERS(PDSPDaoxxn, 0x49);
> - ROP3_FILL_HANDLERS(DPSDoax, 0x4a);
> - ROP3_FILL_HANDLERS(PDSnox, 0x4b);
> - ROP3_FILL_HANDLERS(SDPana, 0x4c);
> - ROP3_FILL_HANDLERS(SSPxDSxoxn, 0x4d);
> - ROP3_FILL_HANDLERS(PDSPxox, 0x4e);
> - ROP3_FILL_HANDLERS(PDSnoan, 0x4f);
> - ROP3_FILL_HANDLERS(DSPnaon, 0x51);
> - ROP3_FILL_HANDLERS(DPSDaox, 0x52);
> - ROP3_FILL_HANDLERS(SPDSxaxn, 0x53);
> - ROP3_FILL_HANDLERS(DPSonon, 0x54);
> - ROP3_FILL_HANDLERS(DPSox, 0x56);
> - ROP3_FILL_HANDLERS(DPSoan, 0x57);
> - ROP3_FILL_HANDLERS(PDSPoax, 0x58);
> - ROP3_FILL_HANDLERS(DPSnox, 0x59);
> - ROP3_FILL_HANDLERS(DPSDonox, 0x5b);
> - ROP3_FILL_HANDLERS(DPSDxox, 0x5c);
> - ROP3_FILL_HANDLERS(DPSnoan, 0x5d);
> - ROP3_FILL_HANDLERS(DPSDnaox, 0x5e);
> - ROP3_FILL_HANDLERS(PDSxa, 0x60);
> - ROP3_FILL_HANDLERS(DSPDSaoxxn, 0x61);
> - ROP3_FILL_HANDLERS(DSPDoax, 0x62);
> - ROP3_FILL_HANDLERS(SDPnox, 0x63);
> - ROP3_FILL_HANDLERS(SDPSoax, 0x64);
> - ROP3_FILL_HANDLERS(DSPnox, 0x65);
> - ROP3_FILL_HANDLERS(SDPSonox, 0x67);
> - ROP3_FILL_HANDLERS(DSPDSonoxxn, 0x68);
> - ROP3_FILL_HANDLERS(PDSxxn, 0x69);
> - ROP3_FILL_HANDLERS(DPSax, 0x6a);
> - ROP3_FILL_HANDLERS(PSDPSoaxxn, 0x6b);
> - ROP3_FILL_HANDLERS(SDPax, 0x6c);
> - ROP3_FILL_HANDLERS(PDSPDoaxxn, 0x6d);
> - ROP3_FILL_HANDLERS(SDPSnoax, 0x6e);
> - ROP3_FILL_HANDLERS(PDSxnan, 0x6f);
> - ROP3_FILL_HANDLERS(PDSana, 0x70);
> - ROP3_FILL_HANDLERS(SSDxPDxaxn, 0x71);
> - ROP3_FILL_HANDLERS(SDPSxox, 0x72);
> - ROP3_FILL_HANDLERS(SDPnoan, 0x73);
> - ROP3_FILL_HANDLERS(DSPDxox, 0x74);
> - ROP3_FILL_HANDLERS(DSPnoan, 0x75);
> - ROP3_FILL_HANDLERS(SDPSnaox, 0x76);
> - ROP3_FILL_HANDLERS(PDSax, 0x78);
> - ROP3_FILL_HANDLERS(DSPDSoaxxn, 0x79);
> - ROP3_FILL_HANDLERS(DPSDnoax, 0x7a);
> - ROP3_FILL_HANDLERS(SDPxnan, 0x7b);
> - ROP3_FILL_HANDLERS(SPDSnoax, 0x7c);
> - ROP3_FILL_HANDLERS(DPSxnan, 0x7d);
> - ROP3_FILL_HANDLERS(SPxDSxo, 0x7e);
> - ROP3_FILL_HANDLERS(DPSaan, 0x7f);
> - ROP3_FILL_HANDLERS(DPSaa, 0x80);
> - ROP3_FILL_HANDLERS(SPxDSxon, 0x81);
> - ROP3_FILL_HANDLERS(DPSxna, 0x82);
> - ROP3_FILL_HANDLERS(SPDSnoaxn, 0x83);
> - ROP3_FILL_HANDLERS(SDPxna, 0x84);
> - ROP3_FILL_HANDLERS(PDSPnoaxn, 0x85);
> - ROP3_FILL_HANDLERS(DSPDSoaxx, 0x86);
> - ROP3_FILL_HANDLERS(PDSaxn, 0x87);
> - ROP3_FILL_HANDLERS(SDPSnaoxn, 0x89);
> - ROP3_FILL_HANDLERS(DSPnoa, 0x8a);
> - ROP3_FILL_HANDLERS(DSPDxoxn, 0x8b);
> - ROP3_FILL_HANDLERS(SDPnoa, 0x8c);
> - ROP3_FILL_HANDLERS(SDPSxoxn, 0x8d);
> - ROP3_FILL_HANDLERS(SSDxPDxax, 0x8e);
> - ROP3_FILL_HANDLERS(PDSanan, 0x8f);
> - ROP3_FILL_HANDLERS(PDSxna, 0x90);
> - ROP3_FILL_HANDLERS(SDPSnoaxn, 0x91);
> - ROP3_FILL_HANDLERS(DPSDPoaxx, 0x92);
> - ROP3_FILL_HANDLERS(SPDaxn, 0x93);
> - ROP3_FILL_HANDLERS(PSDPSoaxx, 0x94);
> - ROP3_FILL_HANDLERS(DPSaxn, 0x95);
> - ROP3_FILL_HANDLERS(DPSxx, 0x96);
> - ROP3_FILL_HANDLERS(PSDPSonoxx, 0x97);
> - ROP3_FILL_HANDLERS(SDPSonoxn, 0x98);
> - ROP3_FILL_HANDLERS(DPSnax, 0x9a);
> - ROP3_FILL_HANDLERS(SDPSoaxn, 0x9b);
> - ROP3_FILL_HANDLERS(SPDnax, 0x9c);
> - ROP3_FILL_HANDLERS(DSPDoaxn, 0x9d);
> - ROP3_FILL_HANDLERS(DSPDSaoxx, 0x9e);
> - ROP3_FILL_HANDLERS(PDSxan, 0x9f);
> - ROP3_FILL_HANDLERS(PDSPnaoxn, 0xa1);
> - ROP3_FILL_HANDLERS(DPSnoa, 0xa2);
> - ROP3_FILL_HANDLERS(DPSDxoxn, 0xa3);
> - ROP3_FILL_HANDLERS(PDSPonoxn, 0xa4);
> - ROP3_FILL_HANDLERS(DSPnax, 0xa6);
> - ROP3_FILL_HANDLERS(PDSPoaxn, 0xa7);
> - ROP3_FILL_HANDLERS(DPSoa, 0xa8);
> - ROP3_FILL_HANDLERS(DPSoxn, 0xa9);
> - ROP3_FILL_HANDLERS(DPSono, 0xab);
> - ROP3_FILL_HANDLERS(SPDSxax, 0xac);
> - ROP3_FILL_HANDLERS(DPSDaoxn, 0xad);
> - ROP3_FILL_HANDLERS(DSPnao, 0xae);
> - ROP3_FILL_HANDLERS(PDSnoa, 0xb0);
> - ROP3_FILL_HANDLERS(PDSPxoxn, 0xb1);
> - ROP3_FILL_HANDLERS(SSPxDSxox, 0xb2);
> - ROP3_FILL_HANDLERS(SDPanan, 0xb3);
> - ROP3_FILL_HANDLERS(PSDnax, 0xb4);
> - ROP3_FILL_HANDLERS(DPSDoaxn, 0xb5);
> - ROP3_FILL_HANDLERS(DPSDPaoxx, 0xb6);
> - ROP3_FILL_HANDLERS(SDPxan, 0xb7);
> - ROP3_FILL_HANDLERS(PSDPxax, 0xb8);
> - ROP3_FILL_HANDLERS(DSPDaoxn, 0xb9);
> - ROP3_FILL_HANDLERS(DPSnao, 0xba);
> - ROP3_FILL_HANDLERS(SPDSanax, 0xbc);
> - ROP3_FILL_HANDLERS(SDxPDxan, 0xbd);
> - ROP3_FILL_HANDLERS(DPSxo, 0xbe);
> - ROP3_FILL_HANDLERS(DPSano, 0xbf);
> - ROP3_FILL_HANDLERS(SPDSnaoxn, 0xc1);
> - ROP3_FILL_HANDLERS(SPDSonoxn, 0xc2);
> - ROP3_FILL_HANDLERS(SPDnoa, 0xc4);
> - ROP3_FILL_HANDLERS(SPDSxoxn, 0xc5);
> - ROP3_FILL_HANDLERS(SDPnax, 0xc6);
> - ROP3_FILL_HANDLERS(PSDPoaxn, 0xc7);
> - ROP3_FILL_HANDLERS(SDPoa, 0xc8);
> - ROP3_FILL_HANDLERS(SPDoxn, 0xc9);
> - ROP3_FILL_HANDLERS(DPSDxax, 0xca);
> - ROP3_FILL_HANDLERS(SPDSaoxn, 0xcb);
> - ROP3_FILL_HANDLERS(SDPono, 0xcd);
> - ROP3_FILL_HANDLERS(SDPnao, 0xce);
> - ROP3_FILL_HANDLERS(PSDnoa, 0xd0);
> - ROP3_FILL_HANDLERS(PSDPxoxn, 0xd1);
> - ROP3_FILL_HANDLERS(PDSnax, 0xd2);
> - ROP3_FILL_HANDLERS(SPDSoaxn, 0xd3);
> - ROP3_FILL_HANDLERS(SSPxPDxax, 0xd4);
> - ROP3_FILL_HANDLERS(DPSanan, 0xd5);
> - ROP3_FILL_HANDLERS(PSDPSaoxx, 0xd6);
> - ROP3_FILL_HANDLERS(DPSxan, 0xd7);
> - ROP3_FILL_HANDLERS(PDSPxax, 0xd8);
> - ROP3_FILL_HANDLERS(SDPSaoxn, 0xd9);
> - ROP3_FILL_HANDLERS(DPSDanax, 0xda);
> - ROP3_FILL_HANDLERS(SPxDSxan, 0xdb);
> - ROP3_FILL_HANDLERS(SPDnao, 0xdc);
> - ROP3_FILL_HANDLERS(SDPxo, 0xde);
> - ROP3_FILL_HANDLERS(SDPano, 0xdf);
> - ROP3_FILL_HANDLERS(PDSoa, 0xe0);
> - ROP3_FILL_HANDLERS(PDSoxn, 0xe1);
> - ROP3_FILL_HANDLERS(DSPDxax, 0xe2);
> - ROP3_FILL_HANDLERS(PSDPaoxn, 0xe3);
> - ROP3_FILL_HANDLERS(SDPSxax, 0xe4);
> - ROP3_FILL_HANDLERS(PDSPaoxn, 0xe5);
> - ROP3_FILL_HANDLERS(SDPSanax, 0xe6);
> - ROP3_FILL_HANDLERS(SPxPDxan, 0xe7);
> - ROP3_FILL_HANDLERS(SSPxDSxax, 0xe8);
> - ROP3_FILL_HANDLERS(DSPDSanaxxn, 0xe9);
> - ROP3_FILL_HANDLERS(DPSao, 0xea);
> - ROP3_FILL_HANDLERS(DPSxno, 0xeb);
> - ROP3_FILL_HANDLERS(SDPao, 0xec);
> - ROP3_FILL_HANDLERS(SDPxno, 0xed);
> - ROP3_FILL_HANDLERS(SDPnoo, 0xef);
> - ROP3_FILL_HANDLERS(PDSono, 0xf1);
> - ROP3_FILL_HANDLERS(PDSnao, 0xf2);
> - ROP3_FILL_HANDLERS(PSDnao, 0xf4);
> - ROP3_FILL_HANDLERS(PDSxo, 0xf6);
> - ROP3_FILL_HANDLERS(PDSano, 0xf7);
> - ROP3_FILL_HANDLERS(PDSao, 0xf8);
> - ROP3_FILL_HANDLERS(PDSxno, 0xf9);
> - ROP3_FILL_HANDLERS(DPSnoo, 0xfb);
> - ROP3_FILL_HANDLERS(PSDnoo, 0xfd);
> - ROP3_FILL_HANDLERS(DPSoo, 0xfe);
> -
> - for (i = 0; i< ROP3_NUM_OPS; i++) {
> - rop3_test_handlers_32[i]();
> - rop3_test_handlers_16[i]();
> - }
> -}
> -
> -void do_rop3_with_pattern(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
> - pixman_image_t *p, SpicePoint *pat_pos)
> -{
> - int bpp;
> -
> - bpp = spice_pixman_image_get_bpp(d);
> - ASSERT (bpp == spice_pixman_image_get_bpp(s));
> - ASSERT (bpp == spice_pixman_image_get_bpp(p));
> -
> - if (bpp == 32) {
> - rop3_with_pattern_handlers_32[rop3](d, s, src_pos, p, pat_pos);
> - } else {
> - rop3_with_pattern_handlers_16[rop3](d, s, src_pos, p, pat_pos);
> - }
> -}
> -
> -void do_rop3_with_color(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
> - uint32_t rgb)
> -{
> - int bpp;
> -
> - bpp = spice_pixman_image_get_bpp(d);
> - ASSERT (bpp == spice_pixman_image_get_bpp(s));
> -
> - if (bpp == 32) {
> - rop3_with_color_handlers_32[rop3](d, s, src_pos, rgb);
> - } else {
> - rop3_with_color_handlers_16[rop3](d, s, src_pos, rgb);
> - }
> -}
> diff --git a/common/rop3.h b/common/rop3.h
> deleted file mode 100644
> index cbfa940..0000000
> --- a/common/rop3.h
> +++ /dev/null
> @@ -1,34 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H_ROP3
> -#define _H_ROP3
> -
> -#include<stdint.h>
> -
> -#include "draw.h"
> -#include "pixman_utils.h"
> -
> -void do_rop3_with_pattern(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
> - pixman_image_t *p, SpicePoint *pat_pos);
> -void do_rop3_with_color(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
> - uint32_t rgb);
> -
> -void rop3_init(void);
> -#endif
> -
> diff --git a/common/ssl_verify.c b/common/ssl_verify.c
> deleted file mode 100644
> index b19a323..0000000
> --- a/common/ssl_verify.c
> +++ /dev/null
> @@ -1,477 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2011 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include "mem.h"
> -#include "ssl_verify.h"
> -
> -#ifndef WIN32
> -#include<sys/socket.h>
> -#include<netinet/in.h>
> -#include<arpa/inet.h>
> -#endif
> -#include<ctype.h>
> -#include<string.h>
> -
> -#ifndef SPICE_DEBUG
> -# define SPICE_DEBUG(format, ...)
> -#endif
> -
> -#ifdef WIN32
> -static int inet_aton(const char* ip, struct in_addr* in_addr)
> -{
> - unsigned long addr = inet_addr(ip);
> -
> - if (addr == INADDR_NONE) {
> - return 0;
> - }
> - in_addr->S_un.S_addr = addr;
> - return 1;
> -}
> -#endif
> -
> -static int verify_pubkey(X509* cert, const char *key, size_t key_size)
> -{
> - EVP_PKEY* cert_pubkey = NULL;
> - EVP_PKEY* orig_pubkey = NULL;
> - BIO* bio = NULL;
> - int ret = 0;
> -
> - if (!key || key_size == 0)
> - return 0;
> -
> - if (!cert) {
> - SPICE_DEBUG("warning: no cert!");
> - return 0;
> - }
> -
> - cert_pubkey = X509_get_pubkey(cert);
> - if (!cert_pubkey) {
> - SPICE_DEBUG("warning: reading public key from certificate failed");
> - goto finish;
> - }
> -
> - bio = BIO_new_mem_buf((void*)key, key_size);
> - if (!bio) {
> - SPICE_DEBUG("creating BIO failed");
> - goto finish;
> - }
> -
> - orig_pubkey = d2i_PUBKEY_bio(bio, NULL);
> - if (!orig_pubkey) {
> - SPICE_DEBUG("reading pubkey from bio failed");
> - goto finish;
> - }
> -
> - ret = EVP_PKEY_cmp(orig_pubkey, cert_pubkey);
> -
> - if (ret == 1) {
> - SPICE_DEBUG("public keys match");
> - } else if (ret == 0) {
> - SPICE_DEBUG("public keys mismatch");
> - } else {
> - SPICE_DEBUG("public keys types mismatch");
> - }
> -
> -finish:
> - if (bio)
> - BIO_free(bio);
> -
> - if (orig_pubkey)
> - EVP_PKEY_free(orig_pubkey);
> -
> - if (cert_pubkey)
> - EVP_PKEY_free(cert_pubkey);
> -
> - return ret;
> -}
> -
> -/* from gnutls
> - * compare hostname against certificate, taking account of wildcards
> - * return 1 on success or 0 on error
> - *
> - * note: certnamesize is required as X509 certs can contain embedded NULs in
> - * the strings such as CN or subjectAltName
> - */
> -static int _gnutls_hostname_compare(const char *certname,
> - size_t certnamesize, const char *hostname)
> -{
> - /* find the first different character */
> - for (; *certname&& *hostname&& toupper (*certname) == toupper (*hostname);
> - certname++, hostname++, certnamesize--)
> - ;
> -
> - /* the strings are the same */
> - if (certnamesize == 0&& *hostname == '\0')
> - return 1;
> -
> - if (*certname == '*')
> - {
> - /* a wildcard certificate */
> -
> - certname++;
> - certnamesize--;
> -
> - while (1)
> - {
> - /* Use a recursive call to allow multiple wildcards */
> - if (_gnutls_hostname_compare (certname, certnamesize, hostname))
> - return 1;
> -
> - /* wildcards are only allowed to match a single domain
> - component or component fragment */
> - if (*hostname == '\0' || *hostname == '.')
> - break;
> - hostname++;
> - }
> -
> - return 0;
> - }
> -
> - return 0;
> -}
> -
> -/**
> - * From gnutls and spice red_peer.c
> - * TODO: switch to gnutls and get rid of this
> - *
> - * This function will check if the given certificate's subject matches
> - * the given hostname. This is a basic implementation of the matching
> - * described in RFC2818 (HTTPS), which takes into account wildcards,
> - * and the DNSName/IPAddress subject alternative name PKIX extension.
> - *
> - * Returns: 1 for a successful match, and 0 on failure.
> - **/
> -static int verify_hostname(X509* cert, const char *hostname)
> -{
> - GENERAL_NAMES* subject_alt_names;
> - int found_dns_name = 0;
> - struct in_addr addr;
> - int addr_len = 0;
> - int cn_match = 0;
> -
> - if (!cert) {
> - SPICE_DEBUG("warning: no cert!");
> - return 0;
> - }
> -
> - // only IpV4 supported
> - if (inet_aton(hostname,&addr)) {
> - addr_len = sizeof(struct in_addr);
> - }
> -
> - /* try matching against:
> - * 1) a DNS name as an alternative name (subjectAltName) extension
> - * in the certificate
> - * 2) the common name (CN) in the certificate
> - *
> - * either of these may be of the form: *.domain.tld
> - *
> - * only try (2) if there is no subjectAltName extension of
> - * type dNSName
> - */
> -
> - /* Check through all included subjectAltName extensions, comparing
> - * against all those of type dNSName.
> - */
> - subject_alt_names = (GENERAL_NAMES*)X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
> -
> - if (subject_alt_names) {
> - int num_alts = sk_GENERAL_NAME_num(subject_alt_names);
> - int i;
> - for (i = 0; i< num_alts; i++) {
> - const GENERAL_NAME* name = sk_GENERAL_NAME_value(subject_alt_names, i);
> - if (name->type == GEN_DNS) {
> - found_dns_name = 1;
> - if (_gnutls_hostname_compare((char *)ASN1_STRING_data(name->d.dNSName),
> - ASN1_STRING_length(name->d.dNSName),
> - hostname)) {
> - SPICE_DEBUG("alt name match=%s", ASN1_STRING_data(name->d.dNSName));
> - GENERAL_NAMES_free(subject_alt_names);
> - return 1;
> - }
> - } else if (name->type == GEN_IPADD) {
> - int alt_ip_len = ASN1_STRING_length(name->d.iPAddress);
> - found_dns_name = 1;
> - if ((addr_len == alt_ip_len)&&
> - !memcmp(ASN1_STRING_data(name->d.iPAddress),&addr, addr_len)) {
> - SPICE_DEBUG("alt name IP match=%s",
> - inet_ntoa(*((struct in_addr*)ASN1_STRING_data(name->d.dNSName))));
> - GENERAL_NAMES_free(subject_alt_names);
> - return 1;
> - }
> - }
> - }
> - GENERAL_NAMES_free(subject_alt_names);
> - }
> -
> - if (found_dns_name) {
> - SPICE_DEBUG("warning: SubjectAltName mismatch");
> - return 0;
> - }
> -
> - /* extracting commonNames */
> - X509_NAME* subject = X509_get_subject_name(cert);
> - if (subject) {
> - int pos = -1;
> - X509_NAME_ENTRY* cn_entry;
> - ASN1_STRING* cn_asn1;
> -
> - while ((pos = X509_NAME_get_index_by_NID(subject, NID_commonName, pos)) != -1) {
> - cn_entry = X509_NAME_get_entry(subject, pos);
> - if (!cn_entry) {
> - continue;
> - }
> - cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry);
> - if (!cn_asn1) {
> - continue;
> - }
> -
> - if (_gnutls_hostname_compare((char*)ASN1_STRING_data(cn_asn1),
> - ASN1_STRING_length(cn_asn1),
> - hostname)) {
> - SPICE_DEBUG("common name match=%s", (char*)ASN1_STRING_data(cn_asn1));
> - cn_match = 1;
> - break;
> - }
> - }
> - }
> -
> - if (!cn_match) {
> - SPICE_DEBUG("warning: common name mismatch");
> - }
> -
> - return cn_match;
> -}
> -
> -static X509_NAME* subject_to_x509_name(const char *subject, int *nentries)
> -{
> - X509_NAME* in_subject;
> - const char *p;
> - char *key, *val, *k, *v = NULL;
> - int escape;
> - enum {
> - KEY,
> - VALUE
> - } state;
> -
> - key = (char*)alloca(strlen(subject));
> - val = (char*)alloca(strlen(subject));
> - in_subject = X509_NAME_new();
> -
> - if (!in_subject || !key || !val) {
> - SPICE_DEBUG("failed to allocate");
> - return NULL;
> - }
> -
> - *nentries = 0;
> -
> - k = key;
> - state = KEY;
> - for (p = subject;; ++p) {
> - escape = 0;
> - if (*p == '\\') {
> - ++p;
> - if (*p != '\\'&& *p != ',') {
> - SPICE_DEBUG("Invalid character after \\");
> - goto fail;
> - }
> - escape = 1;
> - }
> -
> - switch (state) {
> - case KEY:
> - if (*p == 0) {
> - if (k == key) /* empty key */
> - goto success;
> - goto fail;
> - } else if (*p == '='&& !escape) {
> - state = VALUE;
> - *k = 0;
> - v = val;
> - } else
> - *k++ = *p;
> - break;
> - case VALUE:
> - if (*p == 0 || (*p == ','&& !escape)) {
> - if (v == val) /* empty value */
> - goto fail;
> -
> - *v = 0;
> -
> - if (!X509_NAME_add_entry_by_txt(in_subject, key,
> - MBSTRING_UTF8,
> - (const unsigned char*)val,
> - strlen(val), -1, 0)) {
> - SPICE_DEBUG("warning: failed to add entry %s=%s to X509_NAME",
> - key, val);
> - goto fail;
> - }
> - *nentries += 1;
> -
> - if (*p == 0)
> - goto success;
> -
> - state = KEY;
> - k = key;
> - } else
> - *v++ = *p;
> - }
> - }
> -
> -success:
> - return in_subject;
> -
> -fail:
> - if (in_subject)
> - X509_NAME_free(in_subject);
> -
> - return NULL;
> -}
> -
> -static int verify_subject(X509* cert, SpiceOpenSSLVerify* verify)
> -{
> - X509_NAME *cert_subject = NULL;
> - int ret;
> - int in_entries;
> -
> - if (!cert) {
> - SPICE_DEBUG("warning: no cert!");
> - return 0;
> - }
> -
> - cert_subject = X509_get_subject_name(cert);
> - if (!cert_subject) {
> - SPICE_DEBUG("warning: reading certificate subject failed");
> - return 0;
> - }
> -
> - if (!verify->in_subject) {
> - verify->in_subject = subject_to_x509_name(verify->subject,&in_entries);
> - if (!verify->in_subject) {
> - SPICE_DEBUG("warning: no in_subject!");
> - return 0;
> - }
> - }
> -
> - /* Note: this check is redundant with the pre-condition in X509_NAME_cmp */
> - if (X509_NAME_entry_count(cert_subject) != in_entries) {
> - SPICE_DEBUG("subject mismatch: #entries cert=%d, input=%d",
> - X509_NAME_entry_count(cert_subject), in_entries);
> - return 0;
> - }
> -
> - ret = X509_NAME_cmp(cert_subject, verify->in_subject);
> -
> - if (ret == 0) {
> - SPICE_DEBUG("subjects match");
> - } else {
> - SPICE_DEBUG("subjects mismatch");
> - }
> -
> - return !ret;
> -}
> -
> -static int openssl_verify(int preverify_ok, X509_STORE_CTX *ctx)
> -{
> - int depth;
> - SpiceOpenSSLVerify *v;
> - SSL *ssl;
> - X509* cert;
> -
> - ssl = (SSL*)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
> - v = (SpiceOpenSSLVerify*)SSL_get_app_data(ssl);
> -
> - depth = X509_STORE_CTX_get_error_depth(ctx);
> - if (depth> 0) {
> - if (!preverify_ok) {
> - SPICE_DEBUG("openssl verify failed at depth=%d", depth);
> - v->all_preverify_ok = 0;
> - return 0;
> - } else
> - return 1;
> - }
> -
> - /* depth == 0 */
> - cert = X509_STORE_CTX_get_current_cert(ctx);
> - if (!cert) {
> - SPICE_DEBUG("failed to get server certificate");
> - return 0;
> - }
> -
> - if (v->verifyop& SPICE_SSL_VERIFY_OP_PUBKEY&&
> - verify_pubkey(cert, v->pubkey, v->pubkey_size))
> - return 1;
> -
> - if (!v->all_preverify_ok || !preverify_ok)
> - return 0;
> -
> - if (v->verifyop& SPICE_SSL_VERIFY_OP_HOSTNAME&&
> - verify_hostname(cert, v->hostname))
> - return 1;
> -
> - if (v->verifyop& SPICE_SSL_VERIFY_OP_SUBJECT&&
> - verify_subject(cert, v))
> - return 1;
> -
> - return 0;
> -}
> -
> -SpiceOpenSSLVerify* spice_openssl_verify_new(SSL *ssl, SPICE_SSL_VERIFY_OP verifyop,
> - const char *hostname,
> - const char *pubkey, size_t pubkey_size,
> - const char *subject)
> -{
> - SpiceOpenSSLVerify *v;
> -
> - if (!verifyop)
> - return NULL;
> -
> - v = spice_new0(SpiceOpenSSLVerify, 1);
> -
> - v->ssl = ssl;
> - v->verifyop = verifyop;
> - v->hostname = spice_strdup(hostname);
> - v->pubkey = (char*)spice_memdup(pubkey, pubkey_size);
> - v->pubkey_size = pubkey_size;
> - v->subject = spice_strdup(subject);
> -
> - v->all_preverify_ok = 1;
> -
> - SSL_set_app_data(ssl, v);
> - SSL_set_verify(ssl,
> - SSL_VERIFY_PEER, openssl_verify);
> -
> - return v;
> -}
> -
> -void spice_openssl_verify_free(SpiceOpenSSLVerify* verify)
> -{
> - if (!verify)
> - return;
> -
> - free(verify->pubkey);
> - free(verify->subject);
> - free(verify->hostname);
> -
> - if (verify->in_subject)
> - X509_NAME_free(verify->in_subject);
> -
> - if (verify->ssl)
> - SSL_set_app_data(verify->ssl, NULL);
> - free(verify);
> -}
> diff --git a/common/ssl_verify.h b/common/ssl_verify.h
> deleted file mode 100644
> index 6922c56..0000000
> --- a/common/ssl_verify.h
> +++ /dev/null
> @@ -1,59 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2011 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef __SSL_VERIFY_H
> -#define __SSL_VERIFY_H
> -
> -#include "ring.h"
> -
> -#include<openssl/rsa.h>
> -#include<openssl/evp.h>
> -#include<openssl/x509.h>
> -#include<openssl/ssl.h>
> -#include<openssl/err.h>
> -#ifdef X509_NAME
> -/* wincrypt.h has already a different define... */
> -#undef X509_NAME
> -#endif
> -#include<openssl/x509v3.h>
> -
> -typedef enum {
> - SPICE_SSL_VERIFY_OP_NONE = 0,
> - SPICE_SSL_VERIFY_OP_PUBKEY = (1<< 0),
> - SPICE_SSL_VERIFY_OP_HOSTNAME = (1<< 1),
> - SPICE_SSL_VERIFY_OP_SUBJECT = (1<< 2),
> -} SPICE_SSL_VERIFY_OP;
> -
> -typedef struct {
> - SSL *ssl;
> - SPICE_SSL_VERIFY_OP verifyop;
> - int all_preverify_ok;
> - char *hostname;
> - char *pubkey;
> - size_t pubkey_size;
> - char *subject;
> - X509_NAME *in_subject;
> -} SpiceOpenSSLVerify;
> -
> -SpiceOpenSSLVerify* spice_openssl_verify_new(SSL *ssl, SPICE_SSL_VERIFY_OP verifyop,
> - const char *hostname,
> - const char *pubkey, size_t pubkey_size,
> - const char *subject);
> -void spice_openssl_verify_free(SpiceOpenSSLVerify* verify);
> -
> -#endif
> diff --git a/common/sw_canvas.c b/common/sw_canvas.c
> deleted file mode 100644
> index 34ca910..0000000
> --- a/common/sw_canvas.c
> +++ /dev/null
> @@ -1,1321 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#include<math.h>
> -#include "sw_canvas.h"
> -#define CANVAS_USE_PIXMAN
> -#define CANVAS_SINGLE_INSTANCE
> -#include "canvas_base.c"
> -#include "rect.h"
> -#include "region.h"
> -#include "pixman_utils.h"
> -
> -typedef struct SwCanvas SwCanvas;
> -
> -struct SwCanvas {
> - CanvasBase base;
> - uint32_t *private_data;
> - int private_data_size;
> - pixman_image_t *image;
> -};
> -
> -static pixman_image_t *canvas_get_pixman_brush(SwCanvas *canvas,
> - SpiceBrush *brush)
> -{
> - switch (brush->type) {
> - case SPICE_BRUSH_TYPE_SOLID: {
> - uint32_t color = brush->u.color;
> - pixman_color_t c;
> -
> - c.blue = ((color& canvas->base.color_mask) * 0xffff) / canvas->base.color_mask;
> - color>>= canvas->base.color_shift;
> - c.green = ((color& canvas->base.color_mask) * 0xffff) / canvas->base.color_mask;
> - color>>= canvas->base.color_shift;
> - c.red = ((color& canvas->base.color_mask) * 0xffff) / canvas->base.color_mask;
> - c.alpha = 0xffff;
> -
> - return pixman_image_create_solid_fill(&c);
> - }
> - case SPICE_BRUSH_TYPE_PATTERN: {
> - SwCanvas *surface_canvas;
> - pixman_image_t* surface;
> - pixman_transform_t t;
> -
> - surface_canvas = (SwCanvas *)canvas_get_surface(&canvas->base, brush->u.pattern.pat);
> - if (surface_canvas) {
> - surface = surface_canvas->image;
> - surface = pixman_image_ref(surface);
> - } else {
> - surface = canvas_get_image(&canvas->base, brush->u.pattern.pat, FALSE);
> - }
> - pixman_transform_init_translate(&t,
> - pixman_int_to_fixed(-brush->u.pattern.pos.x),
> - pixman_int_to_fixed(-brush->u.pattern.pos.y));
> - pixman_image_set_transform(surface,&t);
> - pixman_image_set_repeat(surface, PIXMAN_REPEAT_NORMAL);
> - return surface;
> - }
> - case SPICE_BRUSH_TYPE_NONE:
> - return NULL;
> - default:
> - spice_warn_if_reached();
> - return NULL;
> - }
> - return NULL;
> -}
> -
> -static pixman_image_t *get_image(SpiceCanvas *canvas)
> -{
> - SwCanvas *sw_canvas = (SwCanvas *)canvas;
> -
> - pixman_image_ref(sw_canvas->image);
> -
> - return sw_canvas->image;
> -}
> -
> -static void copy_region(SpiceCanvas *spice_canvas,
> - pixman_region32_t *dest_region,
> - int dx, int dy)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - pixman_box32_t *dest_rects;
> - int n_rects;
> - int i, j, end_line;
> -
> - dest_rects = pixman_region32_rectangles(dest_region,&n_rects);
> -
> - if (dy> 0) {
> - if (dx>= 0) {
> - /* south-east: copy x and y in reverse order */
> - for (i = n_rects - 1; i>= 0; i--) {
> - spice_pixman_copy_rect(canvas->image,
> - dest_rects[i].x1 - dx, dest_rects[i].y1 - dy,
> - dest_rects[i].x2 - dest_rects[i].x1,
> - dest_rects[i].y2 - dest_rects[i].y1,
> - dest_rects[i].x1, dest_rects[i].y1);
> - }
> - } else {
> - /* south-west: Copy y in reverse order, but x in forward order */
> - i = n_rects - 1;
> -
> - while (i>= 0) {
> - /* Copy all rects with same y in forward order */
> - for (end_line = i - 1;
> - end_line>= 0&& dest_rects[end_line].y1 == dest_rects[i].y1;
> - end_line--) {
> - }
> - for (j = end_line + 1; j<= i; j++) {
> - spice_pixman_copy_rect(canvas->image,
> - dest_rects[j].x1 - dx, dest_rects[j].y1 - dy,
> - dest_rects[j].x2 - dest_rects[j].x1,
> - dest_rects[j].y2 - dest_rects[j].y1,
> - dest_rects[j].x1, dest_rects[j].y1);
> - }
> - i = end_line;
> - }
> - }
> - } else {
> - if (dx> 0) {
> - /* north-east: copy y in forward order, but x in reverse order */
> - i = 0;
> -
> - while (i< n_rects) {
> - /* Copy all rects with same y in reverse order */
> - for (end_line = i;
> - end_line< n_rects&& dest_rects[end_line].y1 == dest_rects[i].y1;
> - end_line++) {
> - }
> - for (j = end_line - 1; j>= i; j--) {
> - spice_pixman_copy_rect(canvas->image,
> - dest_rects[j].x1 - dx, dest_rects[j].y1 - dy,
> - dest_rects[j].x2 - dest_rects[j].x1,
> - dest_rects[j].y2 - dest_rects[j].y1,
> - dest_rects[j].x1, dest_rects[j].y1);
> - }
> - i = end_line;
> - }
> - } else {
> - /* north-west: Copy x and y in forward order */
> - for (i = 0; i< n_rects; i++) {
> - spice_pixman_copy_rect(canvas->image,
> - dest_rects[i].x1 - dx, dest_rects[i].y1 - dy,
> - dest_rects[i].x2 - dest_rects[i].x1,
> - dest_rects[i].y2 - dest_rects[i].y1,
> - dest_rects[i].x1, dest_rects[i].y1);
> - }
> - }
> - }
> -}
> -
> -static void fill_solid_spans(SpiceCanvas *spice_canvas,
> - SpicePoint *points,
> - int *widths,
> - int n_spans,
> - uint32_t color)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - int i;
> -
> - for (i = 0; i< n_spans; i++) {
> - spice_pixman_fill_rect(canvas->image,
> - points[i].x, points[i].y,
> - widths[i],
> - 1,
> - color);
> - }
> -}
> -
> -static void fill_solid_rects(SpiceCanvas *spice_canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - uint32_t color)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - int i;
> -
> - for (i = 0; i< n_rects; i++) {
> - spice_pixman_fill_rect(canvas->image,
> - rects[i].x1, rects[i].y1,
> - rects[i].x2 - rects[i].x1,
> - rects[i].y2 - rects[i].y1,
> - color);
> - }
> -}
> -
> -static void fill_solid_rects_rop(SpiceCanvas *spice_canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - uint32_t color,
> - SpiceROP rop)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - int i;
> -
> - for (i = 0; i< n_rects; i++) {
> - spice_pixman_fill_rect_rop(canvas->image,
> - rects[i].x1, rects[i].y1,
> - rects[i].x2 - rects[i].x1,
> - rects[i].y2 - rects[i].y1,
> - color, rop);
> - }
> -}
> -
> -static void __fill_tiled_rects(SpiceCanvas *spice_canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - pixman_image_t *tile,
> - int offset_x, int offset_y)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - int i;
> -
> - for (i = 0; i< n_rects; i++) {
> - spice_pixman_tile_rect(canvas->image,
> - rects[i].x1, rects[i].y1,
> - rects[i].x2 - rects[i].x1,
> - rects[i].y2 - rects[i].y1,
> - tile, offset_x, offset_y);
> - }
> -}
> -
> -static void fill_tiled_rects(SpiceCanvas *spice_canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - pixman_image_t *tile,
> - int offset_x, int offset_y)
> -{
> - __fill_tiled_rects(spice_canvas, rects, n_rects, tile, offset_x, offset_y);
> -}
> -
> -static void fill_tiled_rects_from_surface(SpiceCanvas *spice_canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - SpiceCanvas *surface_canvas,
> - int offset_x, int offset_y)
> -{
> - SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
> - __fill_tiled_rects(spice_canvas, rects, n_rects, sw_surface_canvas->image, offset_x,
> - offset_y);
> -}
> -
> -static void __fill_tiled_rects_rop(SpiceCanvas *spice_canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - pixman_image_t *tile,
> - int offset_x, int offset_y,
> - SpiceROP rop)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - int i;
> -
> - for (i = 0; i< n_rects; i++) {
> - spice_pixman_tile_rect_rop(canvas->image,
> - rects[i].x1, rects[i].y1,
> - rects[i].x2 - rects[i].x1,
> - rects[i].y2 - rects[i].y1,
> - tile, offset_x, offset_y,
> - rop);
> - }
> -}
> -static void fill_tiled_rects_rop(SpiceCanvas *spice_canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - pixman_image_t *tile,
> - int offset_x, int offset_y,
> - SpiceROP rop)
> -{
> - __fill_tiled_rects_rop(spice_canvas, rects, n_rects, tile, offset_x, offset_y, rop);
> -}
> -
> -static void fill_tiled_rects_rop_from_surface(SpiceCanvas *spice_canvas,
> - pixman_box32_t *rects,
> - int n_rects,
> - SpiceCanvas *surface_canvas,
> - int offset_x, int offset_y,
> - SpiceROP rop)
> -{
> - SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
> - __fill_tiled_rects_rop(spice_canvas, rects, n_rects, sw_surface_canvas->image, offset_x,
> - offset_y, rop);
> -}
> -
> -/* Some pixman implementations of OP_OVER on xRGB32 sets
> - the high bit to 0xff (which is the right value if the
> - destination was ARGB32, and it should be ignored for
> - xRGB32. However, this fills our alpha bits with
> - data that is not wanted or expected by windows, and its
> - causing us to send rgba images rather than rgb images to
> - the client. So, we manually clear these bytes. */
> -static void clear_dest_alpha(pixman_image_t *dest,
> - int x, int y,
> - int width, int height)
> -{
> - uint32_t *data;
> - int stride;
> - int w, h;
> -
> - w = pixman_image_get_width(dest);
> - h = pixman_image_get_height(dest);
> -
> - if (x + width<= 0 || x>= w ||
> - y + height<= 0 || y>= h ||
> - width == 0 || height == 0) {
> - return;
> - }
> -
> - if (x< 0) {
> - width += x;
> - x = 0;
> - }
> - if (x + width> w) {
> - width = w - x;
> - }
> -
> - if (y< 0) {
> - height += y;
> - y = 0;
> - }
> - if (y + height> h) {
> - height = h - y;
> - }
> -
> - stride = pixman_image_get_stride(dest);
> - data = (uint32_t *) (
> - (uint8_t *)pixman_image_get_data(dest) + y * stride + 4 * x);
> -
> - if ((*data& 0xff000000U) == 0xff000000U) {
> - spice_pixman_fill_rect_rop(dest,
> - x, y, width, height,
> - 0x00ffffff, SPICE_ROP_AND);
> - }
> -}
> -
> -static void __blit_image(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src_image,
> - int offset_x, int offset_y)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - pixman_box32_t *rects;
> - int n_rects, i;
> -
> - rects = pixman_region32_rectangles(region,&n_rects);
> -
> - for (i = 0; i< n_rects; i++) {
> - int src_x, src_y, dest_x, dest_y, width, height;
> -
> - dest_x = rects[i].x1;
> - dest_y = rects[i].y1;
> - width = rects[i].x2 - rects[i].x1;
> - height = rects[i].y2 - rects[i].y1;
> -
> - src_x = rects[i].x1 - offset_x;
> - src_y = rects[i].y1 - offset_y;
> -
> - spice_pixman_blit(canvas->image,
> - src_image,
> - src_x, src_y,
> - dest_x, dest_y,
> - width, height);
> - }
> -}
> -
> -static void blit_image(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src_image,
> - int offset_x, int offset_y)
> -{
> - __blit_image(spice_canvas, region, src_image, offset_x, offset_y);
> -}
> -
> -static void blit_image_from_surface(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - SpiceCanvas *surface_canvas,
> - int offset_x, int offset_y)
> -{
> - SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
> - __blit_image(spice_canvas, region, sw_surface_canvas->image, offset_x, offset_y);
> -}
> -
> -static void __blit_image_rop(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src_image,
> - int offset_x, int offset_y,
> - SpiceROP rop)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - pixman_box32_t *rects;
> - int n_rects, i;
> -
> - rects = pixman_region32_rectangles(region,&n_rects);
> -
> - for (i = 0; i< n_rects; i++) {
> - int src_x, src_y, dest_x, dest_y, width, height;
> -
> - dest_x = rects[i].x1;
> - dest_y = rects[i].y1;
> - width = rects[i].x2 - rects[i].x1;
> - height = rects[i].y2 - rects[i].y1;
> -
> - src_x = rects[i].x1 - offset_x;
> - src_y = rects[i].y1 - offset_y;
> -
> - spice_pixman_blit_rop(canvas->image,
> - src_image,
> - src_x, src_y,
> - dest_x, dest_y,
> - width, height, rop);
> - }
> -}
> -
> -static void blit_image_rop(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src_image,
> - int offset_x, int offset_y,
> - SpiceROP rop)
> -{
> - __blit_image_rop(spice_canvas, region, src_image, offset_x, offset_y, rop);
> -}
> -
> -static void blit_image_rop_from_surface(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - SpiceCanvas *surface_canvas,
> - int offset_x, int offset_y,
> - SpiceROP rop)
> -{
> - SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
> - __blit_image_rop(spice_canvas, region, sw_surface_canvas->image, offset_x, offset_y, rop);
> -}
> -
> -
> -
> -static void __scale_image(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - pixman_transform_t transform;
> - pixman_fixed_t fsx, fsy;
> -
> - fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
> - fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
> -
> - pixman_image_set_clip_region32(canvas->image, region);
> -
> - pixman_transform_init_scale(&transform, fsx, fsy);
> - pixman_transform_translate(&transform, NULL,
> - pixman_int_to_fixed (src_x),
> - pixman_int_to_fixed (src_y));
> -
> - pixman_image_set_transform(src,&transform);
> - pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
> - spice_return_if_fail(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE ||
> - scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST);
> - pixman_image_set_filter(src,
> - (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?
> - PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
> - NULL, 0);
> -
> - pixman_image_composite32(PIXMAN_OP_SRC,
> - src, NULL, canvas->image,
> - 0, 0, /* src */
> - 0, 0, /* mask */
> - dest_x, dest_y, /* dst */
> - dest_width, dest_height);
> -
> - pixman_transform_init_identity(&transform);
> - pixman_image_set_transform(src,&transform);
> -
> - pixman_image_set_clip_region32(canvas->image, NULL);
> -}
> -
> -static void scale_image(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode)
> -{
> - __scale_image(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x, dest_y,
> - dest_width,dest_height,scale_mode);
> -}
> -
> -static void scale_image_from_surface(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - SpiceCanvas *surface_canvas,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode)
> -{
> - SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
> - __scale_image(spice_canvas, region, sw_surface_canvas->image, src_x, src_y, src_width,
> - src_height, dest_x, dest_y, dest_width,dest_height,scale_mode);
> -}
> -
> -static void __scale_image_rop(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode, SpiceROP rop)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - pixman_transform_t transform;
> - pixman_image_t *scaled;
> - pixman_box32_t *rects;
> - int n_rects, i;
> - pixman_fixed_t fsx, fsy;
> -
> - fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
> - fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
> -
> - scaled = pixman_image_create_bits(spice_pixman_image_get_format(src),
> - dest_width,
> - dest_height,
> - NULL, 0);
> -
> - pixman_region32_translate(region, -dest_x, -dest_y);
> - pixman_image_set_clip_region32(scaled, region);
> -
> - pixman_transform_init_scale(&transform, fsx, fsy);
> - pixman_transform_translate(&transform, NULL,
> - pixman_int_to_fixed (src_x),
> - pixman_int_to_fixed (src_y));
> -
> - pixman_image_set_transform(src,&transform);
> - pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
> - spice_return_if_fail(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE ||
> - scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST);
> - pixman_image_set_filter(src,
> - (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?
> - PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
> - NULL, 0);
> -
> - pixman_image_composite32(PIXMAN_OP_SRC,
> - src, NULL, scaled,
> - 0, 0, /* src */
> - 0, 0, /* mask */
> - 0, 0, /* dst */
> - dest_width,
> - dest_height);
> -
> - pixman_transform_init_identity(&transform);
> - pixman_image_set_transform(src,&transform);
> -
> - /* Translate back */
> - pixman_region32_translate(region, dest_x, dest_y);
> -
> - rects = pixman_region32_rectangles(region,&n_rects);
> -
> - for (i = 0; i< n_rects; i++) {
> - spice_pixman_blit_rop(canvas->image,
> - scaled,
> - rects[i].x1 - dest_x,
> - rects[i].y1 - dest_y,
> - rects[i].x1, rects[i].y1,
> - rects[i].x2 - rects[i].x1,
> - rects[i].y2 - rects[i].y1,
> - rop);
> - }
> -
> - pixman_image_unref(scaled);
> -}
> -
> -static void scale_image_rop(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode, SpiceROP rop)
> -{
> - __scale_image_rop(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x,
> - dest_y, dest_width, dest_height, scale_mode, rop);
> -}
> -
> -static void scale_image_rop_from_surface(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - SpiceCanvas *surface_canvas,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode, SpiceROP rop)
> -{
> - SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
> - __scale_image_rop(spice_canvas, region, sw_surface_canvas->image, src_x, src_y, src_width,
> - src_height, dest_x, dest_y, dest_width, dest_height, scale_mode, rop);
> -}
> -
> -static pixman_image_t *canvas_get_as_surface(SwCanvas *canvas,
> - int with_alpha)
> -{
> - pixman_image_t *target;
> -
> - if (with_alpha&&
> - canvas->base.format == SPICE_SURFACE_FMT_32_xRGB) {
> - target = pixman_image_create_bits(PIXMAN_a8r8g8b8,
> - pixman_image_get_width(canvas->image),
> - pixman_image_get_height(canvas->image),
> - pixman_image_get_data(canvas->image),
> - pixman_image_get_stride(canvas->image));
> - } else {
> - target = pixman_image_ref(canvas->image);
> - }
> -
> - return target;
> -}
> -
> -static void __blend_image(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - int dest_has_alpha,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int dest_x, int dest_y,
> - int width, int height,
> - int overall_alpha)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - pixman_image_t *mask, *dest;
> -
> - dest = canvas_get_as_surface(canvas, dest_has_alpha);
> -
> - pixman_image_set_clip_region32(dest, region);
> -
> - mask = NULL;
> - if (overall_alpha != 0xff) {
> - pixman_color_t color = { 0 };
> - color.alpha = overall_alpha * 0x101;
> - mask = pixman_image_create_solid_fill(&color);
> - }
> -
> - pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
> -
> - pixman_image_composite32(PIXMAN_OP_OVER,
> - src, mask, dest,
> - src_x, src_y, /* src */
> - 0, 0, /* mask */
> - dest_x, dest_y, /* dst */
> - width,
> - height);
> -
> - if (canvas->base.format == SPICE_SURFACE_FMT_32_xRGB&&
> - !dest_has_alpha) {
> - clear_dest_alpha(dest, dest_x, dest_y, width, height);
> - }
> -
> - if (mask) {
> - pixman_image_unref(mask);
> - }
> -
> - pixman_image_set_clip_region32(dest, NULL);
> - pixman_image_unref(dest);
> -}
> -
> -static void blend_image(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - int dest_has_alpha,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int dest_x, int dest_y,
> - int width, int height,
> - int overall_alpha)
> -{
> - __blend_image(spice_canvas, region, dest_has_alpha, src, src_x, src_y,
> - dest_x, dest_y, width, height,
> - overall_alpha);
> -}
> -
> -static void blend_image_from_surface(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - int dest_has_alpha,
> - SpiceCanvas *surface_canvas,
> - int src_has_alpha,
> - int src_x, int src_y,
> - int dest_x, int dest_y,
> - int width, int height,
> - int overall_alpha)
> -{
> - SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
> - pixman_image_t *src;
> -
> - src = canvas_get_as_surface(sw_surface_canvas, src_has_alpha);
> - __blend_image(spice_canvas, region, dest_has_alpha,
> - src, src_x, src_y,
> - dest_x, dest_y,
> - width, height, overall_alpha);
> - pixman_image_unref(src);
> -}
> -
> -static void __blend_scale_image(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - int dest_has_alpha,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode,
> - int overall_alpha)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - pixman_transform_t transform;
> - pixman_image_t *mask, *dest;
> - pixman_fixed_t fsx, fsy;
> -
> - fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
> - fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
> -
> - dest = canvas_get_as_surface(canvas, dest_has_alpha);
> -
> - pixman_image_set_clip_region32(dest, region);
> -
> - pixman_transform_init_scale(&transform, fsx, fsy);
> - pixman_transform_translate(&transform, NULL,
> - pixman_int_to_fixed (src_x),
> - pixman_int_to_fixed (src_y));
> -
> - mask = NULL;
> - if (overall_alpha != 0xff) {
> - pixman_color_t color = { 0 };
> - color.alpha = overall_alpha * 0x101;
> - mask = pixman_image_create_solid_fill(&color);
> - }
> -
> - pixman_image_set_transform(src,&transform);
> - pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
> - spice_return_if_fail(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE ||
> - scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST);
> - pixman_image_set_filter(src,
> - (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?
> - PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
> - NULL, 0);
> -
> - pixman_image_composite32(PIXMAN_OP_OVER,
> - src, mask, dest,
> - 0, 0, /* src */
> - 0, 0, /* mask */
> - dest_x, dest_y, /* dst */
> - dest_width, dest_height);
> -
> - if (canvas->base.format == SPICE_SURFACE_FMT_32_xRGB&&
> - !dest_has_alpha) {
> - clear_dest_alpha(dest, dest_x, dest_y, dest_width, dest_height);
> - }
> -
> - pixman_transform_init_identity(&transform);
> - pixman_image_set_transform(src,&transform);
> -
> - if (mask) {
> - pixman_image_unref(mask);
> - }
> -
> - pixman_image_set_clip_region32(dest, NULL);
> - pixman_image_unref(dest);
> -}
> -
> -static void blend_scale_image(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - int dest_has_alpha,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode,
> - int overall_alpha)
> -{
> - __blend_scale_image(spice_canvas, region, dest_has_alpha,
> - src, src_x, src_y, src_width, src_height,
> - dest_x, dest_y, dest_width, dest_height,
> - scale_mode, overall_alpha);
> -}
> -
> -static void blend_scale_image_from_surface(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - int dest_has_alpha,
> - SpiceCanvas *surface_canvas,
> - int src_has_alpha,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - int scale_mode,
> - int overall_alpha)
> -{
> - SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
> - pixman_image_t *src;
> -
> - src = canvas_get_as_surface(sw_surface_canvas, src_has_alpha);
> - __blend_scale_image(spice_canvas, region, dest_has_alpha, src, src_x, src_y, src_width,
> - src_height, dest_x, dest_y, dest_width, dest_height, scale_mode,
> - overall_alpha);
> - pixman_image_unref(src);
> -}
> -
> -static void __colorkey_image(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src_image,
> - int offset_x, int offset_y,
> - uint32_t transparent_color)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - pixman_box32_t *rects;
> - int n_rects, i;
> -
> - rects = pixman_region32_rectangles(region,&n_rects);
> -
> - for (i = 0; i< n_rects; i++) {
> - int src_x, src_y, dest_x, dest_y, width, height;
> -
> - dest_x = rects[i].x1;
> - dest_y = rects[i].y1;
> - width = rects[i].x2 - rects[i].x1;
> - height = rects[i].y2 - rects[i].y1;
> -
> - src_x = rects[i].x1 - offset_x;
> - src_y = rects[i].y1 - offset_y;
> -
> - spice_pixman_blit_colorkey(canvas->image,
> - src_image,
> - src_x, src_y,
> - dest_x, dest_y,
> - width, height,
> - transparent_color);
> - }
> -}
> -
> -static void colorkey_image(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src_image,
> - int offset_x, int offset_y,
> - uint32_t transparent_color)
> -{
> - __colorkey_image(spice_canvas, region, src_image, offset_x, offset_y, transparent_color);
> -}
> -
> -static void colorkey_image_from_surface(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - SpiceCanvas *surface_canvas,
> - int offset_x, int offset_y,
> - uint32_t transparent_color)
> -{
> - SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
> - __colorkey_image(spice_canvas, region, sw_surface_canvas->image, offset_x, offset_y,
> - transparent_color);
> -}
> -
> -static void __colorkey_scale_image(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - uint32_t transparent_color)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - pixman_transform_t transform;
> - pixman_image_t *scaled;
> - pixman_box32_t *rects;
> - int n_rects, i;
> - pixman_fixed_t fsx, fsy;
> -
> - fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
> - fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
> -
> - scaled = pixman_image_create_bits(spice_pixman_image_get_format (src),
> - dest_width,
> - dest_height,
> - NULL, 0);
> -
> - pixman_region32_translate(region, -dest_x, -dest_y);
> - pixman_image_set_clip_region32(scaled, region);
> -
> - pixman_transform_init_scale(&transform, fsx, fsy);
> - pixman_transform_translate(&transform, NULL,
> - pixman_int_to_fixed (src_x),
> - pixman_int_to_fixed (src_y));
> -
> - pixman_image_set_transform(src,&transform);
> - pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
> - pixman_image_set_filter(src,
> - PIXMAN_FILTER_NEAREST,
> - NULL, 0);
> -
> - pixman_image_composite32(PIXMAN_OP_SRC,
> - src, NULL, scaled,
> - 0, 0, /* src */
> - 0, 0, /* mask */
> - 0, 0, /* dst */
> - dest_width,
> - dest_height);
> -
> - pixman_transform_init_identity(&transform);
> - pixman_image_set_transform(src,&transform);
> -
> - /* Translate back */
> - pixman_region32_translate(region, dest_x, dest_y);
> -
> - rects = pixman_region32_rectangles(region,&n_rects);
> -
> - for (i = 0; i< n_rects; i++) {
> - spice_pixman_blit_colorkey(canvas->image,
> - scaled,
> - rects[i].x1 - dest_x,
> - rects[i].y1 - dest_y,
> - rects[i].x1, rects[i].y1,
> - rects[i].x2 - rects[i].x1,
> - rects[i].y2 - rects[i].y1,
> - transparent_color);
> - }
> -
> - pixman_image_unref(scaled);
> -}
> -
> -static void colorkey_scale_image(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - pixman_image_t *src,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - uint32_t transparent_color)
> -{
> - __colorkey_scale_image(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x,
> - dest_y, dest_width, dest_height, transparent_color);
> -}
> -
> -static void colorkey_scale_image_from_surface(SpiceCanvas *spice_canvas,
> - pixman_region32_t *region,
> - SpiceCanvas *surface_canvas,
> - int src_x, int src_y,
> - int src_width, int src_height,
> - int dest_x, int dest_y,
> - int dest_width, int dest_height,
> - uint32_t transparent_color)
> -{
> - SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
> - __colorkey_scale_image(spice_canvas, region, sw_surface_canvas->image, src_x, src_y,
> - src_width, src_height, dest_x, dest_y, dest_width, dest_height,
> - transparent_color);
> -}
> -
> -static void canvas_put_image(SpiceCanvas *spice_canvas,
> -#ifdef WIN32
> - HDC dc,
> -#endif
> - const SpiceRect *dest, const uint8_t *src_data,
> - uint32_t src_width, uint32_t src_height, int src_stride,
> - const QRegion *clip)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - pixman_image_t *src;
> - uint32_t dest_width;
> - uint32_t dest_height;
> - double sx, sy;
> - pixman_transform_t transform;
> -
> - src = pixman_image_create_bits(PIXMAN_x8r8g8b8,
> - src_width,
> - src_height,
> - (uint32_t*)src_data,
> - src_stride);
> -
> -
> - if (clip) {
> - pixman_image_set_clip_region32 (canvas->image, (pixman_region32_t *)clip);
> - }
> -
> - dest_width = dest->right - dest->left;
> - dest_height = dest->bottom - dest->top;
> -
> - if (dest_width != src_width || dest_height != src_height) {
> - sx = (double)(src_width) / (dest_width);
> - sy = (double)(src_height) / (dest_height);
> -
> - pixman_transform_init_scale(&transform,
> - pixman_double_to_fixed(sx),
> - pixman_double_to_fixed(sy));
> - pixman_image_set_transform(src,&transform);
> - pixman_image_set_filter(src,
> - PIXMAN_FILTER_NEAREST,
> - NULL, 0);
> - }
> -
> - pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
> -
> - pixman_image_composite32(PIXMAN_OP_SRC,
> - src, NULL, canvas->image,
> - 0, 0, /* src */
> - 0, 0, /* mask */
> - dest->left, dest->top, /* dst */
> - dest_width, dest_height);
> -
> -
> - if (clip) {
> - pixman_image_set_clip_region32(canvas->image, NULL);
> - }
> - pixman_image_unref(src);
> -}
> -
> -
> -static void canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox,
> - SpiceClip *clip, SpiceText *text)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - pixman_region32_t dest_region;
> - pixman_image_t *str_mask, *brush;
> - SpiceString *str;
> - SpicePoint pos = { 0, };
> - int depth;
> -
> - pixman_region32_init_rect(&dest_region,
> - bbox->left, bbox->top,
> - bbox->right - bbox->left,
> - bbox->bottom - bbox->top);
> -
> - canvas_clip_pixman(&canvas->base,&dest_region, clip);
> -
> - if (!pixman_region32_not_empty(&dest_region)) {
> - touch_brush(&canvas->base,&text->fore_brush);
> - touch_brush(&canvas->base,&text->back_brush);
> - pixman_region32_fini(&dest_region);
> - return;
> - }
> -
> - if (!rect_is_empty(&text->back_area)) {
> - pixman_region32_t back_region;
> -
> - /* Nothing else makes sense for text and we should deprecate it
> - * and actually it means OVER really */
> - spice_return_if_fail(text->fore_mode == SPICE_ROPD_OP_PUT);
> -
> - pixman_region32_init_rect(&back_region,
> - text->back_area.left,
> - text->back_area.top,
> - text->back_area.right - text->back_area.left,
> - text->back_area.bottom - text->back_area.top);
> -
> - pixman_region32_intersect(&back_region,&back_region,&dest_region);
> -
> - if (pixman_region32_not_empty(&back_region)) {
> - draw_brush(spice_canvas,&back_region,&text->back_brush, SPICE_ROP_COPY);
> - }
> -
> - pixman_region32_fini(&back_region);
> - }
> - str = (SpiceString *)SPICE_GET_ADDRESS(text->str);
> -
> - if (str->flags& SPICE_STRING_FLAGS_RASTER_A1) {
> - depth = 1;
> - } else if (str->flags& SPICE_STRING_FLAGS_RASTER_A4) {
> - depth = 4;
> - } else if (str->flags& SPICE_STRING_FLAGS_RASTER_A8) {
> - spice_warning("untested path A8 glyphs");
> - depth = 8;
> - } else {
> - spice_warning("unsupported path vector glyphs");
> - pixman_region32_fini (&dest_region);
> - return;
> - }
> -
> - brush = canvas_get_pixman_brush(canvas,&text->fore_brush);
> -
> - str_mask = canvas_get_str_mask(&canvas->base, str, depth,&pos);
> - if (brush) {
> - pixman_image_set_clip_region32(canvas->image,&dest_region);
> -
> - pixman_image_composite32(PIXMAN_OP_OVER,
> - brush,
> - str_mask,
> - canvas->image,
> - 0, 0,
> - 0, 0,
> - pos.x, pos.y,
> - pixman_image_get_width(str_mask),
> - pixman_image_get_height(str_mask));
> - if (canvas->base.format == SPICE_SURFACE_FMT_32_xRGB) {
> - clear_dest_alpha(canvas->image, pos.x, pos.y,
> - pixman_image_get_width(str_mask),
> - pixman_image_get_height(str_mask));
> - }
> - pixman_image_unref(brush);
> -
> - pixman_image_set_clip_region32(canvas->image, NULL);
> - }
> - pixman_image_unref(str_mask);
> - pixman_region32_fini(&dest_region);
> -}
> -
> -static void canvas_read_bits(SpiceCanvas *spice_canvas, uint8_t *dest,
> - int dest_stride, const SpiceRect *area)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - pixman_image_t* surface;
> - uint8_t *src;
> - int src_stride;
> - uint8_t *dest_end;
> - int bpp;
> -
> - spice_return_if_fail(canvas&& area);
> -
> - surface = canvas->image;
> -
> - bpp = spice_pixman_image_get_bpp(surface) / 8;
> -
> - src_stride = pixman_image_get_stride(surface);
> - src = (uint8_t *)pixman_image_get_data(surface) +
> - area->top * src_stride + area->left * bpp;
> - dest_end = dest + (area->bottom - area->top) * dest_stride;
> - for (; dest != dest_end; dest += dest_stride, src += src_stride) {
> - memcpy(dest, src, (area->right - area->left) * bpp);
> - }
> -}
> -
> -static void canvas_clear(SpiceCanvas *spice_canvas)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - spice_pixman_fill_rect(canvas->image,
> - 0, 0,
> - pixman_image_get_width(canvas->image),
> - pixman_image_get_height(canvas->image),
> - 0);
> -}
> -
> -static void canvas_destroy(SpiceCanvas *spice_canvas)
> -{
> - SwCanvas *canvas = (SwCanvas *)spice_canvas;
> - if (!canvas) {
> - return;
> - }
> - pixman_image_unref(canvas->image);
> - canvas_base_destroy(&canvas->base);
> - if (canvas->private_data) {
> - free(canvas->private_data);
> - }
> - free(canvas);
> -}
> -
> -static int need_init = 1;
> -static SpiceCanvasOps sw_canvas_ops;
> -
> -static SpiceCanvas *canvas_create_common(pixman_image_t *image,
> - uint32_t format
> -#ifdef SW_CANVAS_CACHE
> - , SpiceImageCache *bits_cache
> - , SpicePaletteCache *palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , SpiceImageCache *bits_cache
> -#endif
> - , SpiceImageSurfaces *surfaces
> - , SpiceGlzDecoder *glz_decoder
> - , SpiceJpegDecoder *jpeg_decoder
> - , SpiceZlibDecoder *zlib_decoder
> - )
> -{
> - SwCanvas *canvas;
> -
> - if (need_init) {
> - return NULL;
> - }
> - spice_pixman_image_set_format(image,
> - spice_surface_format_to_pixman (format));
> -
> - canvas = spice_new0(SwCanvas, 1);
> - canvas_base_init(&canvas->base,&sw_canvas_ops,
> - pixman_image_get_width (image),
> - pixman_image_get_height (image),
> - format
> -#ifdef SW_CANVAS_CACHE
> - , bits_cache
> - , palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , bits_cache
> -#endif
> - , surfaces
> - , glz_decoder
> - , jpeg_decoder
> - , zlib_decoder
> - );
> - canvas->private_data = NULL;
> - canvas->private_data_size = 0;
> -
> - canvas->image = image;
> -
> - return (SpiceCanvas *)canvas;
> -}
> -
> -SpiceCanvas *canvas_create(int width, int height, uint32_t format
> -#ifdef SW_CANVAS_CACHE
> - , SpiceImageCache *bits_cache
> - , SpicePaletteCache *palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , SpiceImageCache *bits_cache
> -#endif
> - , SpiceImageSurfaces *surfaces
> - , SpiceGlzDecoder *glz_decoder
> - , SpiceJpegDecoder *jpeg_decoder
> - , SpiceZlibDecoder *zlib_decoder
> - )
> -{
> - pixman_image_t *image;
> -
> - image = pixman_image_create_bits(spice_surface_format_to_pixman (format),
> - width, height, NULL, 0);
> -
> - return canvas_create_common(image, format
> -#ifdef SW_CANVAS_CACHE
> - , bits_cache
> - , palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , bits_cache
> -#endif
> - , surfaces
> - , glz_decoder
> - , jpeg_decoder
> - , zlib_decoder
> - );
> -}
> -
> -SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format,
> - uint8_t *data, int stride
> -#ifdef SW_CANVAS_CACHE
> - , SpiceImageCache *bits_cache
> - , SpicePaletteCache *palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , SpiceImageCache *bits_cache
> -#endif
> - , SpiceImageSurfaces *surfaces
> - , SpiceGlzDecoder *glz_decoder
> - , SpiceJpegDecoder *jpeg_decoder
> - , SpiceZlibDecoder *zlib_decoder
> - )
> -{
> - pixman_image_t *image;
> -
> - image = pixman_image_create_bits(spice_surface_format_to_pixman (format),
> - width, height, (uint32_t *)data, stride);
> -
> - return canvas_create_common(image, format
> -#ifdef SW_CANVAS_CACHE
> - , bits_cache
> - , palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , bits_cache
> -#endif
> - , surfaces
> - , glz_decoder
> - , jpeg_decoder
> - , zlib_decoder
> - );
> -}
> -
> -void sw_canvas_init(void) //unsafe global function
> -{
> - if (!need_init) {
> - return;
> - }
> - need_init = 0;
> -
> - canvas_base_init_ops(&sw_canvas_ops);
> - sw_canvas_ops.draw_text = canvas_draw_text;
> - sw_canvas_ops.put_image = canvas_put_image;
> - sw_canvas_ops.clear = canvas_clear;
> - sw_canvas_ops.read_bits = canvas_read_bits;
> - sw_canvas_ops.destroy = canvas_destroy;
> -
> - sw_canvas_ops.fill_solid_spans = fill_solid_spans;
> - sw_canvas_ops.fill_solid_rects = fill_solid_rects;
> - sw_canvas_ops.fill_solid_rects_rop = fill_solid_rects_rop;
> - sw_canvas_ops.fill_tiled_rects = fill_tiled_rects;
> - sw_canvas_ops.fill_tiled_rects_from_surface = fill_tiled_rects_from_surface;
> - sw_canvas_ops.fill_tiled_rects_rop = fill_tiled_rects_rop;
> - sw_canvas_ops.fill_tiled_rects_rop_from_surface = fill_tiled_rects_rop_from_surface;
> - sw_canvas_ops.blit_image = blit_image;
> - sw_canvas_ops.blit_image_from_surface = blit_image_from_surface;
> - sw_canvas_ops.blit_image_rop = blit_image_rop;
> - sw_canvas_ops.blit_image_rop_from_surface = blit_image_rop_from_surface;
> - sw_canvas_ops.scale_image = scale_image;
> - sw_canvas_ops.scale_image_from_surface = scale_image_from_surface;
> - sw_canvas_ops.scale_image_rop = scale_image_rop;
> - sw_canvas_ops.scale_image_rop_from_surface = scale_image_rop_from_surface;
> - sw_canvas_ops.blend_image = blend_image;
> - sw_canvas_ops.blend_image_from_surface = blend_image_from_surface;
> - sw_canvas_ops.blend_scale_image = blend_scale_image;
> - sw_canvas_ops.blend_scale_image_from_surface = blend_scale_image_from_surface;
> - sw_canvas_ops.colorkey_image = colorkey_image;
> - sw_canvas_ops.colorkey_image_from_surface = colorkey_image_from_surface;
> - sw_canvas_ops.colorkey_scale_image = colorkey_scale_image;
> - sw_canvas_ops.colorkey_scale_image_from_surface = colorkey_scale_image_from_surface;
> - sw_canvas_ops.copy_region = copy_region;
> - sw_canvas_ops.get_image = get_image;
> - rop3_init();
> -}
> diff --git a/common/sw_canvas.h b/common/sw_canvas.h
> deleted file mode 100644
> index 51e594c..0000000
> --- a/common/sw_canvas.h
> +++ /dev/null
> @@ -1,58 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> - Copyright (C) 2009 Red Hat, Inc.
> -
> - This library is free software; you can redistribute it and/or
> - modify it under the terms of the GNU Lesser General Public
> - License as published by the Free Software Foundation; either
> - version 2.1 of the License, or (at your option) any later version.
> -
> - This library is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - Lesser General Public License for more details.
> -
> - You should have received a copy of the GNU Lesser General Public
> - License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -
> -#ifndef _H__CANVAS
> -#define _H__CANVAS
> -
> -#include<stdint.h>
> -
> -#include "draw.h"
> -#include "pixman_utils.h"
> -#include "canvas_base.h"
> -#include "region.h"
> -
> -SpiceCanvas *canvas_create(int width, int height, uint32_t format
> -#ifdef SW_CANVAS_CACHE
> - , SpiceImageCache *bits_cache
> - , SpicePaletteCache *palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , SpiceImageCache *bits_cache
> -#endif
> - , SpiceImageSurfaces *surfaces
> - , SpiceGlzDecoder *glz_decoder
> - , SpiceJpegDecoder *jpeg_decoder
> - , SpiceZlibDecoder *zlib_decoder
> - );
> -
> -SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format, uint8_t *data, int stride
> -#ifdef SW_CANVAS_CACHE
> - , SpiceImageCache *bits_cache
> - , SpicePaletteCache *palette_cache
> -#elif defined(SW_CANVAS_IMAGE_CACHE)
> - , SpiceImageCache *bits_cache
> -#endif
> - , SpiceImageSurfaces *surfaces
> - , SpiceGlzDecoder *glz_decoder
> - , SpiceJpegDecoder *jpeg_decoder
> - , SpiceZlibDecoder *zlib_decoder
> - );
> -
> -
> -void sw_canvas_init(void);
> -
> -#endif
> diff --git a/configure.ac b/configure.ac
> index 2d062b1..760736a 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -25,6 +25,8 @@ GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
>
> # Define default SPICE_COMMON_SRCDIR
> SPICE_COMMON_SRCDIR='$(top_srcdir)'/common
> +# no opengl support yet
> +AM_CONDITIONAL(SUPPORT_GL, false)
>
> AC_PROG_CC
> AC_PROG_CC_C99
> diff --git a/gtk/Makefile.am b/gtk/Makefile.am
> index f4869b9..9628cc7 100644
> --- a/gtk/Makefile.am
> +++ b/gtk/Makefile.am
> @@ -233,6 +233,8 @@ libspice_client_glib_2_0_la_SOURCES = \
> decode-jpeg.c \
> decode-zlib.c \
> \
> + $(COMMON_DIR)/backtrace.c \
> + $(COMMON_DIR)/backtrace.h \
> $(COMMON_DIR)/mem.c \
> $(COMMON_DIR)/mem.h \
> $(COMMON_DIR)/marshaller.c \
> @@ -249,6 +251,8 @@ libspice_client_glib_2_0_la_SOURCES = \
> $(COMMON_DIR)/rop3.h \
> $(COMMON_DIR)/quic.c \
> $(COMMON_DIR)/quic.h \
> + $(COMMON_DIR)/log.c \
> + $(COMMON_DIR)/log.h \
> $(COMMON_DIR)/lz.c \
> $(COMMON_DIR)/lz.h \
> $(COMMON_DIR)/region.c \
> @@ -503,10 +507,10 @@ generated_demarshallers1.c: $(top_srcdir)/spice1.proto
> $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --client --include messages.h --prefix 1 --ptrsize 8 $< $@>/dev/null
>
> generated_marshallers.c: $(top_srcdir)/spice.proto
> - $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include messages.h --include marshallers.h --client $< $@>/dev/null
> + $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include messages.h --include client_marshallers.h --client $< $@>/dev/null
>
> generated_marshallers1.c: $(top_srcdir)/spice1.proto
> - $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include messages.h --include marshallers.h --client --prefix 1 --ptrsize 8 $< $@>/dev/null
> + $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include messages.h --include client_marshallers.h --client --prefix 1 --ptrsize 8 $< $@>/dev/null
>
> vncdisplaykeymap.c: $(KEYMAPS)
>
> diff --git a/gtk/decode.h b/gtk/decode.h
> index 9fee749..9db6383 100644
> --- a/gtk/decode.h
> +++ b/gtk/decode.h
> @@ -19,6 +19,7 @@
> # define SPICEGTK_DECODE_H_
>
> #include<glib.h>
> +
> #include "canvas_base.h"
>
> G_BEGIN_DECLS
> diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h
> index 482927b..88611d0 100644
> --- a/gtk/spice-channel-priv.h
> +++ b/gtk/spice-channel-priv.h
> @@ -32,9 +32,8 @@
> #include "coroutine.h"
> #include "gio-coroutine.h"
>
> -/* common/ */
> -#include "marshallers.h"
> -#include "demarshallers.h"
> +#include "client_marshallers.h"
> +#include "client_demarshallers.h"
>
> #include "ssl_verify.h"
>
More information about the Spice-devel
mailing list