Commit cc37cf78 authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann
Browse files

applied (a slightly modified version of) a patch from Nils Philippsen that

2005-01-18  Sven Neumann  <sven@gimp.org>

	* plug-ins/common/jpeg.c: applied (a slightly modified version of)
	a patch from Nils Philippsen that makes sure that the EXIF
	thumbnail doesn't cause the EXIF data block to grow beyond its
	maximum size.  Fixes bug #164087.
parent 99ddaf29
2005-01-18 Sven Neumann <sven@gimp.org>
* plug-ins/common/jpeg.c: applied (a slightly modified version of)
a patch from Nils Philippsen that makes sure that the EXIF
thumbnail doesn't cause the EXIF data block exceed its maximum
size. Fixes bug #164087.
2005-01-18 Michael Natterer <mitch@gimp.org>
Merged from HEAD branch:
......
......@@ -147,6 +147,15 @@
* parameters of the shot along with a thumbnail image.
*/
/*
* 14-JAN-05 - avoid to write more than 65533 bytes of EXIF marker length
* - Nils Philippsen <nphilipp@redhat.com>
*
* When writing thumbnails with high quality settings, EXIF marker length could
* get more than 65533 (sanity checking in libjpeg). Gradually decrease
* thumbnail quality (in 5% steps) until it fits.
*/
#include "config.h" /* configure cares about HAVE_PROGRESSIVE_JPEG */
#include <glib.h> /* We want glib.h first because of some
......@@ -183,7 +192,7 @@
/* #define HAVE_PROGRESSIVE_JPEG if your library knows how to handle it */
/* See bugs #63610 and #61088 for a discussion about the quality settings */
#define DEFAULT_QUALITY 85
#define DEFAULT_QUALITY 85.0
#define DEFAULT_SMOOTHING 0.0
#define DEFAULT_OPTIMIZE TRUE
#define DEFAULT_PROGRESSIVE FALSE
......@@ -260,6 +269,7 @@ static gint32 load_thumbnail_image(const gchar *filename,
static gint create_thumbnail (gint32 image_ID,
gint32 drawable_ID,
gdouble quality,
gchar **thumbnail_buffer);
#endif /* HAVE_EXIF */
......@@ -1436,16 +1446,6 @@ save_image (const gchar *filename,
gimp_pixel_rgn_init (&pixel_rgn, drawable,
0, 0, drawable->width, drawable->height, FALSE, FALSE);
#ifdef HAVE_EXIF
/* Create the thumbnail JPEG in a buffer */
if (jsvals.save_thumbnail)
thumbnail_buffer_length = create_thumbnail (image_ID, drawable_ID,
&thumbnail_buffer);
#endif /* HAVE_EXIF */
if (!preview)
{
name = g_strdup_printf (_("Saving '%s'..."),
......@@ -1547,8 +1547,7 @@ save_image (const gchar *filename,
*/
jpeg_set_defaults (&cinfo);
jpeg_set_quality (&cinfo, (gint) (jsvals.quality + 0.5),
jsvals.baseline);
jpeg_set_quality (&cinfo, (gint) (jsvals.quality + 0.5), jsvals.baseline);
cinfo.smoothing_factor = (gint) (jsvals.smoothing * 100);
cinfo.optimize_coding = jsvals.optimize;
......@@ -1645,22 +1644,71 @@ save_image (const gchar *filename,
* Pass TRUE unless you are very sure of what you're doing.
*/
jpeg_start_compress (&cinfo, TRUE);
#ifdef HAVE_EXIF
/* Create the thumbnail JPEG in a buffer */
if (jsvals.save_exif || jsvals.save_thumbnail)
{
guchar *exif_buf;
guchar *exif_buf = NULL;
guint exif_buf_len;
gdouble quality = MIN (75.0, jsvals.quality);
if ( (! jsvals.save_exif) || (! exif_data))
exif_data = exif_data_new ();
exif_data->data = thumbnail_buffer;
exif_data->size = thumbnail_buffer_length;
/* avoid to save markers longer than 65533, gradually decrease
* quality in 5% steps until exif_buf_len is lower than that.
*/
for (exif_buf_len = 65535;
exif_buf_len > 65533 && quality > 0.0;
quality -= 5.0)
{
if (jsvals.save_thumbnail)
thumbnail_buffer_length = create_thumbnail (image_ID, drawable_ID,
quality,
&thumbnail_buffer);
exif_data->data = thumbnail_buffer;
exif_data->size = thumbnail_buffer_length;
if (exif_buf)
free (exif_buf);
exif_data_save_data (exif_data, &exif_buf, &exif_buf_len);
}
if (exif_buf_len > 65533)
{
/* last attempt with quality 0.0 */
if (jsvals.save_thumbnail)
thumbnail_buffer_length = create_thumbnail (image_ID, drawable_ID,
0.0,
&thumbnail_buffer);
exif_data->data = thumbnail_buffer;
exif_data->size = thumbnail_buffer_length;
if (exif_buf)
free (exif_buf);
exif_data_save_data (exif_data, &exif_buf, &exif_buf_len);
}
if (exif_buf_len > 65533)
{
/* still no go? save without thumbnail */
exif_data->data = NULL;
exif_data->size = 0;
if (exif_buf)
free (exif_buf);
exif_data_save_data (exif_data, &exif_buf, &exif_buf_len);
}
exif_data_save_data (exif_data, &exif_buf, &exif_buf_len);
jpeg_write_marker (&cinfo, 0xe1, exif_buf, exif_buf_len);
free (exif_buf);
if (exif_buf)
free (exif_buf);
}
#endif /* HAVE_EXIF */
......@@ -2611,10 +2659,10 @@ load_thumbnail_image (const gchar *filename,
return image_ID;
}
gchar *tbuffer = NULL;
gchar *tbuffer2 = NULL;
static gchar *tbuffer = NULL;
static gchar *tbuffer2 = NULL;
gint tbuffer_count = 0;
static gint tbuffer_count = 0;
typedef struct
{
......@@ -2659,6 +2707,7 @@ term_destination (j_compress_ptr cinfo)
static gint
create_thumbnail (gint32 image_ID,
gint32 drawable_ID,
gdouble quality,
gchar **thumbnail_buffer)
{
GimpDrawable *drawable;
......@@ -2677,7 +2726,7 @@ create_thumbnail (gint32 image_ID,
req_width = 196;
req_height = 196;
if (MIN(drawable->width, drawable->height) < 196)
if (MIN (drawable->width, drawable->height) < 196)
req_width = req_height = MIN(drawable->width, drawable->height);
thumbnail_data = gimp_drawable_get_thumbnail_data (drawable_ID,
......@@ -2695,18 +2744,8 @@ create_thumbnail (gint32 image_ID,
rbpp = bpp - 1;
}
buf = (gchar *) g_malloc (req_width * bpp);
if (!buf)
return 0;
tbuffer2 = (gchar *) g_malloc(16384);
if (!tbuffer2)
{
g_free (buf);
return 0;
}
buf = g_new (guchar, req_width * bpp);
tbuffer2 = g_new (gchar, 16384);
tbuffer_count = 0;
......@@ -2777,8 +2816,7 @@ create_thumbnail (gint32 image_ID,
*/
jpeg_set_defaults (&cinfo);
jpeg_set_quality (&cinfo, (gint) (jsvals.quality + 0.5),
jsvals.baseline);
jpeg_set_quality (&cinfo, (gint) (quality + 0.5), jsvals.baseline);
/* Step 4: Start compressor */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment