[Spice-devel] [PATCH 12/19] server: rename _tmpl files
Fabiano Fidêncio
fabiano at fidencio.org
Thu Nov 26 01:37:31 PST 2015
On Wed, Nov 25, 2015 at 4:27 PM, Frediano Ziglio <fziglio at redhat.com> wrote:
> From: Marc-André Lureau <marcandre.lureau at gmail.com>
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
> server/Makefile.am | 8 +-
> server/cache-item.tmpl.c | 143 ++++++++++
> server/cache_item.tmpl.c | 143 ----------
> server/cursor-channel.c | 2 +-
> server/dcc.c | 2 +-
> server/glz-encode-match.tmpl.c | 154 +++++++++++
> server/glz-encode.tmpl.c | 574 +++++++++++++++++++++++++++++++++++++++
> server/glz_encode_match_tmpl.c | 154 -----------
> server/glz_encode_tmpl.c | 574 ---------------------------------------
> server/glz_encoder.c | 14 +-
> server/red_bitmap_utils_tmpl.c | 160 -----------
> server/spice-bitmap-utils.c | 6 +-
> server/spice-bitmap-utils.tmpl.c | 160 +++++++++++
> 13 files changed, 1047 insertions(+), 1047 deletions(-)
> create mode 100644 server/cache-item.tmpl.c
> delete mode 100644 server/cache_item.tmpl.c
> create mode 100644 server/glz-encode-match.tmpl.c
> create mode 100644 server/glz-encode.tmpl.c
> delete mode 100644 server/glz_encode_match_tmpl.c
> delete mode 100644 server/glz_encode_tmpl.c
> delete mode 100644 server/red_bitmap_utils_tmpl.c
> create mode 100644 server/spice-bitmap-utils.tmpl.c
>
> diff --git a/server/Makefile.am b/server/Makefile.am
> index 4e4fc6f..6b45a42 100644
> --- a/server/Makefile.am
> +++ b/server/Makefile.am
> @@ -154,10 +154,10 @@ libspice_server_la_SOURCES += \
> endif
>
> EXTRA_DIST = \
> - red_bitmap_utils_tmpl.c \
> - cache_item.tmpl.c \
> - glz_encode_match_tmpl.c \
> - glz_encode_tmpl.c \
> + spice-bitmap-utils.tmpl.c \
> + cache-item.tmpl.c \
> + glz-encode-match.tmpl.c \
> + glz-encode.tmpl.c \
> spice-server.syms \
> $(NULL)
>
> diff --git a/server/cache-item.tmpl.c b/server/cache-item.tmpl.c
> new file mode 100644
> index 0000000..09add79
> --- /dev/null
> +++ b/server/cache-item.tmpl.c
> @@ -0,0 +1,143 @@
> +/*
> + 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 HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#if defined(CLIENT_CURSOR_CACHE)
> +
> +#define CACHE_NAME cursor_cache
> +#define CACHE_HASH_KEY CURSOR_CACHE_HASH_KEY
> +#define CACHE_HASH_SIZE CURSOR_CACHE_HASH_SIZE
> +#define CACHE_INVAL_TYPE SPICE_MSG_CURSOR_INVAL_ONE
> +#define FUNC_NAME(name) red_cursor_cache_##name
> +#define VAR_NAME(name) cursor_cache_##name
> +#define CHANNEL CursorChannel
> +#define CHANNELCLIENT CursorChannelClient
> +
> +#elif defined(CLIENT_PALETTE_CACHE)
> +
> +#define CACHE_NAME palette_cache
> +#define CACHE_HASH_KEY PALETTE_CACHE_HASH_KEY
> +#define CACHE_HASH_SIZE PALETTE_CACHE_HASH_SIZE
> +#define CACHE_INVAL_TYPE SPICE_MSG_DISPLAY_INVAL_PALETTE
> +#define FUNC_NAME(name) red_palette_cache_##name
> +#define VAR_NAME(name) palette_cache_##name
> +#define CHANNEL DisplayChannel
> +#define CHANNELCLIENT DisplayChannelClient
> +#else
> +
> +#error "no cache type."
> +
> +#endif
> +
> +#define CHANNEL_FROM_RCC(rcc) SPICE_CONTAINEROF((rcc)->channel, CHANNEL, common.base);
> +
> +static CacheItem *FUNC_NAME(find)(CHANNELCLIENT *channel_client, uint64_t id)
> +{
> + CacheItem *item = channel_client->CACHE_NAME[CACHE_HASH_KEY(id)];
> +
> + while (item) {
> + if (item->id == id) {
> + ring_remove(&item->u.cache_data.lru_link);
> + ring_add(&channel_client->VAR_NAME(lru), &item->u.cache_data.lru_link);
> + break;
> + }
> + item = item->u.cache_data.next;
> + }
> + return item;
> +}
> +
> +static void FUNC_NAME(remove)(CHANNELCLIENT *channel_client, CacheItem *item)
> +{
> + CacheItem **now;
> + CHANNEL *channel = CHANNEL_FROM_RCC(&channel_client->common.base);
> + spice_assert(item);
> +
> + now = &channel_client->CACHE_NAME[CACHE_HASH_KEY(item->id)];
> + for (;;) {
> + spice_assert(*now);
> + if (*now == item) {
> + *now = item->u.cache_data.next;
> + break;
> + }
> + now = &(*now)->u.cache_data.next;
> + }
> + ring_remove(&item->u.cache_data.lru_link);
> + channel_client->VAR_NAME(items)--;
> + channel_client->VAR_NAME(available) += item->size;
> +
> + red_channel_pipe_item_init(&channel->common.base, &item->u.pipe_data, PIPE_ITEM_TYPE_INVAL_ONE);
> + red_channel_client_pipe_add_tail(&channel_client->common.base, &item->u.pipe_data); // for now
> +}
> +
> +static int FUNC_NAME(add)(CHANNELCLIENT *channel_client, uint64_t id, size_t size)
> +{
> + CacheItem *item;
> + int key;
> +
> + item = spice_new(CacheItem, 1);
> +
> + channel_client->VAR_NAME(available) -= size;
> + while (channel_client->VAR_NAME(available) < 0) {
> + CacheItem *tail = (CacheItem *)ring_get_tail(&channel_client->VAR_NAME(lru));
> + if (!tail) {
> + channel_client->VAR_NAME(available) += size;
> + free(item);
> + return FALSE;
> + }
> + FUNC_NAME(remove)(channel_client, tail);
> + }
> + ++channel_client->VAR_NAME(items);
> + item->u.cache_data.next = channel_client->CACHE_NAME[(key = CACHE_HASH_KEY(id))];
> + channel_client->CACHE_NAME[key] = item;
> + ring_item_init(&item->u.cache_data.lru_link);
> + ring_add(&channel_client->VAR_NAME(lru), &item->u.cache_data.lru_link);
> + item->id = id;
> + item->size = size;
> + item->inval_type = CACHE_INVAL_TYPE;
> + return TRUE;
> +}
> +
> +static void FUNC_NAME(reset)(CHANNELCLIENT *channel_client, long size)
> +{
> + int i;
> +
> + for (i = 0; i < CACHE_HASH_SIZE; i++) {
> + while (channel_client->CACHE_NAME[i]) {
> + CacheItem *item = channel_client->CACHE_NAME[i];
> + channel_client->CACHE_NAME[i] = item->u.cache_data.next;
> + free(item);
> + }
> + }
> + ring_init(&channel_client->VAR_NAME(lru));
> + channel_client->VAR_NAME(available) = size;
> + channel_client->VAR_NAME(items) = 0;
> +}
> +
> +
> +#undef CACHE_NAME
> +#undef CACHE_HASH_KEY
> +#undef CACHE_HASH_SIZE
> +#undef CACHE_INVAL_TYPE
> +#undef CACHE_MAX_CLIENT_SIZE
> +#undef FUNC_NAME
> +#undef VAR_NAME
> +#undef CHANNEL
> +#undef CHANNELCLIENT
> +#undef CHANNEL_FROM_RCC
> diff --git a/server/cache_item.tmpl.c b/server/cache_item.tmpl.c
> deleted file mode 100644
> index 09add79..0000000
> --- a/server/cache_item.tmpl.c
> +++ /dev/null
> @@ -1,143 +0,0 @@
> -/*
> - 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 HAVE_CONFIG_H
> -#include <config.h>
> -#endif
> -
> -#if defined(CLIENT_CURSOR_CACHE)
> -
> -#define CACHE_NAME cursor_cache
> -#define CACHE_HASH_KEY CURSOR_CACHE_HASH_KEY
> -#define CACHE_HASH_SIZE CURSOR_CACHE_HASH_SIZE
> -#define CACHE_INVAL_TYPE SPICE_MSG_CURSOR_INVAL_ONE
> -#define FUNC_NAME(name) red_cursor_cache_##name
> -#define VAR_NAME(name) cursor_cache_##name
> -#define CHANNEL CursorChannel
> -#define CHANNELCLIENT CursorChannelClient
> -
> -#elif defined(CLIENT_PALETTE_CACHE)
> -
> -#define CACHE_NAME palette_cache
> -#define CACHE_HASH_KEY PALETTE_CACHE_HASH_KEY
> -#define CACHE_HASH_SIZE PALETTE_CACHE_HASH_SIZE
> -#define CACHE_INVAL_TYPE SPICE_MSG_DISPLAY_INVAL_PALETTE
> -#define FUNC_NAME(name) red_palette_cache_##name
> -#define VAR_NAME(name) palette_cache_##name
> -#define CHANNEL DisplayChannel
> -#define CHANNELCLIENT DisplayChannelClient
> -#else
> -
> -#error "no cache type."
> -
> -#endif
> -
> -#define CHANNEL_FROM_RCC(rcc) SPICE_CONTAINEROF((rcc)->channel, CHANNEL, common.base);
> -
> -static CacheItem *FUNC_NAME(find)(CHANNELCLIENT *channel_client, uint64_t id)
> -{
> - CacheItem *item = channel_client->CACHE_NAME[CACHE_HASH_KEY(id)];
> -
> - while (item) {
> - if (item->id == id) {
> - ring_remove(&item->u.cache_data.lru_link);
> - ring_add(&channel_client->VAR_NAME(lru), &item->u.cache_data.lru_link);
> - break;
> - }
> - item = item->u.cache_data.next;
> - }
> - return item;
> -}
> -
> -static void FUNC_NAME(remove)(CHANNELCLIENT *channel_client, CacheItem *item)
> -{
> - CacheItem **now;
> - CHANNEL *channel = CHANNEL_FROM_RCC(&channel_client->common.base);
> - spice_assert(item);
> -
> - now = &channel_client->CACHE_NAME[CACHE_HASH_KEY(item->id)];
> - for (;;) {
> - spice_assert(*now);
> - if (*now == item) {
> - *now = item->u.cache_data.next;
> - break;
> - }
> - now = &(*now)->u.cache_data.next;
> - }
> - ring_remove(&item->u.cache_data.lru_link);
> - channel_client->VAR_NAME(items)--;
> - channel_client->VAR_NAME(available) += item->size;
> -
> - red_channel_pipe_item_init(&channel->common.base, &item->u.pipe_data, PIPE_ITEM_TYPE_INVAL_ONE);
> - red_channel_client_pipe_add_tail(&channel_client->common.base, &item->u.pipe_data); // for now
> -}
> -
> -static int FUNC_NAME(add)(CHANNELCLIENT *channel_client, uint64_t id, size_t size)
> -{
> - CacheItem *item;
> - int key;
> -
> - item = spice_new(CacheItem, 1);
> -
> - channel_client->VAR_NAME(available) -= size;
> - while (channel_client->VAR_NAME(available) < 0) {
> - CacheItem *tail = (CacheItem *)ring_get_tail(&channel_client->VAR_NAME(lru));
> - if (!tail) {
> - channel_client->VAR_NAME(available) += size;
> - free(item);
> - return FALSE;
> - }
> - FUNC_NAME(remove)(channel_client, tail);
> - }
> - ++channel_client->VAR_NAME(items);
> - item->u.cache_data.next = channel_client->CACHE_NAME[(key = CACHE_HASH_KEY(id))];
> - channel_client->CACHE_NAME[key] = item;
> - ring_item_init(&item->u.cache_data.lru_link);
> - ring_add(&channel_client->VAR_NAME(lru), &item->u.cache_data.lru_link);
> - item->id = id;
> - item->size = size;
> - item->inval_type = CACHE_INVAL_TYPE;
> - return TRUE;
> -}
> -
> -static void FUNC_NAME(reset)(CHANNELCLIENT *channel_client, long size)
> -{
> - int i;
> -
> - for (i = 0; i < CACHE_HASH_SIZE; i++) {
> - while (channel_client->CACHE_NAME[i]) {
> - CacheItem *item = channel_client->CACHE_NAME[i];
> - channel_client->CACHE_NAME[i] = item->u.cache_data.next;
> - free(item);
> - }
> - }
> - ring_init(&channel_client->VAR_NAME(lru));
> - channel_client->VAR_NAME(available) = size;
> - channel_client->VAR_NAME(items) = 0;
> -}
> -
> -
> -#undef CACHE_NAME
> -#undef CACHE_HASH_KEY
> -#undef CACHE_HASH_SIZE
> -#undef CACHE_INVAL_TYPE
> -#undef CACHE_MAX_CLIENT_SIZE
> -#undef FUNC_NAME
> -#undef VAR_NAME
> -#undef CHANNEL
> -#undef CHANNELCLIENT
> -#undef CHANNEL_FROM_RCC
> diff --git a/server/cursor-channel.c b/server/cursor-channel.c
> index aafc807..9d72299 100644
> --- a/server/cursor-channel.c
> +++ b/server/cursor-channel.c
> @@ -86,7 +86,7 @@ struct CursorChannelClient {
> #define RCC_TO_CCC(rcc) SPICE_CONTAINEROF((rcc), CursorChannelClient, common.base)
>
> #define CLIENT_CURSOR_CACHE
> -#include "cache_item.tmpl.c"
> +#include "cache-item.tmpl.c"
> #undef CLIENT_CURSOR_CACHE
>
> static CursorItem *cursor_item_new(QXLInstance *qxl, RedCursorCmd *cmd, uint32_t group_id)
> diff --git a/server/dcc.c b/server/dcc.c
> index ffe5b34..6e8c876 100644
> --- a/server/dcc.c
> +++ b/server/dcc.c
> @@ -1184,7 +1184,7 @@ int dcc_compress_image(DisplayChannelClient *dcc,
> }
>
> #define CLIENT_PALETTE_CACHE
> -#include "cache_item.tmpl.c"
> +#include "cache-item.tmpl.c"
> #undef CLIENT_PALETTE_CACHE
>
> void dcc_palette_cache_palette(DisplayChannelClient *dcc, SpicePalette *palette,
> diff --git a/server/glz-encode-match.tmpl.c b/server/glz-encode-match.tmpl.c
> new file mode 100644
> index 0000000..1fd251e
> --- /dev/null
> +++ b/server/glz-encode-match.tmpl.c
> @@ -0,0 +1,154 @@
> +/*
> + 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 HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#define SHORT_PIX_IMAGE_DIST_LEVEL_1 64 //(1 << 6)
> +#define SHORT_PIX_IMAGE_DIST_LEVEL_2 16384 // (1 << 14)
> +#define SHORT_PIX_IMAGE_DIST_LEVEL_3 4194304 // (1 << 22)
> +#define FAR_PIX_IMAGE_DIST_LEVEL_1 256 // (1 << 8)
> +#define FAR_PIX_IMAGE_DIST_LEVEL_2 65536 // (1 << 16)
> +#define FAR_PIX_IMAGE_DIST_LEVEL_3 16777216 // (1 << 24)
> +
> +/* if image_distance = 0, pixel_distance is the distance between the matching pixels.
> + Otherwise, it is the offset from the beginning of the referred image */
> +#if defined(GLZ_ENCODE_MATCH) /* actually performing the encoding */
> +static inline void encode_match(Encoder *encoder, uint32_t image_distance,
> + size_t pixel_distance, size_t len)
> +#elif defined(GLZ_ENCODE_SIZE) /* compute the size of the encoding except for the match length*/
> +static inline int get_encode_ref_size(uint32_t image_distance, size_t pixel_distance)
> +#endif
> +{
> +#if defined(GLZ_ENCODE_SIZE)
> + int encode_size;
> +#endif
> +
> +#if defined(GLZ_ENCODE_MATCH)
> + /* encoding the match length + Long/Short dist bit + 12 LSB pixels of pixel_distance*/
> + if (len < 7) {
> + if (pixel_distance < MAX_PIXEL_SHORT_DISTANCE) {
> + encode(encoder, (uint8_t)((len << 5) + (pixel_distance & 0x0f)));
> + } else {
> + encode(encoder, (uint8_t)((len << 5) + 16 + (pixel_distance & 0x0f)));
> + }
> + encode(encoder, (uint8_t)((pixel_distance >> 4) & 255));
> + } else {
> + if (pixel_distance < MAX_PIXEL_SHORT_DISTANCE) {
> + encode(encoder, (uint8_t)((7 << 5) + (pixel_distance & 0x0f)));
> + } else {
> + encode(encoder, (uint8_t)((7 << 5) + 16 + (pixel_distance & 0x0f)));
> + }
> + for (len -= 7; len >= 255; len -= 255) {
> + encode(encoder, 255);
> + }
> + encode(encoder, (uint8_t)len);
> + encode(encoder, (uint8_t)((pixel_distance >> 4) & 255));
> + }
> +#endif
> +
> +
> + /* encoding the rest of the pixel distance and the image_dist and its 2 control bits */
> +
> + /* The first 2 MSB bits indicate how many more bytes should be read for image dist */
> + if (pixel_distance < MAX_PIXEL_SHORT_DISTANCE) {
> + if (image_distance < SHORT_PIX_IMAGE_DIST_LEVEL_1) {
> +#if defined(GLZ_ENCODE_MATCH)
> + encode(encoder, (uint8_t)(image_distance & 0x3f));
> +#elif defined(GLZ_ENCODE_SIZE)
> + encode_size = 3;
> +#endif
> + } else if (image_distance < SHORT_PIX_IMAGE_DIST_LEVEL_2) {
> +#if defined(GLZ_ENCODE_MATCH)
> + encode(encoder, (uint8_t)((1 << 6) + (image_distance & 0x3f)));
> + encode(encoder, (uint8_t)((image_distance >> 6) & 255));
> +#elif defined(GLZ_ENCODE_SIZE)
> + encode_size = 4;
> +#endif
> + } else if (image_distance < SHORT_PIX_IMAGE_DIST_LEVEL_3) {
> +#if defined(GLZ_ENCODE_MATCH)
> + encode(encoder, (uint8_t)((1 << 7) + (image_distance & 0x3f)));
> + encode(encoder, (uint8_t)((image_distance >> 6) & 255));
> + encode(encoder, (uint8_t)((image_distance >> 14) & 255));
> +#elif defined(GLZ_ENCODE_SIZE)
> + encode_size = 5;
> +#endif
> + } else {
> +#if defined(GLZ_ENCODE_MATCH)
> + encode(encoder, (uint8_t)((1 << 7) + (1 << 6) + (image_distance & 0x3f)));
> + encode(encoder, (uint8_t)((image_distance >> 6) & 255));
> + encode(encoder, (uint8_t)((image_distance >> 14) & 255));
> + encode(encoder, (uint8_t)((image_distance >> 22) & 255));
> +#elif defined(GLZ_ENCODE_SIZE)
> + encode_size = 6;
> +#endif
> + }
> + } else {
> + /* the third MSB bit indicates if the pixel_distance is medium/long*/
> + uint8_t long_dist_control = (pixel_distance < MAX_PIXEL_MEDIUM_DISTANCE) ? 0 : 32;
> + if (image_distance == 0) {
> +#if defined(GLZ_ENCODE_MATCH)
> + encode(encoder, (uint8_t)(long_dist_control + ((pixel_distance >> 12) & 31)));
> +#elif defined(GLZ_ENCODE_SIZE)
> + encode_size = 3;
> +#endif
> + } else if (image_distance < FAR_PIX_IMAGE_DIST_LEVEL_1) {
> +#if defined(GLZ_ENCODE_MATCH)
> + encode(encoder,
> + (uint8_t)(long_dist_control + (1 << 6) + ((pixel_distance >> 12) & 31)));
> + encode(encoder, (uint8_t)(image_distance & 255));
> +#elif defined(GLZ_ENCODE_SIZE)
> + encode_size = 4;
> +#endif
> + } else if (image_distance < FAR_PIX_IMAGE_DIST_LEVEL_2) {
> +#if defined(GLZ_ENCODE_MATCH)
> + encode(encoder,
> + (uint8_t)(long_dist_control + (1 << 7) + ((pixel_distance >> 12) & 31)));
> + encode(encoder, (uint8_t)(image_distance & 255));
> + encode(encoder, (uint8_t)((image_distance >> 8) & 255));
> +#elif defined(GLZ_ENCODE_SIZE)
> + encode_size = 5;
> +#endif
> + } else {
> +#if defined(GLZ_ENCODE_MATCH)
> + encode(encoder,
> + (uint8_t)(long_dist_control + (1 << 7) + (1 << 6) +
> + ((pixel_distance >> 12) & 31)));
> + encode(encoder, (uint8_t)(image_distance & 255));
> + encode(encoder, (uint8_t)((image_distance >> 8) & 255));
> + encode(encoder, (uint8_t)((image_distance >> 16) & 255));
> +#elif defined(GLZ_ENCODE_SIZE)
> + encode_size = 6;
> +#endif
> + }
> +
> + if (long_dist_control) {
> +#if defined(GLZ_ENCODE_MATCH)
> + encode(encoder, (uint8_t)((pixel_distance >> 17) & 255));
> +#elif defined(GLZ_ENCODE_SIZE)
> + encode_size++;
> +#endif
> + }
> + }
> +
> +#if defined(GLZ_ENCODE_SIZE)
> + return encode_size;
> +#endif
> +}
> +
> +#undef GLZ_ENCODE_SIZE
> +#undef GLZ_ENCODE_MATCH
> diff --git a/server/glz-encode.tmpl.c b/server/glz-encode.tmpl.c
> new file mode 100644
> index 0000000..46dd1d4
> --- /dev/null
> +++ b/server/glz-encode.tmpl.c
> @@ -0,0 +1,574 @@
> +/*
> + 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 HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#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) glz_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 MIN_REF_ENCODE_SIZE 4
> +#define MAX_REF_ENCODE_SIZE 7
> +#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) glz_rgb_alpha_##name
> +#define ENCODE_PIXEL(e, pix) {encode(e, (pix).pad);}
> +#define SAME_PIXEL(pix1, pix2) ((pix1).pad == (pix2).pad)
> +#define MIN_REF_ENCODE_SIZE 4
> +#define MAX_REF_ENCODE_SIZE 7
> +#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) glz_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 MIN_REF_ENCODE_SIZE 2
> +#define MAX_REF_ENCODE_SIZE 3
> +#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) glz_rgb24_##name
> +#define ENCODE_PIXEL(e, pix) {encode(e, (pix).b); encode(e, (pix).g); encode(e, (pix).r);}
> +#define MIN_REF_ENCODE_SIZE 2
> +#define MAX_REF_ENCODE_SIZE 2
> +#endif
> +
> +#ifdef LZ_RGB32
> +#define PIXEL rgb32_pixel_t
> +#define FNAME(name) glz_rgb32_##name
> +#define ENCODE_PIXEL(e, pix) {encode(e, (pix).b); encode(e, (pix).g); encode(e, (pix).r);}
> +#define MIN_REF_ENCODE_SIZE 2
> +#define MAX_REF_ENCODE_SIZE 2
> +#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
> +
> +#ifndef LZ_PLT
> +#define PIXEL_ID(pix_ptr, seg_ptr) \
> + ((pix_ptr) - ((PIXEL *)(seg_ptr)->lines) + (seg_ptr)->pixels_so_far)
> +#define PIXEL_DIST(src_pix_ptr, src_seg_ptr, ref_pix_ptr, ref_seg_ptr) \
> + (PIXEL_ID(src_pix_ptr,src_seg_ptr) - PIXEL_ID(ref_pix_ptr, ref_seg_ptr))
> +#else
> +#define PIXEL_ID(pix_ptr, seg_ptr, pix_per_byte) \
> + (((pix_ptr) - ((PIXEL *)(seg_ptr)->lines)) * pix_per_byte + (seg_ptr)->pixels_so_far)
> +#define PIXEL_DIST(src_pix_ptr, src_seg_ptr, ref_pix_ptr, ref_seg_ptr, pix_per_byte) \
> + ((PIXEL_ID(src_pix_ptr,src_seg_ptr, pix_per_byte) - \
> + PIXEL_ID(ref_pix_ptr, ref_seg_ptr, pix_per_byte)) / pix_per_byte)
> +#endif
> +
> +/* returns the length of the match. 0 if no match.
> + if image_distance = 0, pixel_distance is the distance between the matching pixels.
> + Otherwise, it is the offset from the beginning of the referred image */
> +static inline size_t FNAME(do_match)(SharedDictionary *dict,
> + WindowImageSegment *ref_seg, const PIXEL *ref,
> + const PIXEL *ref_limit,
> + WindowImageSegment *ip_seg, const PIXEL *ip,
> + const PIXEL *ip_limit,
> +#ifdef LZ_PLT
> + int pix_per_byte,
> +#endif
> + size_t *o_image_dist, size_t *o_pix_distance)
> +{
> + int encode_size;
> + const PIXEL *tmp_ip = ip;
> + const PIXEL *tmp_ref = ref;
> +
> + if (ref > (ref_limit - MIN_REF_ENCODE_SIZE)) {
> + return 0; // in case the hash entry is not relevant
> + }
> +
> +
> + /* min match length == MIN_REF_ENCODE_SIZE (depends on pixel type) */
> +
> + if (!SAME_PIXEL(*tmp_ref, *tmp_ip)) {
> + return 0;
> + } else {
> + tmp_ref++;
> + tmp_ip++;
> + }
> +
> +
> + if (!SAME_PIXEL(*tmp_ref, *tmp_ip)) {
> + return 0;
> + } else {
> + tmp_ref++;
> + tmp_ip++;
> + }
> +
> +#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
> + if (!SAME_PIXEL(*tmp_ref, *tmp_ip)) {
> + return 0;
> + } else {
> + tmp_ref++;
> + tmp_ip++;
> + }
> +
> +
> + if (!SAME_PIXEL(*tmp_ref, *tmp_ip)) {
> + return 0;
> + } else {
> + tmp_ref++;
> + tmp_ip++;
> + }
> +
> +#endif
> +
> +
> + *o_image_dist = ip_seg->image->id - ref_seg->image->id;
> +
> + if (!(*o_image_dist)) { // the ref is inside the same image - encode distance
> +#ifndef LZ_PLT
> + *o_pix_distance = PIXEL_DIST(ip, ip_seg, ref, ref_seg);
> +#else
> + // in bytes
> + *o_pix_distance = PIXEL_DIST(ip, ip_seg, ref, ref_seg, pix_per_byte);
> +#endif
> + } else { // the ref is at different image - encode offset from the image start
> +#ifndef LZ_PLT
> + *o_pix_distance = PIXEL_DIST(ref, ref_seg,
> + (PIXEL *)(dict->window.segs[ref_seg->image->first_seg].lines),
> + &dict->window.segs[ref_seg->image->first_seg]
> + );
> +#else
> + // in bytes
> + *o_pix_distance = PIXEL_DIST(ref, ref_seg,
> + (PIXEL *)(dict->window.segs[ref_seg->image->first_seg].lines),
> + &dict->window.segs[ref_seg->image->first_seg],
> + pix_per_byte);
> +#endif
> + }
> +
> + if ((*o_pix_distance == 0) || (*o_pix_distance >= MAX_PIXEL_LONG_DISTANCE) ||
> + (*o_image_dist > MAX_IMAGE_DIST)) {
> + return 0;
> + }
> +
> +
> + /* continue the match*/
> + while ((tmp_ip < ip_limit) && (tmp_ref < ref_limit)) {
> + if (!SAME_PIXEL(*tmp_ref, *tmp_ip)) {
> + break;
> + } else {
> + tmp_ref++;
> + tmp_ip++;
> + }
> + }
> +
> +
> + if ((tmp_ip - ip) > MAX_REF_ENCODE_SIZE) {
> + return (tmp_ip - ip);
> + }
> +
> + encode_size = get_encode_ref_size(*o_image_dist, *o_pix_distance);
> +
> + // min number of identical pixels for a match
> +#if defined(LZ_RGB16)
> + encode_size /= 2;
> +#elif defined(LZ_RGB24) || defined(LZ_RGB32)
> + encode_size /= 3;
> +#endif
> +
> + encode_size++; // the minimum match
> + // match len is smaller than the encoding - not worth encoding
> + if ((tmp_ip - ip) < encode_size) {
> + return 0;
> + }
> + return (tmp_ip - ip);
> +}
> +
> +/* compresses one segment starting from 'from'.
> + In order to encode a match, we use pixels resolution when we encode RGB image,
> + and bytes count when we encode PLT.
> +*/
> +static void FNAME(compress_seg)(Encoder *encoder, uint32_t seg_idx, PIXEL *from, int copied)
> +{
> + WindowImageSegment *seg = &encoder->dict->window.segs[seg_idx];
> + const PIXEL *ip = from;
> + const PIXEL *ip_bound = (PIXEL *)(seg->lines_end) - BOUND_OFFSET;
> + const PIXEL *ip_limit = (PIXEL *)(seg->lines_end) - LIMIT_OFFSET;
> + int hval;
> + int copy = copied;
> +#ifdef LZ_PLT
> + int pix_per_byte = PLT_PIXELS_PER_BYTE[encoder->cur_image.type];
> +#endif
> +
> +#ifdef DEBUG_ENCODE
> + int n_encoded = 0;
> +#endif
> +
> + if (copy == 0) {
> + encode_copy_count(encoder, MAX_COPY - 1);
> + }
> +
> +
> + while (LZ_EXPECT_CONDITIONAL(ip < ip_limit)) {
> + const PIXEL *ref;
> + const PIXEL *ref_limit;
> + WindowImageSegment *ref_seg;
> + uint32_t ref_seg_idx;
> + size_t pix_dist;
> + size_t image_dist;
> + /* minimum match length */
> + size_t len = 0;
> +
> + /* comparison starting-point */
> + const PIXEL *anchor = ip;
> +#ifdef CHAINED_HASH
> + int hash_id = 0;
> + size_t best_len = 0;
> + size_t best_pix_dist = 0;
> + size_t best_image_dist = 0;
> +#endif
> +
> + /* check for a run */
> +
> + 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])) {
> + PIXEL x;
> + pix_dist = 1;
> + image_dist = 0;
> +
> + ip += 3;
> + ref = anchor + 2;
> + ref_limit = (PIXEL *)(seg->lines_end);
> + len = 3;
> +
> + x = *ref;
> +
> + while (ip < ip_bound) { // TODO: maybe separate a run from the same seg or from
> + // different ones in order to spare ref < ref_limit
> + if (!SAME_PIXEL(*ip, x)) {
> + ip++;
> + break;
> + } else {
> + ip++;
> + len++;
> + }
> + }
> +
> + goto match;
> + } // END RLE MATCH
> + }
> +
> + /* find potential match */
> + HASH_FUNC(hval, ip);
> +
> +#ifdef CHAINED_HASH
> + for (hash_id = 0; hash_id < HASH_CHAIN_SIZE; hash_id++) {
> + ref_seg_idx = encoder->dict->htab[hval][hash_id].image_seg_idx;
> +#else
> + ref_seg_idx = encoder->dict->htab[hval].image_seg_idx;
> +#endif
> + ref_seg = encoder->dict->window.segs + ref_seg_idx;
> + if (REF_SEG_IS_VALID(encoder->dict, encoder->id,
> + ref_seg, seg)) {
> +#ifdef CHAINED_HASH
> + ref = ((PIXEL *)ref_seg->lines) + encoder->dict->htab[hval][hash_id].ref_pix_idx;
> +#else
> + ref = ((PIXEL *)ref_seg->lines) + encoder->dict->htab[hval].ref_pix_idx;
> +#endif
> + ref_limit = (PIXEL *)ref_seg->lines_end;
> +
> + len = FNAME(do_match)(encoder->dict, ref_seg, ref, ref_limit, seg, ip, ip_bound,
> +#ifdef LZ_PLT
> + pix_per_byte,
> +#endif
> + &image_dist, &pix_dist);
> +
> +#ifdef CHAINED_HASH
> + // TODO. not compare len but rather len - encode_size
> + if (len > best_len) {
> + best_len = len;
> + best_pix_dist = pix_dist;
> + best_image_dist = image_dist;
> + }
> +#endif
> + }
> +
> +#ifdef CHAINED_HASH
> + } // end chain loop
> + len = best_len;
> + pix_dist = best_pix_dist;
> + image_dist = best_image_dist;
> +#endif
> +
> + /* update hash table */
> + UPDATE_HASH(encoder->dict, hval, seg_idx, anchor - ((PIXEL *)seg->lines));
> +
> + if (!len) {
> + goto literal;
> + }
> +
> +match: // RLE or dictionary (both are encoded by distance from ref (-1) and length)
> +#ifdef DEBUG_ENCODE
> + printf(", match(%d, %d, %d)", image_dist, pix_dist, len);
> + n_encoded += len;
> +#endif
> +
> + /* distance is biased */
> + if (!image_dist) {
> + pix_dist--;
> + }
> +
> + /* 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 = anchor + len - 2;
> +
> +#if defined(LZ_RGB16)
> + len--;
> +#elif defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
> + len -= 2;
> +#endif
> + GLZ_ASSERT(encoder->usr, len > 0);
> + encode_match(encoder, image_dist, pix_dist, len);
> +
> + /* update the hash at match boundary */
> +#if defined(LZ_RGB16) || defined(LZ_RGB24) || defined(LZ_RGB32)
> + if (ip > anchor) {
> +#endif
> + HASH_FUNC(hval, ip);
> + UPDATE_HASH(encoder->dict, hval, seg_idx, ip - ((PIXEL *)seg->lines));
> + ip++;
> +#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);
> + UPDATE_HASH(encoder->dict, hval, seg_idx, ip - ((PIXEL *)seg->lines));
> + ip++;
> +#if defined(LZ_RGB24) || defined(LZ_RGB32)
> + } else {
> + ip++;
> + }
> +#endif
> + /* assuming literal copy */
> + encode_copy_count(encoder, MAX_COPY - 1);
> + continue;
> +
> +literal:
> +#ifdef DEBUG_ENCODE
> + printf(", copy");
> + n_encoded++;
> +#endif
> + 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) {
> +#ifdef DEBUG_ENCODE
> + printf(", copy");
> + n_encoded++;
> +#endif
> + 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);
> + }
> +#ifdef DEBUG_ENCODE
> + printf("\ntotal encoded=%d\n", n_encoded);
> +#endif
> +}
> +
> +
> +/* 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)
> +{
> + uint32_t seg_id = encoder->cur_image.first_win_seg;
> + PIXEL *ip;
> + SharedDictionary *dict = encoder->dict;
> + int hval;
> +
> + // fetch the first image segment that is not too small
> + while ((seg_id != NULL_IMAGE_SEG_ID) &&
> + (dict->window.segs[seg_id].image->id == encoder->cur_image.id) &&
> + ((((PIXEL *)dict->window.segs[seg_id].lines_end) -
> + ((PIXEL *)dict->window.segs[seg_id].lines)) < 4)) {
> + // coping the segment
> + if (dict->window.segs[seg_id].lines != dict->window.segs[seg_id].lines_end) {
> + ip = (PIXEL *)dict->window.segs[seg_id].lines;
> + // Note: we assume MAX_COPY > 3
> + encode_copy_count(encoder, (uint8_t)(
> + (((PIXEL *)dict->window.segs[seg_id].lines_end) -
> + ((PIXEL *)dict->window.segs[seg_id].lines)) - 1));
> + while (ip < (PIXEL *)dict->window.segs[seg_id].lines_end) {
> + ENCODE_PIXEL(encoder, *ip);
> + ip++;
> + }
> + }
> + seg_id = dict->window.segs[seg_id].next;
> + }
> +
> + if ((seg_id == NULL_IMAGE_SEG_ID) ||
> + (dict->window.segs[seg_id].image->id != encoder->cur_image.id)) {
> + return;
> + }
> +
> + ip = (PIXEL *)dict->window.segs[seg_id].lines;
> +
> +
> + encode_copy_count(encoder, MAX_COPY - 1);
> +
> + HASH_FUNC(hval, ip);
> + UPDATE_HASH(encoder->dict, hval, seg_id, 0);
> +
> + ENCODE_PIXEL(encoder, *ip);
> + ip++;
> + ENCODE_PIXEL(encoder, *ip);
> + ip++;
> +#ifdef DEBUG_ENCODE
> + printf("copy, copy");
> +#endif
> + // compressing the first segment
> + FNAME(compress_seg)(encoder, seg_id, ip, 2);
> +
> + // compressing the next segments
> + for (seg_id = dict->window.segs[seg_id].next;
> + seg_id != NULL_IMAGE_SEG_ID && (
> + dict->window.segs[seg_id].image->id == encoder->cur_image.id);
> + seg_id = dict->window.segs[seg_id].next) {
> + FNAME(compress_seg)(encoder, seg_id, (PIXEL *)dict->window.segs[seg_id].lines, 0);
> + }
> +}
> +
> +#undef FNAME
> +#undef PIXEL_ID
> +#undef PIXEL_DIST
> +#undef PIXEL
> +#undef ENCODE_PIXEL
> +#undef SAME_PIXEL
> +#undef HASH_FUNC
> +#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 MIN_REF_ENCODE_SIZE
> +#undef MAX_REF_ENCODE_SIZE
> diff --git a/server/glz_encode_match_tmpl.c b/server/glz_encode_match_tmpl.c
> deleted file mode 100644
> index 1fd251e..0000000
> --- a/server/glz_encode_match_tmpl.c
> +++ /dev/null
> @@ -1,154 +0,0 @@
> -/*
> - 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 HAVE_CONFIG_H
> -#include <config.h>
> -#endif
> -
> -#define SHORT_PIX_IMAGE_DIST_LEVEL_1 64 //(1 << 6)
> -#define SHORT_PIX_IMAGE_DIST_LEVEL_2 16384 // (1 << 14)
> -#define SHORT_PIX_IMAGE_DIST_LEVEL_3 4194304 // (1 << 22)
> -#define FAR_PIX_IMAGE_DIST_LEVEL_1 256 // (1 << 8)
> -#define FAR_PIX_IMAGE_DIST_LEVEL_2 65536 // (1 << 16)
> -#define FAR_PIX_IMAGE_DIST_LEVEL_3 16777216 // (1 << 24)
> -
> -/* if image_distance = 0, pixel_distance is the distance between the matching pixels.
> - Otherwise, it is the offset from the beginning of the referred image */
> -#if defined(GLZ_ENCODE_MATCH) /* actually performing the encoding */
> -static inline void encode_match(Encoder *encoder, uint32_t image_distance,
> - size_t pixel_distance, size_t len)
> -#elif defined(GLZ_ENCODE_SIZE) /* compute the size of the encoding except for the match length*/
> -static inline int get_encode_ref_size(uint32_t image_distance, size_t pixel_distance)
> -#endif
> -{
> -#if defined(GLZ_ENCODE_SIZE)
> - int encode_size;
> -#endif
> -
> -#if defined(GLZ_ENCODE_MATCH)
> - /* encoding the match length + Long/Short dist bit + 12 LSB pixels of pixel_distance*/
> - if (len < 7) {
> - if (pixel_distance < MAX_PIXEL_SHORT_DISTANCE) {
> - encode(encoder, (uint8_t)((len << 5) + (pixel_distance & 0x0f)));
> - } else {
> - encode(encoder, (uint8_t)((len << 5) + 16 + (pixel_distance & 0x0f)));
> - }
> - encode(encoder, (uint8_t)((pixel_distance >> 4) & 255));
> - } else {
> - if (pixel_distance < MAX_PIXEL_SHORT_DISTANCE) {
> - encode(encoder, (uint8_t)((7 << 5) + (pixel_distance & 0x0f)));
> - } else {
> - encode(encoder, (uint8_t)((7 << 5) + 16 + (pixel_distance & 0x0f)));
> - }
> - for (len -= 7; len >= 255; len -= 255) {
> - encode(encoder, 255);
> - }
> - encode(encoder, (uint8_t)len);
> - encode(encoder, (uint8_t)((pixel_distance >> 4) & 255));
> - }
> -#endif
> -
> -
> - /* encoding the rest of the pixel distance and the image_dist and its 2 control bits */
> -
> - /* The first 2 MSB bits indicate how many more bytes should be read for image dist */
> - if (pixel_distance < MAX_PIXEL_SHORT_DISTANCE) {
> - if (image_distance < SHORT_PIX_IMAGE_DIST_LEVEL_1) {
> -#if defined(GLZ_ENCODE_MATCH)
> - encode(encoder, (uint8_t)(image_distance & 0x3f));
> -#elif defined(GLZ_ENCODE_SIZE)
> - encode_size = 3;
> -#endif
> - } else if (image_distance < SHORT_PIX_IMAGE_DIST_LEVEL_2) {
> -#if defined(GLZ_ENCODE_MATCH)
> - encode(encoder, (uint8_t)((1 << 6) + (image_distance & 0x3f)));
> - encode(encoder, (uint8_t)((image_distance >> 6) & 255));
> -#elif defined(GLZ_ENCODE_SIZE)
> - encode_size = 4;
> -#endif
> - } else if (image_distance < SHORT_PIX_IMAGE_DIST_LEVEL_3) {
> -#if defined(GLZ_ENCODE_MATCH)
> - encode(encoder, (uint8_t)((1 << 7) + (image_distance & 0x3f)));
> - encode(encoder, (uint8_t)((image_distance >> 6) & 255));
> - encode(encoder, (uint8_t)((image_distance >> 14) & 255));
> -#elif defined(GLZ_ENCODE_SIZE)
> - encode_size = 5;
> -#endif
> - } else {
> -#if defined(GLZ_ENCODE_MATCH)
> - encode(encoder, (uint8_t)((1 << 7) + (1 << 6) + (image_distance & 0x3f)));
> - encode(encoder, (uint8_t)((image_distance >> 6) & 255));
> - encode(encoder, (uint8_t)((image_distance >> 14) & 255));
> - encode(encoder, (uint8_t)((image_distance >> 22) & 255));
> -#elif defined(GLZ_ENCODE_SIZE)
> - encode_size = 6;
> -#endif
> - }
> - } else {
> - /* the third MSB bit indicates if the pixel_distance is medium/long*/
> - uint8_t long_dist_control = (pixel_distance < MAX_PIXEL_MEDIUM_DISTANCE) ? 0 : 32;
> - if (image_distance == 0) {
> -#if defined(GLZ_ENCODE_MATCH)
> - encode(encoder, (uint8_t)(long_dist_control + ((pixel_distance >> 12) & 31)));
> -#elif defined(GLZ_ENCODE_SIZE)
> - encode_size = 3;
> -#endif
> - } else if (image_distance < FAR_PIX_IMAGE_DIST_LEVEL_1) {
> -#if defined(GLZ_ENCODE_MATCH)
> - encode(encoder,
> - (uint8_t)(long_dist_control + (1 << 6) + ((pixel_distance >> 12) & 31)));
> - encode(encoder, (uint8_t)(image_distance & 255));
> -#elif defined(GLZ_ENCODE_SIZE)
> - encode_size = 4;
> -#endif
> - } else if (image_distance < FAR_PIX_IMAGE_DIST_LEVEL_2) {
> -#if defined(GLZ_ENCODE_MATCH)
> - encode(encoder,
> - (uint8_t)(long_dist_control + (1 << 7) + ((pixel_distance >> 12) & 31)));
> - encode(encoder, (uint8_t)(image_distance & 255));
> - encode(encoder, (uint8_t)((image_distance >> 8) & 255));
> -#elif defined(GLZ_ENCODE_SIZE)
> - encode_size = 5;
> -#endif
> - } else {
> -#if defined(GLZ_ENCODE_MATCH)
> - encode(encoder,
> - (uint8_t)(long_dist_control + (1 << 7) + (1 << 6) +
> - ((pixel_distance >> 12) & 31)));
> - encode(encoder, (uint8_t)(image_distance & 255));
> - encode(encoder, (uint8_t)((image_distance >> 8) & 255));
> - encode(encoder, (uint8_t)((image_distance >> 16) & 255));
> -#elif defined(GLZ_ENCODE_SIZE)
> - encode_size = 6;
> -#endif
> - }
> -
> - if (long_dist_control) {
> -#if defined(GLZ_ENCODE_MATCH)
> - encode(encoder, (uint8_t)((pixel_distance >> 17) & 255));
> -#elif defined(GLZ_ENCODE_SIZE)
> - encode_size++;
> -#endif
> - }
> - }
> -
> -#if defined(GLZ_ENCODE_SIZE)
> - return encode_size;
> -#endif
> -}
> -
> -#undef GLZ_ENCODE_SIZE
> -#undef GLZ_ENCODE_MATCH
> diff --git a/server/glz_encode_tmpl.c b/server/glz_encode_tmpl.c
> deleted file mode 100644
> index 46dd1d4..0000000
> --- a/server/glz_encode_tmpl.c
> +++ /dev/null
> @@ -1,574 +0,0 @@
> -/*
> - 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 HAVE_CONFIG_H
> -#include <config.h>
> -#endif
> -
> -#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) glz_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 MIN_REF_ENCODE_SIZE 4
> -#define MAX_REF_ENCODE_SIZE 7
> -#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) glz_rgb_alpha_##name
> -#define ENCODE_PIXEL(e, pix) {encode(e, (pix).pad);}
> -#define SAME_PIXEL(pix1, pix2) ((pix1).pad == (pix2).pad)
> -#define MIN_REF_ENCODE_SIZE 4
> -#define MAX_REF_ENCODE_SIZE 7
> -#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) glz_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 MIN_REF_ENCODE_SIZE 2
> -#define MAX_REF_ENCODE_SIZE 3
> -#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) glz_rgb24_##name
> -#define ENCODE_PIXEL(e, pix) {encode(e, (pix).b); encode(e, (pix).g); encode(e, (pix).r);}
> -#define MIN_REF_ENCODE_SIZE 2
> -#define MAX_REF_ENCODE_SIZE 2
> -#endif
> -
> -#ifdef LZ_RGB32
> -#define PIXEL rgb32_pixel_t
> -#define FNAME(name) glz_rgb32_##name
> -#define ENCODE_PIXEL(e, pix) {encode(e, (pix).b); encode(e, (pix).g); encode(e, (pix).r);}
> -#define MIN_REF_ENCODE_SIZE 2
> -#define MAX_REF_ENCODE_SIZE 2
> -#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
> -
> -#ifndef LZ_PLT
> -#define PIXEL_ID(pix_ptr, seg_ptr) \
> - ((pix_ptr) - ((PIXEL *)(seg_ptr)->lines) + (seg_ptr)->pixels_so_far)
> -#define PIXEL_DIST(src_pix_ptr, src_seg_ptr, ref_pix_ptr, ref_seg_ptr) \
> - (PIXEL_ID(src_pix_ptr,src_seg_ptr) - PIXEL_ID(ref_pix_ptr, ref_seg_ptr))
> -#else
> -#define PIXEL_ID(pix_ptr, seg_ptr, pix_per_byte) \
> - (((pix_ptr) - ((PIXEL *)(seg_ptr)->lines)) * pix_per_byte + (seg_ptr)->pixels_so_far)
> -#define PIXEL_DIST(src_pix_ptr, src_seg_ptr, ref_pix_ptr, ref_seg_ptr, pix_per_byte) \
> - ((PIXEL_ID(src_pix_ptr,src_seg_ptr, pix_per_byte) - \
> - PIXEL_ID(ref_pix_ptr, ref_seg_ptr, pix_per_byte)) / pix_per_byte)
> -#endif
> -
> -/* returns the length of the match. 0 if no match.
> - if image_distance = 0, pixel_distance is the distance between the matching pixels.
> - Otherwise, it is the offset from the beginning of the referred image */
> -static inline size_t FNAME(do_match)(SharedDictionary *dict,
> - WindowImageSegment *ref_seg, const PIXEL *ref,
> - const PIXEL *ref_limit,
> - WindowImageSegment *ip_seg, const PIXEL *ip,
> - const PIXEL *ip_limit,
> -#ifdef LZ_PLT
> - int pix_per_byte,
> -#endif
> - size_t *o_image_dist, size_t *o_pix_distance)
> -{
> - int encode_size;
> - const PIXEL *tmp_ip = ip;
> - const PIXEL *tmp_ref = ref;
> -
> - if (ref > (ref_limit - MIN_REF_ENCODE_SIZE)) {
> - return 0; // in case the hash entry is not relevant
> - }
> -
> -
> - /* min match length == MIN_REF_ENCODE_SIZE (depends on pixel type) */
> -
> - if (!SAME_PIXEL(*tmp_ref, *tmp_ip)) {
> - return 0;
> - } else {
> - tmp_ref++;
> - tmp_ip++;
> - }
> -
> -
> - if (!SAME_PIXEL(*tmp_ref, *tmp_ip)) {
> - return 0;
> - } else {
> - tmp_ref++;
> - tmp_ip++;
> - }
> -
> -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
> - if (!SAME_PIXEL(*tmp_ref, *tmp_ip)) {
> - return 0;
> - } else {
> - tmp_ref++;
> - tmp_ip++;
> - }
> -
> -
> - if (!SAME_PIXEL(*tmp_ref, *tmp_ip)) {
> - return 0;
> - } else {
> - tmp_ref++;
> - tmp_ip++;
> - }
> -
> -#endif
> -
> -
> - *o_image_dist = ip_seg->image->id - ref_seg->image->id;
> -
> - if (!(*o_image_dist)) { // the ref is inside the same image - encode distance
> -#ifndef LZ_PLT
> - *o_pix_distance = PIXEL_DIST(ip, ip_seg, ref, ref_seg);
> -#else
> - // in bytes
> - *o_pix_distance = PIXEL_DIST(ip, ip_seg, ref, ref_seg, pix_per_byte);
> -#endif
> - } else { // the ref is at different image - encode offset from the image start
> -#ifndef LZ_PLT
> - *o_pix_distance = PIXEL_DIST(ref, ref_seg,
> - (PIXEL *)(dict->window.segs[ref_seg->image->first_seg].lines),
> - &dict->window.segs[ref_seg->image->first_seg]
> - );
> -#else
> - // in bytes
> - *o_pix_distance = PIXEL_DIST(ref, ref_seg,
> - (PIXEL *)(dict->window.segs[ref_seg->image->first_seg].lines),
> - &dict->window.segs[ref_seg->image->first_seg],
> - pix_per_byte);
> -#endif
> - }
> -
> - if ((*o_pix_distance == 0) || (*o_pix_distance >= MAX_PIXEL_LONG_DISTANCE) ||
> - (*o_image_dist > MAX_IMAGE_DIST)) {
> - return 0;
> - }
> -
> -
> - /* continue the match*/
> - while ((tmp_ip < ip_limit) && (tmp_ref < ref_limit)) {
> - if (!SAME_PIXEL(*tmp_ref, *tmp_ip)) {
> - break;
> - } else {
> - tmp_ref++;
> - tmp_ip++;
> - }
> - }
> -
> -
> - if ((tmp_ip - ip) > MAX_REF_ENCODE_SIZE) {
> - return (tmp_ip - ip);
> - }
> -
> - encode_size = get_encode_ref_size(*o_image_dist, *o_pix_distance);
> -
> - // min number of identical pixels for a match
> -#if defined(LZ_RGB16)
> - encode_size /= 2;
> -#elif defined(LZ_RGB24) || defined(LZ_RGB32)
> - encode_size /= 3;
> -#endif
> -
> - encode_size++; // the minimum match
> - // match len is smaller than the encoding - not worth encoding
> - if ((tmp_ip - ip) < encode_size) {
> - return 0;
> - }
> - return (tmp_ip - ip);
> -}
> -
> -/* compresses one segment starting from 'from'.
> - In order to encode a match, we use pixels resolution when we encode RGB image,
> - and bytes count when we encode PLT.
> -*/
> -static void FNAME(compress_seg)(Encoder *encoder, uint32_t seg_idx, PIXEL *from, int copied)
> -{
> - WindowImageSegment *seg = &encoder->dict->window.segs[seg_idx];
> - const PIXEL *ip = from;
> - const PIXEL *ip_bound = (PIXEL *)(seg->lines_end) - BOUND_OFFSET;
> - const PIXEL *ip_limit = (PIXEL *)(seg->lines_end) - LIMIT_OFFSET;
> - int hval;
> - int copy = copied;
> -#ifdef LZ_PLT
> - int pix_per_byte = PLT_PIXELS_PER_BYTE[encoder->cur_image.type];
> -#endif
> -
> -#ifdef DEBUG_ENCODE
> - int n_encoded = 0;
> -#endif
> -
> - if (copy == 0) {
> - encode_copy_count(encoder, MAX_COPY - 1);
> - }
> -
> -
> - while (LZ_EXPECT_CONDITIONAL(ip < ip_limit)) {
> - const PIXEL *ref;
> - const PIXEL *ref_limit;
> - WindowImageSegment *ref_seg;
> - uint32_t ref_seg_idx;
> - size_t pix_dist;
> - size_t image_dist;
> - /* minimum match length */
> - size_t len = 0;
> -
> - /* comparison starting-point */
> - const PIXEL *anchor = ip;
> -#ifdef CHAINED_HASH
> - int hash_id = 0;
> - size_t best_len = 0;
> - size_t best_pix_dist = 0;
> - size_t best_image_dist = 0;
> -#endif
> -
> - /* check for a run */
> -
> - 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])) {
> - PIXEL x;
> - pix_dist = 1;
> - image_dist = 0;
> -
> - ip += 3;
> - ref = anchor + 2;
> - ref_limit = (PIXEL *)(seg->lines_end);
> - len = 3;
> -
> - x = *ref;
> -
> - while (ip < ip_bound) { // TODO: maybe separate a run from the same seg or from
> - // different ones in order to spare ref < ref_limit
> - if (!SAME_PIXEL(*ip, x)) {
> - ip++;
> - break;
> - } else {
> - ip++;
> - len++;
> - }
> - }
> -
> - goto match;
> - } // END RLE MATCH
> - }
> -
> - /* find potential match */
> - HASH_FUNC(hval, ip);
> -
> -#ifdef CHAINED_HASH
> - for (hash_id = 0; hash_id < HASH_CHAIN_SIZE; hash_id++) {
> - ref_seg_idx = encoder->dict->htab[hval][hash_id].image_seg_idx;
> -#else
> - ref_seg_idx = encoder->dict->htab[hval].image_seg_idx;
> -#endif
> - ref_seg = encoder->dict->window.segs + ref_seg_idx;
> - if (REF_SEG_IS_VALID(encoder->dict, encoder->id,
> - ref_seg, seg)) {
> -#ifdef CHAINED_HASH
> - ref = ((PIXEL *)ref_seg->lines) + encoder->dict->htab[hval][hash_id].ref_pix_idx;
> -#else
> - ref = ((PIXEL *)ref_seg->lines) + encoder->dict->htab[hval].ref_pix_idx;
> -#endif
> - ref_limit = (PIXEL *)ref_seg->lines_end;
> -
> - len = FNAME(do_match)(encoder->dict, ref_seg, ref, ref_limit, seg, ip, ip_bound,
> -#ifdef LZ_PLT
> - pix_per_byte,
> -#endif
> - &image_dist, &pix_dist);
> -
> -#ifdef CHAINED_HASH
> - // TODO. not compare len but rather len - encode_size
> - if (len > best_len) {
> - best_len = len;
> - best_pix_dist = pix_dist;
> - best_image_dist = image_dist;
> - }
> -#endif
> - }
> -
> -#ifdef CHAINED_HASH
> - } // end chain loop
> - len = best_len;
> - pix_dist = best_pix_dist;
> - image_dist = best_image_dist;
> -#endif
> -
> - /* update hash table */
> - UPDATE_HASH(encoder->dict, hval, seg_idx, anchor - ((PIXEL *)seg->lines));
> -
> - if (!len) {
> - goto literal;
> - }
> -
> -match: // RLE or dictionary (both are encoded by distance from ref (-1) and length)
> -#ifdef DEBUG_ENCODE
> - printf(", match(%d, %d, %d)", image_dist, pix_dist, len);
> - n_encoded += len;
> -#endif
> -
> - /* distance is biased */
> - if (!image_dist) {
> - pix_dist--;
> - }
> -
> - /* 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 = anchor + len - 2;
> -
> -#if defined(LZ_RGB16)
> - len--;
> -#elif defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
> - len -= 2;
> -#endif
> - GLZ_ASSERT(encoder->usr, len > 0);
> - encode_match(encoder, image_dist, pix_dist, len);
> -
> - /* update the hash at match boundary */
> -#if defined(LZ_RGB16) || defined(LZ_RGB24) || defined(LZ_RGB32)
> - if (ip > anchor) {
> -#endif
> - HASH_FUNC(hval, ip);
> - UPDATE_HASH(encoder->dict, hval, seg_idx, ip - ((PIXEL *)seg->lines));
> - ip++;
> -#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);
> - UPDATE_HASH(encoder->dict, hval, seg_idx, ip - ((PIXEL *)seg->lines));
> - ip++;
> -#if defined(LZ_RGB24) || defined(LZ_RGB32)
> - } else {
> - ip++;
> - }
> -#endif
> - /* assuming literal copy */
> - encode_copy_count(encoder, MAX_COPY - 1);
> - continue;
> -
> -literal:
> -#ifdef DEBUG_ENCODE
> - printf(", copy");
> - n_encoded++;
> -#endif
> - 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) {
> -#ifdef DEBUG_ENCODE
> - printf(", copy");
> - n_encoded++;
> -#endif
> - 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);
> - }
> -#ifdef DEBUG_ENCODE
> - printf("\ntotal encoded=%d\n", n_encoded);
> -#endif
> -}
> -
> -
> -/* 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)
> -{
> - uint32_t seg_id = encoder->cur_image.first_win_seg;
> - PIXEL *ip;
> - SharedDictionary *dict = encoder->dict;
> - int hval;
> -
> - // fetch the first image segment that is not too small
> - while ((seg_id != NULL_IMAGE_SEG_ID) &&
> - (dict->window.segs[seg_id].image->id == encoder->cur_image.id) &&
> - ((((PIXEL *)dict->window.segs[seg_id].lines_end) -
> - ((PIXEL *)dict->window.segs[seg_id].lines)) < 4)) {
> - // coping the segment
> - if (dict->window.segs[seg_id].lines != dict->window.segs[seg_id].lines_end) {
> - ip = (PIXEL *)dict->window.segs[seg_id].lines;
> - // Note: we assume MAX_COPY > 3
> - encode_copy_count(encoder, (uint8_t)(
> - (((PIXEL *)dict->window.segs[seg_id].lines_end) -
> - ((PIXEL *)dict->window.segs[seg_id].lines)) - 1));
> - while (ip < (PIXEL *)dict->window.segs[seg_id].lines_end) {
> - ENCODE_PIXEL(encoder, *ip);
> - ip++;
> - }
> - }
> - seg_id = dict->window.segs[seg_id].next;
> - }
> -
> - if ((seg_id == NULL_IMAGE_SEG_ID) ||
> - (dict->window.segs[seg_id].image->id != encoder->cur_image.id)) {
> - return;
> - }
> -
> - ip = (PIXEL *)dict->window.segs[seg_id].lines;
> -
> -
> - encode_copy_count(encoder, MAX_COPY - 1);
> -
> - HASH_FUNC(hval, ip);
> - UPDATE_HASH(encoder->dict, hval, seg_id, 0);
> -
> - ENCODE_PIXEL(encoder, *ip);
> - ip++;
> - ENCODE_PIXEL(encoder, *ip);
> - ip++;
> -#ifdef DEBUG_ENCODE
> - printf("copy, copy");
> -#endif
> - // compressing the first segment
> - FNAME(compress_seg)(encoder, seg_id, ip, 2);
> -
> - // compressing the next segments
> - for (seg_id = dict->window.segs[seg_id].next;
> - seg_id != NULL_IMAGE_SEG_ID && (
> - dict->window.segs[seg_id].image->id == encoder->cur_image.id);
> - seg_id = dict->window.segs[seg_id].next) {
> - FNAME(compress_seg)(encoder, seg_id, (PIXEL *)dict->window.segs[seg_id].lines, 0);
> - }
> -}
> -
> -#undef FNAME
> -#undef PIXEL_ID
> -#undef PIXEL_DIST
> -#undef PIXEL
> -#undef ENCODE_PIXEL
> -#undef SAME_PIXEL
> -#undef HASH_FUNC
> -#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 MIN_REF_ENCODE_SIZE
> -#undef MAX_REF_ENCODE_SIZE
> diff --git a/server/glz_encoder.c b/server/glz_encoder.c
> index d9d6be1..65f4478 100644
> --- a/server/glz_encoder.c
> +++ b/server/glz_encoder.c
> @@ -203,24 +203,24 @@ typedef uint16_t rgb16_pixel_t;
>
>
> #define GLZ_ENCODE_SIZE
> -#include "glz_encode_match_tmpl.c"
> +#include "glz-encode-match.tmpl.c"
> #define GLZ_ENCODE_MATCH
> -#include "glz_encode_match_tmpl.c"
> +#include "glz-encode-match.tmpl.c"
>
> #define LZ_PLT
> -#include "glz_encode_tmpl.c"
> +#include "glz-encode.tmpl.c"
>
> #define LZ_RGB16
> -#include "glz_encode_tmpl.c"
> +#include "glz-encode.tmpl.c"
>
> #define LZ_RGB24
> -#include "glz_encode_tmpl.c"
> +#include "glz-encode.tmpl.c"
>
> #define LZ_RGB32
> -#include "glz_encode_tmpl.c"
> +#include "glz-encode.tmpl.c"
>
> #define LZ_RGB_ALPHA
> -#include "glz_encode_tmpl.c"
> +#include "glz-encode.tmpl.c"
>
>
> int glz_encode(GlzEncoderContext *opaque_encoder,
> diff --git a/server/red_bitmap_utils_tmpl.c b/server/red_bitmap_utils_tmpl.c
> deleted file mode 100644
> index 35f8227..0000000
> --- a/server/red_bitmap_utils_tmpl.c
> +++ /dev/null
> @@ -1,160 +0,0 @@
> -/*
> - 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 HAVE_CONFIG_H
> -#include <config.h>
> -#endif
> -
> -#ifdef RED_BITMAP_UTILS_RGB16
> -#define PIXEL rgb16_pixel_t
> -#define FNAME(name) name##_rgb16
> -#define GET_r(pix) (((pix) >> 10) & 0x1f)
> -#define GET_g(pix) (((pix) >> 5) & 0x1f)
> -#define GET_b(pix) ((pix) & 0x1f)
> -#endif
> -
> -#if defined(RED_BITMAP_UTILS_RGB24) || defined(RED_BITMAP_UTILS_RGB32)
> -#define GET_r(pix) ((pix).r)
> -#define GET_g(pix) ((pix).g)
> -#define GET_b(pix) ((pix).b)
> -#endif
> -
> -#ifdef RED_BITMAP_UTILS_RGB24
> -#define PIXEL rgb24_pixel_t
> -#define FNAME(name) name##_rgb24
> -#endif
> -
> -#ifdef RED_BITMAP_UTILS_RGB32
> -#define PIXEL rgb32_pixel_t
> -#define FNAME(name) name##_rgb32
> -#endif
> -
> -
> -#define SAME_PIXEL_WEIGHT 0.5
> -#define NOT_CONTRAST_PIXELS_WEIGHT -0.25
> -#define CONTRAST_PIXELS_WEIGHT 1.0
> -
> -#ifndef RED_BITMAP_UTILS_RGB16
> -#define CONTRAST_TH 60
> -#else
> -#define CONTRAST_TH 8
> -#endif
> -#define CONTRASTING(n) ((n) <= -CONTRAST_TH || (n) >= CONTRAST_TH)
> -
> -
> -#define SAMPLE_JUMP 15
> -
> -static const double FNAME(PIX_PAIR_SCORE)[] = {
> - SAME_PIXEL_WEIGHT,
> - CONTRAST_PIXELS_WEIGHT,
> - NOT_CONTRAST_PIXELS_WEIGHT,
> -};
> -
> -// return 0 - equal, 1 - for contrast, 2 for no contrast (PIX_PAIR_SCORE is defined accordingly)
> -static inline int FNAME(pixelcmp)(PIXEL p1, PIXEL p2)
> -{
> - int diff, any_different;
> -
> - diff = GET_r(p1) - GET_r(p2);
> - any_different = diff;
> - if (CONTRASTING(diff)) {
> - return 1;
> - }
> -
> - diff = GET_g(p1) - GET_g(p2);
> - any_different |= diff;
> - if (CONTRASTING(diff)) {
> - return 1;
> - }
> -
> - diff = GET_b(p1) - GET_b(p2);
> - any_different |= diff;
> - if (CONTRASTING(diff)) {
> - return 1;
> - }
> -
> - if (!any_different) {
> - return 0;
> - } else {
> - return 2;
> - }
> -}
> -
> -static inline double FNAME(pixels_square_score)(PIXEL *line1, PIXEL *line2)
> -{
> - double ret;
> - int any_different = 0;
> - int cmp_res;
> - cmp_res = FNAME(pixelcmp)(*line1, line1[1]);
> - any_different |= cmp_res;
> - ret = FNAME(PIX_PAIR_SCORE)[cmp_res];
> - cmp_res = FNAME(pixelcmp)(*line1, *line2);
> - any_different |= cmp_res;
> - ret += FNAME(PIX_PAIR_SCORE)[cmp_res];
> - cmp_res = FNAME(pixelcmp)(*line1, line2[1]);
> - any_different |= cmp_res;
> - ret += FNAME(PIX_PAIR_SCORE)[cmp_res];
> -
> - // ignore squares where all pixels are identical
> - if (!any_different) {
> - ret = 0;
> - }
> -
> - return ret;
> -}
> -
> -static void FNAME(compute_lines_gradual_score)(PIXEL *lines, int width, int num_lines,
> - double *o_samples_sum_score, int *o_num_samples)
> -{
> - int jump = (SAMPLE_JUMP % width) ? SAMPLE_JUMP : SAMPLE_JUMP - 1;
> - PIXEL *cur_pix = lines + width / 2;
> - PIXEL *bottom_pix;
> - PIXEL *last_line = lines + (num_lines - 1) * width;
> -
> - if ((width <= 1) || (num_lines <= 1)) {
> - *o_num_samples = 1;
> - *o_samples_sum_score = 1.0;
> - return;
> - }
> -
> - *o_samples_sum_score = 0;
> - *o_num_samples = 0;
> -
> - while (cur_pix < last_line) {
> - if ((cur_pix + 1 - lines) % width == 0) { // last pixel in the row
> - cur_pix--; // jump is bigger than 1 so we will not enter endless loop
> - }
> - bottom_pix = cur_pix + width;
> - (*o_samples_sum_score) += FNAME(pixels_square_score)(cur_pix, bottom_pix);
> - (*o_num_samples)++;
> - cur_pix += jump;
> - }
> -
> - (*o_num_samples) *= 3;
> -}
> -
> -#undef PIXEL
> -#undef FNAME
> -#undef GET_r
> -#undef GET_g
> -#undef GET_b
> -#undef RED_BITMAP_UTILS_RGB16
> -#undef RED_BITMAP_UTILS_RGB24
> -#undef RED_BITMAP_UTILS_RGB32
> -#undef SAMPLE_JUMP
> -#undef CONTRAST_TH
> -#undef SAME_PIXEL_WEIGHT
> -#undef NOT_CONTRAST_PIXELS_WEIGHT
> diff --git a/server/spice-bitmap-utils.c b/server/spice-bitmap-utils.c
> index c4ec625..03d7694 100644
> --- a/server/spice-bitmap-utils.c
> +++ b/server/spice-bitmap-utils.c
> @@ -21,11 +21,11 @@
> #include "spice-bitmap-utils.h"
>
> #define RED_BITMAP_UTILS_RGB16
> -#include "red_bitmap_utils_tmpl.c"
> +#include "spice-bitmap-utils.tmpl.c"
> #define RED_BITMAP_UTILS_RGB24
> -#include "red_bitmap_utils_tmpl.c"
> +#include "spice-bitmap-utils.tmpl.c"
> #define RED_BITMAP_UTILS_RGB32
> -#include "red_bitmap_utils_tmpl.c"
> +#include "spice-bitmap-utils.tmpl.c"
>
> #define GRADUAL_HIGH_RGB24_TH -0.03
> #define GRADUAL_HIGH_RGB16_TH 0
> diff --git a/server/spice-bitmap-utils.tmpl.c b/server/spice-bitmap-utils.tmpl.c
> new file mode 100644
> index 0000000..35f8227
> --- /dev/null
> +++ b/server/spice-bitmap-utils.tmpl.c
> @@ -0,0 +1,160 @@
> +/*
> + 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 HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#ifdef RED_BITMAP_UTILS_RGB16
> +#define PIXEL rgb16_pixel_t
> +#define FNAME(name) name##_rgb16
> +#define GET_r(pix) (((pix) >> 10) & 0x1f)
> +#define GET_g(pix) (((pix) >> 5) & 0x1f)
> +#define GET_b(pix) ((pix) & 0x1f)
> +#endif
> +
> +#if defined(RED_BITMAP_UTILS_RGB24) || defined(RED_BITMAP_UTILS_RGB32)
> +#define GET_r(pix) ((pix).r)
> +#define GET_g(pix) ((pix).g)
> +#define GET_b(pix) ((pix).b)
> +#endif
> +
> +#ifdef RED_BITMAP_UTILS_RGB24
> +#define PIXEL rgb24_pixel_t
> +#define FNAME(name) name##_rgb24
> +#endif
> +
> +#ifdef RED_BITMAP_UTILS_RGB32
> +#define PIXEL rgb32_pixel_t
> +#define FNAME(name) name##_rgb32
> +#endif
> +
> +
> +#define SAME_PIXEL_WEIGHT 0.5
> +#define NOT_CONTRAST_PIXELS_WEIGHT -0.25
> +#define CONTRAST_PIXELS_WEIGHT 1.0
> +
> +#ifndef RED_BITMAP_UTILS_RGB16
> +#define CONTRAST_TH 60
> +#else
> +#define CONTRAST_TH 8
> +#endif
> +#define CONTRASTING(n) ((n) <= -CONTRAST_TH || (n) >= CONTRAST_TH)
> +
> +
> +#define SAMPLE_JUMP 15
> +
> +static const double FNAME(PIX_PAIR_SCORE)[] = {
> + SAME_PIXEL_WEIGHT,
> + CONTRAST_PIXELS_WEIGHT,
> + NOT_CONTRAST_PIXELS_WEIGHT,
> +};
> +
> +// return 0 - equal, 1 - for contrast, 2 for no contrast (PIX_PAIR_SCORE is defined accordingly)
> +static inline int FNAME(pixelcmp)(PIXEL p1, PIXEL p2)
> +{
> + int diff, any_different;
> +
> + diff = GET_r(p1) - GET_r(p2);
> + any_different = diff;
> + if (CONTRASTING(diff)) {
> + return 1;
> + }
> +
> + diff = GET_g(p1) - GET_g(p2);
> + any_different |= diff;
> + if (CONTRASTING(diff)) {
> + return 1;
> + }
> +
> + diff = GET_b(p1) - GET_b(p2);
> + any_different |= diff;
> + if (CONTRASTING(diff)) {
> + return 1;
> + }
> +
> + if (!any_different) {
> + return 0;
> + } else {
> + return 2;
> + }
> +}
> +
> +static inline double FNAME(pixels_square_score)(PIXEL *line1, PIXEL *line2)
> +{
> + double ret;
> + int any_different = 0;
> + int cmp_res;
> + cmp_res = FNAME(pixelcmp)(*line1, line1[1]);
> + any_different |= cmp_res;
> + ret = FNAME(PIX_PAIR_SCORE)[cmp_res];
> + cmp_res = FNAME(pixelcmp)(*line1, *line2);
> + any_different |= cmp_res;
> + ret += FNAME(PIX_PAIR_SCORE)[cmp_res];
> + cmp_res = FNAME(pixelcmp)(*line1, line2[1]);
> + any_different |= cmp_res;
> + ret += FNAME(PIX_PAIR_SCORE)[cmp_res];
> +
> + // ignore squares where all pixels are identical
> + if (!any_different) {
> + ret = 0;
> + }
> +
> + return ret;
> +}
> +
> +static void FNAME(compute_lines_gradual_score)(PIXEL *lines, int width, int num_lines,
> + double *o_samples_sum_score, int *o_num_samples)
> +{
> + int jump = (SAMPLE_JUMP % width) ? SAMPLE_JUMP : SAMPLE_JUMP - 1;
> + PIXEL *cur_pix = lines + width / 2;
> + PIXEL *bottom_pix;
> + PIXEL *last_line = lines + (num_lines - 1) * width;
> +
> + if ((width <= 1) || (num_lines <= 1)) {
> + *o_num_samples = 1;
> + *o_samples_sum_score = 1.0;
> + return;
> + }
> +
> + *o_samples_sum_score = 0;
> + *o_num_samples = 0;
> +
> + while (cur_pix < last_line) {
> + if ((cur_pix + 1 - lines) % width == 0) { // last pixel in the row
> + cur_pix--; // jump is bigger than 1 so we will not enter endless loop
> + }
> + bottom_pix = cur_pix + width;
> + (*o_samples_sum_score) += FNAME(pixels_square_score)(cur_pix, bottom_pix);
> + (*o_num_samples)++;
> + cur_pix += jump;
> + }
> +
> + (*o_num_samples) *= 3;
> +}
> +
> +#undef PIXEL
> +#undef FNAME
> +#undef GET_r
> +#undef GET_g
> +#undef GET_b
> +#undef RED_BITMAP_UTILS_RGB16
> +#undef RED_BITMAP_UTILS_RGB24
> +#undef RED_BITMAP_UTILS_RGB32
> +#undef SAMPLE_JUMP
> +#undef CONTRAST_TH
> +#undef SAME_PIXEL_WEIGHT
> +#undef NOT_CONTRAST_PIXELS_WEIGHT
> --
> 2.4.3
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
Acked-by: Fabiano Fidêncio <fidencio at redhat.com>
--
Fabiano Fidêncio
More information about the Spice-devel
mailing list