On Wed, Nov 25, 2015 at 4:27 PM, Frediano Ziglio <fziglio@xxxxxxxxxx> wrote: > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > > Signed-off-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> > --- > 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@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel Acked-by: Fabiano Fidêncio <fidencio@xxxxxxxxxx> -- Fabiano Fidêncio _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel