aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy-gtk
diff options
context:
space:
mode:
Diffstat (limited to 'libempathy-gtk')
-rw-r--r--libempathy-gtk/empathy-avatar-chooser.c55
1 files changed, 37 insertions, 18 deletions
diff --git a/libempathy-gtk/empathy-avatar-chooser.c b/libempathy-gtk/empathy-avatar-chooser.c
index e9d8485a3..6e6c28310 100644
--- a/libempathy-gtk/empathy-avatar-chooser.c
+++ b/libempathy-gtk/empathy-avatar-chooser.c
@@ -411,8 +411,9 @@ avatar_chooser_maybe_convert_and_scale (EmpathyAvatarChooser *chooser,
gchar *new_mime_type = NULL;
gdouble min_factor, max_factor;
gdouble factor;
- gchar *converted_image_data = NULL;
- gsize converted_image_size = 0;
+ gchar *best_image_data = NULL;
+ gsize best_image_size = 0;
+ guint count = 0;
req = tp_connection_get_avatar_requirements (priv->connection);
if (req == NULL) {
@@ -484,10 +485,10 @@ avatar_chooser_maybe_convert_and_scale (EmpathyAvatarChooser *chooser,
GdkPixbuf *pixbuf_scaled = NULL;
gboolean saved;
gint new_width, new_height;
+ gchar *converted_image_data;
+ gsize converted_image_size;
GError *error = NULL;
- g_free (converted_image_data);
-
if (factor != 1) {
new_width = width * factor;
new_height = height * factor;
@@ -524,8 +525,23 @@ avatar_chooser_maybe_convert_and_scale (EmpathyAvatarChooser *chooser,
DEBUG ("Produced an image data of %"G_GSIZE_FORMAT" bytes.",
converted_image_size);
- if (req->maximum_bytes == 0)
- break;
+ /* If the new image satisfy the req, keep it as current best */
+ if (req->maximum_bytes == 0 ||
+ converted_image_size <= req->maximum_bytes) {
+ if (best_image_data)
+ g_free (best_image_data);
+
+ best_image_data = converted_image_data;
+ best_image_size = converted_image_size;
+
+ /* If this image is close enough to the optimal size,
+ * stop searching */
+ if (req->maximum_bytes == 0 ||
+ req->maximum_bytes - converted_image_size <= 1024)
+ break;
+ } else {
+ g_free (converted_image_data);
+ }
/* Make a binary search for the bigest factor that produce
* an image data size less than max_size */
@@ -535,20 +551,23 @@ avatar_chooser_maybe_convert_and_scale (EmpathyAvatarChooser *chooser,
min_factor = factor;
factor = (min_factor + max_factor)/2;
- /* We are done if either:
- * - min_factor == max_factor. That happens if we resized to
- * the max required dimension and the produced data size is
- * less than max_size.
- * - The data size is close enough to max_size. Here we accept
- * a difference of 1k.
- */
- } while (min_factor != max_factor &&
- abs (req->maximum_bytes - converted_image_size) > 1024);
+ if ((int) (width * factor) == new_width ||
+ (int) (height * factor) == new_height) {
+ /* min_factor and max_factor are too close, so the new
+ * factor will produce the same image as previous
+ * iteration. No need to continue, we already found
+ * the optimal size. */
+ break;
+ }
+
+ /* Do 10 iterations in the worst case */
+ } while (++count < 10);
+
g_free (new_format_name);
- /* Takes ownership of new_mime_type and converted_image_data */
- avatar = empathy_avatar_new ((guchar *) converted_image_data,
- converted_image_size, new_mime_type, NULL, NULL);
+ /* Takes ownership of new_mime_type and best_image_data */
+ avatar = empathy_avatar_new ((guchar *) best_image_data,
+ best_image_size, new_mime_type, NULL, NULL);
return avatar;
}