[Spice-commits] server/cache_item.tmpl.c server/cache-item.tmpl.c server/cursor-channel.c server/dcc.c server/glz_encode_match_tmpl.c server/glz-encode-match.tmpl.c server/glz_encoder.c server/glz_encode_tmpl.c server/glz-encode.tmpl.c server/Makefile.am server/red_bitmap_utils_tmpl.c server/spice-bitmap-utils.c server/spice-bitmap-utils.tmpl.c
Frediano Ziglio
fziglio at kemper.freedesktop.org
Thu Nov 26 05:35:21 PST 2015
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(-)
New commits:
commit 82fa233fa6d04ea5a1fd320492a169c77b1c3a94
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date: Mon Sep 30 14:57:10 2013 +0200
server: rename _tmpl files
Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
Acked-by: Fabiano Fidêncio <fidencio at redhat.com>
diff --git a/server/Makefile.am b/server/Makefile.am
index db1cbc3..e52c780 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 6c089da..198c7ab 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -1170,7 +1170,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
More information about the Spice-commits
mailing list