downscale big stickers

use sticker downscaling to keep readabillity in chats with many stickers
This commit is contained in:
mjentsch 2015-06-04 14:27:49 +02:00
parent 0d62d1bed3
commit 006890a29c
3 changed files with 49 additions and 33 deletions

View file

@ -22,6 +22,11 @@
#include "config.h"
#endif
#ifdef HAVE_LIBWEBP
#include <webp/decode.h>
#include "lodepng/lodepng.h"
#endif
#include "telegram-purple.h"
#include "tgp-2prpl.h"
#include "tgp-structs.h"
@ -436,15 +441,54 @@ int p2tgl_imgstore_add_with_id (const char* filename) {
#ifdef HAVE_LIBWEBP
int p2tgl_imgstore_add_with_id_webp (const char *filename) {
size_t pngsize;
void *png = tgp_webp_load_png (filename, &pngsize);
if (!png) { return -1; }
const uint8_t *data = NULL;
size_t len;
GError *err = NULL;
g_file_get_contents (filename, (gchar **) &data, &len, &err);
if (err) { warning ("cannot open file %s: %s.", filename, err->message); return 0; }
// downscale oversized sticker images displayed in chat, otherwise it would harm readabillity
WebPDecoderConfig config;
WebPInitDecoderConfig (&config);
if (! WebPGetFeatures(data, len, &config.input) == VP8_STATUS_OK) {
warning ("error reading webp bitstream: %s", filename);
g_free ((gchar *)data);
return 0;
}
int H = config.input.height;
int W = config.input.width;
while (H > 256 || W > 256) {
H /= 2;
W /= 2;
}
config.options.use_scaling = 1;
config.options.scaled_width = W;
config.options.scaled_height = H;
config.output.colorspace = MODE_RGBA;
if (! WebPDecode(data, len, &config) == VP8_STATUS_OK) {
warning ("error decoding webp: %s", filename);
g_free ((gchar *)data);
return 0;
}
g_free ((gchar *)data);
const uint8_t *decoded = config.output.u.RGBA.rgba;
// convert to png
unsigned char* png = NULL;
size_t pnglen;
unsigned error = lodepng_encode32 (&png, &pnglen, decoded, config.options.scaled_width, config.options.scaled_height);
WebPFreeDecBuffer (&config.output);
if (error) {
warning ("error encoding webp as png: %s", filename);
return 0;
}
// will be owned by libpurple imgstore, which uses glib functions for managing memory
void *pngdub = g_memdup (png, (guint)pngsize);
void *pngdub = g_memdup (png, (guint)pnglen);
free (png);
int imgStoreId = purple_imgstore_add_with_id (pngdub, pngsize, NULL);
int imgStoreId = purple_imgstore_add_with_id (pngdub, pnglen, NULL);
return imgStoreId;
}
#endif

View file

@ -27,9 +27,6 @@
#include "lodepng/lodepng.h"
#include <purple.h>
#ifdef HAVE_LIBWEBP
#include <webp/decode.h>
#endif
connection_data *get_conn_from_buddy (PurpleBuddy *buddy) {
connection_data *c = purple_connection_get_protocol_data (
@ -145,27 +142,3 @@ const char *tgp_mime_to_filetype (const char *mime) {
}
return NULL;
}
#ifdef HAVE_LIBWEBP
void *tgp_webp_load_png (const char *filename, size_t *size) {
gchar *data = NULL;
size_t len;
GError *err = NULL;
g_file_get_contents (filename, &data, &len, &err);
if (err) { warning ("cannot open file %s: %s.", filename, err->message); return NULL; }
int width, height;
uint8_t* decoded = WebPDecodeRGBA ((const uint8_t*)data, len, &width, &height);
g_free (data);
if (! decoded) { warning ("failed decoding webp"); return NULL; }
unsigned char* png = NULL;
size_t pnglen;
unsigned error = lodepng_encode32 (&png, &pnglen, decoded, width, height);
free (decoded);
if (error) { warning ("failed encoding png"); return NULL; }
*size = pnglen;
return png;
}
#endif

View file

@ -50,6 +50,5 @@ char *tgp_g_format_size (gint64 size);
void tgp_g_queue_free_full (GQueue *queue, GDestroyNotify free_func);
void tgp_g_list_free_full (GList *list, GDestroyNotify free_func);
const char *tgp_mime_to_filetype (const char *mime);
void *tgp_webp_load_png (const char *filename, size_t *size);
#endif