[eog: 1/3] Fix #30 - use librsvg's stream API instead of write()/close()



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]