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.
This commit is contained in:
Michael Natterer 2018-01-01 22:35:48 +01:00
parent 89ef0dd684
commit abcf372d7f
1 changed files with 24 additions and 2 deletions

View File

@ -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);