summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2014-05-12 00:23:19 +0300
committerAlon Levy <alevy@redhat.com>2014-05-12 00:23:19 +0300
commiteeb3a4c9ef56e3142dcbfbb254b97f2b87a249bc (patch)
tree3523773161490269a23a2c5fc94b4e32445f6c73
parente3da0c4f01f16e504d48793bb9a5b37b65fa345e (diff)
move glz to spice-commonglz
-rw-r--r--server/Makefile.am6
-rw-r--r--server/glz_encode_match_tmpl.c154
-rw-r--r--server/glz_encode_tmpl.c574
-rw-r--r--server/glz_encoder.c310
-rw-r--r--server/glz_encoder.h55
-rw-r--r--server/glz_encoder_config.h61
-rw-r--r--server/glz_encoder_dictionary.c633
-rw-r--r--server/glz_encoder_dictionary.h69
-rw-r--r--server/glz_encoder_dictionary_protected.h186
-rw-r--r--server/migration_protocol.h2
-rw-r--r--server/red_memslots.c12
-rw-r--r--server/red_worker.c4
m---------spice-common0
13 files changed, 15 insertions, 2051 deletions
diff --git a/server/Makefile.am b/server/Makefile.am
index 34219c80..b7175584 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -50,12 +50,6 @@ libspice_server_la_SOURCES = \
char_device.c \
char_device.h \
demarshallers.h \
- glz_encoder.c \
- glz_encoder.h \
- glz_encoder_config.h \
- glz_encoder_dictionary.c \
- glz_encoder_dictionary.h \
- glz_encoder_dictionary_protected.h \
inputs_channel.c \
inputs_channel.h \
jpeg_encoder.c \
diff --git a/server/glz_encode_match_tmpl.c b/server/glz_encode_match_tmpl.c
deleted file mode 100644
index b793e7f0..00000000
--- 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 1402f953..00000000
--- 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
deleted file mode 100644
index 1ec1f9bd..00000000
--- a/server/glz_encoder.c
+++ /dev/null
@@ -1,310 +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
-
-#include <pthread.h>
-#include <stdio.h>
-#include "glz_encoder.h"
-#include "glz_encoder_dictionary_protected.h"
-
-
-/* Holds a specific data for one encoder, and data that is relevant for the current image encoded */
-typedef struct Encoder {
- GlzEncoderUsrContext *usr;
- uint8_t id;
- SharedDictionary *dict;
-
- struct {
- LzImageType type;
- uint32_t id;
- uint32_t first_win_seg;
- } cur_image;
-
- struct {
- uint8_t *start;
- uint8_t *now;
- uint8_t *end;
- size_t bytes_count;
- uint8_t *last_copy; // pointer to the last byte in which copy count was written
- } io;
-} Encoder;
-
-
-/**************************************************************************
-* Handling writing the encoded image to the output buffer
-***************************************************************************/
-static INLINE int more_io_bytes(Encoder *encoder)
-{
- uint8_t *io_ptr;
- int num_io_bytes = encoder->usr->more_space(encoder->usr, &io_ptr);
- encoder->io.bytes_count += num_io_bytes;
- encoder->io.now = io_ptr;
- encoder->io.end = encoder->io.now + num_io_bytes;
- return num_io_bytes;
-}
-
-static INLINE void encode(Encoder *encoder, uint8_t byte)
-{
- if (encoder->io.now == encoder->io.end) {
- if (more_io_bytes(encoder) <= 0) {
- encoder->usr->error(encoder->usr, "%s: no more bytes\n", __FUNCTION__);
- }
- GLZ_ASSERT(encoder->usr, encoder->io.now);
- }
-
- GLZ_ASSERT(encoder->usr, encoder->io.now < encoder->io.end);
- *(encoder->io.now++) = byte;
-}
-
-static INLINE void encode_32(Encoder *encoder, unsigned int word)
-{
- encode(encoder, (uint8_t)(word >> 24));
- encode(encoder, (uint8_t)(word >> 16) & 0x0000ff);
- encode(encoder, (uint8_t)(word >> 8) & 0x0000ff);
- encode(encoder, (uint8_t)(word & 0x0000ff));
-}
-
-static INLINE void encode_64(Encoder *encoder, uint64_t word)
-{
- encode_32(encoder, (uint32_t)(word >> 32));
- encode_32(encoder, (uint32_t)(word & 0xffffff));
-}
-
-static INLINE void encode_copy_count(Encoder *encoder, uint8_t copy_count)
-{
- encode(encoder, copy_count);
- encoder->io.last_copy = encoder->io.now - 1; // io_now cannot be the first byte of the buffer
-}
-
-static INLINE void update_copy_count(Encoder *encoder, uint8_t copy_count)
-{
- GLZ_ASSERT(encoder->usr, encoder->io.last_copy);
- *(encoder->io.last_copy) = copy_count;
-}
-
-// decrease the io ptr by 1
-static INLINE void compress_output_prev(Encoder *encoder)
-{
- // io_now cannot be the first byte of the buffer
- encoder->io.now--;
- // the function should be called only when copy count is written unnecessarily by glz_compress
- GLZ_ASSERT(encoder->usr, encoder->io.now == encoder->io.last_copy)
-}
-
-static int encoder_reset(Encoder *encoder, uint8_t *io_ptr, uint8_t *io_ptr_end)
-{
- GLZ_ASSERT(encoder->usr, io_ptr <= io_ptr_end);
- encoder->io.bytes_count = io_ptr_end - io_ptr;
- encoder->io.start = io_ptr;
- encoder->io.now = io_ptr;
- encoder->io.end = io_ptr_end;
- encoder->io.last_copy = NULL;
-
- return TRUE;
-}
-
-/**********************************************************
-* Encoding
-***********************************************************/
-
-GlzEncoderContext *glz_encoder_create(uint8_t id, GlzEncDictContext *dictionary,
- GlzEncoderUsrContext *usr)
-{
- Encoder *encoder;
-
- if (!usr || !usr->error || !usr->warn || !usr->info || !usr->malloc ||
- !usr->free || !usr->more_space) {
- return NULL;
- }
-
- if (!(encoder = (Encoder *)usr->malloc(usr, sizeof(Encoder)))) {
- return NULL;
- }
-
- encoder->id = id;
- encoder->usr = usr;
- encoder->dict = (SharedDictionary *)dictionary;
-
- return (GlzEncoderContext *)encoder;
-}
-
-void glz_encoder_destroy(GlzEncoderContext *opaque_encoder)
-{
- Encoder *encoder = (Encoder *)opaque_encoder;
-
- if (!opaque_encoder) {
- return;
- }
-
- encoder->usr->free(encoder->usr, encoder);
-}
-
-/*
- * Give hints to the compiler for branch prediction optimization.
- */
-#if defined(__GNUC__) && (__GNUC__ > 2)
-#define LZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
-#define LZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
-#else
-#define LZ_EXPECT_CONDITIONAL(c) (c)
-#define LZ_UNEXPECT_CONDITIONAL(c) (c)
-#endif
-
-
-typedef uint8_t BYTE;
-
-typedef struct __attribute__ ((__packed__)) one_byte_pixel_t {
- BYTE a;
-} one_byte_pixel_t;
-
-typedef struct __attribute__ ((__packed__)) rgb32_pixel_t {
- BYTE b;
- BYTE g;
- BYTE r;
- BYTE pad;
-} rgb32_pixel_t;
-
-typedef struct __attribute__ ((__packed__)) rgb24_pixel_t {
- BYTE b;
- BYTE g;
- BYTE r;
-} rgb24_pixel_t;
-
-typedef uint16_t rgb16_pixel_t;
-
-#define BOUND_OFFSET 2
-#define LIMIT_OFFSET 6
-#define MIN_FILE_SIZE 4
-
-#define MAX_PIXEL_SHORT_DISTANCE 4096 // (1 << 12)
-#define MAX_PIXEL_MEDIUM_DISTANCE 131072 // (1 << 17) 2 ^ (12 + 5)
-#define MAX_PIXEL_LONG_DISTANCE 33554432 // (1 << 25) 2 ^ (12 + 5 + 8)
-#define MAX_IMAGE_DIST 16777215 // (1 << 24 - 1)
-
-
-//#define DEBUG_ENCODE
-
-
-#define GLZ_ENCODE_SIZE
-#include "glz_encode_match_tmpl.c"
-#define GLZ_ENCODE_MATCH
-#include "glz_encode_match_tmpl.c"
-
-#define LZ_PLT
-#include "glz_encode_tmpl.c"
-
-#define LZ_RGB16
-#include "glz_encode_tmpl.c"
-
-#define LZ_RGB24
-#include "glz_encode_tmpl.c"
-
-#define LZ_RGB32
-#include "glz_encode_tmpl.c"
-
-#define LZ_RGB_ALPHA
-#include "glz_encode_tmpl.c"
-
-
-int glz_encode(GlzEncoderContext *opaque_encoder,
- LzImageType type, int width, int height, int top_down,
- uint8_t *lines, unsigned int num_lines, int stride,
- uint8_t *io_ptr, unsigned int num_io_bytes,
- GlzUsrImageContext *usr_context, GlzEncDictImageContext **o_enc_dict_context)
-{
- Encoder *encoder = (Encoder *)opaque_encoder;
- WindowImage *dict_image;
- uint8_t *io_ptr_end = io_ptr + num_io_bytes;
- uint32_t win_head_image_dist;
-
- if (IS_IMAGE_TYPE_PLT[type]) {
- if (stride > (width / PLT_PIXELS_PER_BYTE[type])) {
- if (((width % PLT_PIXELS_PER_BYTE[type]) == 0) || (
- (stride - (width / PLT_PIXELS_PER_BYTE[type])) > 1)) {
- encoder->usr->error(encoder->usr, "stride overflows (plt)\n");
- }
- }
- } else {
- if (stride != width * RGB_BYTES_PER_PIXEL[type]) {
- encoder->usr->error(encoder->usr, "stride != width*bytes_per_pixel (rgb)\n");
- }
- }
-
- // assign the output buffer
- if (!encoder_reset(encoder, io_ptr, io_ptr_end)) {
- encoder->usr->error(encoder->usr, "lz encoder io reset failed\n");
- }
-
- // first read the list of the image segments into the dictionary window
- dict_image = glz_dictionary_pre_encode(encoder->id, encoder->usr,
- encoder->dict, type, width, height, stride,
- lines, num_lines, usr_context, &win_head_image_dist);
- *o_enc_dict_context = (GlzEncDictImageContext *)dict_image;
-
- encoder->cur_image.type = type;
- encoder->cur_image.id = dict_image->id;
- encoder->cur_image.first_win_seg = dict_image->first_seg;
-
- encode_32(encoder, LZ_MAGIC);
- encode_32(encoder, LZ_VERSION);
- if (top_down) {
- encode(encoder, (type & LZ_IMAGE_TYPE_MASK) | (1 << LZ_IMAGE_TYPE_LOG));
- } else {
- encode(encoder, (type & LZ_IMAGE_TYPE_MASK));
- }
-
- encode_32(encoder, width);
- encode_32(encoder, height);
- encode_32(encoder, stride);
- encode_64(encoder, dict_image->id);
- encode_32(encoder, win_head_image_dist);
-
- switch (encoder->cur_image.type) {
- case LZ_IMAGE_TYPE_PLT1_BE:
- case LZ_IMAGE_TYPE_PLT1_LE:
- case LZ_IMAGE_TYPE_PLT4_BE:
- case LZ_IMAGE_TYPE_PLT4_LE:
- case LZ_IMAGE_TYPE_PLT8:
- glz_plt_compress(encoder);
- break;
- case LZ_IMAGE_TYPE_RGB16:
- glz_rgb16_compress(encoder);
- break;
- case LZ_IMAGE_TYPE_RGB24:
- glz_rgb24_compress(encoder);
- break;
- case LZ_IMAGE_TYPE_RGB32:
- glz_rgb32_compress(encoder);
- break;
- case LZ_IMAGE_TYPE_RGBA:
- glz_rgb32_compress(encoder);
- glz_rgb_alpha_compress(encoder);
- break;
- case LZ_IMAGE_TYPE_INVALID:
- default:
- encoder->usr->error(encoder->usr, "bad image type\n");
- }
-
- glz_dictionary_post_encode(encoder->id, encoder->usr, encoder->dict);
-
- // move all the used segments to the free ones
- encoder->io.bytes_count -= (encoder->io.end - encoder->io.now);
-
- return encoder->io.bytes_count;
-}
diff --git a/server/glz_encoder.h b/server/glz_encoder.h
deleted file mode 100644
index 34c363a3..00000000
--- a/server/glz_encoder.h
+++ /dev/null
@@ -1,55 +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/>.
-*/
-
-#ifndef _H_GLZ_ENCODER
-#define _H_GLZ_ENCODER
-
-/* Manging the lz encoding using a dictionary that is shared among encoders */
-
-#include <stdint.h>
-#include "common/lz_common.h"
-#include "glz_encoder_dictionary.h"
-#include "glz_encoder_config.h"
-
-typedef void GlzEncoderContext;
-
-GlzEncoderContext *glz_encoder_create(uint8_t id, GlzEncDictContext *dictionary,
- GlzEncoderUsrContext *usr);
-
-void glz_encoder_destroy(GlzEncoderContext *opaque_encoder);
-
-/*
- assumes width is in pixels and stride is in bytes
- usr_context : when an image is released from the window due to capacity overflow,
- usr_context is given as a parameter to the free_image callback.
- o_enc_dict_context: if glz_enc_dictionary_remove_image is called, it should be
- called with the o_enc_dict_context that is associated with
- the image.
-
- return: the number of bytes in the compressed data and sets o_enc_dict_context
-
- NOTE : currently supports only rgb images in which width*bytes_per_pixel = stride OR
- palette images in which stride equals the min number of bytes to hold a line.
- The stride should be > 0
-*/
-int glz_encode(GlzEncoderContext *opaque_encoder, LzImageType type, int width, int height,
- int top_down, uint8_t *lines, unsigned int num_lines, int stride,
- uint8_t *io_ptr, unsigned int num_io_bytes, GlzUsrImageContext *usr_context,
- GlzEncDictImageContext **o_enc_dict_context);
-
-
-#endif // _H_GLZ_ENCODER
diff --git a/server/glz_encoder_config.h b/server/glz_encoder_config.h
deleted file mode 100644
index 886c68ba..00000000
--- a/server/glz_encoder_config.h
+++ /dev/null
@@ -1,61 +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/>.
-*/
-
-#ifndef _H_GLZ_ENCODER_CONFIG
-#define _H_GLZ_ENCODER_CONFIG
-
-#include <spice/macros.h>
-#include "common/lz_common.h"
-
-typedef void GlzUsrImageContext;
-typedef struct GlzEncoderUsrContext GlzEncoderUsrContext;
-
-struct GlzEncoderUsrContext {
- SPICE_GNUC_PRINTF(2, 3) void (*error)(GlzEncoderUsrContext *usr, const char *fmt, ...);
- SPICE_GNUC_PRINTF(2, 3) void (*warn)(GlzEncoderUsrContext *usr, const char *fmt, ...);
- SPICE_GNUC_PRINTF(2, 3) void (*info)(GlzEncoderUsrContext *usr, const char *fmt, ...);
- void *(*malloc)(GlzEncoderUsrContext *usr, int size);
- void (*free)(GlzEncoderUsrContext *usr, void *ptr);
-
- // get the next chunk of the image which is entered to the dictionary. If the image is down to
- // top, return it from the last line to the first one (stride should always be positive)
- int (*more_lines)(GlzEncoderUsrContext *usr, uint8_t **lines);
-
- // get the next chunk of the compressed buffer.return number of bytes in the chunk.
- int (*more_space)(GlzEncoderUsrContext *usr, uint8_t **io_ptr);
-
- // called when an image is removed from the dictionary, due to the window size limit
- void (*free_image)(GlzEncoderUsrContext *usr, GlzUsrImageContext *image);
-
-};
-
-
-#ifdef DEBUG
-
-#define GLZ_ASSERT(usr, x) \
- if (!(x)) (usr)->error(usr, "%s: ASSERT %s failed\n", __FUNCTION__, #x);
-
-#else
-
-#define GLZ_ASSERT(usr, x)
-
-#endif
-
-#define INLINE inline
-
-
-#endif
diff --git a/server/glz_encoder_dictionary.c b/server/glz_encoder_dictionary.c
deleted file mode 100644
index df346d08..00000000
--- a/server/glz_encoder_dictionary.c
+++ /dev/null
@@ -1,633 +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
-
-#include <pthread.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "glz_encoder_dictionary.h"
-#include "glz_encoder_dictionary_protected.h"
-
-/* turning all used images to free ones. If they are alive, calling the free_image callback for
- each one */
-static INLINE void __glz_dictionary_window_reset_images(SharedDictionary *dict)
-{
- WindowImage *tmp;
-
- while (dict->window.used_images_head) {
- tmp = dict->window.used_images_head;
- dict->window.used_images_head = dict->window.used_images_head->next;
- if (tmp->is_alive) {
- dict->cur_usr->free_image(dict->cur_usr, tmp->usr_context);
- }
- tmp->next = dict->window.free_images;
- tmp->is_alive = FALSE;
- dict->window.free_images = tmp;
- }
- dict->window.used_images_tail = NULL;
-}
-
-/* allocate window fields (no reset)*/
-static int glz_dictionary_window_create(SharedDictionary *dict, uint32_t size)
-{
- if (size > LZ_MAX_WINDOW_SIZE) {
- return FALSE;
- }
-
- dict->window.size_limit = size;
- dict->window.segs = (WindowImageSegment *)(
- dict->cur_usr->malloc(dict->cur_usr, sizeof(WindowImageSegment) * INIT_IMAGE_SEGS_NUM));
-
- if (!dict->window.segs) {
- return FALSE;
- }
-
- dict->window.segs_quota = INIT_IMAGE_SEGS_NUM;
-
- dict->window.encoders_heads = (uint32_t *)dict->cur_usr->malloc(dict->cur_usr,
- sizeof(uint32_t) * dict->max_encoders);
-
- if (!dict->window.encoders_heads) {
- dict->cur_usr->free(dict->cur_usr, dict->window.segs);
- return FALSE;
- }
-
- dict->window.used_images_head = NULL;
- dict->window.used_images_tail = NULL;
- dict->window.free_images = NULL;
- dict->window.pixels_so_far = 0;
-
- return TRUE;
-}
-
-/* initializes an empty window (segs and encoder_heads should be pre allocated.
- resets the image infos, and calls the free_image usr callback*/
-static void glz_dictionary_window_reset(SharedDictionary *dict)
-{
- uint32_t i;
- WindowImageSegment *seg, *last_seg;
-
- last_seg = dict->window.segs + dict->window.segs_quota;
- /* reset free segs list */
- dict->window.free_segs_head = 0;
- for (seg = dict->window.segs, i = 0; seg < last_seg; seg++, i++) {
- seg->next = i + 1;
- seg->image = NULL;
- seg->lines = NULL;
- seg->lines_end = NULL;
- seg->pixels_num = 0;
- seg->pixels_so_far = 0;
- }
- dict->window.segs[dict->window.segs_quota - 1].next = NULL_IMAGE_SEG_ID;
-
- dict->window.used_segs_head = NULL_IMAGE_SEG_ID;
- dict->window.used_segs_tail = NULL_IMAGE_SEG_ID;
-
- // reset encoders heads
- for (i = 0; i < dict->max_encoders; i++) {
- dict->window.encoders_heads[i] = NULL_IMAGE_SEG_ID;
- }
-
- __glz_dictionary_window_reset_images(dict);
-}
-
-static INLINE void glz_dictionary_reset_hash(SharedDictionary *dict)
-{
- memset(dict->htab, 0, sizeof(HashEntry) * HASH_SIZE * HASH_CHAIN_SIZE);
-#ifdef CHAINED_HASH
- memset(dict->htab_counter, 0, HASH_SIZE * sizeof(uint8_t));
-#endif
-}
-
-static INLINE void glz_dictionary_window_destroy(SharedDictionary *dict)
-{
- __glz_dictionary_window_reset_images(dict);
-
- if (dict->window.segs) {
- dict->cur_usr->free(dict->cur_usr, dict->window.segs);
- dict->window.segs = NULL;
- }
-
- while (dict->window.free_images) {
- WindowImage *tmp = dict->window.free_images;
- dict->window.free_images = tmp->next;
-
- dict->cur_usr->free(dict->cur_usr, tmp);
- }
-
- if (dict->window.encoders_heads) {
- dict->cur_usr->free(dict->cur_usr, dict->window.encoders_heads);
- dict->window.encoders_heads = NULL;
- }
-}
-
-/* logic removal only */
-static INLINE void glz_dictionary_window_kill_image(SharedDictionary *dict, WindowImage *image)
-{
- image->is_alive = FALSE;
-}
-
-GlzEncDictContext *glz_enc_dictionary_create(uint32_t size, uint32_t max_encoders,
- GlzEncoderUsrContext *usr)
-{
- SharedDictionary *dict;
-
- if (!(dict = (SharedDictionary *)usr->malloc(usr,
- sizeof(SharedDictionary)))) {
- return NULL;
- }
-
- dict->cur_usr = usr;
- dict->last_image_id = 0;
- dict->max_encoders = max_encoders;
-
- pthread_mutex_init(&dict->lock, NULL);
- pthread_rwlock_init(&dict->rw_alloc_lock, NULL);
-
- dict->window.encoders_heads = NULL;
-
- // alloc window fields and reset
- if (!glz_dictionary_window_create(dict, size)) {
- dict->cur_usr->free(usr, dict);
- return NULL;
- }
-
- // reset window and hash
- glz_enc_dictionary_reset((GlzEncDictContext *)dict, usr);
-
- return (GlzEncDictContext *)dict;
-}
-
-void glz_enc_dictionary_get_restore_data(GlzEncDictContext *opaque_dict,
- GlzEncDictRestoreData *out_data, GlzEncoderUsrContext *usr)
-{
- SharedDictionary *dict = (SharedDictionary *)opaque_dict;
- dict->cur_usr = usr;
- GLZ_ASSERT(dict->cur_usr, opaque_dict);
- GLZ_ASSERT(dict->cur_usr, out_data);
-
- out_data->last_image_id = dict->last_image_id;
- out_data->max_encoders = dict->max_encoders;
- out_data->size = dict->window.size_limit;
-}
-
-GlzEncDictContext *glz_enc_dictionary_restore(GlzEncDictRestoreData *restore_data,
- GlzEncoderUsrContext *usr)
-{
- if (!restore_data) {
- return NULL;
- }
- SharedDictionary *ret = (SharedDictionary *)glz_enc_dictionary_create(
- restore_data->size, restore_data->max_encoders, usr);
- ret->last_image_id = restore_data->last_image_id;
- return ((GlzEncDictContext *)ret);
-}
-
-void glz_enc_dictionary_reset(GlzEncDictContext *opaque_dict, GlzEncoderUsrContext *usr)
-{
- SharedDictionary *dict = (SharedDictionary *)opaque_dict;
- dict->cur_usr = usr;
- GLZ_ASSERT(dict->cur_usr, opaque_dict);
-
- dict->last_image_id = 0;
- glz_dictionary_window_reset(dict);
- glz_dictionary_reset_hash(dict);
-}
-
-void glz_enc_dictionary_destroy(GlzEncDictContext *opaque_dict, GlzEncoderUsrContext *usr)
-{
- SharedDictionary *dict = (SharedDictionary *)opaque_dict;
-
- if (!opaque_dict) {
- return;
- }
-
- dict->cur_usr = usr;
- glz_dictionary_window_destroy(dict);
-
- pthread_mutex_destroy(&dict->lock);
- pthread_rwlock_destroy(&dict->rw_alloc_lock);
-
- dict->cur_usr->free(dict->cur_usr, dict);
-}
-
-uint32_t glz_enc_dictionary_get_size(GlzEncDictContext *opaque_dict)
-{
- SharedDictionary *dict = (SharedDictionary *)opaque_dict;
-
- if (!opaque_dict) {
- return 0;
- }
- return dict->window.size_limit;
-}
-
-/* doesn't call the remove image callback */
-void glz_enc_dictionary_remove_image(GlzEncDictContext *opaque_dict,
- GlzEncDictImageContext *opaque_image,
- GlzEncoderUsrContext *usr)
-{
- SharedDictionary *dict = (SharedDictionary *)opaque_dict;
- WindowImage *image = (WindowImage *)opaque_image;
- dict->cur_usr = usr;
- GLZ_ASSERT(dict->cur_usr, opaque_image && opaque_dict);
-
- glz_dictionary_window_kill_image(dict, image);
-}
-
-/***********************************************************************************
- Mutators of the window. Should be called by the encoder before and after encoding.
- ***********************************************************************************/
-
-static INLINE int __get_pixels_num(LzImageType image_type, unsigned int num_lines, int stride)
-{
- if (IS_IMAGE_TYPE_RGB[image_type]) {
- return num_lines * stride / RGB_BYTES_PER_PIXEL[image_type];
- } else {
- return num_lines * stride * PLT_PIXELS_PER_BYTE[image_type];
- }
-}
-
-static void __glz_dictionary_window_segs_realloc(SharedDictionary *dict)
-{
- WindowImageSegment *new_segs;
- uint32_t new_quota = (MAX_IMAGE_SEGS_NUM < (dict->window.segs_quota * 2)) ?
- MAX_IMAGE_SEGS_NUM : (dict->window.segs_quota * 2);
- WindowImageSegment *seg;
- uint32_t i;
-
- pthread_rwlock_wrlock(&dict->rw_alloc_lock);
-
- if (dict->window.segs_quota == MAX_IMAGE_SEGS_NUM) {
- dict->cur_usr->error(dict->cur_usr, "overflow in image segments window\n");
- }
-
- new_segs = (WindowImageSegment*)dict->cur_usr->malloc(
- dict->cur_usr, sizeof(WindowImageSegment) * new_quota);
-
- if (!new_segs) {
- dict->cur_usr->error(dict->cur_usr,
- "realloc of dictionary window failed\n");
- }
-
- memcpy(new_segs, dict->window.segs,
- sizeof(WindowImageSegment) * dict->window.segs_quota);
-
- // reseting the new elements
- for (i = dict->window.segs_quota, seg = new_segs + i; i < new_quota; i++, seg++) {
- seg->image = NULL;
- seg->lines = NULL;
- seg->lines_end = NULL;
- seg->pixels_num = 0;
- seg->pixels_so_far = 0;
- seg->next = i + 1;
- }
- new_segs[new_quota - 1].next = dict->window.free_segs_head;
- dict->window.free_segs_head = dict->window.segs_quota;
-
- dict->cur_usr->free(dict->cur_usr, dict->window.segs);
- dict->window.segs = new_segs;
- dict->window.segs_quota = new_quota;
-
- pthread_rwlock_unlock(&dict->rw_alloc_lock);
-}
-
-/* NOTE - it also updates the used_images_list*/
-static WindowImage *__glz_dictionary_window_alloc_image(SharedDictionary *dict)
-{
- WindowImage *ret;
-
- if (dict->window.free_images) {
- ret = dict->window.free_images;
- dict->window.free_images = ret->next;
- } else {
- if (!(ret = (WindowImage *)dict->cur_usr->malloc(dict->cur_usr,
- sizeof(*ret)))) {
- return NULL;
- }
- }
-
- ret->next = NULL;
- if (dict->window.used_images_tail) {
- dict->window.used_images_tail->next = ret;
- }
- dict->window.used_images_tail = ret;
-
- if (!dict->window.used_images_head) {
- dict->window.used_images_head = ret;
- }
- return ret;
-}
-
-/* NOTE - it doesn't update the used_segs list*/
-static uint32_t __glz_dictionary_window_alloc_image_seg(SharedDictionary *dict)
-{
- uint32_t seg_id;
- WindowImageSegment *seg;
-
- // TODO: when is it best to realloc? when full or when half full?
- if (dict->window.free_segs_head == NULL_IMAGE_SEG_ID) {
- __glz_dictionary_window_segs_realloc(dict);
- }
-
- GLZ_ASSERT(dict->cur_usr, dict->window.free_segs_head != NULL_IMAGE_SEG_ID);
-
- seg_id = dict->window.free_segs_head;
- seg = dict->window.segs + seg_id;
- dict->window.free_segs_head = seg->next;
-
- return seg_id;
-}
-
-/* moves image to free list and "kill" it. Calls the free_image callback if was alive. */
-static INLINE void __glz_dictionary_window_free_image(SharedDictionary *dict, WindowImage *image)
-{
- if (image->is_alive) {
- dict->cur_usr->free_image(dict->cur_usr, image->usr_context);
- }
- image->is_alive = FALSE;
- image->next = dict->window.free_images;
- dict->window.free_images = image;
-}
-
-/* moves all the segments that were associated with the images to the free segments */
-static INLINE void __glz_dictionary_window_free_image_segs(SharedDictionary *dict,
- WindowImage *image)
-{
- uint32_t old_free_head = dict->window.free_segs_head;
- uint32_t seg_id, next_seg_id;
-
- GLZ_ASSERT(dict->cur_usr, image->first_seg != NULL_IMAGE_SEG_ID);
- dict->window.free_segs_head = image->first_seg;
-
- // retrieving the last segment of the image
- for (seg_id = image->first_seg, next_seg_id = dict->window.segs[seg_id].next;
- (next_seg_id != NULL_IMAGE_SEG_ID) && (dict->window.segs[next_seg_id].image == image);
- seg_id = next_seg_id, next_seg_id = dict->window.segs[seg_id].next) {
- }
-
- // concatenate the free list
- dict->window.segs[seg_id].next = old_free_head;
-}
-
-/* Returns the logical head of the window after we add an image with the give size to its tail.
- Returns NULL when the window is empty, of when we have to empty the window in order
- to insert the new image. */
-static WindowImage *glz_dictionary_window_get_new_head(SharedDictionary *dict, int new_image_size)
-{
- uint32_t cur_win_size;
- WindowImage *cur_head;
-
- if ((uint32_t)new_image_size > dict->window.size_limit) {
- dict->cur_usr->error(dict->cur_usr, "image is bigger than window\n");
- }
-
- GLZ_ASSERT(dict->cur_usr, new_image_size < dict->window.size_limit)
-
- // the window is empty
- if (!dict->window.used_images_head) {
- return NULL;
- }
-
- GLZ_ASSERT(dict->cur_usr, dict->window.used_segs_head != NULL_IMAGE_SEG_ID);
- GLZ_ASSERT(dict->cur_usr, dict->window.used_segs_tail != NULL_IMAGE_SEG_ID);
-
- // used_segs_head is the latest logical head (the physical head may preceed it)
- cur_head = dict->window.segs[dict->window.used_segs_head].image;
- cur_win_size = dict->window.segs[dict->window.used_segs_tail].pixels_num +
- dict->window.segs[dict->window.used_segs_tail].pixels_so_far -
- dict->window.segs[dict->window.used_segs_head].pixels_so_far;
-
- while ((cur_win_size + new_image_size) > dict->window.size_limit) {
- GLZ_ASSERT(dict->cur_usr, cur_head);
- cur_win_size -= cur_head->size;
- cur_head = cur_head->next;
- }
-
- return cur_head;
-}
-
-static INLINE int glz_dictionary_is_in_use(SharedDictionary *dict)
-{
- uint32_t i = 0;
- for (i = 0; i < dict->max_encoders; i++) {
- if (dict->window.encoders_heads[i] != NULL_IMAGE_SEG_ID) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/* remove from the window (and free relevant data) the images between the oldest physical head
- (inclusive) and the end_image (exclusive). If end_image is NULL, empties the window*/
-static void glz_dictionary_window_remove_head(SharedDictionary *dict, uint32_t encoder_id,
- WindowImage *end_image)
-{
- // note that the segs list heads (one per encoder) may be different than the
- // used_segs_head and it is updated somewhere else
- while (dict->window.used_images_head != end_image) {
- WindowImage *image = dict->window.used_images_head;
-
- __glz_dictionary_window_free_image_segs(dict, image);
- dict->window.used_images_head = image->next;
- __glz_dictionary_window_free_image(dict, image);
- }
-
- if (!dict->window.used_images_head) {
- dict->window.used_segs_head = NULL_IMAGE_SEG_ID;
- dict->window.used_segs_tail = NULL_IMAGE_SEG_ID;
- dict->window.used_images_tail = NULL;
- } else {
- dict->window.used_segs_head = end_image->first_seg;
- }
-}
-
-static uint32_t glz_dictionary_window_alloc_image_seg(SharedDictionary *dict, WindowImage* image,
- int size, int stride,
- uint8_t *lines, unsigned int num_lines)
-{
- uint32_t seg_id = __glz_dictionary_window_alloc_image_seg(dict);
- WindowImageSegment *seg = &dict->window.segs[seg_id];
-
- seg->image = image;
- seg->lines = lines;
- seg->lines_end = lines + num_lines * stride;
- seg->pixels_num = size;
- seg->pixels_so_far = dict->window.pixels_so_far;
- dict->window.pixels_so_far += seg->pixels_num;
-
- seg->next = NULL_IMAGE_SEG_ID;
-
- return seg_id;
-}
-
-static WindowImage *glz_dictionary_window_add_image(SharedDictionary *dict, LzImageType image_type,
- int image_size, int image_height,
- int image_stride, uint8_t *first_lines,
- unsigned int num_first_lines,
- GlzUsrImageContext *usr_image_context)
-{
- unsigned int num_lines = num_first_lines;
- unsigned int row;
- uint32_t seg_id, prev_seg_id;
- uint8_t* lines = first_lines;
- // alloc image info,update used head tail, if used_head null - update head
- WindowImage *image = __glz_dictionary_window_alloc_image(dict);
- image->id = dict->last_image_id++;
- image->size = image_size;
- image->type = image_type;
- image->usr_context = usr_image_context;
-
- if (num_lines <= 0) {
- num_lines = dict->cur_usr->more_lines(dict->cur_usr, &lines);
- if (num_lines <= 0) {
- dict->cur_usr->error(dict->cur_usr, "more lines failed\n");
- }
- }
-
- for (row = 0;;) {
- seg_id = glz_dictionary_window_alloc_image_seg(dict, image,
- image_size * num_lines / image_height,
- image_stride,
- lines, num_lines);
- if (row == 0) {
- image->first_seg = seg_id;
- } else {
- dict->window.segs[prev_seg_id].next = seg_id;
- }
-
- row += num_lines;
- if (row < (uint32_t)image_height) {
- num_lines = dict->cur_usr->more_lines(dict->cur_usr, &lines);
- if (num_lines <= 0) {
- dict->cur_usr->error(dict->cur_usr, "more lines failed\n");
- }
- } else {
- break;
- }
- prev_seg_id = seg_id;
- }
-
- if (dict->window.used_segs_tail == NULL_IMAGE_SEG_ID) {
- dict->window.used_segs_head = image->first_seg;
- dict->window.used_segs_tail = seg_id;
- } else {
- int prev_tail = dict->window.used_segs_tail;
-
- // The used segs may be in use by another thread which is during encoding
- // (read-only use - when going over the segs of an image,
- // see glz_encode_tmpl::compress).
- // Thus, the 'next' field of the list's tail can be accessed only
- // after all the new tail's data was set. Note that we are relying on
- // an atomic assignment (32 bit variable).
- // For the other thread that may read 'next' of the old tail, NULL_IMAGE_SEG_ID
- // is equivalent to a segment with an image id that is different
- // from the image id of the tail, so we don't need to further protect this field.
- dict->window.segs[prev_tail].next = image->first_seg;
- dict->window.used_segs_tail = seg_id;
- }
- image->is_alive = TRUE;
-
- return image;
-}
-
-WindowImage *glz_dictionary_pre_encode(uint32_t encoder_id, GlzEncoderUsrContext *usr,
- SharedDictionary *dict, LzImageType image_type,
- int image_width, int image_height, int image_stride,
- uint8_t *first_lines, unsigned int num_first_lines,
- GlzUsrImageContext *usr_image_context,
- uint32_t *image_head_dist)
-{
- WindowImage *new_win_head, *ret;
- int image_size;
-
-
- pthread_mutex_lock(&dict->lock);
-
- dict->cur_usr = usr;
- GLZ_ASSERT(dict->cur_usr, dict->window.encoders_heads[encoder_id] == NULL_IMAGE_SEG_ID);
-
- image_size = __get_pixels_num(image_type, image_height, image_stride);
- new_win_head = glz_dictionary_window_get_new_head(dict, image_size);
-
- if (!glz_dictionary_is_in_use(dict)) {
- glz_dictionary_window_remove_head(dict, encoder_id, new_win_head);
- }
-
- ret = glz_dictionary_window_add_image(dict, image_type, image_size, image_height, image_stride,
- first_lines, num_first_lines, usr_image_context);
-
- if (new_win_head) {
- dict->window.encoders_heads[encoder_id] = new_win_head->first_seg;
- *image_head_dist = (uint32_t)(ret->id - new_win_head->id); // shouldn't be greater than 32
- // bit because the window size is
- // limited to 2^25
- } else {
- dict->window.encoders_heads[encoder_id] = ret->first_seg;
- *image_head_dist = 0;
- }
-
-
- // update encoders head (the other heads were already updated)
- pthread_mutex_unlock(&dict->lock);
- pthread_rwlock_rdlock(&dict->rw_alloc_lock);
- return ret;
-}
-
-void glz_dictionary_post_encode(uint32_t encoder_id, GlzEncoderUsrContext *usr,
- SharedDictionary *dict)
-{
- uint32_t i;
- uint32_t early_head_seg = NULL_IMAGE_SEG_ID;
- uint32_t this_encoder_head_seg;
-
- pthread_rwlock_unlock(&dict->rw_alloc_lock);
- pthread_mutex_lock(&dict->lock);
- dict->cur_usr = usr;
-
- GLZ_ASSERT(dict->cur_usr, dict->window.encoders_heads[encoder_id] != NULL_IMAGE_SEG_ID);
- // get the earliest head in use (not including this encoder head)
- for (i = 0; i < dict->max_encoders; i++) {
- if (i != encoder_id) {
- if (IMAGE_SEG_IS_EARLIER(dict, dict->window.encoders_heads[i], early_head_seg)) {
- early_head_seg = dict->window.encoders_heads[i];
- }
- }
- }
-
- // possible only if early_head_seg == NULL
- if (IMAGE_SEG_IS_EARLIER(dict, dict->window.used_segs_head, early_head_seg)) {
- early_head_seg = dict->window.used_segs_head;
- }
-
- this_encoder_head_seg = dict->window.encoders_heads[encoder_id];
-
- GLZ_ASSERT(dict->cur_usr, early_head_seg != NULL_IMAGE_SEG_ID);
-
- if (IMAGE_SEG_IS_EARLIER(dict, this_encoder_head_seg, early_head_seg)) {
- GLZ_ASSERT(dict->cur_usr,
- this_encoder_head_seg == dict->window.used_images_head->first_seg);
- glz_dictionary_window_remove_head(dict, encoder_id,
- dict->window.segs[early_head_seg].image);
- }
-
-
- dict->window.encoders_heads[encoder_id] = NULL_IMAGE_SEG_ID;
- pthread_mutex_unlock(&dict->lock);
-}
diff --git a/server/glz_encoder_dictionary.h b/server/glz_encoder_dictionary.h
deleted file mode 100644
index eb57aa54..00000000
--- a/server/glz_encoder_dictionary.h
+++ /dev/null
@@ -1,69 +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/>.
-*/
-
-#ifndef _H_GLZ_ENCODER_DICTIONARY
-#define _H_GLZ_ENCODER_DICTIONARY
-
-#include <stdint.h>
-#include "glz_encoder_config.h"
-
-/*
- Interface for maintaining lz dictionary that is shared among several encoders.
- The interface for accessing the dictionary for encoding purposes is located in
- glz_encoder_dictionary_protected.h
-*/
-
-typedef void GlzEncDictContext;
-typedef void GlzEncDictImageContext;
-
-/* NOTE: DISPLAY_MIGRATE_DATA_VERSION should change in case GlzEncDictRestoreData changes*/
-typedef struct GlzEncDictRestoreData {
- uint32_t size;
- uint32_t max_encoders;
- uint64_t last_image_id;
-} GlzEncDictRestoreData;
-
-/* size : maximal number of pixels occupying the window
- max_encoders: maximal number of encoders that use the dictionary
- usr : callbacks */
-GlzEncDictContext *glz_enc_dictionary_create(uint32_t size, uint32_t max_encoders,
- GlzEncoderUsrContext *usr);
-
-void glz_enc_dictionary_destroy(GlzEncDictContext *opaque_dict, GlzEncoderUsrContext *usr);
-
-/* returns the window capacity in pixels */
-uint32_t glz_enc_dictionary_get_size(GlzEncDictContext *);
-
-/* returns the current state of the dictionary.
- NOTE - you should use it only when no encoder uses the dictionary. */
-void glz_enc_dictionary_get_restore_data(GlzEncDictContext *opaque_dict,
- GlzEncDictRestoreData *out_data,
- GlzEncoderUsrContext *usr);
-
-/* creates a dictionary and initialized it by use the given info */
-GlzEncDictContext *glz_enc_dictionary_restore(GlzEncDictRestoreData *restore_data,
- GlzEncoderUsrContext *usr);
-
-/* NOTE - you should use this routine only when no encoder uses the dictionary. */
-void glz_enc_dictionary_reset(GlzEncDictContext *opaque_dict, GlzEncoderUsrContext *usr);
-
-/* image: the context returned by the encoder when the image was encoded.
- NOTE - you should use this routine only when no encoder uses the dictionary.*/
-void glz_enc_dictionary_remove_image(GlzEncDictContext *opaque_dict,
- GlzEncDictImageContext *image, GlzEncoderUsrContext *usr);
-
-#endif // _H_GLZ_ENCODER_DICTIONARY
diff --git a/server/glz_encoder_dictionary_protected.h b/server/glz_encoder_dictionary_protected.h
deleted file mode 100644
index ee1f8d8e..00000000
--- a/server/glz_encoder_dictionary_protected.h
+++ /dev/null
@@ -1,186 +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/>.
-*/
-
-#ifndef _H_GLZ_ENCODER_DICTIONARY_PROTECTED
-#define _H_GLZ_ENCODER_DICTIONARY_PROTECTED
-
-/* Interface for using the dictionary for encoding.
- Data structures are exposed for the encoder for efficiency
- purposes. */
-typedef struct WindowImage WindowImage;
-typedef struct WindowImageSegment WindowImageSegment;
-
-
-//#define CHAINED_HASH
-
-#ifdef CHAINED_HASH
-#define HASH_SIZE_LOG 16
-#define HASH_CHAIN_SIZE 4
-#else
-#define HASH_SIZE_LOG 20
-#define HASH_CHAIN_SIZE 1
-#endif
-
-#define HASH_SIZE (1 << HASH_SIZE_LOG)
-#define HASH_MASK (HASH_SIZE - 1)
-
-typedef struct HashEntry HashEntry;
-
-typedef struct SharedDictionary SharedDictionary;
-
-struct WindowImage {
- uint64_t id;
- LzImageType type;
- int size; // in pixels
- uint32_t first_seg;
- GlzUsrImageContext *usr_context;
- WindowImage* next;
- uint8_t is_alive;
-};
-
-#define MAX_IMAGE_SEGS_NUM (0xffffffff)
-#define NULL_IMAGE_SEG_ID MAX_IMAGE_SEGS_NUM
-#define INIT_IMAGE_SEGS_NUM 1000
-
-/* Images can be separated into several chunks. The basic unit of the
- dictionary window is one image segment. Each segment is encoded separately.
- An encoded match can refer to only one segment.*/
-struct WindowImageSegment {
- WindowImage *image;
- uint8_t *lines;
- uint8_t *lines_end;
- uint32_t pixels_num; // Number of pixels in the segment
- uint64_t pixels_so_far; // Total no. pixels passed through the window till this segment.
- // NOTE - never use size delta independently. It should
- // always be used with respect to a previous size delta
- uint32_t next;
-};
-
-
-struct __attribute__ ((__packed__)) HashEntry {
- uint32_t image_seg_idx;
- uint32_t ref_pix_idx;
-};
-
-
-struct SharedDictionary {
- struct {
- /* The segments storage. A dynamic array.
- By referring to a segment by its index, instead of address,
- we save space in the hash entries (32bit instead of 64bit) */
- WindowImageSegment *segs;
- uint32_t segs_quota;
-
- /* The window is manged as a linked list rather than as a cyclic
- array in order to keep the indices of the segments consistent
- after reallocation */
-
- /* the window in a resolution of image segments */
- uint32_t used_segs_head; // the latest head
- uint32_t used_segs_tail;
- uint32_t free_segs_head;
-
- uint32_t *encoders_heads; // Holds for each encoder (by id), the window head when
- // it started the encoding.
- // The head is NULL_IMAGE_SEG_ID when the encoder is
- // not encoding.
-
- /* the window in a resolution of images. But here the head contains the oldest head*/
- WindowImage* used_images_tail;
- WindowImage* used_images_head;
- WindowImage* free_images;
-
- uint64_t pixels_so_far;
- uint32_t size_limit; // max number of pixels in a window (per encoder)
- } window;
-
- /* Concurrency issues: the reading/writing of each entry field should be atomic.
- It is allowed that the reading/writing of the whole entry won't be atomic,
- since before we access a reference we check its validity*/
-#ifdef CHAINED_HASH
- HashEntry htab[HASH_SIZE][HASH_CHAIN_SIZE];
- uint8_t htab_counter[HASH_SIZE]; //cyclic counter for the next entry in a chain to be assigned
-#else
- HashEntry htab[HASH_SIZE];
-#endif
-
- uint64_t last_image_id;
- uint32_t max_encoders;
- pthread_mutex_t lock;
- pthread_rwlock_t rw_alloc_lock;
- GlzEncoderUsrContext *cur_usr; // each encoder has other context.
-};
-
-/*
- Add the image to the tail of the window.
- If possible, release images from the head of the window.
- Also perform concurrency related operations.
-
- usr_image_context: when an image is released from the window due to capacity overflow,
- usr_image_context is given as a parameter to the free_image callback.
-
- image_head_dist : the number of images between the current image and the head of the
- window that is associated with the encoder.
-*/
-WindowImage *glz_dictionary_pre_encode(uint32_t encoder_id, GlzEncoderUsrContext *usr,
- SharedDictionary *dict, LzImageType image_type,
- int image_width, int image_height, int image_stride,
- uint8_t *first_lines, unsigned int num_first_lines,
- GlzUsrImageContext *usr_image_context,
- uint32_t *image_head_dist);
-
-/*
- Performs concurrency related operations.
- If possible, release images from the head of the window.
-*/
-void glz_dictionary_post_encode(uint32_t encoder_id, GlzEncoderUsrContext *usr,
- SharedDictionary *dict);
-
-#define IMAGE_SEG_IS_EARLIER(dict, dst_seg, src_seg) ( \
- ((src_seg) == NULL_IMAGE_SEG_ID) || (((dst_seg) != NULL_IMAGE_SEG_ID) \
- && ((dict)->window.segs[(dst_seg)].pixels_so_far < \
- (dict)->window.segs[(src_seg)].pixels_so_far)))
-
-
-#ifdef CHAINED_HASH
-#define UPDATE_HASH(dict, hval, seg, pix) { \
- uint8_t tmp_count = (dict)->htab_counter[hval]; \
- (dict)->htab[hval][tmp_count].image_seg_idx = seg; \
- (dict)->htab[hval][tmp_count].ref_pix_idx = pix; \
- tmp_count = ((tmp_count) + 1) & (HASH_CHAIN_SIZE - 1); \
- dict->htab_counter[hval] = tmp_count; \
-}
-#else
-#define UPDATE_HASH(dict, hval, seg, pix) { \
- (dict)->htab[hval].image_seg_idx = seg; \
- (dict)->htab[hval].ref_pix_idx = pix; \
-}
-#endif
-
-/* checks if the reference segment is located in the range of the window
- of the current encoder */
-#define REF_SEG_IS_VALID(dict, enc_id, ref_seg, src_seg) ( \
- ((ref_seg) == (src_seg)) || \
- ((ref_seg)->image && \
- (ref_seg)->image->is_alive && \
- (src_seg->image->type == ref_seg->image->type) && \
- (ref_seg->pixels_so_far <= src_seg->pixels_so_far) && \
- ((dict)->window.segs[ \
- (dict)->window.encoders_heads[enc_id]].pixels_so_far <= \
- ref_seg->pixels_so_far)))
-
-#endif // _H_GLZ_ENCODER_DICTIONARY_PROTECTED
diff --git a/server/migration_protocol.h b/server/migration_protocol.h
index fa17c7c4..ad4cca3f 100644
--- a/server/migration_protocol.h
+++ b/server/migration_protocol.h
@@ -19,7 +19,7 @@
#define _H_MIGRATION_PROTOCOL
#include <spice/vd_agent.h>
-#include "glz_encoder_dictionary.h"
+#include "common/glz_encoder_dictionary.h"
/* ************************************************
* src-server to dst-server migration data messages
diff --git a/server/red_memslots.c b/server/red_memslots.c
index 1b3ec622..841ea4c0 100644
--- a/server/red_memslots.c
+++ b/server/red_memslots.c
@@ -118,6 +118,18 @@ unsigned long get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size
*error = 1;
return 0;
}
+ {
+ static int memset_test = -1;
+ uint8_t *start = (uint8_t *)h_virt;
+
+ if (memset_test == -1) {
+ memset_test = (getenv("SPICE_GET_VIRT_MEMSET") != NULL);
+ }
+
+ if (memset_test > 0) {
+ memmove(start, start, add_size);
+ }
+ }
return h_virt;
}
diff --git a/server/red_worker.c b/server/red_worker.c
index 619f7bcc..8c6dd411 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -66,8 +66,8 @@
#include "red_worker.h"
#include "reds_stream.h"
#include "reds_sw_canvas.h"
-#include "glz_encoder_dictionary.h"
-#include "glz_encoder.h"
+#include "common/glz_encoder_dictionary.h"
+#include "common/glz_encoder.h"
#include "stat.h"
#include "reds.h"
#include "mjpeg_encoder.h"
diff --git a/spice-common b/spice-common
-Subproject b3a00f4411962e0c06c7ad89a9936df388aa002
+Subproject 4edc6c0daa0f967445982945d351eab61c68b08