From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Kshitij Suri <kshitij.suri@nutanix.com>
Cc: soham.ghosh@nutanix.com, thuth@redhat.com,
prerna.saxena@nutanix.com, armbru@redhat.com,
qemu-devel@nongnu.org, kraxel@redhat.com,
prachatos.mitra@nutanix.com, eblake@redhat.com,
dgilbert@redhat.com
Subject: Re: [PATCH v2] Added parameter to take screenshot with screendump as PNG
Date: Thu, 24 Feb 2022 16:18:14 +0000 [thread overview]
Message-ID: <YhevxnLUi5BHWJ9G@redhat.com> (raw)
In-Reply-To: <20220224115908.102285-1-kshitij.suri@nutanix.com>
On Thu, Feb 24, 2022 at 11:59:08AM +0000, Kshitij Suri wrote:
> Currently screendump only supports PPM format, which is un-compressed and not
> standard. Added a "format" parameter to qemu monitor screendump capabilites
> to support PNG image capture using libpng. The param was added in QAPI schema
> of screendump present in ui.json along with png_save() function which converts
> pixman_image to PNG. HMP command equivalent was also modified to support the
> feature.
>
> Example usage:
> { "execute": "screendump", "arguments": { "filename": "/tmp/image", "format":"png" } }
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/718
>
> Signed-off-by: Kshitij Suri <kshitij.suri@nutanix.com>
> ---
> diff to v1:
> - Removed repeated alpha conversion operation.
> - Modified logic to mirror png conversion in vnc-enc-tight.c file.
> - Added a new CONFIG_PNG parameter for libpng support.
> - Changed input format to enum instead of string.
>
> hmp-commands.hx | 11 +++---
> meson.build | 13 +++++--
> meson_options.txt | 2 +
> monitor/hmp-cmds.c | 8 +++-
> qapi/ui.json | 24 ++++++++++--
> ui/console.c | 97 ++++++++++++++++++++++++++++++++++++++++++++--
> 6 files changed, 139 insertions(+), 16 deletions(-)
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 70a9136ac2..e43c9954b5 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -244,17 +244,18 @@ ERST
>
> {
> .name = "screendump",
> - .args_type = "filename:F,device:s?,head:i?",
> - .params = "filename [device [head]]",
> - .help = "save screen from head 'head' of display device 'device' "
> - "into PPM image 'filename'",
> + .args_type = "filename:F,device:s?,head:i?,format:f?",
> + .params = "filename [device [head]] [format]",
> + .help = "save screen from head 'head' of display device 'device'"
> + "in specified format 'format' as image 'filename'."
> + "Currently only 'png' and 'ppm' formats are supported.",
> .cmd = hmp_screendump,
> .coroutine = true,
> },
>
> SRST
> ``screendump`` *filename*
> - Save screen into PPM image *filename*.
> + Save screen as an image *filename*.
> ERST
>
> {
> diff --git a/meson.build b/meson.build
> index 8df40bfac4..fd550c01ec 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1112,13 +1112,16 @@ if gtkx11.found()
> x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
> kwargs: static_kwargs)
> endif
> -vnc = not_found
> png = not_found
> +png = dependency('libpng', required: get_option('png'),
> + method: 'pkg-config', kwargs: static_kwargs)
> +vnc = not_found
> +vnc_png = not_found
> jpeg = not_found
> sasl = not_found
> if get_option('vnc').allowed() and have_system
> vnc = declare_dependency() # dummy dependency
> - png = dependency('libpng', required: get_option('vnc_png'),
> + vnc_png = dependency('libpng', required: get_option('vnc_png'),
> method: 'pkg-config', kwargs: static_kwargs)
> jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
> method: 'pkg-config', kwargs: static_kwargs)
> @@ -1537,9 +1540,10 @@ config_host_data.set('CONFIG_TPM', have_tpm)
> config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
> config_host_data.set('CONFIG_VDE', vde.found())
> config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
> +config_host_data.set('CONFIG_PNG', png.found())
> config_host_data.set('CONFIG_VNC', vnc.found())
> config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
> -config_host_data.set('CONFIG_VNC_PNG', png.found())
> +config_host_data.set('CONFIG_VNC_PNG', vnc_png.found())
I think we should be removing CONFIG_VNC_PNG entirely - the VNC
code should just use CONFIG_PNG.
I'd suggest splitting ths into two patches. The first patch
updates meson.build to look for libpng unconditionally and
rename to CONFIG_PNG. The second patch introduces the PNG
support for screendump.
> config_host_data.set('CONFIG_VNC_SASL', sasl.found())
> config_host_data.set('CONFIG_VIRTFS', have_virtfs)
> config_host_data.set('CONFIG_VTE', vte.found())
> @@ -3579,11 +3583,12 @@ summary_info += {'curses support': curses}
> summary_info += {'virgl support': virgl}
> summary_info += {'curl support': curl}
> summary_info += {'Multipath support': mpathpersist}
> +summary_info += {'PNG support': png}
> summary_info += {'VNC support': vnc}
> if vnc.found()
> summary_info += {'VNC SASL support': sasl}
> summary_info += {'VNC JPEG support': jpeg}
> - summary_info += {'VNC PNG support': png}
> + summary_info += {'VNC PNG support': vnc_png}
> endif
> if targetos not in ['darwin', 'haiku', 'windows']
> summary_info += {'OSS support': oss}
> diff --git a/meson_options.txt b/meson_options.txt
> index 52b11cead4..88148dec6c 100644
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -177,6 +177,8 @@ option('vde', type : 'feature', value : 'auto',
> description: 'vde network backend support')
> option('virglrenderer', type : 'feature', value : 'auto',
> description: 'virgl rendering support')
> +option('png', type : 'feature', value : 'auto',
> + description: 'PNG support with libpng')
> option('vnc', type : 'feature', value : 'auto',
> description: 'VNC server')
> option('vnc_jpeg', type : 'feature', value : 'auto',
> diff --git a/qapi/ui.json b/qapi/ui.json
> index 9354f4c467..8caeb2d3bb 100644
> --- a/qapi/ui.json
> +++ b/qapi/ui.json
> @@ -73,12 +73,27 @@
> ##
> { 'command': 'expire_password', 'data': {'protocol': 'str', 'time': 'str'} }
>
> +##
> +# @ImageFormat:
> +#
> +# Available list of supported types.
> +#
> +# @png: PNG format
> +#
> +# @ppm: PPM format
> +#
> +# Since: 6.3
> +#
> +##
> +{ 'enum': 'ImageFormat',
> + 'data': ['ppm', 'png'] }
> +
> ##
> # @screendump:
> #
> -# Write a PPM of the VGA screen to a file.
> +# Write a screenshot of the VGA screen to a file.
> #
> -# @filename: the path of a new PPM file to store the image
> +# @filename: the path of a new file to store the image
> #
> # @device: ID of the display device that should be dumped. If this parameter
> # is missing, the primary display will be used. (Since 2.12)
> @@ -87,6 +102,9 @@
> # parameter is missing, head #0 will be used. Also note that the head
> # can only be specified in conjunction with the device ID. (Since 2.12)
> #
> +# @format: image format for screendump is specified. Currently only PNG and
> +# PPM are supported.
Mention that PPM is the default if omitted.
> diff --git a/ui/console.c b/ui/console.c
> index 40eebb6d2c..911092c908 100644
> --- a/ui/console.c
> +++ b/ui/console.c
> @@ -37,6 +37,9 @@
> #include "exec/memory.h"
> #include "io/channel-file.h"
> #include "qom/object.h"
> +#ifdef CONFIG_PNG
> +#include "png.h"
System headers should use <...> for includes
> +#endif
> +static bool png_save(int fd, pixman_image_t *image, Error **errp)
> +{
> + int width = pixman_image_get_width(image);
> + int height = pixman_image_get_height(image);
> + png_structp png_ptr;
> + png_infop info_ptr;
> + g_autoptr(pixman_image_t) linebuf =
> + qemu_pixman_linebuf_create(PIXMAN_a8r8g8b8, width);
> + uint8_t *buf = (uint8_t *)pixman_image_get_data(linebuf);
> + FILE *f = fdopen(fd, "wb");
> + int y;
> + if (!f) {
> + error_setg(errp, "Failed to create file from file descriptor");
> + return false;
> + }
This leaks 'f', as do following error paths.
> +
> + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
> + NULL, NULL);
> + if (!png_ptr) {
> + error_setg(errp, "PNG creation failed. Unable to write struct");
> + return false;
> + }
> +
> + info_ptr = png_create_info_struct(png_ptr);
> +
> + if (!info_ptr) {
> + error_setg(errp, "PNG creation failed. Unable to write info");
> + return false;
This leaks 'png_ptr' too
> + }
> +
> + png_init_io(png_ptr, f);
> +
> + png_set_IHDR(png_ptr, info_ptr, width, height, 8,
> + PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
> + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
> +
> + png_write_info(png_ptr, info_ptr);
> +
> + for (y = 0; y < height; ++y) {
> + qemu_pixman_linebuf_fill(linebuf, image, width, 0, y);
> + png_write_row(png_ptr, buf);
> + }
> + qemu_pixman_image_unref(linebuf);
> +
> + png_write_end(png_ptr, NULL);
> +
> + png_destroy_write_struct(&png_ptr, &info_ptr);
> +
> + if (fclose(f) != 0) {
> + error_setg(errp, "PNG creation failed. Unable to close file");
> + return false;
> + }
> +
> + return true;
> +}
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2022-02-24 16:20 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-24 11:59 [PATCH v2] Added parameter to take screenshot with screendump as PNG Kshitij Suri
2022-02-24 16:02 ` Eric Blake
2022-02-25 5:31 ` Kshitij Suri
2022-02-24 16:18 ` Daniel P. Berrangé [this message]
2022-02-25 5:56 ` Kshitij Suri
2022-02-25 9:10 ` Daniel P. Berrangé
2022-02-25 9:35 ` Kshitij Suri
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YhevxnLUi5BHWJ9G@redhat.com \
--to=berrange@redhat.com \
--cc=armbru@redhat.com \
--cc=dgilbert@redhat.com \
--cc=eblake@redhat.com \
--cc=kraxel@redhat.com \
--cc=kshitij.suri@nutanix.com \
--cc=prachatos.mitra@nutanix.com \
--cc=prerna.saxena@nutanix.com \
--cc=qemu-devel@nongnu.org \
--cc=soham.ghosh@nutanix.com \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.