[gthumb] jpeg loader: try to load broken images



commit 04478a41d57cd2c968d0e9c5f777051f92b2ed33
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Tue May 15 09:49:56 2018 +0200

    jpeg loader: try to load broken images
    
    ignore the error if the surface is not null
    
    [bug #795879]

 extensions/cairo_io/cairo-image-surface-jpeg.c |   82 ++++++++++++-----------
 gthumb/gth-image-loader.c                      |   13 +++-
 gthumb/gth-image.c                             |   26 ++++++++
 gthumb/gth-image.h                             |    1 +
 4 files changed, 79 insertions(+), 43 deletions(-)
---
diff --git a/extensions/cairo_io/cairo-image-surface-jpeg.c b/extensions/cairo_io/cairo-image-surface-jpeg.c
index f61d5e0..73cb0e2 100644
--- a/extensions/cairo_io/cairo-image-surface-jpeg.c
+++ b/extensions/cairo_io/cairo-image-surface-jpeg.c
@@ -185,8 +185,10 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
        guint32                        pixel;
        unsigned char                 *p_buffer;
        int                            x;
+       gboolean                       read_all_scanlines = FALSE;
 
        image = gth_image_new ();
+       surface = NULL;
 
        if (! _g_input_stream_read_all (istream,
                                        &in_buffer,
@@ -234,11 +236,8 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 
        jpeg_create_decompress (&srcinfo);
 
-       if (sigsetjmp (jsrcerr.setjmp_buffer, 1)) {
-               g_free (in_buffer);
-               jpeg_destroy_decompress (&srcinfo);
-               return image;
-       }
+       if (sigsetjmp (jsrcerr.setjmp_buffer, 1))
+               goto stop_loading;
 
        _jpeg_memory_src (&srcinfo, in_buffer, in_buffer_size);
 
@@ -545,52 +544,57 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
                break;
        }
 
+       read_all_scanlines = TRUE;
+
        stop_loading:
 
-       cairo_surface_mark_dirty (surface);
+       if (surface != NULL) {
+               cairo_surface_mark_dirty (surface);
 
-       if (! g_cancellable_is_cancelled (cancellable)) {
-               int original_width;
-               int original_height;
+               if (! g_cancellable_is_cancelled (cancellable)) {
+                       int original_width;
+                       int original_height;
 
-               /* Set the original dimensions */
+                       /* Set the original dimensions */
 
-               if ((orientation == GTH_TRANSFORM_ROTATE_90)
-                    || (orientation == GTH_TRANSFORM_ROTATE_270)
-                    || (orientation == GTH_TRANSFORM_TRANSPOSE)
-                    || (orientation == GTH_TRANSFORM_TRANSVERSE))
-               {
-                       original_width = srcinfo.image_height;
-                       original_height = srcinfo.image_width;
-               }
-               else {
-                       original_width = srcinfo.image_width;
-                       original_height = srcinfo.image_height;
-               }
+                       if ((orientation == GTH_TRANSFORM_ROTATE_90)
+                            || (orientation == GTH_TRANSFORM_ROTATE_270)
+                            || (orientation == GTH_TRANSFORM_TRANSPOSE)
+                            || (orientation == GTH_TRANSFORM_TRANSVERSE))
+                       {
+                               original_width = srcinfo.image_height;
+                               original_height = srcinfo.image_width;
+                       }
+                       else {
+                               original_width = srcinfo.image_width;
+                               original_height = srcinfo.image_height;
+                       }
 
-               _cairo_metadata_set_original_size (metadata, original_width, original_height);
+                       _cairo_metadata_set_original_size (metadata, original_width, original_height);
 
-               if (original_width_p != NULL)
-                       *original_width_p = original_width;
-               if (original_height_p != NULL)
-                       *original_height_p = original_height;
-               if (loaded_original_p != NULL)
-                       *loaded_original_p = ! load_scaled;
+                       if (original_width_p != NULL)
+                               *original_width_p = original_width;
+                       if (original_height_p != NULL)
+                               *original_height_p = original_height;
+                       if (loaded_original_p != NULL)
+                               *loaded_original_p = ! load_scaled;
 
-               jpeg_finish_decompress (&srcinfo);
-               jpeg_destroy_decompress (&srcinfo);
+                       /*_cairo_image_surface_set_attribute_int (surface, "Image::Rotation", rotation); 
FIXME*/
+                       /* FIXME _cairo_image_surface_set_attribute (surface, "Jpeg::ColorSpace", 
jpeg_color_space_name (srcinfo.jpeg_color_space)); */
 
-               /*_cairo_image_surface_set_attribute_int (surface, "Image::Rotation", rotation); FIXME*/
-               /* FIXME _cairo_image_surface_set_attribute (surface, "Jpeg::ColorSpace", 
jpeg_color_space_name (srcinfo.jpeg_color_space)); */
+                       gth_image_set_cairo_surface (image, surface);
+               }
+               else
+                       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, "");
 
-               gth_image_set_cairo_surface (image, surface);
-       }
-       else {
-               jpeg_destroy_decompress (&srcinfo);
-               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, "");
+               cairo_surface_destroy (surface);
        }
 
-       cairo_surface_destroy (surface);
+       if (read_all_scanlines)
+               jpeg_finish_decompress (&srcinfo);
+       else
+               jpeg_abort_decompress (&srcinfo);
+       jpeg_destroy_decompress (&srcinfo);
        g_free (in_buffer);
 
        return image;
diff --git a/gthumb/gth-image-loader.c b/gthumb/gth-image-loader.c
index 7c60bf4..e464b99 100644
--- a/gthumb/gth-image-loader.c
+++ b/gthumb/gth-image-loader.c
@@ -238,10 +238,15 @@ load_image_thread (GSimpleAsyncResult *result,
        }
 
        if (error != NULL) {
-               _g_object_unref (image);
-               g_simple_async_result_set_from_error (result, error);
-               g_error_free (error);
-               return;
+               if ((image == NULL) || gth_image_get_is_null (image)) {
+                       _g_object_unref (image);
+                       g_simple_async_result_set_from_error (result, error);
+                       g_error_free (error);
+                       return;
+               }
+
+               /* ignore the error if the image is not null. */
+               g_clear_error (&error);
        }
 
        load_data->image = image;
diff --git a/gthumb/gth-image.c b/gthumb/gth-image.c
index f6cd00e..6bdd091 100644
--- a/gthumb/gth-image.c
+++ b/gthumb/gth-image.c
@@ -305,6 +305,32 @@ gth_image_get_is_zoomable (GthImage *self)
 
 
 gboolean
+gth_image_get_is_null (GthImage *self)
+{
+       gboolean is_null = TRUE;
+
+       switch (self->priv->format) {
+       case GTH_IMAGE_FORMAT_CAIRO_SURFACE:
+               is_null = self->priv->data.surface == NULL;
+               break;
+
+       case GTH_IMAGE_FORMAT_GDK_PIXBUF:
+               is_null = self->priv->data.pixbuf == NULL;
+               break;
+
+       case GTH_IMAGE_FORMAT_GDK_PIXBUF_ANIMATION:
+               is_null = self->priv->data.pixbuf_animation == NULL;
+               break;
+
+       default:
+               break;
+       }
+
+       return is_null;
+}
+
+
+gboolean
 gth_image_set_zoom (GthImage *self,
                    double    zoom,
                    int      *original_width,
diff --git a/gthumb/gth-image.h b/gthumb/gth-image.h
index 7bae2ce..67e7b5c 100644
--- a/gthumb/gth-image.h
+++ b/gthumb/gth-image.h
@@ -91,6 +91,7 @@ gboolean              gth_image_get_original_size         (GthImage           *image
                                                             int                *width,
                                                             int                *height);
 gboolean              gth_image_get_is_zoomable             (GthImage           *image);
+gboolean              gth_image_get_is_null                 (GthImage           *image);
 gboolean              gth_image_set_zoom                    (GthImage           *image,
                                                             double              zoom,
                                                             int                *original_width,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]