summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2010-06-09 11:40:25 +0200
committerAlexander Larsson <alexl@redhat.com>2010-06-09 11:40:25 +0200
commit263646a1f7e705766f7d46017679812d4b1406b8 (patch)
treebd8056f34c7413e5fb2f66959db085cd6efecdb4 /common
parentea74fc64543ef486085a82aec0c67a3b265ba3ac (diff)
downloadspice-263646a1f7e705766f7d46017679812d4b1406b8.tar.gz
spice-263646a1f7e705766f7d46017679812d4b1406b8.tar.xz
spice-263646a1f7e705766f7d46017679812d4b1406b8.zip
JPEG support: introducing jpeg encoding for spice bitmaps
Diffstat (limited to 'common')
-rw-r--r--common/canvas_base.c82
-rw-r--r--common/canvas_base.h18
-rw-r--r--common/gdi_canvas.c4
-rw-r--r--common/gdi_canvas.h3
-rw-r--r--common/gl_canvas.c2
-rw-r--r--common/gl_canvas.h1
-rw-r--r--common/sw_canvas.c6
-rw-r--r--common/sw_canvas.h2
8 files changed, 115 insertions, 3 deletions
diff --git a/common/canvas_base.c b/common/canvas_base.c
index 9d9c9772..8180f09d 100644
--- a/common/canvas_base.c
+++ b/common/canvas_base.c
@@ -199,6 +199,7 @@ typedef struct CanvasBase {
LzData lz_data;
GlzData glz_data;
+ SpiceJpegDecoder* jpeg;
void *usr_data;
spice_destroy_fn_t usr_data_destroy;
@@ -547,6 +548,78 @@ static pixman_image_t *canvas_get_quic(CanvasBase *canvas, SpiceQUICImage *image
return surface;
}
+
+//#define DUMP_JPEG
+#ifdef DUMP_JPEG
+static int jpeg_id = 0;
+static void dump_jpeg(uint8_t* data, int data_size)
+{
+ char file_str[200];
+ uint32_t id = ++jpeg_id;
+
+#ifdef WIN32
+ sprintf(file_str, "c:\\tmp\\spice_dump\\%u.jpg", id);
+#else
+ sprintf(file_str, "/tmp/spice_dump/%u.jpg", id);
+#endif
+
+ FILE *f = fopen(file_str, "wb");
+ if (!f) {
+ return;
+ }
+
+ fwrite(data, 1, data_size, f);
+ fclose(f);
+}
+#endif
+
+static pixman_image_t *canvas_get_jpeg(CanvasBase *canvas, SpiceJPEGImage *image, int invers)
+{
+ pixman_image_t *surface = NULL;
+ int stride;
+ int width;
+ int height;
+ uint8_t *dest;
+
+ canvas->jpeg->ops->begin_decode(canvas->jpeg, image->jpeg.data, image->jpeg.data_size,
+ &width, &height);
+ ASSERT((uint32_t)width == image->descriptor.width);
+ ASSERT((uint32_t)height == image->descriptor.height);
+
+ surface = surface_create(
+#ifdef WIN32
+ canvas->dc,
+#endif
+ PIXMAN_x8r8g8b8,
+ width, height, FALSE);
+ if (surface == NULL) {
+ CANVAS_ERROR("create surface failed");
+ }
+
+ dest = (uint8_t *)pixman_image_get_data(surface);
+ stride = pixman_image_get_stride(surface);
+
+ canvas->jpeg->ops->decode(canvas->jpeg, dest, stride, SPICE_BITMAP_FMT_32BIT);
+
+ if (invers) {
+ uint8_t *end = dest + height * stride;
+ for (; dest != end; dest += stride) {
+ uint32_t *pix;
+ uint32_t *end_pix;
+
+ pix = (uint32_t *)dest;
+ end_pix = pix + width;
+ for (; pix < end_pix; pix++) {
+ *pix ^= 0x00ffffff;
+ }
+ }
+ }
+#ifdef DUMP_JPEG
+ dump_jpeg(image->jpeg.data, image->jpeg.data_size);
+#endif
+ return surface;
+}
+
static pixman_image_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap* bitmap,
SpicePalette *palette, int want_original)
{
@@ -1001,7 +1074,12 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
break;
}
#endif
-
+ case SPICE_IMAGE_TYPE_JPEG: {
+ SpiceJPEGImage *image = (SpiceJPEGImage *)descriptor;
+ access_test(canvas, descriptor, sizeof(SpiceJPEGImage));
+ surface = canvas_get_jpeg(canvas, image, 0);
+ break;
+ }
#if defined(SW_CANVAS_CACHE)
case SPICE_IMAGE_TYPE_GLZ_RGB: {
access_test(canvas, descriptor, sizeof(SpiceLZRGBImage));
@@ -3234,6 +3312,7 @@ static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops,
#endif
, SpiceImageSurfaces *surfaces
, SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
#ifndef SW_CANVAS_NO_CHUNKS
, SpiceVirtMapping *virt_mapping
#endif
@@ -3267,6 +3346,7 @@ static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops,
#endif
canvas->surfaces = surfaces;
canvas->glz_data.decoder = glz_decoder;
+ canvas->jpeg = jpeg_decoder;
canvas->format = format;
diff --git a/common/canvas_base.h b/common/canvas_base.h
index f78b0b8d..4eaafbbd 100644
--- a/common/canvas_base.h
+++ b/common/canvas_base.h
@@ -31,6 +31,7 @@ typedef struct _SpiceImageCache SpiceImageCache;
typedef struct _SpiceImageSurfaces SpiceImageSurfaces;
typedef struct _SpicePaletteCache SpicePaletteCache;
typedef struct _SpiceGlzDecoder SpiceGlzDecoder;
+typedef struct _SpiceJpegDecoder SpiceJpegDecoder;
typedef struct _SpiceVirtMapping SpiceVirtMapping;
typedef struct _SpiceCanvas SpiceCanvas;
@@ -79,6 +80,23 @@ struct _SpiceGlzDecoder {
SpiceGlzDecoderOps *ops;
};
+
+typedef struct SpiceJpegDecoderOps {
+ void (*begin_decode)(SpiceJpegDecoder *decoder,
+ uint8_t* data,
+ int data_size,
+ int* out_width,
+ int* out_height);
+ void (*decode)(SpiceJpegDecoder *decoder,
+ uint8_t* dest,
+ int stride,
+ int format);
+} SpiceJpegDecoderOps;
+
+struct _SpiceJpegDecoder {
+ SpiceJpegDecoderOps *ops;
+};
+
typedef struct {
void *(*get_virt)(SpiceVirtMapping *mapping, unsigned long addr, uint32_t add_size);
void (*validate_virt)(SpiceVirtMapping *mapping, unsigned long virt,
diff --git a/common/gdi_canvas.c b/common/gdi_canvas.c
index af1de950..d01d9cde 100644
--- a/common/gdi_canvas.c
+++ b/common/gdi_canvas.c
@@ -1866,6 +1866,7 @@ SpiceCanvas *gdi_canvas_create(int width, int height,
#endif
, SpiceImageSurfaces *surfaces
, SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
)
{
GdiCanvas *canvas;
@@ -1884,7 +1885,8 @@ SpiceCanvas *gdi_canvas_create(int width, int height,
, bits_cache
#endif
, surfaces
- , glz_decoder);
+ , glz_decoder
+ , jpeg_decoder);
canvas->dc = dc;
canvas->lock = lock;
return (SpiceCanvas *)canvas;
diff --git a/common/gdi_canvas.h b/common/gdi_canvas.h
index 7af0e02d..02e053d2 100644
--- a/common/gdi_canvas.h
+++ b/common/gdi_canvas.h
@@ -31,7 +31,8 @@ SpiceCanvas *gdi_canvas_create(int width, int height,
SpiceImageCache *bits_cache,
SpicePaletteCache *palette_cache,
SpiceImageSurfaces *surfaces,
- SpiceGlzDecoder *glz_decoder);
+ SpiceGlzDecoder *glz_decoder,
+ SpiceJpegDecoder *jpeg_decoder);
void gdi_canvas_init();
diff --git a/common/gl_canvas.c b/common/gl_canvas.c
index ea10c96e..f98c72a0 100644
--- a/common/gl_canvas.c
+++ b/common/gl_canvas.c
@@ -830,6 +830,7 @@ SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format
#endif
, SpiceImageSurfaces *surfaces
, SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
#ifndef SW_CANVAS_NO_CHUNKS
, SpiceVirtMapping *virt_mapping
#endif
@@ -857,6 +858,7 @@ SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format
#endif
, surfaces
, glz_decoder
+ , jpeg_decoder
#ifndef SW_CANVAS_NO_CHUNKS
, virt_mapping
#endif
diff --git a/common/gl_canvas.h b/common/gl_canvas.h
index 6dd25e92..cd76f8d9 100644
--- a/common/gl_canvas.h
+++ b/common/gl_canvas.h
@@ -30,6 +30,7 @@ SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format
#endif
, SpiceImageSurfaces *surfaces
, SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
#ifndef SW_CANVAS_NO_CHUNKS
, SpiceVirtMapping *virt_mapping
#endif
diff --git a/common/sw_canvas.c b/common/sw_canvas.c
index a541c7df..8280362c 100644
--- a/common/sw_canvas.c
+++ b/common/sw_canvas.c
@@ -1180,6 +1180,7 @@ static SpiceCanvas *canvas_create_common(pixman_image_t *image,
#endif
, SpiceImageSurfaces *surfaces
, SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
#ifndef SW_CANVAS_NO_CHUNKS
, SpiceVirtMapping *virt_mapping
#endif
@@ -1207,6 +1208,7 @@ static SpiceCanvas *canvas_create_common(pixman_image_t *image,
#endif
, surfaces
, glz_decoder
+ , jpeg_decoder
#ifndef SW_CANVAS_NO_CHUNKS
, virt_mapping
#endif
@@ -1228,6 +1230,7 @@ SpiceCanvas *canvas_create(int width, int height, uint32_t format
#endif
, SpiceImageSurfaces *surfaces
, SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
#ifndef SW_CANVAS_NO_CHUNKS
, SpiceVirtMapping *virt_mapping
#endif
@@ -1247,6 +1250,7 @@ SpiceCanvas *canvas_create(int width, int height, uint32_t format
#endif
, surfaces
, glz_decoder
+ , jpeg_decoder
#ifndef SW_CANVAS_NO_CHUNKS
, virt_mapping
#endif
@@ -1263,6 +1267,7 @@ SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format,
#endif
, SpiceImageSurfaces *surfaces
, SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
#ifndef SW_CANVAS_NO_CHUNKS
, SpiceVirtMapping *virt_mapping
#endif
@@ -1282,6 +1287,7 @@ SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format,
#endif
, surfaces
, glz_decoder
+ , jpeg_decoder
#ifndef SW_CANVAS_NO_CHUNKS
, virt_mapping
#endif
diff --git a/common/sw_canvas.h b/common/sw_canvas.h
index c3aef240..63a78630 100644
--- a/common/sw_canvas.h
+++ b/common/sw_canvas.h
@@ -35,6 +35,7 @@ SpiceCanvas *canvas_create(int width, int height, uint32_t format
#endif
, SpiceImageSurfaces *surfaces
, SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
#ifndef SW_CANVAS_NO_CHUNKS
, SpiceVirtMapping *virt_mapping
#endif
@@ -49,6 +50,7 @@ SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format, uint
#endif
, SpiceImageSurfaces *surfaces
, SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
#ifndef SW_CANVAS_NO_CHUNKS
, SpiceVirtMapping *virt_mapping
#endif