4 * Copyright (C) 2009 by ProFUSION embedded systems
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or (at your
9 * option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * @author Rafael Antognolli <antognolli@profusion.mobi>
27 #include <eina_safety_checks.h>
29 #include "ethumb_private.h"
30 #include "Ethumb_Plugin.h"
37 #include <sys/types.h>
49 #include <Ecore_Evas.h>
50 #include <Ecore_File.h>
53 static int _log_dom = -1;
54 #define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
55 #define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
56 #define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
57 #define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
59 static int initcount = 0;
60 static const char *_home_thumb_dir = NULL;
61 static const char *_thumb_category_normal = NULL;
62 static const char *_thumb_category_large = NULL;
64 static const int THUMB_SIZE_NORMAL = 128;
65 static const int THUMB_SIZE_LARGE = 256;
67 static Eina_Hash *_plugins_ext = NULL;
68 static Eina_Array *_plugins = NULL;
71 _ethumb_plugin_list_cb(Eina_Module *m, void *data __UNUSED__)
75 Ethumb_Plugin *plugin;
76 Ethumb_Plugin *(*plugin_get)(void);
78 file = eina_module_file_get(m);
79 if (!eina_module_load(m))
81 ERR("could not load module \"%s\": %s\n",
82 file, eina_error_msg_get(eina_error_get()));
86 plugin_get = eina_module_symbol_get(m, "ethumb_plugin_get");
89 ERR("could not find ethumb_plugin_get() in module \"%s\": %s\n",
90 file, eina_error_msg_get(eina_error_get()));
91 eina_module_unload(m);
95 plugin = plugin_get();
98 ERR("plugin \"%s\" failed to init.\n", file);
99 eina_module_unload(m);
103 DBG("loaded plugin \"%s\" (%p) with extensions:\n", file, plugin);
104 for (ext = plugin->extensions; *ext; ext++)
106 DBG(" extension \"%s\"\n", *ext);
107 eina_hash_add(_plugins_ext, *ext, plugin);
114 _ethumb_plugins_load(void)
116 _plugins_ext = eina_hash_string_small_new(NULL);
117 EINA_SAFETY_ON_NULL_RETURN(_plugins_ext);
119 _plugins = eina_module_list_get(_plugins, PLUGINSDIR, 1,
120 &_ethumb_plugin_list_cb, NULL);
124 _ethumb_plugins_unload(void)
126 eina_hash_free(_plugins_ext);
128 eina_module_list_unload(_plugins);
129 eina_module_list_flush(_plugins);
130 eina_array_free(_plugins);
145 fprintf(stderr, "ERROR: Could not initialize eina.\n");
148 _log_dom = eina_log_domain_register("ethumb", EINA_COLOR_GREEN);
151 EINA_LOG_ERR("Could not register log domain: ethumb");
161 home = getenv("HOME");
162 snprintf(buf, sizeof(buf), "%s/.thumbnails", home);
164 _home_thumb_dir = eina_stringshare_add(buf);
165 _thumb_category_normal = eina_stringshare_add("normal");
166 _thumb_category_large = eina_stringshare_add("large");
168 _ethumb_plugins_load();
173 ethumb_shutdown(void)
178 _ethumb_plugins_unload();
179 eina_stringshare_del(_home_thumb_dir);
180 eina_stringshare_del(_thumb_category_normal);
181 eina_stringshare_del(_thumb_category_large);
184 ecore_evas_shutdown();
186 eina_log_domain_unregister(_log_dom);
198 Ecore_Evas *ee, *sub_ee;
200 Evas_Object *o, *img;
202 ethumb = calloc(1, sizeof(Ethumb));
203 EINA_SAFETY_ON_NULL_RETURN_VAL(ethumb, NULL);
205 ethumb->tw = THUMB_SIZE_NORMAL;
206 ethumb->th = THUMB_SIZE_NORMAL;
207 ethumb->crop_x = 0.5;
208 ethumb->crop_y = 0.5;
209 ethumb->quality = 80;
210 ethumb->compress = 9;
211 ethumb->video.start = 0.1;
212 ethumb->video.time = 3;
213 ethumb->video.interval = 0.05;
214 ethumb->video.ntimes = 3;
215 ethumb->video.fps = 10;
217 ee = ecore_evas_buffer_new(1, 1);
218 e = ecore_evas_get(ee);
221 ERR("could not create ecore evas buffer\n");
225 evas_image_cache_set(e, 0);
226 evas_font_cache_set(e, 0);
228 o = ecore_evas_object_image_new(ee);
231 ERR("could not create sub ecore evas buffer\n");
237 sub_ee = evas_object_data_get(o, "Ecore_Evas");
238 sub_e = ecore_evas_get(sub_ee);
240 evas_image_cache_set(sub_e, 0);
241 evas_font_cache_set(sub_e, 0);
243 img = evas_object_image_add(sub_e);
246 ERR("could not create source objects.\n");
254 ethumb->sub_ee = sub_ee;
255 ethumb->sub_e = sub_e;
259 DBG("ethumb=%p\n", ethumb);
265 _ethumb_frame_free(Ethumb_Frame *frame)
272 if (frame->swallow && frame->edje)
274 o = edje_object_part_swallow_get(frame->edje, frame->swallow);
276 edje_object_part_unswallow(frame->edje, o);
278 eina_stringshare_del(frame->file);
279 eina_stringshare_del(frame->group);
280 eina_stringshare_del(frame->swallow);
283 evas_object_del(frame->edje);
289 ethumb_free(Ethumb *ethumb)
291 EINA_SAFETY_ON_NULL_RETURN(ethumb);
293 DBG("ethumb=%p", ethumb);
296 _ethumb_frame_free(ethumb->frame);
297 ethumb_file_free(ethumb);
298 ecore_evas_free(ethumb->ee);
299 eina_stringshare_del(ethumb->thumb_dir);
300 eina_stringshare_del(ethumb->category);
301 if (ethumb->finished_idler)
302 ecore_idler_del(ethumb->finished_idler);
307 ethumb_thumb_fdo_set(Ethumb *e, Ethumb_Thumb_FDO_Size s)
309 EINA_SAFETY_ON_NULL_RETURN(e);
310 EINA_SAFETY_ON_FALSE_RETURN(s == ETHUMB_THUMB_NORMAL ||
311 s == ETHUMB_THUMB_LARGE);
312 DBG("ethumb=%p, size=%d", e, s);
314 if (s == ETHUMB_THUMB_NORMAL)
316 e->tw = THUMB_SIZE_NORMAL;
317 e->th = THUMB_SIZE_NORMAL;
321 e->tw = THUMB_SIZE_LARGE;
322 e->th = THUMB_SIZE_LARGE;
325 e->format = ETHUMB_THUMB_FDO;
326 e->aspect = ETHUMB_THUMB_KEEP_ASPECT;
327 _ethumb_frame_free(e->frame);
329 eina_stringshare_del(e->thumb_dir);
330 eina_stringshare_del(e->category);
336 ethumb_thumb_size_set(Ethumb *e, int tw, int th)
338 EINA_SAFETY_ON_NULL_RETURN(e);
339 EINA_SAFETY_ON_FALSE_RETURN(tw > 0);
340 EINA_SAFETY_ON_FALSE_RETURN(th > 0);
342 DBG("ethumb=%p, w=%d, h=%d", e, tw, th);
348 ethumb_thumb_size_get(const Ethumb *e, int *tw, int *th)
350 EINA_SAFETY_ON_NULL_RETURN(e);
357 ethumb_thumb_format_set(Ethumb *e, Ethumb_Thumb_Format f)
359 EINA_SAFETY_ON_NULL_RETURN(e);
360 EINA_SAFETY_ON_FALSE_RETURN(f == ETHUMB_THUMB_FDO ||
361 f == ETHUMB_THUMB_JPEG ||
362 f == ETHUMB_THUMB_EET);
364 DBG("ethumb=%p, format=%d", e, f);
368 EAPI Ethumb_Thumb_Format
369 ethumb_thumb_format_get(const Ethumb *e)
371 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
376 ethumb_thumb_aspect_set(Ethumb *e, Ethumb_Thumb_Aspect a)
378 EINA_SAFETY_ON_NULL_RETURN(e);
379 EINA_SAFETY_ON_FALSE_RETURN(a == ETHUMB_THUMB_KEEP_ASPECT ||
380 a == ETHUMB_THUMB_IGNORE_ASPECT ||
381 a == ETHUMB_THUMB_CROP);
383 DBG("ethumb=%p, aspect=%d", e, a);
387 EAPI Ethumb_Thumb_Aspect
388 ethumb_thumb_aspect_get(const Ethumb *e)
390 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
395 ethumb_thumb_crop_align_set(Ethumb *e, float x, float y)
397 EINA_SAFETY_ON_NULL_RETURN(e);
399 DBG("ethumb=%p, x=%f, y=%f", e, x, y);
405 ethumb_thumb_crop_align_get(const Ethumb *e, float *x, float *y)
407 EINA_SAFETY_ON_NULL_RETURN(e);
409 if (x) *x = e->crop_x;
410 if (y) *y = e->crop_y;
414 ethumb_thumb_quality_set(Ethumb *e, int quality)
416 EINA_SAFETY_ON_NULL_RETURN(e);
418 DBG("ethumb=%p, quality=%d", e, quality);
419 e->quality = quality;
423 ethumb_thumb_quality_get(const Ethumb *e)
425 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
430 ethumb_thumb_compress_set(Ethumb *e, int compress)
432 EINA_SAFETY_ON_NULL_RETURN(e);
434 DBG("ethumb=%p, compress=%d", e, compress);
435 e->compress = compress;
439 ethumb_thumb_compress_get(const Ethumb *e)
441 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
446 ethumb_frame_set(Ethumb *e, const char *theme_file, const char *group, const char *swallow)
448 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
453 DBG("ethumb=%p, theme_file=%s, group=%s, swallow=%s",
454 e, theme_file ? theme_file : "", group ? group : "",
455 swallow ? swallow : "");
459 edje_object_part_unswallow(frame->edje, e->img);
461 _ethumb_frame_free(frame);
472 frame = calloc(1, sizeof(Ethumb_Frame));
475 ERR("could not allocate Ethumb_Frame structure.\n");
479 frame->edje = edje_object_add(e->sub_e);
482 ERR("could not create edje frame object.\n");
483 _ethumb_frame_free(frame);
489 if (!edje_object_file_set(frame->edje, theme_file, group))
491 ERR("could not load frame theme.\n");
492 _ethumb_frame_free(frame);
497 edje_object_part_swallow(frame->edje, swallow, e->img);
498 if (!edje_object_part_swallow_get(frame->edje, swallow))
500 ERR("could not swallow image to edje frame.\n");
501 _ethumb_frame_free(frame);
506 eina_stringshare_replace(&frame->file, theme_file);
507 eina_stringshare_replace(&frame->group, group);
508 eina_stringshare_replace(&frame->swallow, swallow);
516 ethumb_frame_get(const Ethumb *e, const char **theme_file, const char **group, const char **swallow)
518 EINA_SAFETY_ON_NULL_RETURN(e);
522 if (theme_file) *theme_file = e->frame->file;
523 if (group) *group = e->frame->group;
524 if (swallow) *swallow = e->frame->swallow;
528 if (theme_file) *theme_file = NULL;
529 if (group) *group = NULL;
530 if (swallow) *swallow = NULL;
535 _ethumb_build_absolute_path(const char *path, char buf[])
547 else if (path[0] == '~')
549 strcpy(p, getenv("HOME"));
570 ethumb_thumb_dir_path_set(Ethumb *e, const char *path)
573 EINA_SAFETY_ON_NULL_RETURN(e);
575 DBG("ethumb=%p, path=%s", e, path ? path : "");
576 path = _ethumb_build_absolute_path(path, buf);
577 eina_stringshare_replace(&e->thumb_dir, path);
581 ethumb_thumb_dir_path_get(const Ethumb *e)
583 EINA_SAFETY_ON_NULL_RETURN_VAL(e, NULL);
589 ethumb_thumb_category_set(Ethumb *e, const char *category)
591 EINA_SAFETY_ON_NULL_RETURN(e);
593 DBG("ethumb=%p, category=%s", e, category ? category : "");
594 eina_stringshare_replace(&e->category, category);
598 ethumb_thumb_category_get(const Ethumb *e)
600 EINA_SAFETY_ON_NULL_RETURN_VAL(e, NULL);
606 ethumb_video_start_set(Ethumb *e, float start)
608 EINA_SAFETY_ON_NULL_RETURN(e);
610 DBG("ethumb=%p, video_start=%f", e, start);
611 e->video.start = start;
615 ethumb_video_start_get(const Ethumb *e)
617 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
619 return e->video.start;
623 ethumb_video_time_set(Ethumb *e, float time)
625 EINA_SAFETY_ON_NULL_RETURN(e);
627 DBG("ethumb=%p, video_start=%f", e, time);
628 e->video.time = time;
632 ethumb_video_time_get(const Ethumb *e)
634 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
636 return e->video.time;
640 ethumb_video_interval_set(Ethumb *e, float interval)
642 EINA_SAFETY_ON_NULL_RETURN(e);
644 DBG("ethumb=%p, video_interval=%f", e, interval);
645 e->video.interval = interval;
649 ethumb_video_interval_get(const Ethumb *e)
651 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
653 return e->video.interval;
657 ethumb_video_ntimes_set(Ethumb *e, int ntimes)
659 EINA_SAFETY_ON_NULL_RETURN(e);
661 DBG("ethumb=%p, video_ntimes=%d", e, ntimes);
662 e->video.ntimes = ntimes;
666 ethumb_video_ntimes_get(const Ethumb *e)
668 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
670 return e->video.ntimes;
674 ethumb_video_fps_set(Ethumb *e, int fps)
676 EINA_SAFETY_ON_NULL_RETURN(e);
678 DBG("ethumb=%p, video_fps=%d", e, fps);
683 ethumb_video_fps_get(const Ethumb *e)
685 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
691 ethumb_document_page_set(Ethumb *e, int page)
693 EINA_SAFETY_ON_NULL_RETURN(e);
695 DBG("ethumb=%p, document_page=%d", e, page);
696 e->document.page = page;
700 ethumb_document_page_get(const Ethumb *e)
702 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
704 return e->document.page;
708 ethumb_file_set(Ethumb *e, const char *path, const char *key)
711 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
713 DBG("ethumb=%p, path=%s, key=%s", e, path ? path : "", key ? key : "");
714 if (path && access(path, R_OK))
716 ERR("couldn't access file \"%s\"\n", path);
720 path = _ethumb_build_absolute_path(path, buf);
721 eina_stringshare_replace(&e->src_path, path);
722 eina_stringshare_replace(&e->src_key, key);
723 eina_stringshare_replace(&e->thumb_path, NULL);
724 eina_stringshare_replace(&e->thumb_key, NULL);
730 ethumb_file_get(const Ethumb *e, const char **path, const char **key)
732 EINA_SAFETY_ON_NULL_RETURN(e);
734 if (path) *path = e->src_path;
735 if (key) *key = e->src_key;
738 static const char ACCEPTABLE_URI_CHARS[96] = {
739 /* ! " # $ % & ' ( ) * + , - . / */
740 0x00,0x3F,0x20,0x20,0x28,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x2A,0x28,0x3F,0x3F,0x1C,
741 /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
742 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x20,
743 /* @ A B C D E F G H I J K L M N O */
744 0x38,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
745 /* P Q R S T U V W X Y Z [ \ ] ^ _ */
746 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F,
747 /* ` a b c d e f g h i j k l m n o */
748 0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
749 /* p q r s t u v w x y z { | } ~ DEL */
750 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20
754 _ethumb_generate_hash(const char *file)
758 char md5out[(2 * MD5_HASHBYTES) + 1];
759 unsigned char hash[MD5_HASHBYTES];
760 static const char hex[] = "0123456789abcdef";
764 const unsigned char *c;
766 #define _check_uri_char(c) \
767 ((c) >= 32 && (c) < 128 && (ACCEPTABLE_URI_CHARS[(c) - 32] & 0x08))
769 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
771 uri = alloca(3 * strlen(file) + 9);
772 strncpy(uri, "file://", sizeof(uri));
775 for (c = (const unsigned char *)file; *c != '\0'; c++)
777 if (!_check_uri_char(*c))
788 #undef _check_uri_char
791 MD5Update (&ctx, (unsigned char const*)uri, (unsigned)strlen (uri));
792 MD5Final (hash, &ctx);
794 for (n = 0; n < MD5_HASHBYTES; n++)
796 md5out[2 * n] = hex[hash[n] >> 4];
797 md5out[2 * n + 1] = hex[hash[n] & 0x0f];
799 md5out[2 * n] = '\0';
801 DBG("md5=%s, file=%s\n", md5out, file);
802 return eina_stringshare_add(md5out);
806 _ethumb_file_check_fdo(Ethumb *e)
808 if (!((e->tw == THUMB_SIZE_NORMAL && e->th == THUMB_SIZE_NORMAL) ||
809 (e->tw == THUMB_SIZE_LARGE && e->th == THUMB_SIZE_LARGE)))
812 if (e->format != ETHUMB_THUMB_FDO)
815 if (e->aspect != ETHUMB_THUMB_KEEP_ASPECT)
825 _ethumb_file_generate_custom_category(Ethumb *e)
828 const char *aspect, *format;
831 if (e->aspect == ETHUMB_THUMB_KEEP_ASPECT)
832 aspect = "keep_aspect";
833 else if (e->aspect == ETHUMB_THUMB_IGNORE_ASPECT)
834 aspect = "ignore_aspect";
838 if (e->format == ETHUMB_THUMB_FDO)
840 else if (e->format == ETHUMB_THUMB_JPEG)
850 snprintf(buf, sizeof(buf), "%dx%d-%s%s-%s",
851 e->tw, e->th, aspect, frame, format);
853 return eina_stringshare_add(buf);
857 _ethumb_file_generate_path(Ethumb *e)
862 const char *thumb_dir, *category;
867 fdo_format = _ethumb_file_check_fdo(e);
870 thumb_dir = eina_stringshare_ref(e->thumb_dir);
872 thumb_dir = eina_stringshare_ref(_home_thumb_dir);
875 category = eina_stringshare_ref(e->category);
876 else if (!fdo_format)
877 category = _ethumb_file_generate_custom_category(e);
880 if (e->tw == THUMB_SIZE_NORMAL)
881 category = eina_stringshare_ref(_thumb_category_normal);
882 else if (e->tw == THUMB_SIZE_LARGE)
883 category = eina_stringshare_ref(_thumb_category_large);
886 if (e->format == ETHUMB_THUMB_FDO)
888 else if (e->format == ETHUMB_THUMB_JPEG)
894 fullname = ecore_file_realpath(e->src_path);
895 hash = _ethumb_generate_hash(fullname);
896 snprintf(buf, sizeof(buf), "%s/%s/%s.%s", thumb_dir, category, hash, ext);
898 DBG("ethumb=%p, path=%s", e, buf);
899 eina_stringshare_replace(&e->thumb_path, buf);
900 if (e->format == ETHUMB_THUMB_EET)
901 eina_stringshare_replace(&e->thumb_key, "thumbnail");
904 eina_stringshare_del(e->thumb_key);
908 eina_stringshare_del(thumb_dir);
909 eina_stringshare_del(category);
910 eina_stringshare_del(hash);
914 ethumb_file_free(Ethumb *e)
916 EINA_SAFETY_ON_NULL_RETURN(e);
919 eina_stringshare_replace(&e->src_path, NULL);
920 eina_stringshare_replace(&e->src_key, NULL);
921 eina_stringshare_replace(&e->thumb_path, NULL);
922 eina_stringshare_replace(&e->thumb_key, NULL);
926 ethumb_thumb_path_set(Ethumb *e, const char *path, const char *key)
930 EINA_SAFETY_ON_NULL_RETURN(e);
931 DBG("ethumb=%p, path=%s, key=%s", e, path ? path : "", key ? key : "");
935 eina_stringshare_replace(&e->thumb_path, NULL);
936 eina_stringshare_replace(&e->thumb_key, NULL);
940 path = _ethumb_build_absolute_path(path, buf);
941 eina_stringshare_replace(&e->thumb_path, path);
942 eina_stringshare_replace(&e->thumb_key, key);
947 ethumb_thumb_path_get(Ethumb *e, const char **path, const char **key)
949 EINA_SAFETY_ON_NULL_RETURN(e);
951 _ethumb_file_generate_path(e);
953 if (path) *path = e->thumb_path;
954 if (key) *key = e->thumb_key;
958 ethumb_calculate_aspect_from_ratio(Ethumb *e, float ia, int *w, int *h)
968 a = e->tw / (float)e->th;
970 if (e->aspect == ETHUMB_THUMB_KEEP_ASPECT)
972 if ((ia > a && e->tw > 0) || e->th <= 0)
980 ethumb_calculate_aspect(Ethumb *e, int iw, int ih, int *w, int *h)
986 ethumb_calculate_aspect_from_ratio(e, ia, w, h);
990 ethumb_calculate_fill_from_ratio(Ethumb *e, float ia, int *fx, int *fy, int *fw, int *fh)
1001 a = e->tw / (float)e->th;
1003 if (e->aspect == ETHUMB_THUMB_CROP)
1005 if ((ia > a && e->tw > 0) || e->th <= 0)
1010 *fx = - e->crop_x * (*fw - e->tw);
1011 *fy = - e->crop_y * (*fh - e->th);
1013 else if (e->aspect == ETHUMB_THUMB_KEEP_ASPECT)
1015 if ((ia > a && e->tw > 0) || e->th <= 0)
1023 ethumb_calculate_fill(Ethumb *e, int iw, int ih, int *fx, int *fy, int *fw, int *fh)
1026 ia = iw / (float)ih;
1028 ethumb_calculate_fill_from_ratio(e, ia, fx, fy, fw, fh);
1032 _ethumb_plugin_generate(Ethumb *e)
1035 Ethumb_Plugin *plugin;
1037 ext = strrchr(e->src_path, '.');
1040 ERR("could not get extension for file \"%s\"\n", e->src_path);
1044 plugin = eina_hash_find(_plugins_ext, ext + 1);
1047 DBG("no plugin for extension: \"%s\"\n", ext + 1);
1052 evas_object_hide(e->frame->edje);
1054 evas_object_hide(e->img);
1056 plugin->generate_thumb(e);
1062 ethumb_plugin_image_resize(Ethumb *e, int w, int h)
1070 edje_extern_object_min_size_set(img, w, h);
1071 edje_extern_object_max_size_set(img, w, h);
1072 edje_object_calc_force(e->frame->edje);
1073 evas_object_move(e->frame->edje, 0, 0);
1074 evas_object_resize(e->frame->edje, w, h);
1078 evas_object_move(img, 0, 0);
1079 evas_object_resize(img, w, h);
1082 evas_object_image_size_set(e->o, w, h);
1083 ecore_evas_resize(e->sub_ee, w, h);
1092 ethumb_image_save(Ethumb *e)
1098 evas_damage_rectangle_add(e->sub_e, 0, 0, e->rw, e->rh);
1099 evas_render(e->sub_e);
1102 _ethumb_file_generate_path(e);
1106 ERR("could not create file path...\n");
1110 dname = ecore_file_dir_get(e->thumb_path);
1111 r = ecore_file_mkpath(dname);
1115 ERR("could not create directory '%s'\n", dname);
1119 snprintf(flags, sizeof(flags), "quality=%d compress=%d",
1120 e->quality, e->compress);
1121 r = evas_object_image_save(e->o, e->thumb_path, e->thumb_key, flags);
1125 ERR("could not save image.\n");
1133 _ethumb_image_load(Ethumb *e)
1136 Evas_Coord w, h, ww, hh, fx, fy, fw, fh;
1142 evas_object_hide(e->frame->edje);
1144 evas_object_hide(img);
1145 evas_object_image_file_set(img, NULL, NULL);
1146 evas_object_image_load_size_set(img, e->tw, e->th);
1147 evas_object_image_file_set(img, e->src_path, e->src_key);
1150 evas_object_show(e->frame->edje);
1152 evas_object_show(img);
1154 error = evas_object_image_load_error_get(img);
1155 if (error != EVAS_LOAD_ERROR_NONE)
1157 ERR("could not load image '%s': %d\n", e->src_path, error);
1161 evas_object_image_size_get(img, &w, &h);
1162 if ((w <= 0) || (h <= 0))
1165 ethumb_calculate_aspect(e, w, h, &ww, &hh);
1169 edje_extern_object_min_size_set(img, ww, hh);
1170 edje_extern_object_max_size_set(img, ww, hh);
1171 edje_object_calc_force(e->frame->edje);
1172 evas_object_move(e->frame->edje, 0, 0);
1173 evas_object_resize(e->frame->edje, ww, hh);
1177 evas_object_move(img, 0, 0);
1178 evas_object_resize(img, ww, hh);
1181 ethumb_calculate_fill(e, w, h, &fx, &fy, &fw, &fh);
1182 evas_object_image_fill_set(img, fx, fy, fw, fh);
1184 evas_object_image_size_set(e->o, ww, hh);
1185 ecore_evas_resize(e->sub_ee, ww, hh);
1194 _ethumb_finished_idler_cb(void *data)
1198 e->finished_cb(e->cb_data, e, e->cb_result);
1199 if (e->cb_data_free)
1200 e->cb_data_free(e->cb_data);
1201 e->finished_idler = NULL;
1202 e->finished_cb = NULL;
1204 e->cb_data_free = NULL;
1210 ethumb_finished_callback_call(Ethumb *e, int result)
1212 EINA_SAFETY_ON_NULL_RETURN(e);
1214 e->cb_result = result;
1215 if (e->finished_idler)
1216 ecore_idler_del(e->finished_idler);
1217 e->finished_idler = ecore_idler_add(_ethumb_finished_idler_cb, e);
1221 ethumb_generate(Ethumb *e, Ethumb_Generate_Cb finished_cb, const void *data, Eina_Free_Cb free_data)
1225 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
1226 EINA_SAFETY_ON_NULL_RETURN_VAL(finished_cb, 0);
1227 DBG("ethumb=%p, finished_cb=%p, data=%p, free_data=%p, path=%s, key=%s",
1228 e, finished_cb, data, free_data,
1229 e->src_path ? e->src_path : "", e->src_key ? e->src_key : "");
1231 if (e->finished_idler)
1233 ERR("thumbnail generation already in progress.\n");
1236 e->finished_cb = finished_cb;
1237 e->cb_data = (void *)data;
1238 e->cb_data_free = free_data;
1242 ERR("no file set.\n");
1243 ethumb_finished_callback_call(e, 0);
1247 r = _ethumb_plugin_generate(e);
1251 if (!_ethumb_image_load(e))
1253 ERR("could not load input image.\n");
1254 ethumb_finished_callback_call(e, 0);
1258 r = ethumb_image_save(e);
1260 ethumb_finished_callback_call(e, r);
1266 ethumb_exists(Ethumb *e)
1268 struct stat thumb, src;
1270 Eina_Bool r = EINA_FALSE;
1272 EINA_SAFETY_ON_NULL_RETURN_VAL(e, 0);
1273 EINA_SAFETY_ON_NULL_RETURN_VAL(e->src_path, 0);
1274 DBG("ethumb=%p, path=%s", e, e->src_path ? e->src_path : "");
1277 _ethumb_file_generate_path(e);
1279 EINA_SAFETY_ON_NULL_RETURN_VAL(e->thumb_path, 0);
1281 r_thumb = stat(e->thumb_path, &thumb);
1282 r_src = stat(e->src_path, &src);
1284 EINA_SAFETY_ON_TRUE_RETURN_VAL(r_src, 0);
1286 if (r_thumb && errno != ENOENT)
1287 ERR("could not access file \"%s\": %s\n", e->thumb_path, strerror(errno));
1288 else if (!r_thumb && thumb.st_mtime > src.st_mtime)
1295 ethumb_evas_get(const Ethumb *e)
1297 EINA_SAFETY_ON_NULL_RETURN_VAL(e, NULL);
1303 ethumb_ecore_evas_get(const Ethumb *e)
1305 EINA_SAFETY_ON_NULL_RETURN_VAL(e, NULL);