On Fri, Jun 15, 2012 at 02:59:24PM -0400, Søren Sandmann wrote: > From: Søren Sandmann Pedersen <ssp@xxxxxxxxxx> > Looks good, one comment below. > This format is needed to add Render support to the X driver, so we > need the ability to compress and decompress it. > --- > common/canvas_base.c | 4 ++++ > common/lz.c | 24 +++++++++++++++++++++++- > common/lz_common.h | 5 +++-- > common/lz_compress_tmpl.c | 28 +++++++++++++++++++++++----- > common/lz_decompress_tmpl.c | 19 ++++++++++++++++++- > common/pixman_utils.c | 15 +++++++++++++++ > spice-protocol | 2 +- > 7 files changed, 87 insertions(+), 10 deletions(-) > > diff --git a/common/canvas_base.c b/common/canvas_base.c > index 4f40306..c60c5cf 100644 > --- a/common/canvas_base.c > +++ b/common/canvas_base.c > @@ -776,6 +776,10 @@ static pixman_image_t *canvas_get_lz(CanvasBase *canvas, SpiceImage *image, int > as_type = LZ_IMAGE_TYPE_RGB32; > pixman_format = PIXMAN_x8r8g8b8; > break; > + case LZ_IMAGE_TYPE_A8: > + as_type = LZ_IMAGE_TYPE_A8; > + pixman_format = PIXMAN_a8; > + break; > case LZ_IMAGE_TYPE_RGB16: > if (!want_original && > (canvas->format == SPICE_SURFACE_FMT_32_xRGB || > diff --git a/common/lz.c b/common/lz.c > index 568aae7..3d77aed 100644 > --- a/common/lz.c > +++ b/common/lz.c > @@ -465,6 +465,13 @@ typedef uint16_t rgb16_pixel_t; > #define TO_RGB32 > #include "lz_decompress_tmpl.c" > > +#define LZ_A8 > +#include "lz_compress_tmpl.c" > +#define LZ_A8 > +#include "lz_decompress_tmpl.c" > +#define LZ_A8 > +#define TO_RGB32 > +#include "lz_decompress_tmpl.c" > > #define LZ_RGB16 > #include "lz_compress_tmpl.c" > @@ -514,7 +521,8 @@ int lz_encode(LzContext *lz, LzImageType type, int width, int height, int top_do > } > } else { > if (encoder->stride != width * RGB_BYTES_PER_PIXEL[encoder->type]) { > - encoder->usr->error(encoder->usr, "stride != width*bytes_per_pixel (rgb)\n"); > + encoder->usr->error(encoder->usr, "stride != width*bytes_per_pixel (rgb) %d %d %d\n", > + encoder->stride, width, RGB_BYTES_PER_PIXEL[encoder->type]); > } > } > > @@ -560,6 +568,9 @@ int lz_encode(LzContext *lz, LzImageType type, int width, int height, int top_do > case LZ_IMAGE_TYPE_XXXA: > lz_rgb_alpha_compress(encoder); > break; > + case LZ_IMAGE_TYPE_A8: > + lz_a8_compress(encoder); > + break; > case LZ_IMAGE_TYPE_INVALID: > default: > encoder->usr->error(encoder->usr, "bad image type\n"); > @@ -709,6 +720,17 @@ void lz_decode(LzContext *lz, LzImageType to_type, uint8_t *buf) > encoder->usr->error(encoder->usr, "unsupported output format\n"); > } > break; > + case LZ_IMAGE_TYPE_A8: > + if (encoder->type == to_type) { > + alpha_size = lz_a8_decompress(encoder, (one_byte_pixel_t *)buf, size); > + out_size = alpha_size; > + } else if (to_type == LZ_IMAGE_TYPE_RGB32) { > + alpha_size = lz_a8_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size); > + out_size = alpha_size; > + } else { > + encoder->usr->error(encoder->usr, "unsupported output format\n"); > + } > + break; > case LZ_IMAGE_TYPE_PLT1_LE: > case LZ_IMAGE_TYPE_PLT1_BE: > case LZ_IMAGE_TYPE_PLT4_LE: > diff --git a/common/lz_common.h b/common/lz_common.h > index 2ec374b..b5ce212 100644 > --- a/common/lz_common.h > +++ b/common/lz_common.h > @@ -44,7 +44,8 @@ typedef enum { > LZ_IMAGE_TYPE_RGB24, > LZ_IMAGE_TYPE_RGB32, > LZ_IMAGE_TYPE_RGBA, > - LZ_IMAGE_TYPE_XXXA > + LZ_IMAGE_TYPE_XXXA, > + LZ_IMAGE_TYPE_A8 > } LzImageType; > > #define LZ_IMAGE_TYPE_MASK 0x0f > @@ -54,7 +55,7 @@ typedef enum { > static const int IS_IMAGE_TYPE_PLT[] = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}; > static const int IS_IMAGE_TYPE_RGB[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}; > static const int PLT_PIXELS_PER_BYTE[] = {0, 8, 8, 2, 2, 1}; > -static const int RGB_BYTES_PER_PIXEL[] = {0, 1, 1, 1, 1, 1, 2, 3, 4, 4, 4}; > +static const int RGB_BYTES_PER_PIXEL[] = {0, 1, 1, 1, 1, 1, 2, 3, 4, 4, 4, 1}; > > > #define LZ_MAGIC (*(uint32_t *)"LZ ") > diff --git a/common/lz_compress_tmpl.c b/common/lz_compress_tmpl.c > index 6db5387..7e2ce42 100644 > --- a/common/lz_compress_tmpl.c > +++ b/common/lz_compress_tmpl.c > @@ -71,6 +71,21 @@ > } > #endif > > +#ifdef LZ_A8 > +#define PIXEL one_byte_pixel_t > +#define FNAME(name) lz_a8_##name > +#define ENCODE_PIXEL(e, pix) encode(e, (pix).a) // gets the pixel and write only the needed bytes > + // from the pixel > +#define SAME_PIXEL(pix1, pix2) ((pix1).a == (pix2).a) > +#define HASH_FUNC(v, p) { \ > + v = DJB2_START; \ > + DJB2_HASH(v, p[0].a); \ > + DJB2_HASH(v, p[1].a); \ > + DJB2_HASH(v, p[2].a); \ > + v &= HASH_MASK; \ > + } > +#endif > + > #ifdef LZ_RGB_ALPHA > //#undef LZ_RGB_ALPHA > #define PIXEL rgb32_pixel_t > @@ -177,7 +192,7 @@ static void FNAME(compress_seg)(Encoder *encoder, LzImageSegment *seg, PIXEL *fr > size_t distance; > > /* minimum match length */ > -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) > +#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_A8) > size_t len = 3; > #elif defined(LZ_RGB16) > size_t len = 2; > @@ -234,7 +249,7 @@ static void FNAME(compress_seg)(Encoder *encoder, LzImageSegment *seg, PIXEL *fr > ip++; > > /* minimum match length for rgb16 is 2 and for plt and alpha is 3 */ > -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_RGB16) > +#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_RGB16) || defined(LZ_A8) > if (!SAME_PIXEL(*ref, *ip)) { > ref++; > ip++; > @@ -244,7 +259,7 @@ static void FNAME(compress_seg)(Encoder *encoder, LzImageSegment *seg, PIXEL *fr > ip++; > #endif > > -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) > +#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_A8) > if (!SAME_PIXEL(*ref, *ip)) { > ref++; > ip++; > @@ -255,7 +270,7 @@ static void FNAME(compress_seg)(Encoder *encoder, LzImageSegment *seg, PIXEL *fr > #endif > /* far, needs at least 5-byte match */ > if (distance >= MAX_DISTANCE) { > -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) > +#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_A8) > if (ref >= (ref_limit - 1)) { > goto literal; > } > @@ -272,7 +287,7 @@ static void FNAME(compress_seg)(Encoder *encoder, LzImageSegment *seg, PIXEL *fr > ref++; > ip++; > len++; > -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) > +#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_A8) > if (!SAME_PIXEL(*ref, *ip)) { > ref++; > ip++; > @@ -464,9 +479,11 @@ static void FNAME(compress)(Encoder *encoder) > LzImageSegment *cur_seg = encoder->head_image_segs; > HashEntry *hslot; > PIXEL *ip; > + PIXEL *ip_start; Is this a debugging left over? I don't see it being used. > > // fetch the first image segment that is not too small > while (cur_seg && ((((PIXEL *)cur_seg->lines_end) - ((PIXEL *)cur_seg->lines)) < 4)) { > + ip_start = cur_seg->lines; > // coping the segment > if (cur_seg->lines != cur_seg->lines_end) { > ip = (PIXEL *)cur_seg->lines; > @@ -526,4 +543,5 @@ static void FNAME(compress)(Encoder *encoder) > #undef LZ_RGB16 > #undef LZ_RGB24 > #undef LZ_RGB32 > +#undef LZ_A8 > #undef HASH_FUNC2 > diff --git a/common/lz_decompress_tmpl.c b/common/lz_decompress_tmpl.c > index fb41e77..04a5121 100644 > --- a/common/lz_decompress_tmpl.c > +++ b/common/lz_decompress_tmpl.c > @@ -153,6 +153,22 @@ > #endif // TO_RGB32 > #endif > > +#ifdef LZ_A8 > +#ifndef TO_RGB32 > +#define OUT_PIXEL one_byte_pixel_t > +#define FNAME(name) lz_a8_##name > +#define COPY_COMP_PIXEL(encoder, out) {out->a = decode(encoder); out++;} > +#else // TO_RGB32 > +#define OUT_PIXEL rgb32_pixel_t > +#define FNAME(name) lz_a8_to_rgb32_##name > +#define COPY_COMP_PIXEL(encoder, out) { \ > + (out)->b = (out)->g = (out)->r = 0; \ > + (out)->pad = decode(encoder); \ > + (out)++; \ > + } > +#endif > +#endif > + > #ifdef LZ_RGB16 > #ifndef TO_RGB32 > #define OUT_PIXEL rgb16_pixel_t > @@ -237,7 +253,7 @@ static size_t FNAME(decompress)(Encoder *encoder, OUT_PIXEL *out_buf, int size) > } > } > > -#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) > +#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_A8) > len += 3; // length is biased by 2 + 1 (fixing bias) > #elif defined(LZ_RGB16) > len += 2; // length is biased by 1 + 1 (fixing bias) > @@ -315,6 +331,7 @@ static size_t FNAME(decompress)(Encoder *encoder, OUT_PIXEL *out_buf, int size) > #undef LZ_RGB16 > #undef LZ_RGB24 > #undef LZ_RGB32 > +#undef LZ_A8 > #undef LZ_RGB_ALPHA > #undef TO_RGB32 > #undef OUT_PIXEL > diff --git a/common/pixman_utils.c b/common/pixman_utils.c > index d4020e6..311c22e 100644 > --- a/common/pixman_utils.c > +++ b/common/pixman_utils.c > @@ -963,6 +963,9 @@ pixman_format_code_t spice_bitmap_format_to_pixman(int bitmap_format, > case SPICE_BITMAP_FMT_RGBA: > return PIXMAN_a8r8g8b8; > > + case SPICE_BITMAP_FMT_8BIT_A: > + return PIXMAN_a8; > + > case SPICE_BITMAP_FMT_INVALID: > default: > printf("Unknown bitmap format %d\n", bitmap_format); > @@ -1083,6 +1086,15 @@ static void bitmap_32_to_32(uint8_t* dest, int dest_stride, > #endif > } > > +static void bitmap_8_to_8(uint8_t* dest, int dest_stride, > + uint8_t* src, int src_stride, > + int width, uint8_t* end) > +{ > + for (; src != end; src += src_stride, dest += dest_stride) { > + memcpy(dest, src, width); > + } > +} > + > static void bitmap_24_to_32(uint8_t* dest, int dest_stride, > uint8_t* src, int src_stride, > int width, uint8_t* end) > @@ -1477,6 +1489,9 @@ pixman_image_t *spice_bitmap_to_pixman(pixman_image_t *dest_image, > case SPICE_BITMAP_FMT_RGBA: > bitmap_32_to_32(dest, dest_stride, src, src_stride, width, end); > break; > + case SPICE_BITMAP_FMT_8BIT_A: > + bitmap_8_to_8(dest, dest_stride, src, src_stride, width, end); > + break; > case SPICE_BITMAP_FMT_24BIT: > bitmap_24_to_32(dest, dest_stride, src, src_stride, width, end); > break; > diff --git a/spice-protocol b/spice-protocol > index bf0daeb..bba7ed7 160000 > --- a/spice-protocol > +++ b/spice-protocol > @@ -1 +1 @@ > -Subproject commit bf0daeb3a3c834133e781439f76b1c702470581b > +Subproject commit bba7ed70380dc702c180d4a16a1e82c2887f9830 > -- > 1.7.4 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel