comparison gtk/gtkutils.c @ 15227:a5ef8fc9fbeb

[gaim-migrate @ 18017] Print an error and don't set the icon if the file is too big committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 17 Dec 2006 19:17:36 +0000
parents 26357b7f117e
children 30932055bb7c
comparison
equal deleted inserted replaced
15226:2af69418b24e 15227:a5ef8fc9fbeb
2453 return TRUE; 2453 return TRUE;
2454 return FALSE; 2454 return FALSE;
2455 } 2455 }
2456 #endif 2456 #endif
2457 2457
2458 /* TODO: Use icon_spec.filesize */
2459 char * 2458 char *
2460 gaim_gtk_convert_buddy_icon(GaimPlugin *plugin, const char *path) 2459 gaim_gtk_convert_buddy_icon(GaimPlugin *plugin, const char *path)
2461 { 2460 {
2462 GaimPluginProtocolInfo *prpl_info; 2461 GaimPluginProtocolInfo *prpl_info;
2462 #if GTK_CHECK_VERSION(2,2,0)
2463 char **prpl_formats; 2463 char **prpl_formats;
2464 #if GTK_CHECK_VERSION(2,2,0)
2465 int width, height; 2464 int width, height;
2466 char **pixbuf_formats = NULL; 2465 char **pixbuf_formats = NULL;
2467 GdkPixbufFormat *format; 2466 GdkPixbufFormat *format;
2468 GdkPixbuf *pixbuf; 2467 GdkPixbuf *pixbuf;
2469 #if !GTK_CHECK_VERSION(2,4,0) 2468 #if !GTK_CHECK_VERSION(2,4,0)
2473 gchar *contents; 2472 gchar *contents;
2474 gsize length; 2473 gsize length;
2475 const char *dirname; 2474 const char *dirname;
2476 char *random; 2475 char *random;
2477 char *filename; 2476 char *filename;
2477 struct stat st;
2478 2478
2479 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); 2479 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin);
2480 2480
2481 g_return_val_if_fail(prpl_info->icon_spec.format != NULL, NULL); 2481 g_return_val_if_fail(prpl_info->icon_spec.format != NULL, NULL);
2482 2482
2483 prpl_formats = g_strsplit(prpl_info->icon_spec.format,",",0);
2484 dirname = gaim_buddy_icons_get_cache_dir(); 2483 dirname = gaim_buddy_icons_get_cache_dir();
2485 random = g_strdup_printf("%x", g_random_int());
2486 filename = g_build_filename(dirname, random, NULL);
2487
2488 if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) { 2484 if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) {
2489 gaim_debug_info("buddyicon", "Creating icon cache directory.\n"); 2485 gaim_debug_info("buddyicon", "Creating icon cache directory.\n");
2490 2486
2491 if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) { 2487 if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) {
2492 gaim_debug_error("buddyicon", 2488 gaim_debug_error("buddyicon",
2493 "Unable to create directory %s: %s\n", 2489 "Unable to create directory %s: %s\n",
2494 dirname, strerror(errno)); 2490 dirname, strerror(errno));
2495 g_strfreev(prpl_formats);
2496 g_free(random);
2497 g_free(filename);
2498 return NULL; 2491 return NULL;
2499 } 2492 }
2500 } 2493 }
2494
2495 random = g_strdup_printf("%x", g_random_int());
2496 filename = g_build_filename(dirname, random, NULL);
2501 2497
2502 #if GTK_CHECK_VERSION(2,2,0) 2498 #if GTK_CHECK_VERSION(2,2,0)
2503 #if GTK_CHECK_VERSION(2,4,0) 2499 #if GTK_CHECK_VERSION(2,4,0)
2504 format = gdk_pixbuf_get_file_info (path, &width, &height); 2500 format = gdk_pixbuf_get_file_info(path, &width, &height);
2505 #else 2501 #else
2506 loader = gdk_pixbuf_loader_new(); 2502 loader = gdk_pixbuf_loader_new();
2507 if (g_file_get_contents(path, &contents, &length, NULL)) { 2503 if (g_file_get_contents(path, &contents, &length, NULL)) {
2508 gdk_pixbuf_loader_write(loader, contents, length, NULL); 2504 gdk_pixbuf_loader_write(loader, contents, length, NULL);
2509 g_free(contents); 2505 g_free(contents);
2515 format = gdk_pixbuf_loader_get_format(loader); 2511 format = gdk_pixbuf_loader_get_format(loader);
2516 g_object_unref(G_OBJECT(loader)); 2512 g_object_unref(G_OBJECT(loader));
2517 #endif 2513 #endif
2518 if (format == NULL) 2514 if (format == NULL)
2519 return NULL; 2515 return NULL;
2520 pixbuf_formats = gdk_pixbuf_format_get_extensions(format); 2516
2521 2517 pixbuf_formats = gdk_pixbuf_format_get_extensions(format);
2518 prpl_formats = g_strsplit(prpl_info->icon_spec.format,",",0);
2522 if (str_array_match(pixbuf_formats, prpl_formats) && /* This is an acceptable format AND */ 2519 if (str_array_match(pixbuf_formats, prpl_formats) && /* This is an acceptable format AND */
2523 (!(prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) || /* The prpl doesn't scale before it sends OR */ 2520 (!(prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) || /* The prpl doesn't scale before it sends OR */
2524 (prpl_info->icon_spec.min_width <= width && 2521 (prpl_info->icon_spec.min_width <= width &&
2525 prpl_info->icon_spec.max_width >= width && 2522 prpl_info->icon_spec.max_width >= width &&
2526 prpl_info->icon_spec.min_height <= height && 2523 prpl_info->icon_spec.min_height <= height &&
2566 g_free(contents); 2563 g_free(contents);
2567 2564
2568 #if GTK_CHECK_VERSION(2,2,0) && !GTK_CHECK_VERSION(2,4,0) 2565 #if GTK_CHECK_VERSION(2,2,0) && !GTK_CHECK_VERSION(2,4,0)
2569 g_object_unref(G_OBJECT(pixbuf)); 2566 g_object_unref(G_OBJECT(pixbuf));
2570 #endif 2567 #endif
2571
2572 g_free(filename);
2573 return random;
2574 } 2568 }
2575 #if GTK_CHECK_VERSION(2,2,0) 2569 #if GTK_CHECK_VERSION(2,2,0)
2576 else 2570 else
2577 { 2571 {
2578 int i; 2572 int i;
2579 GError *error = NULL; 2573 GError *error = NULL;
2580 GdkPixbuf *scale; 2574 GdkPixbuf *scale;
2575 g_strfreev(pixbuf_formats);
2576
2581 pixbuf = gdk_pixbuf_new_from_file(path, &error); 2577 pixbuf = gdk_pixbuf_new_from_file(path, &error);
2582 g_strfreev(pixbuf_formats); 2578 if (error) {
2583 if (!error && (prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) && 2579 gaim_debug_error("buddyicon", "Could not open icon for conversion: %s\n", error->message);
2580 g_error_free(error);
2581 g_free(random);
2582 g_free(filename);
2583 g_strfreev(prpl_formats);
2584 return NULL;
2585 }
2586
2587 if ((prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) &&
2584 (width < prpl_info->icon_spec.min_width || 2588 (width < prpl_info->icon_spec.min_width ||
2585 width > prpl_info->icon_spec.max_width || 2589 width > prpl_info->icon_spec.max_width ||
2586 height < prpl_info->icon_spec.min_height || 2590 height < prpl_info->icon_spec.min_height ||
2587 height > prpl_info->icon_spec.max_height)) 2591 height > prpl_info->icon_spec.max_height))
2588 { 2592 {
2589 int new_width = width; 2593 int new_width = width;
2590 int new_height = height; 2594 int new_height = height;
2591 2595
2592 gaim_buddy_icon_get_scale_size(&prpl_info->icon_spec, &new_width, &new_height); 2596 gaim_buddy_icon_get_scale_size(&prpl_info->icon_spec, &new_width, &new_height);
2593 2597
2594 scale = gdk_pixbuf_scale_simple (pixbuf, new_width, new_height, 2598 scale = gdk_pixbuf_scale_simple(pixbuf, new_width, new_height,
2595 GDK_INTERP_HYPER); 2599 GDK_INTERP_HYPER);
2596 g_object_unref(G_OBJECT(pixbuf)); 2600 g_object_unref(G_OBJECT(pixbuf));
2597 pixbuf = scale; 2601 pixbuf = scale;
2598 } 2602 }
2599 if (error) {
2600 g_free(random);
2601 g_free(filename);
2602 gaim_debug_error("buddyicon", "Could not open icon for conversion: %s\n", error->message);
2603 g_error_free(error);
2604 g_strfreev(prpl_formats);
2605 return NULL;
2606 }
2607 2603
2608 for (i = 0; prpl_formats[i]; i++) { 2604 for (i = 0; prpl_formats[i]; i++) {
2609 gaim_debug_info("buddyicon", "Converting buddy icon to %s as %s\n", prpl_formats[i], filename); 2605 gaim_debug_info("buddyicon", "Converting buddy icon to %s as %s\n", prpl_formats[i], filename);
2610 if (gdk_pixbuf_save(pixbuf, filename, prpl_formats[i], &error, NULL)) 2606 if (strcmp(prpl_formats[i], "png") == 0) {
2607 if (gdk_pixbuf_save(pixbuf, filename, prpl_formats[i],
2608 &error, "compression", "9", NULL))
2611 /* Success! */ 2609 /* Success! */
2612 break; 2610 break;
2611 } else if (gdk_pixbuf_save(pixbuf, filename, prpl_formats[i],
2612 &error, NULL)) {
2613 /* Success! */
2614 break;
2615 }
2613 gaim_debug_warning("buddyicon", "Could not convert to %s: %s\n", prpl_formats[i], error->message); 2616 gaim_debug_warning("buddyicon", "Could not convert to %s: %s\n", prpl_formats[i], error->message);
2614 g_error_free(error); 2617 g_error_free(error);
2615 error = NULL; 2618 error = NULL;
2616 } 2619 }
2617 g_strfreev(prpl_formats); 2620 g_strfreev(prpl_formats);
2618 if (!error) { 2621 g_object_unref(G_OBJECT(pixbuf));
2619 g_object_unref(G_OBJECT(pixbuf)); 2622 if (error) {
2620 g_free(filename);
2621 return random;
2622 } else {
2623 gaim_debug_error("buddyicon", "Could not convert icon to usable format: %s\n", error->message); 2623 gaim_debug_error("buddyicon", "Could not convert icon to usable format: %s\n", error->message);
2624 g_error_free(error); 2624 g_error_free(error);
2625 } 2625 g_free(random);
2626 g_free(filename);
2627 return NULL;
2628 }
2629 }
2630
2631 if (g_stat(filename, &st) != 0) {
2632 gaim_debug_error("buddyicon",
2633 "Could not stat '%s', which we just wrote to disk: %s\n",
2634 filename, strerror(errno));
2626 g_free(random); 2635 g_free(random);
2627 g_free(filename); 2636 g_free(filename);
2628 g_object_unref(G_OBJECT(pixbuf)); 2637 return NULL;
2629 } 2638 }
2639
2640 /* Check the file size */
2641 /*
2642 * TODO: If the file is too big, it would be cool if we checked if
2643 * the prpl supported jpeg, and then we could convert to that
2644 * and use a lower quality setting.
2645 */
2646 if (st.st_size > prpl_info->icon_spec.max_filesize)
2647 {
2648 gchar *tmp;
2649 tmp = g_strdup_printf(_("The file '%s' is too large for %s. Please try a smaller image.\n"),
2650 path, plugin->info->name);
2651 gaim_notify_error(NULL, _("Icon Error"),
2652 _("Could not set icon"), tmp);
2653 gaim_debug_info("buddyicon",
2654 "'%s' was converted to an image which is %" G_GSIZE_FORMAT
2655 " bytes, but the maximum icon size for %s is %" G_GSIZE_FORMAT
2656 " bytes\n", path, st.st_size, plugin->info->name,
2657 prpl_info->icon_spec.max_filesize);
2658 g_free(tmp);
2659 g_free(random);
2660 g_free(filename);
2661 return NULL;
2662 }
2663
2664 g_free(filename);
2665 return random;
2666 #else
2667 /*
2668 * The chosen icon wasn't the right size, and we're using
2669 * GTK+ 2.0 so we can't scale it.
2670 */
2630 return NULL; 2671 return NULL;
2631 #endif 2672 #endif
2632 } 2673 }
2633 2674
2634 #if !GTK_CHECK_VERSION(2,6,0) 2675 #if !GTK_CHECK_VERSION(2,6,0)