--- hw/vga.c | 62 +++++++++++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/hw/vga.c b/hw/vga.c index bb5df70..9f7ca89 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -2422,32 +2422,37 @@ QEMUFile *qemu_fopen_uri(const char *uri, const char *mode) return f; } -int ppm_save(const char *uri, struct DisplaySurface *ds) +static int ppm_line_handler(void *opaque, uint8_t *line, size_t length) { - QEMUFile *f; + QEMUFile *f = opaque; + + qemu_put_buffer(f, line, length); + + return length; +} + +static int screen_dump_lines(struct DisplaySurface *ds, + int (*line_handler) (void *opaque, uint8_t *data, size_t length), + void *opaque) +{ + char *linebuf, *pbuf; uint8_t *d, *d1; uint32_t v; int y, x; uint8_t r, g, b; - char *linebuf, *pbuf; - gchar *header; - - f = qemu_fopen_uri(uri, "wb"); - g_return_val_if_fail(f != NULL, -1); - - header = g_strdup_printf("P6\n%d %d\n%d\n", ds->width, ds->height, 255); - qemu_put_buffer(f, (uint8_t*)header, strlen(header)); + int ret = -1; linebuf = g_malloc(ds->width * 3); d1 = ds->data; - for(y = 0; y < ds->height; y++) { + for (y = 0; y < ds->height; y++) { d = d1; pbuf = linebuf; - for(x = 0; x < ds->width; x++) { - if (ds->pf.bits_per_pixel == 32) + for (x = 0; x < ds->width; x++) { + if (ds->pf.bits_per_pixel == 32) { v = *(uint32_t *)d; - else + } else { v = (uint32_t) (*(uint16_t *)d); + } /* Limited to 8 or fewer bits per channel: */ r = ((v >> ds->pf.rshift) & ds->pf.rmax) << (8 - ds->pf.rbits); g = ((v >> ds->pf.gshift) & ds->pf.gmax) << (8 - ds->pf.gbits); @@ -2458,13 +2463,36 @@ int ppm_save(const char *uri, struct DisplaySurface *ds) d += ds->pf.bytes_per_pixel; } d1 += ds->linesize; - qemu_put_buffer(f, (uint8_t*)linebuf, pbuf - linebuf); + + if (line_handler(opaque, (uint8_t*)linebuf, pbuf - linebuf) < 0) + goto out; } + ret = 0; +out: g_free(linebuf); - g_free(header); + return ret; +} + +int ppm_save(const char *uri, struct DisplaySurface *ds) +{ + QEMUFile *f; + int ret = -1; + + f = qemu_fopen_uri(uri, "wb"); + g_return_val_if_fail(f != NULL, -1); + + { + gchar *header; + header = g_strdup_printf("P6\n%d %d\n%d\n", ds->width, ds->height, 255); + qemu_put_buffer(f, (uint8_t*)header, strlen(header)); + screen_dump_lines(ds, ppm_line_handler, f); + g_free(header); + } + + ret = 0; qemu_fclose(f); - return 0; + return ret; } /* save the vga display in a PPM image even if no display is -- 1.7.7.6