# HG changeset patch # User Marcus Lundblad # Date 1268689742 0 # Node ID 25a53c299713c86dc5284fd72e56976627ed1d3f # Parent bf0cbb79d629fbdf36817e5689ce738ace849c24 Allow PRPLs to specify the image formats acceptable for thumbnails (in preferred order). diff -r bf0cbb79d629 -r 25a53c299713 libpurple/ft.c --- a/libpurple/ft.c Sun Mar 14 21:20:14 2010 +0000 +++ b/libpurple/ft.c Mon Mar 15 21:49:02 2010 +0000 @@ -179,6 +179,7 @@ g_hash_table_remove(xfers_data, xfer); g_free(xfer->thumbnail_data); + g_free(xfer->thumbnail_mimetype); PURPLE_DBUS_UNREGISTER_POINTER(xfer); xfers = g_list_remove(xfers, xfer); @@ -1630,13 +1631,20 @@ return xfer->thumbnail_size; } +const gchar * +purple_xfer_get_thumbnail_mimetype(const PurpleXfer *xfer) +{ + return xfer->thumbnail_mimetype; +} + void purple_xfer_set_thumbnail(PurpleXfer *xfer, gconstpointer thumbnail, - gsize size) + gsize size, const gchar *mimetype) { if (thumbnail && size > 0) { xfer->thumbnail_data = g_memdup(thumbnail, size); xfer->thumbnail_size = size; + xfer->thumbnail_mimetype = g_strdup(mimetype); } } diff -r bf0cbb79d629 -r 25a53c299713 libpurple/ft.h --- a/libpurple/ft.h Sun Mar 14 21:20:14 2010 +0000 +++ b/libpurple/ft.h Mon Mar 15 21:49:02 2010 +0000 @@ -189,6 +189,7 @@ gpointer thumbnail_data; /**< thumbnail image */ gsize thumbnail_size; + gchar *thumbnail_mimetype; }; #ifdef __cplusplus @@ -711,16 +712,25 @@ */ gsize purple_xfer_get_thumbnail_size(const PurpleXfer *xfer); - +/** + * Gets the mimetype of the thumbnail preview for a transfer + * + * @param xfer The file transfer to get the mimetype for + * @return The mimetype of the thumbnail, or @c NULL if not thumbnail is set + */ +const gchar *purple_xfer_get_thumbnail_mimetype(const PurpleXfer *xfer); + + /** * Sets the thumbnail data for a transfer * * @param xfer The file transfer to set the data for * @param thumbnail A pointer to the thumbnail data, this will be copied * @param size The size in bytes of the passed in thumbnail data + * @param mimetype The mimetype of the generated thumbnail */ void purple_xfer_set_thumbnail(PurpleXfer *xfer, gconstpointer thumbnail, - gsize size); + gsize size, const gchar *mimetype); /** * Prepare a thumbnail for a transfer (if the UI supports it) diff -r bf0cbb79d629 -r 25a53c299713 libpurple/protocols/jabber/libxmpp.c --- a/libpurple/protocols/jabber/libxmpp.c Sun Mar 14 21:20:14 2010 +0000 +++ b/libpurple/protocols/jabber/libxmpp.c Mon Mar 15 21:49:02 2010 +0000 @@ -127,7 +127,8 @@ NULL, /* get_account_text_table */ jabber_initiate_media, /* initiate_media */ jabber_get_media_caps, /* get_media_caps */ - jabber_get_moods /* get_moods */ + jabber_get_moods, /* get_moods */ + {"jpeg,png"} /* file transfer thumbnail spec */ }; static gboolean load_plugin(PurplePlugin *plugin) diff -r bf0cbb79d629 -r 25a53c299713 libpurple/protocols/jabber/si.c --- a/libpurple/protocols/jabber/si.c Sun Mar 14 21:20:14 2010 +0000 +++ b/libpurple/protocols/jabber/si.c Mon Mar 15 21:49:02 2010 +0000 @@ -1267,15 +1267,16 @@ /* add thumbnail, if appropriate */ if (purple_xfer_get_thumbnail_data(xfer)) { - JabberData *thumbnail_data = + const gchar *mimetype = purple_xfer_get_thumbnail_mimetype(xfer); + JabberData *thumbnail_data = jabber_data_create_from_data(purple_xfer_get_thumbnail_data(xfer), - purple_xfer_get_thumbnail_size(xfer), "image/png", TRUE, + purple_xfer_get_thumbnail_size(xfer), mimetype, TRUE, jsx->js); xmlnode *thumbnail = xmlnode_new_child(file, "thumbnail"); xmlnode_set_namespace(thumbnail, NS_THUMBS); xmlnode_set_attrib(thumbnail, "cid", jabber_data_get_cid(thumbnail_data)); - xmlnode_set_attrib(thumbnail, "mime-type", "image/png"); + xmlnode_set_attrib(thumbnail, "mime-type", mimetype); /* cache data */ jabber_data_associate_local(thumbnail_data, NULL); } @@ -1671,7 +1672,7 @@ if (data) { purple_xfer_set_thumbnail(xfer, jabber_data_get_data(data), - jabber_data_get_size(data)); + jabber_data_get_size(data), jabber_data_get_type(data)); jabber_data_destroy(data); } } else if (item_not_found) { diff -r bf0cbb79d629 -r 25a53c299713 libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Sun Mar 14 21:20:14 2010 +0000 +++ b/libpurple/protocols/msn/msn.c Mon Mar 15 21:49:02 2010 +0000 @@ -2733,7 +2733,8 @@ msn_get_account_text_table, /* get_account_text_table */ NULL, /* initiate_media */ NULL, /* get_media_caps */ - NULL /* get_moods */ + NULL, /* get_moods */ + {"png"} /* file transfer thumbnail spec */ }; static PurplePluginInfo info = diff -r bf0cbb79d629 -r 25a53c299713 libpurple/protocols/msn/slp.c --- a/libpurple/protocols/msn/slp.c Sun Mar 14 21:20:14 2010 +0000 +++ b/libpurple/protocols/msn/slp.c Mon Mar 15 21:49:02 2010 +0000 @@ -424,7 +424,8 @@ if (header->type == 0 && bin_len >= sizeof(MsnFileContext)) { purple_xfer_set_thumbnail(xfer, &header->preview, - bin_len - sizeof(MsnFileContext)); + bin_len - sizeof(MsnFileContext), + "image/png"); } purple_xfer_request(xfer); diff -r bf0cbb79d629 -r 25a53c299713 libpurple/prpl.h --- a/libpurple/prpl.h Sun Mar 14 21:20:14 2010 +0000 +++ b/libpurple/prpl.h Mon Mar 15 21:49:02 2010 +0000 @@ -52,6 +52,13 @@ typedef struct _PurpleBuddyIconSpec PurpleBuddyIconSpec; /** + * A description of a file transfer thumbnail specification. + * This tells the UI if and what image formats the prpl support for file + * transfer thumbnails. + */ +typedef struct _PurpleThumbnailSpec PurpleThumbnailSpec; + +/** * This \#define exists just to make it easier to fill out the buddy icon * field in the prpl info struct for protocols that couldn't care less. */ @@ -91,6 +98,14 @@ PurpleIconScaleRules scale_rules; /**< How to stretch this icon */ }; +/** @copydoc PurpleThumbnailSpec */ +struct _PurpleThumbnailSpec { + /** This is a comma-delimited list of image formats or @c NULL if the + * prpl does not support file transfer thumbnails + */ + char *format; +}; + /** Represents an entry containing information that must be supplied by the * user when joining a chat. */ @@ -575,6 +590,11 @@ * "mood" set to @c NULL. */ PurpleMood *(*get_moods)(PurpleAccount *account); + + /** + * File transfer thumbnail spec + */ + PurpleThumbnailSpec thumbnail_spec; }; #define PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl, member) \ diff -r bf0cbb79d629 -r 25a53c299713 pidgin/gtkft.c --- a/pidgin/gtkft.c Sun Mar 14 21:20:14 2010 +0000 +++ b/pidgin/gtkft.c Mon Mar 15 21:49:02 2010 +0000 @@ -1163,29 +1163,75 @@ static void pidgin_xfer_add_thumbnail(PurpleXfer *xfer) { + PurpleAccount *account = purple_xfer_get_account(xfer); + PurpleConnection *gc = purple_account_get_connection(account); + PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); + const char *thumbnail_format = prpl_info->thumbnail_spec.format; + purple_debug_info("pidgin", "creating thumbnail for transfer\n"); - if (purple_xfer_get_size(xfer) <= PIDGIN_XFER_MAX_SIZE_IMAGE_THUMBNAIL) { + if (thumbnail_format != NULL && + purple_xfer_get_size(xfer) <= PIDGIN_XFER_MAX_SIZE_IMAGE_THUMBNAIL) { GdkPixbuf *thumbnail = gdk_pixbuf_new_from_file_at_size( purple_xfer_get_local_filename(xfer), 128, 128, NULL); if (thumbnail) { + gchar **formats = g_strsplit(thumbnail_format, ",", 0); gchar *buffer = NULL; gsize size; - char *option_keys[2] = {"compression", NULL}; - char *option_values[2] = {"9", NULL}; - gdk_pixbuf_save_to_bufferv(thumbnail, &buffer, &size, "png", + char *option_keys[2] = {NULL, NULL}; + char *option_values[2] = {NULL, NULL}; + gboolean supports_jpeg = FALSE; + gboolean supports_png = FALSE; + int i; + gchar *format = NULL; + + for (i = 0 ; formats[i] ; i++) { + if (purple_strequal(formats[i], "jpeg")) { + supports_jpeg = TRUE; + } else if (purple_strequal(formats[i], "png")) { + supports_png = TRUE; + } + } + + /* prefer JPEG, then PNG, otherwise try the first format given + by the PRPL without options */ + if (supports_jpeg) { + purple_debug_info("pidgin", "creating JPEG thumbnail\n"); + option_keys[0] = "quality"; + option_keys[1] = NULL; + option_values[0] = "90"; + option_values[1] = NULL; + format = "jpeg"; + } else if (supports_png) { + purple_debug_info("pidgin", "creating PNG thumbnail\n"); + option_keys[0] = "compression"; + option_keys[1] = NULL; + option_values[0] = "9"; + option_values[1] = NULL; + format = "png"; + } else { + purple_debug_info("pidgin", + "creating thumbnail of format %s as demanded by PRPL\n", + formats[0]); + format = formats[0]; + } + + gdk_pixbuf_save_to_bufferv(thumbnail, &buffer, &size, format, option_keys, option_values, NULL); if (buffer) { + const gchar *mimetype = g_strdup_printf("image/%s", format); purple_debug_info("pidgin", "created thumbnail of %" G_GSIZE_FORMAT " bytes\n", size); - purple_xfer_set_thumbnail(xfer, buffer, size); + purple_xfer_set_thumbnail(xfer, buffer, size, mimetype); g_free(buffer); + g_free(mimetype); } g_object_unref(thumbnail); + g_strfreev(formats); } } }