[eog: 1/3] Fix #30 - use librsvg's stream API instead of write()/close()
- From: Felix Riemann <friemann src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [eog: 1/3] Fix #30 - use librsvg's stream API instead of write()/close()
- Date: Sat, 12 Oct 2019 15:31:51 +0000 (UTC)
commit 31d952ffb6edfca0b158ab3cdacc1dc488393e08
Author: Federico Mena Quintero <federico gnome org>
Date: Thu Feb 21 09:47:46 2019 -0600
Fix #30 - use librsvg's stream API instead of write()/close()
The rsvg_handle_write()/close() code path requires buffering the
entire image data in librsvg before it can be processed. The
streaming API is smarter and does not require this extra copy.
Fixes https://gitlab.gnome.org/GNOME/eog/issues/30
src/eog-image.c | 94 ++++++++++++++++++++++++++++-----------------------------
1 file changed, 46 insertions(+), 48 deletions(-)
---
diff --git a/src/eog-image.c b/src/eog-image.c
index 9ee130ff..55cb1916 100644
--- a/src/eog-image.c
+++ b/src/eog-image.c
@@ -906,7 +906,7 @@ eog_image_real_load (EogImage *img,
gchar *mime_type;
GdkPixbufLoader *loader = NULL;
guchar *buffer;
- goffset bytes_read, bytes_read_total = 0;
+ goffset bytes_read = 0, bytes_read_total = 0;
gboolean failed = FALSE;
gboolean first_run = TRUE;
gboolean set_metadata = TRUE;
@@ -1009,47 +1009,53 @@ eog_image_real_load (EogImage *img,
g_free (mime_type);
while (!priv->cancel_loading) {
- /* FIXME: make this async */
- bytes_read = g_input_stream_read (G_INPUT_STREAM (input_stream),
- buffer,
- EOG_IMAGE_READ_BUFFER_SIZE,
- NULL, error);
-
- if (bytes_read == 0) {
- /* End of the file */
+#ifdef HAVE_RSVG
+ if (use_rsvg && first_run && (read_image_data || read_only_dimension)) {
+ if (rsvg_handle_read_stream_sync (priv->svg,
+ G_INPUT_STREAM (input_stream),
+ NULL,
+ error))
+ {
+ /* The entire file is read by now */
+ bytes_read_total = priv->bytes;
+ } else {
+ failed = TRUE;
+ }
break;
- } else if (bytes_read == -1) {
- failed = TRUE;
+ } else {
+#endif
- g_set_error (error,
- EOG_IMAGE_ERROR,
- EOG_IMAGE_ERROR_VFS,
- "Failed to read from input stream");
+ /* FIXME: make this async */
+ bytes_read = g_input_stream_read (G_INPUT_STREAM (input_stream),
+ buffer,
+ EOG_IMAGE_READ_BUFFER_SIZE,
+ NULL, error);
- break;
- }
+ if (bytes_read == 0) {
+ /* End of the file */
+ break;
+ } else if (bytes_read == -1) {
+ failed = TRUE;
- if ((read_image_data || read_only_dimension)) {
-#ifdef HAVE_RSVG
- if (use_rsvg) {
- gboolean res;
+ g_set_error (error,
+ EOG_IMAGE_ERROR,
+ EOG_IMAGE_ERROR_VFS,
+ "Failed to read from input stream");
- res = rsvg_handle_write (priv->svg, buffer,
- bytes_read, error);
+ break;
+ }
- if (G_UNLIKELY (!res)) {
+ if ((read_image_data || read_only_dimension)) {
+ if (!gdk_pixbuf_loader_write (loader, buffer, bytes_read, error)) {
failed = TRUE;
break;
}
- } else
-#endif
- if (!gdk_pixbuf_loader_write (loader, buffer, bytes_read, error)) {
- failed = TRUE;
- break;
}
- }
- bytes_read_total += bytes_read;
+ bytes_read_total += bytes_read;
+#ifdef HAVE_RSVG
+ }
+#endif
/* For now allow calling from outside of jobs */
if (job != NULL)
@@ -1112,24 +1118,15 @@ eog_image_real_load (EogImage *img,
}
if (read_image_data || read_only_dimension) {
-#ifdef HAVE_RSVG
- if (use_rsvg) {
+ if (!use_rsvg) {
if (failed) {
- /* Ignore the error if loading failed earlier
- * as the error will already be set in that case */
- rsvg_handle_close (priv->svg, NULL);
- } else {
- failed = !rsvg_handle_close (priv->svg, error);
- }
- } else
-#endif
- if (failed) {
- gdk_pixbuf_loader_close (loader, NULL);
- } else if (!gdk_pixbuf_loader_close (loader, error)) {
- if (gdk_pixbuf_loader_get_pixbuf (loader) != NULL) {
- /* Clear error in order to support partial
- * images as well. */
- g_clear_error (error);
+ gdk_pixbuf_loader_close (loader, NULL);
+ } else if (!gdk_pixbuf_loader_close (loader, error)) {
+ if (gdk_pixbuf_loader_get_pixbuf (loader) != NULL) {
+ /* Clear error in order to support partial
+ * images as well. */
+ g_clear_error (error);
+ }
}
}
}
@@ -1267,6 +1264,7 @@ eog_image_has_data (EogImage *img, EogImageData req_data)
if (req_data != 0) {
g_warning ("Asking for unknown data, remaining: %i\n", req_data);
has_data = FALSE;
+
}
return has_data;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]