JPEG support: introducing jpeg encoding for spice bitmaps

This commit is contained in:
Yonit Halperin 2010-06-09 11:40:25 +02:00 committed by Marc-André Lureau
parent 41171d081d
commit 19bca5b373
8 changed files with 115 additions and 3 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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