diff options
author | Javier Celaya <javier.celaya@flexvm.es> | 2015-01-28 11:49:47 +0100 |
---|---|---|
committer | Christophe Fergeau <cfergeau@redhat.com> | 2015-02-03 10:46:34 +0100 |
commit | d167e2ead84b62f7af08a153dc95365910796ae5 (patch) | |
tree | e18a5efed7e4a272b143dc69d0cd3de98194041b /common | |
parent | f76fc28fc54200e1302ca6ffd289d9fc829cc272 (diff) |
LZ4: Fix the row alignment when it is not on a 32bit boundary
Fix the row alignment for 16/24 bpp images when it is not in a 32bit
boundary. This is needed for 16bpp images when the width is an odd
number, and for the future support of 24bpp images.
Diffstat (limited to 'common')
-rw-r--r-- | common/canvas_base.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/common/canvas_base.c b/common/canvas_base.c index d621b39..2f22400 100644 --- a/common/canvas_base.c +++ b/common/canvas_base.c @@ -522,8 +522,7 @@ static pixman_image_t *canvas_get_lz4(CanvasBase *canvas, SpiceImage *image) { pixman_image_t *surface = NULL; int dec_size, enc_size, available; - int stride; - int stride_abs; + int stride, stride_abs, stride_encoded; uint8_t *dest, *data, *data_end; int width, height, top_down; LZ4_streamDecode_t *stream; @@ -534,19 +533,23 @@ static pixman_image_t *canvas_get_lz4(CanvasBase *canvas, SpiceImage *image) data = image->u.lz4.data->chunk[0].data; data_end = data + image->u.lz4.data->chunk[0].len; width = image->descriptor.width; + stride_encoded = width; height = image->descriptor.height; top_down = *(data++); spice_format = *(data++); switch (spice_format) { case SPICE_BITMAP_FMT_16BIT: format = PIXMAN_x1r5g5b5; + stride_encoded *= 2; break; case SPICE_BITMAP_FMT_24BIT: case SPICE_BITMAP_FMT_32BIT: format = PIXMAN_x8r8g8b8; + stride_encoded *= 4; break; case SPICE_BITMAP_FMT_RGBA: format = PIXMAN_a8r8g8b8; + stride_encoded *= 4; break; default: spice_warning("Unsupported bitmap format %d with LZ4\n", spice_format); @@ -590,6 +593,21 @@ static pixman_image_t *canvas_get_lz4(CanvasBase *canvas, SpiceImage *image) data += enc_size; } while (data < data_end); + if (stride_abs > stride_encoded) { + // Fix the row alignment + int row; + dest = (uint8_t *)pixman_image_get_data(surface); + if (!top_down) { + dest -= (stride_abs * (height - 1)); + } + for (row = height - 1; row > 0; --row) { + uint32_t *dest_aligned, *dest_misaligned; + dest_aligned = (uint32_t *)(dest + stride_abs*row); + dest_misaligned = (uint32_t*)(dest + stride_encoded*row); + memmove(dest_aligned, dest_misaligned, stride_encoded); + } + } + LZ4_freeStreamDecode(stream); return surface; } |