Commit 12e230e5 authored by Paolo Bacchilega's avatar Paolo Bacchilega
Browse files

Some changes to the embedded preview loader

Scale the embedded preview to perfectly fit the requested
size;  do not use the embedded preview if it's too small
compared to the requested size; changed the code to
reduce the indentation levels.
parent 131d9788
......@@ -1120,63 +1120,81 @@ exiv2_generate_thumbnail (const char *uri,
char *path;
path = g_filename_from_uri (uri, NULL, NULL);
if (path != NULL) {
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open (path);
image->readMetadata ();
Exiv2::ExifThumbC exifThumb (image->exifData ());
Exiv2::DataBuf thumb = exifThumb.copy ();
if (thumb.pData_ != NULL) {
Exiv2::ExifData &ed = image->exifData();
long orientation = ed["Exif.Image.Orientation"].toLong();
long image_width = ed["Exif.Photo.PixelXDimension"].toLong();
long image_height = ed["Exif.Photo.PixelYDimension"].toLong();
if ((orientation == 1) && (image_width > 0) && (image_height > 0)) {
GInputStream *stream = g_memory_input_stream_new_from_data (thumb.pData_, thumb.size_, NULL);
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL);
if (pixbuf != NULL) {
/* Heuristic to find out-of-date thumbnails: the thumbnail and image aspect ratios must be equal */
double image_ratio = (((double) image_width) / image_height);
double thumbnail_ratio = (((double) gdk_pixbuf_get_width (pixbuf)) / gdk_pixbuf_get_height (pixbuf));
double ratio_delta = (image_ratio > thumbnail_ratio) ? (image_ratio - thumbnail_ratio) : (thumbnail_ratio - image_ratio);
if (ratio_delta > MAX_RATIO_ERROR_TOLERANCE) {
g_object_unref (pixbuf);
pixbuf = NULL;
}
else {
/* Save the original image size in the pixbuf options */
char *s = g_strdup_printf ("%ld", image_width);
gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Width", s);
g_object_set_data (G_OBJECT (pixbuf), "gnome-original-width", GINT_TO_POINTER ((int) image_width));
g_free (s);
s = g_strdup_printf ("%ld", image_height);
gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Height", s);
g_object_set_data (G_OBJECT (pixbuf), "gnome-original-height", GINT_TO_POINTER ((int) image_height));
g_free (s);
/* Set the orientation option to correctly rotate the thumbnail
* in gnome_desktop_thumbnail_factory_generate_thumbnail() */
long orientation = ed["Exif.Image.Orientation"].toLong();
char *orientation_s = g_strdup_printf ("%ld", orientation);
gdk_pixbuf_set_option (pixbuf, "orientation", orientation_s);
g_free (orientation_s);
}
}
if (path == NULL)
return NULL;
g_object_unref (stream);
}
}
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open (path);
image->readMetadata ();
Exiv2::ExifThumbC exifThumb (image->exifData ());
Exiv2::DataBuf thumb = exifThumb.copy ();
g_free (path);
if (thumb.pData_ == NULL)
return NULL;
Exiv2::ExifData &ed = image->exifData();
long orientation = ed["Exif.Image.Orientation"].toLong();
long image_width = ed["Exif.Photo.PixelXDimension"].toLong();
long image_height = ed["Exif.Photo.PixelYDimension"].toLong();
if ((orientation != 1) || (image_width <= 0) || (image_height <= 0))
return NULL;
GInputStream *stream = g_memory_input_stream_new_from_data (thumb.pData_, thumb.size_, NULL);
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL);
g_object_unref (stream);
if (pixbuf == NULL)
return NULL;
g_free (path);
/* Heuristic to find out-of-date thumbnails: the thumbnail and image aspect ratios must be equal */
int pixbuf_width = gdk_pixbuf_get_width (pixbuf);
int pixbuf_height = gdk_pixbuf_get_height (pixbuf);
double image_ratio = (((double) image_width) / image_height);
double thumbnail_ratio = (((double) pixbuf_width) / pixbuf_height);
double ratio_delta = (image_ratio > thumbnail_ratio) ? (image_ratio - thumbnail_ratio) : (thumbnail_ratio - image_ratio);
if ((ratio_delta > MAX_RATIO_ERROR_TOLERANCE) /* the tolerance is used because the reduced image can have a slightly different ratio due to rounding errors */
|| (MAX (pixbuf_width, pixbuf_height) < (requested_size / 2))) /* if the embedded image is too small compared to the requested size */
{
g_object_unref (pixbuf);
return NULL;
}
/* Scale the pixbuf to perfectly fit the requested size */
if (scale_keeping_ratio (&pixbuf_width,
&pixbuf_height,
requested_size,
requested_size,
TRUE))
{
GdkPixbuf *tmp = pixbuf;
pixbuf = gdk_pixbuf_scale_simple (tmp, pixbuf_width, pixbuf_height, GDK_INTERP_BILINEAR);
g_object_unref (tmp);
}
/* Save the original image size in the pixbuf options */
char *s = g_strdup_printf ("%ld", image_width);
gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Width", s);
g_object_set_data (G_OBJECT (pixbuf), "gnome-original-width", GINT_TO_POINTER ((int) image_width));
g_free (s);
s = g_strdup_printf ("%ld", image_height);
gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Height", s);
g_object_set_data (G_OBJECT (pixbuf), "gnome-original-height", GINT_TO_POINTER ((int) image_height));
g_free (s);
/* Set the orientation option to correctly rotate the thumbnail
* in gnome_desktop_thumbnail_factory_generate_thumbnail() */
char *orientation_s = g_strdup_printf ("%ld", orientation);
gdk_pixbuf_set_option (pixbuf, "orientation", orientation_s);
g_free (orientation_s);
}
catch (Exiv2::AnyError& e) {
}
......
Markdown is supported
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