[gimp] Bug 776994 - Gimp fails to open corrupted JPG image



commit abcf372d7f71fed1524075aaca6b50cc5e3bbf9e
Author: Michael Natterer <mitch gimp org>
Date:   Mon Jan 1 22:35:48 2018 +0100

    Bug 776994 - Gimp fails to open corrupted JPG image
    
    Load as much of a broken/truncated JPEG as possible:
    
    As soon as loading the scanlines has started, set a new setjmp()
    location that doesn't abort loading alltogether but keeps the loaded
    part of the image.

 plug-ins/file-jpeg/jpeg-load.c |   26 ++++++++++++++++++++++++--
 1 files changed, 24 insertions(+), 2 deletions(-)
---
diff --git a/plug-ins/file-jpeg/jpeg-load.c b/plug-ins/file-jpeg/jpeg-load.c
index 527b960..75f100b 100644
--- a/plug-ins/file-jpeg/jpeg-load.c
+++ b/plug-ins/file-jpeg/jpeg-load.c
@@ -75,8 +75,7 @@ load_image (const gchar  *filename,
   GeglBuffer      *buffer = NULL;
   const Babl      *format;
   gint             tile_height;
-  gint             scanlines;
-  gint             i, start, end;
+  gint             i;
   cmsHTRANSFORM    cmyk_transform = NULL;
 
   /* We set up the normal JPEG error routines. */
@@ -352,12 +351,26 @@ load_image (const gchar  *filename,
 
   while (cinfo.output_scanline < cinfo.output_height)
     {
+      gint     start, end;
+      gint     scanlines;
+      gboolean image_truncated = FALSE;
+
       start = cinfo.output_scanline;
       end   = cinfo.output_scanline + tile_height;
       end   = MIN (end, cinfo.output_height);
 
       scanlines = end - start;
 
+      /*  in case of error we now jump here, so pertially loaded imaged
+       *  don't get discarded
+       */
+      if (setjmp (jerr.setjmp_buffer))
+        {
+          image_truncated = TRUE;
+
+          goto set_buffer;
+        }
+
       for (i = 0; i < scanlines; i++)
         jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &rowbuf[i], 1);
 
@@ -365,6 +378,7 @@ load_image (const gchar  *filename,
         jpeg_load_cmyk_to_rgb (buf, cinfo.output_width * scanlines,
                                cmyk_transform);
 
+    set_buffer:
       gegl_buffer_set (buffer,
                        GEGL_RECTANGLE (0, start, cinfo.output_width, scanlines),
                        0,
@@ -372,6 +386,12 @@ load_image (const gchar  *filename,
                        buf,
                        GEGL_AUTO_ROWSTRIDE);
 
+      if (image_truncated)
+        /*  jumping to finish skips jpeg_finish_decompress(), its state
+         *  might be broken by whatever caused the loading failure
+         */
+        goto finish;
+
       if (! preview && (cinfo.output_scanline % 32) == 0)
         gimp_progress_update ((gdouble) cinfo.output_scanline /
                               (gdouble) cinfo.output_height);
@@ -384,6 +404,8 @@ load_image (const gchar  *filename,
    * with the stdio data source.
    */
 
+ finish:
+
   if (cmyk_transform)
     cmsDeleteTransform (cmyk_transform);
 


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