Add new files for thumbnailing
This commit is contained in:
parent
4b8ea0492b
commit
c2a555939d
|
@ -0,0 +1,27 @@
|
|||
Ephoto's thumbnailing code is from Enlightenment using the following license:
|
||||
|
||||
Copyright notice for Enlightenment:
|
||||
|
||||
Copyright (C) 2000-2012 Carsten Haitzler and various contributors (see AUTHORS)
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,164 @@
|
|||
#include "ephoto.h"
|
||||
#undef ERR
|
||||
#define ERR(...) do { printf(__VA_ARGS__); putc('\n', stdout); } while(0)
|
||||
|
||||
char *e_ipc_socket = NULL;
|
||||
|
||||
#ifdef USE_IPC
|
||||
/* local subsystem functions */
|
||||
static Eina_Bool _e_ipc_cb_client_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
|
||||
static Eina_Bool _e_ipc_cb_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
|
||||
|
||||
/* local subsystem globals */
|
||||
static Ecore_Ipc_Server *_e_ipc_server = NULL;
|
||||
#endif
|
||||
|
||||
/* externally accessible functions */
|
||||
int
|
||||
e_ipc_init(void)
|
||||
{
|
||||
char buf[4096], buf2[128], buf3[4096];
|
||||
char *tmp, *user, *base;
|
||||
int pid, trynum = 0, id1 = 0;
|
||||
struct stat st;
|
||||
|
||||
tmp = getenv("TMPDIR");
|
||||
if (!tmp) tmp = "/tmp";
|
||||
base = tmp;
|
||||
|
||||
tmp = getenv("XDG_RUNTIME_DIR");
|
||||
if (tmp)
|
||||
{
|
||||
if (stat(tmp, &st) == 0)
|
||||
{
|
||||
if ((st.st_uid == getuid()) &&
|
||||
((st.st_mode & (S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)) ==
|
||||
(S_IRWXU | S_IFDIR)))
|
||||
base = tmp;
|
||||
else
|
||||
ERR("XDG_RUNTIME_DIR of '%s' failed permissions check", tmp);
|
||||
}
|
||||
else
|
||||
ERR("XDG_RUNTIME_DIR of '%s' cannot be accessed", tmp);
|
||||
}
|
||||
|
||||
tmp = getenv("SD_USER_SOCKETS_DIR");
|
||||
if (tmp)
|
||||
{
|
||||
if (stat(tmp, &st) == 0)
|
||||
{
|
||||
if ((st.st_uid == getuid()) &&
|
||||
((st.st_mode & (S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)) ==
|
||||
(S_IRWXU | S_IFDIR)))
|
||||
base = tmp;
|
||||
else
|
||||
ERR("SD_USER_SOCKETS_DIR of '%s' failed permissions check", tmp);
|
||||
}
|
||||
else
|
||||
ERR("SD_USER_SOCKETS_DIR of '%s' cannot be accessed", tmp);
|
||||
}
|
||||
|
||||
user = getenv("USER");
|
||||
if (!user)
|
||||
{
|
||||
int uidint;
|
||||
|
||||
user = "__unknown__";
|
||||
uidint = getuid();
|
||||
if (uidint >= 0)
|
||||
{
|
||||
snprintf(buf2, sizeof(buf2), "%i", uidint);
|
||||
user = buf2;
|
||||
}
|
||||
}
|
||||
|
||||
setenv("EPHOTO_IPC_SOCKET", "", 1);
|
||||
|
||||
pid = (int)getpid();
|
||||
for (trynum = 0; trynum <= 4096; trynum++)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%s/e-%s@%x",
|
||||
base, user, id1);
|
||||
if (!mkdir(buf, S_IRWXU))
|
||||
{
|
||||
#ifdef USE_IPC
|
||||
snprintf(buf3, sizeof(buf3), "%s/%i",
|
||||
buf, pid);
|
||||
_e_ipc_server = ecore_ipc_server_add
|
||||
(ECORE_IPC_LOCAL_SYSTEM, buf3, 0, NULL);
|
||||
if (_e_ipc_server)
|
||||
#endif
|
||||
{
|
||||
e_ipc_socket = strdup(ecore_file_file_get(buf));
|
||||
break;
|
||||
}
|
||||
}
|
||||
id1 = rand();
|
||||
}
|
||||
#ifdef USE_IPC
|
||||
if (!_e_ipc_server)
|
||||
{
|
||||
ERR("Gave up after 4096 sockets in '%s'. All failed", base);
|
||||
return 0;
|
||||
}
|
||||
setenv("EPHOTO_IPC_SOCKET", "", 1);
|
||||
setenv("EPHOTO_IPC_SOCKET", buf3, 1);
|
||||
ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL,
|
||||
_e_ipc_cb_client_del, NULL);
|
||||
ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,
|
||||
_e_ipc_cb_client_data, NULL);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
e_ipc_shutdown(void)
|
||||
{
|
||||
#ifdef USE_IPC
|
||||
if (_e_ipc_server)
|
||||
{
|
||||
ecore_ipc_server_del(_e_ipc_server);
|
||||
_e_ipc_server = NULL;
|
||||
}
|
||||
#endif
|
||||
free(e_ipc_socket);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef USE_IPC
|
||||
/* local subsystem globals */
|
||||
static Eina_Bool
|
||||
_e_ipc_cb_client_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
Ecore_Ipc_Event_Client_Del *e;
|
||||
|
||||
e = event;
|
||||
if (ecore_ipc_client_server_get(e->client) != _e_ipc_server)
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
/* delete client sruct */
|
||||
e_thumb_client_del(e);
|
||||
ecore_ipc_client_del(e->client);
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_ipc_cb_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
Ecore_Ipc_Event_Client_Data *e;
|
||||
|
||||
e = event;
|
||||
if (ecore_ipc_client_server_get(e->client) != _e_ipc_server)
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
switch (e->major)
|
||||
{
|
||||
case EPHOTO_IPC_DOMAIN_THUMB:
|
||||
e_thumb_client_data(e);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,438 @@
|
|||
#include "ephoto.h"
|
||||
|
||||
/* Taken from Enlightenment's Internal Thumbnailer */
|
||||
|
||||
typedef struct _E_Thumb E_Thumb;
|
||||
|
||||
struct _E_Thumb
|
||||
{
|
||||
int objid;
|
||||
int w, h;
|
||||
const char *file;
|
||||
const char *key;
|
||||
char *sort_id;
|
||||
unsigned char queued : 1;
|
||||
unsigned char busy : 1;
|
||||
unsigned char done : 1;
|
||||
};
|
||||
|
||||
/* local subsystem functions */
|
||||
static void _e_thumb_gen_begin(int objid, const char *file, const char *key, int w, int h);
|
||||
static void _e_thumb_gen_end(int objid);
|
||||
static void _e_thumb_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
|
||||
static void _e_thumb_hash_add(int objid, Evas_Object *obj);
|
||||
static void _e_thumb_hash_del(int objid);
|
||||
static Evas_Object *_e_thumb_hash_find(int objid);
|
||||
static void _e_thumb_thumbnailers_kill(void);
|
||||
static void _e_thumb_thumbnailers_kill_cancel(void);
|
||||
static Eina_Bool _e_thumb_cb_kill(void *data);
|
||||
static Eina_Bool _e_thumb_cb_exe_event_del(void *data, int type, void *event);
|
||||
|
||||
/* local subsystem globals */
|
||||
static Eina_List *_thumbnailers = NULL;
|
||||
static Eina_List *_thumbnailers_exe = NULL;
|
||||
static Eina_List *_thumb_queue = NULL;
|
||||
static int _objid = 0;
|
||||
static Eina_Hash *_thumbs = NULL;
|
||||
static int _pending = 0;
|
||||
static int _num_thumbnailers = 1;
|
||||
static Ecore_Event_Handler *_exe_del_handler = NULL;
|
||||
static Ecore_Timer *_kill_timer = NULL;
|
||||
|
||||
/* externally accessible functions */
|
||||
int
|
||||
e_thumb_init(void)
|
||||
{
|
||||
_exe_del_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
|
||||
_e_thumb_cb_exe_event_del,
|
||||
NULL);
|
||||
_thumbs = eina_hash_string_superfast_new(NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
e_thumb_shutdown(void)
|
||||
{
|
||||
Ecore_Exe *exe_free;
|
||||
|
||||
_e_thumb_thumbnailers_kill_cancel();
|
||||
_e_thumb_cb_kill(NULL);
|
||||
if (_exe_del_handler) ecore_event_handler_del(_exe_del_handler);
|
||||
_exe_del_handler = NULL;
|
||||
_thumbnailers = eina_list_free(_thumbnailers);
|
||||
EINA_LIST_FREE(_thumbnailers_exe, exe_free)
|
||||
ecore_exe_free(exe_free);
|
||||
_thumb_queue = eina_list_free(_thumb_queue);
|
||||
_objid = 0;
|
||||
eina_hash_free(_thumbs);
|
||||
_thumbs = NULL;
|
||||
_pending = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
_thumb_preloaded(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
||||
{
|
||||
evas_object_smart_callback_call(data, "e_thumb_gen", NULL);
|
||||
}
|
||||
|
||||
Evas_Object *
|
||||
e_thumb_icon_add(Evas *evas)
|
||||
{
|
||||
Evas_Object *obj;
|
||||
E_Thumb *eth;
|
||||
|
||||
obj = elm_icon_add(evas);
|
||||
elm_image_fill_outside_set(obj, EINA_TRUE);
|
||||
evas_object_smart_callback_add(obj, "preloaded", _thumb_preloaded, obj);
|
||||
_objid++;
|
||||
eth = calloc(1, sizeof(E_Thumb));
|
||||
eth->objid = _objid;
|
||||
eth->w = 64;
|
||||
eth->h = 64;
|
||||
evas_object_data_set(obj, "e_thumbdata", eth);
|
||||
evas_object_event_callback_add(obj, EVAS_CALLBACK_FREE,
|
||||
_e_thumb_del_hook, NULL);
|
||||
_e_thumb_hash_add(eth->objid, obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void
|
||||
e_thumb_icon_file_set(Evas_Object *obj, const char *file, const char *key)
|
||||
{
|
||||
E_Thumb *eth;
|
||||
|
||||
eth = evas_object_data_get(obj, "e_thumbdata");
|
||||
if (!eth) return;
|
||||
eina_stringshare_replace(ð->file, file);
|
||||
eina_stringshare_replace(ð->key, key);
|
||||
free(eth->sort_id);
|
||||
}
|
||||
|
||||
void
|
||||
e_thumb_icon_size_set(Evas_Object *obj, int w, int h)
|
||||
{
|
||||
E_Thumb *eth;
|
||||
|
||||
eth = evas_object_data_get(obj, "e_thumbdata");
|
||||
if (!eth) return;
|
||||
if ((w < 1) || (h < 1)) return;
|
||||
eth->w = w;
|
||||
eth->h = h;
|
||||
}
|
||||
|
||||
void
|
||||
e_thumb_icon_begin(Evas_Object *obj)
|
||||
{
|
||||
E_Thumb *eth, *eth2;
|
||||
char buf[4096];
|
||||
|
||||
eth = evas_object_data_get(obj, "e_thumbdata");
|
||||
if (!eth) return;
|
||||
if (eth->queued) return;
|
||||
if (eth->busy) return;
|
||||
if (eth->done) return;
|
||||
if (!eth->file) return;
|
||||
if (!_thumbnailers)
|
||||
{
|
||||
while ((int)eina_list_count(_thumbnailers_exe) < _num_thumbnailers)
|
||||
{
|
||||
Ecore_Exe *exe;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/ephoto_thumbnail --nice=1", PACKAGE_DATA_DIR);
|
||||
exe = ecore_exe_run(buf, NULL);
|
||||
_thumbnailers_exe = eina_list_append(_thumbnailers_exe, exe);
|
||||
}
|
||||
_thumb_queue = eina_list_append(_thumb_queue, eth);
|
||||
eth->queued = 1;
|
||||
return;
|
||||
}
|
||||
EINA_LIST_FREE(_thumb_queue, eth2)
|
||||
{
|
||||
eth2->queued = 0;
|
||||
eth2->busy = 1;
|
||||
_pending++;
|
||||
if (_pending == 1) _e_thumb_thumbnailers_kill_cancel();
|
||||
_e_thumb_gen_begin(eth2->objid, eth2->file, eth2->key, eth2->w, eth2->h);
|
||||
}
|
||||
eth->busy = 1;
|
||||
_pending++;
|
||||
if (_pending == 1) _e_thumb_thumbnailers_kill_cancel();
|
||||
_e_thumb_gen_begin(eth->objid, eth->file, eth->key, eth->w, eth->h);
|
||||
}
|
||||
|
||||
void
|
||||
e_thumb_icon_end(Evas_Object *obj)
|
||||
{
|
||||
E_Thumb *eth;
|
||||
|
||||
eth = evas_object_data_get(obj, "e_thumbdata");
|
||||
if (!eth) return;
|
||||
if (eth->queued)
|
||||
{
|
||||
_thumb_queue = eina_list_remove(_thumb_queue, eth);
|
||||
eth->queued = 0;
|
||||
}
|
||||
if (eth->busy)
|
||||
{
|
||||
_e_thumb_gen_end(eth->objid);
|
||||
eth->busy = 0;
|
||||
_pending--;
|
||||
if (_pending == 0) _e_thumb_thumbnailers_kill();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
e_thumb_icon_rethumb(Evas_Object *obj)
|
||||
{
|
||||
E_Thumb *eth;
|
||||
eth = evas_object_data_get(obj, "e_thumbdata");
|
||||
if (!eth) return;
|
||||
|
||||
if (eth->done) eth->done = 0;
|
||||
else e_thumb_icon_end(obj);
|
||||
|
||||
e_thumb_icon_begin(obj);
|
||||
}
|
||||
|
||||
#define A(v) (((v) >> 24) & 0xff)
|
||||
#define R(v) (((v) >> 16) & 0xff)
|
||||
#define G(v) (((v) >> 8) & 0xff)
|
||||
#define B(v) (((v)) & 0xff)
|
||||
#define PIX(p, x, y) p[((y) << 2) + (x)]
|
||||
#define PIX2(p, x, y) p[((y) << 1) + (x)]
|
||||
|
||||
static void
|
||||
_e_thumb_key_load(E_Thumb *eth, const char *icon)
|
||||
{
|
||||
Eet_File *ef;
|
||||
int size = 0;
|
||||
|
||||
ef = eet_open(icon, EET_FILE_MODE_READ);
|
||||
if (!ef) return;
|
||||
eth->sort_id = eet_read(ef, "/thumbnail/sort_id", &size);
|
||||
if (eth->sort_id)
|
||||
{
|
||||
if (size > 0) eth->sort_id[size - 1] = 0;
|
||||
else
|
||||
{
|
||||
free(eth->sort_id);
|
||||
eth->sort_id = NULL;
|
||||
}
|
||||
}
|
||||
eet_close(ef);
|
||||
}
|
||||
|
||||
const char *
|
||||
e_thumb_sort_id_get(Evas_Object *obj)
|
||||
{
|
||||
E_Thumb *eth;
|
||||
eth = evas_object_data_get(obj, "e_thumbdata");
|
||||
if (!eth) return "";
|
||||
if (!eth->sort_id) return "";
|
||||
return eth->sort_id;
|
||||
}
|
||||
|
||||
void
|
||||
e_thumb_client_data(Ecore_Ipc_Event_Client_Data *e)
|
||||
{
|
||||
int objid;
|
||||
char *icon;
|
||||
E_Thumb *eth;
|
||||
Evas_Object *obj;
|
||||
|
||||
if (!eina_list_data_find(_thumbnailers, e->client))
|
||||
_thumbnailers = eina_list_prepend(_thumbnailers, e->client);
|
||||
if (e->minor == 2)
|
||||
{
|
||||
objid = e->ref;
|
||||
icon = e->data;
|
||||
if ((icon) && (e->size > 1) && (icon[e->size - 1] == 0))
|
||||
{
|
||||
obj = _e_thumb_hash_find(objid);
|
||||
if (obj)
|
||||
{
|
||||
eth = evas_object_data_get(obj, "e_thumbdata");
|
||||
if (eth)
|
||||
{
|
||||
eth->busy = 0;
|
||||
_pending--;
|
||||
eth->done = 1;
|
||||
if (_pending == 0) _e_thumb_thumbnailers_kill();
|
||||
if (ecore_file_exists(icon))
|
||||
{
|
||||
elm_image_file_set(obj, icon, "/thumbnail/data");
|
||||
_e_thumb_key_load(eth, icon);
|
||||
elm_image_preload_disabled_set(obj, EINA_FALSE);
|
||||
}
|
||||
evas_object_smart_callback_call(obj, "e_thumb_gen", NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e->minor == 1)
|
||||
{
|
||||
/* hello message */
|
||||
EINA_LIST_FREE(_thumb_queue, eth)
|
||||
{
|
||||
eth->queued = 0;
|
||||
eth->busy = 1;
|
||||
_pending++;
|
||||
if (_pending == 1) _e_thumb_thumbnailers_kill_cancel();
|
||||
_e_thumb_gen_begin(eth->objid, eth->file, eth->key, eth->w, eth->h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
e_thumb_client_del(Ecore_Ipc_Event_Client_Del *e)
|
||||
{
|
||||
if (!eina_list_data_find(_thumbnailers, e->client)) return;
|
||||
_thumbnailers = eina_list_remove(_thumbnailers, e->client);
|
||||
if ((!_thumbs) && (!_thumbnailers)) _objid = 0;
|
||||
}
|
||||
|
||||
/* local subsystem functions */
|
||||
static void
|
||||
_e_thumb_gen_begin(int objid, const char *file, const char *key, int w, int h)
|
||||
{
|
||||
char *buf;
|
||||
int l1, l2;
|
||||
Ecore_Ipc_Client *cli;
|
||||
|
||||
/* send thumb req */
|
||||
l1 = strlen(file);
|
||||
l2 = 0;
|
||||
if (key) l2 = strlen(key);
|
||||
buf = alloca(l1 + 1 + l2 + 1);
|
||||
strcpy(buf, file);
|
||||
if (key) strcpy(buf + l1 + 1, key);
|
||||
else buf[l1 + 1] = 0;
|
||||
cli = eina_list_data_get(_thumbnailers);
|
||||
if (!cli) return;
|
||||
_thumbnailers = eina_list_remove_list(_thumbnailers, _thumbnailers);
|
||||
_thumbnailers = eina_list_append(_thumbnailers, cli);
|
||||
ecore_ipc_client_send(cli, EPHOTO_IPC_DOMAIN_THUMB, 1, objid, w, h, buf, l1 + 1 + l2 + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_thumb_gen_end(int objid)
|
||||
{
|
||||
Eina_List *l;
|
||||
Ecore_Ipc_Client *cli;
|
||||
|
||||
/* send thumb cancel */
|
||||
EINA_LIST_FOREACH(_thumbnailers, l, cli)
|
||||
{
|
||||
ecore_ipc_client_send(cli, EPHOTO_IPC_DOMAIN_THUMB, 2, objid, 0, 0, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_thumb_del_hook(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
E_Thumb *eth;
|
||||
|
||||
eth = evas_object_data_get(obj, "e_thumbdata");
|
||||
if (!eth) return;
|
||||
evas_object_data_del(obj, "e_thumbdata");
|
||||
_e_thumb_hash_del(eth->objid);
|
||||
if (eth->busy)
|
||||
{
|
||||
_e_thumb_gen_end(eth->objid);
|
||||
eth->busy = 0;
|
||||
_pending--;
|
||||
if (_pending == 0) _e_thumb_thumbnailers_kill();
|
||||
}
|
||||
if (eth->queued)
|
||||
_thumb_queue = eina_list_remove(_thumb_queue, eth);
|
||||
if (eth->file) eina_stringshare_del(eth->file);
|
||||
if (eth->key) eina_stringshare_del(eth->key);
|
||||
free(eth->sort_id);
|
||||
free(eth);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_thumb_hash_add(int objid, Evas_Object *obj)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%i", objid);
|
||||
eina_hash_add(_thumbs, buf, obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_thumb_hash_del(int objid)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%i", objid);
|
||||
if (_thumbs) eina_hash_del(_thumbs, buf, NULL);
|
||||
if ((!_thumbs) && (!_thumbnailers)) _objid = 0;
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_e_thumb_hash_find(int objid)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%i", objid);
|
||||
return eina_hash_find(_thumbs, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_thumb_thumbnailers_kill(void)
|
||||
{
|
||||
if (_kill_timer) ecore_timer_del(_kill_timer);
|
||||
_kill_timer = ecore_timer_add(1.0, _e_thumb_cb_kill, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_thumb_thumbnailers_kill_cancel(void)
|
||||
{
|
||||
if (_kill_timer) ecore_timer_del(_kill_timer);
|
||||
_kill_timer = NULL;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_thumb_cb_kill(void *data EINA_UNUSED)
|
||||
{
|
||||
Eina_List *l;
|
||||
Ecore_Exe *exe;
|
||||
|
||||
EINA_LIST_FOREACH(_thumbnailers_exe, l, exe)
|
||||
ecore_exe_terminate(exe);
|
||||
_kill_timer = NULL;
|
||||
return ECORE_CALLBACK_DONE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_thumb_cb_exe_event_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
Ecore_Exe_Event_Del *ev;
|
||||
Ecore_Exe *exe;
|
||||
Eina_List *l;
|
||||
|
||||
ev = event;
|
||||
EINA_LIST_FOREACH(_thumbnailers_exe, l, exe)
|
||||
{
|
||||
if (exe == ev->exe)
|
||||
{
|
||||
_thumbnailers_exe = eina_list_remove_list(_thumbnailers_exe, l);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((!_thumbnailers_exe) && (_thumb_queue))
|
||||
{
|
||||
while ((int)eina_list_count(_thumbnailers_exe) < _num_thumbnailers)
|
||||
{
|
||||
Ecore_Exe *exe_thumb;
|
||||
char buf[4096];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/ephoto_thumbnail --nice=1", PACKAGE_DATA_DIR);
|
||||
exe_thumb = ecore_exe_run(buf, NULL);
|
||||
_thumbnailers_exe = eina_list_append(_thumbnailers_exe, exe_thumb);
|
||||
}
|
||||
}
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
|
@ -0,0 +1,709 @@
|
|||
#include "ephoto.h"
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#define SHSH(n, v) ((((v) << (n)) & 0xffffffff) | ((v) >> (32 - (n))))
|
||||
|
||||
typedef struct _E_Thumb E_Thumb;
|
||||
|
||||
struct _E_Thumb
|
||||
{
|
||||
int objid;
|
||||
int w, h;
|
||||
char *file;
|
||||
char *key;
|
||||
};
|
||||
|
||||
/* local subsystem functions */
|
||||
static int _e_ipc_init(void);
|
||||
static Eina_Bool _e_ipc_cb_server_add(void *data,
|
||||
int type,
|
||||
void *event);
|
||||
static Eina_Bool _e_ipc_cb_server_del(void *data,
|
||||
int type,
|
||||
void *event);
|
||||
static Eina_Bool _e_ipc_cb_server_data(void *data,
|
||||
int type,
|
||||
void *event);
|
||||
static Eina_Bool _e_cb_timer(void *data);
|
||||
static void _e_thumb_generate(E_Thumb *eth);
|
||||
static char *_e_thumb_file_id(char *file,
|
||||
char *key);
|
||||
|
||||
/* local subsystem globals */
|
||||
static Ecore_Ipc_Server *_e_ipc_server = NULL;
|
||||
static Eina_List *_thumblist = NULL;
|
||||
static Ecore_Timer *_timer = NULL;
|
||||
static char _thumbdir[4096] = "";
|
||||
|
||||
/* externally accessible functions */
|
||||
int
|
||||
main(int argc,
|
||||
char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if ((!strcmp(argv[i], "-h")) ||
|
||||
(!strcmp(argv[i], "-help")) ||
|
||||
(!strcmp(argv[i], "--help")))
|
||||
{
|
||||
printf(
|
||||
"This is an internal tool for Ephoto.\n"
|
||||
"do not use it.\n"
|
||||
);
|
||||
exit(0);
|
||||
}
|
||||
else if (!strncmp(argv[i], "--nice=", 7))
|
||||
{
|
||||
const char *val;
|
||||
|
||||
val = argv[i] + 7;
|
||||
if (*val)
|
||||
{
|
||||
if (nice(atoi(val)) < 0) perror("nice");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ecore_app_no_system_modules();
|
||||
ecore_init();
|
||||
ecore_app_args_set(argc, (const char **)argv);
|
||||
eet_init();
|
||||
evas_init();
|
||||
ecore_evas_init();
|
||||
edje_init();
|
||||
ecore_file_init();
|
||||
ecore_ipc_init();
|
||||
|
||||
snprintf(_thumbdir, PATH_MAX, "%s/.config/ephoto/thumbnails", getenv("HOME"));
|
||||
ecore_file_mkpath(_thumbdir);
|
||||
|
||||
if (_e_ipc_init()) ecore_main_loop_begin();
|
||||
|
||||
if (_e_ipc_server)
|
||||
{
|
||||
ecore_ipc_server_del(_e_ipc_server);
|
||||
_e_ipc_server = NULL;
|
||||
}
|
||||
|
||||
ecore_ipc_shutdown();
|
||||
ecore_file_shutdown();
|
||||
ecore_evas_shutdown();
|
||||
edje_shutdown();
|
||||
evas_shutdown();
|
||||
eet_shutdown();
|
||||
ecore_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* local subsystem functions */
|
||||
static int
|
||||
_e_ipc_init(void)
|
||||
{
|
||||
char *sdir;
|
||||
|
||||
sdir = getenv("EPHOTO_IPC_SOCKET");
|
||||
if (!sdir)
|
||||
{
|
||||
printf("The EPHOTO_IPC_SOCKET environment variable is not set. This is\n"
|
||||
"exported by Enlightenment to all processes it launches.\n"
|
||||
"This environment variable must be set and must point to\n"
|
||||
"Enlightenment's IPC socket file (minus port number).\n");
|
||||
return 0;
|
||||
}
|
||||
_e_ipc_server = ecore_ipc_server_connect(ECORE_IPC_LOCAL_SYSTEM, sdir, 0, NULL);
|
||||
if (!_e_ipc_server) return 0;
|
||||
|
||||
ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, _e_ipc_cb_server_add, NULL);
|
||||
ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, _e_ipc_cb_server_del, NULL);
|
||||
ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, _e_ipc_cb_server_data, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_ipc_cb_server_add(void *data EINA_UNUSED,
|
||||
int type EINA_UNUSED,
|
||||
void *event)
|
||||
{
|
||||
Ecore_Ipc_Event_Server_Add *e;
|
||||
|
||||
e = event;
|
||||
ecore_ipc_server_send(e->server,
|
||||
EPHOTO_IPC_DOMAIN_THUMB,
|
||||
1 /*hello*/,
|
||||
0, 0, 0, NULL, 0); /* send hello */
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_ipc_cb_server_del(void *data EINA_UNUSED,
|
||||
int type EINA_UNUSED,
|
||||
void *event EINA_UNUSED)
|
||||
{
|
||||
/* quit now */
|
||||
ecore_main_loop_quit();
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_ipc_cb_server_data(void *data EINA_UNUSED,
|
||||
int type EINA_UNUSED,
|
||||
void *event)
|
||||
{
|
||||
Ecore_Ipc_Event_Server_Data *e;
|
||||
E_Thumb *eth;
|
||||
Eina_List *l;
|
||||
char *file = NULL;
|
||||
char *key = NULL;
|
||||
|
||||
e = event;
|
||||
if (e->major != EPHOTO_IPC_DOMAIN_THUMB) return ECORE_CALLBACK_PASS_ON;
|
||||
switch (e->minor)
|
||||
{
|
||||
case 1:
|
||||
if (e->data)
|
||||
{
|
||||
/* begin thumb */
|
||||
/* don't check stuff. since this connects TO E it is connecting */
|
||||
/* TO a trusted process that WILL send this message properly */
|
||||
/* formatted. if the thumbnailer dies anyway - it's not a big loss */
|
||||
/* but it is a sign of a bug in e formatting messages maybe */
|
||||
file = e->data;
|
||||
key = file + strlen(file) + 1;
|
||||
if (!key[0]) key = NULL;
|
||||
eth = calloc(1, sizeof(E_Thumb));
|
||||
if (eth)
|
||||
{
|
||||
eth->objid = e->ref;
|
||||
eth->w = e->ref_to;
|
||||
eth->h = e->response;
|
||||
eth->file = strdup(file);
|
||||
if (key) eth->key = strdup(key);
|
||||
_thumblist = eina_list_append(_thumblist, eth);
|
||||
if (!_timer) _timer = ecore_timer_add(0.001, _e_cb_timer, NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* end thumb */
|
||||
EINA_LIST_FOREACH(_thumblist, l, eth)
|
||||
{
|
||||
if (eth->objid == e->ref)
|
||||
{
|
||||
_thumblist = eina_list_remove_list(_thumblist, l);
|
||||
free(eth->file);
|
||||
free(eth->key);
|
||||
free(eth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* quit now */
|
||||
ecore_main_loop_quit();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_cb_timer(void *data EINA_UNUSED)
|
||||
{
|
||||
E_Thumb *eth;
|
||||
/*
|
||||
Eina_List *del_list = NULL, *l;
|
||||
*/
|
||||
|
||||
/* take thumb at head of list */
|
||||
if (_thumblist)
|
||||
{
|
||||
eth = eina_list_data_get(_thumblist);
|
||||
_thumblist = eina_list_remove_list(_thumblist, _thumblist);
|
||||
_e_thumb_generate(eth);
|
||||
free(eth->file);
|
||||
free(eth->key);
|
||||
free(eth);
|
||||
|
||||
if (_thumblist) _timer = ecore_timer_add(0.01, _e_cb_timer, NULL);
|
||||
else _timer = NULL;
|
||||
}
|
||||
else
|
||||
_timer = NULL;
|
||||
return ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
typedef struct _Color Color;
|
||||
|
||||
struct _Color
|
||||
{
|
||||
Color *closest;
|
||||
int closest_dist;
|
||||
int use;
|
||||
unsigned char r, g, b;
|
||||
};
|
||||
|
||||
static void
|
||||
_e_thumb_generate(E_Thumb *eth)
|
||||
{
|
||||
char buf[4096], dbuf[4096], *id, *td, *ext = NULL;
|
||||
Evas *evas = NULL, *evas_im = NULL;
|
||||
Ecore_Evas *ee = NULL, *ee_im = NULL;
|
||||
Evas_Object *im = NULL, *edje = NULL;
|
||||
Eet_File *ef = NULL;
|
||||
int iw, ih, alpha, ww, hh;
|
||||
const unsigned int *data = NULL;
|
||||
time_t mtime_orig, mtime_thumb;
|
||||
|
||||
id = _e_thumb_file_id(eth->file, eth->key);
|
||||
if (!id) return;
|
||||
|
||||
td = strdup(id);
|
||||
if (!td)
|
||||
{
|
||||
free(id);
|
||||
return;
|
||||
}
|
||||
td[2] = 0;
|
||||
|
||||
snprintf(dbuf, sizeof(dbuf), "%s/%s", _thumbdir, td);
|
||||
snprintf(buf, sizeof(buf), "%s/%s/%s-%ix%i.thm",
|
||||
_thumbdir, td, id + 2, eth->w, eth->h);
|
||||
free(id);
|
||||
free(td);
|
||||
|
||||
mtime_orig = ecore_file_mod_time(eth->file);
|
||||
mtime_thumb = ecore_file_mod_time(buf);
|
||||
while (mtime_thumb <= mtime_orig)
|
||||
{
|
||||
unsigned int *data1;
|
||||
Eina_Bool sortkey;
|
||||
Evas_Object *im2, *bg;
|
||||
|
||||
im = NULL;
|
||||
im2 = NULL;
|
||||
bg = NULL;
|
||||
|
||||
ecore_file_mkdir(dbuf);
|
||||
|
||||
edje_file_cache_set(0);
|
||||
edje_collection_cache_set(0);
|
||||
ee = ecore_evas_buffer_new(1, 1);
|
||||
evas = ecore_evas_get(ee);
|
||||
evas_image_cache_set(evas, 0);
|
||||
evas_font_cache_set(evas, 0);
|
||||
ww = 0;
|
||||
hh = 0;
|
||||
alpha = 1;
|
||||
ext = strrchr(eth->file, '.');
|
||||
|
||||
sortkey = EINA_FALSE;
|
||||
|
||||
if ((ext) && (eth->key) &&
|
||||
((!strcasecmp(ext, ".edj")) ||
|
||||
(!strcasecmp(ext, ".eap"))))
|
||||
{
|
||||
ww = eth->w;
|
||||
hh = eth->h;
|
||||
im = ecore_evas_object_image_new(ee);
|
||||
ee_im = evas_object_data_get(im, "Ecore_Evas");
|
||||
evas_im = ecore_evas_get(ee_im);
|
||||
evas_image_cache_set(evas_im, 0);
|
||||
evas_font_cache_set(evas_im, 0);
|
||||
evas_object_image_size_set(im, ww * 4, hh * 4);
|
||||
evas_object_image_fill_set(im, 0, 0, ww, hh);
|
||||
edje = edje_object_add(evas_im);
|
||||
if ((eth->key) &&
|
||||
((!strcmp(eth->key, "e/desktop/background")) ||
|
||||
(!strcmp(eth->key, "e/init/splash"))))
|
||||
alpha = 0;
|
||||
if (edje_object_file_set(edje, eth->file, eth->key))
|
||||
{
|
||||
evas_object_move(edje, 0, 0);
|
||||
evas_object_resize(edje, ww * 4, hh * 4);
|
||||
evas_object_show(edje);
|
||||
}
|
||||
evas_object_move(im, 0, 0);
|
||||
evas_object_resize(im, ww, hh);
|
||||
sortkey = EINA_TRUE;
|
||||
}
|
||||
else if ((ext) &&
|
||||
((!strcasecmp(ext, ".ttf")) ||
|
||||
(!strcasecmp(ext, ".pcf")) ||
|
||||
(!strcasecmp(ext, ".bdf")) ||
|
||||
(!strcasecmp(ext, ".ttx")) ||
|
||||
(!strcasecmp(ext, ".pfa")) ||
|
||||
(!strcasecmp(ext, ".pfb")) ||
|
||||
(!strcasecmp(ext, ".afm")) ||
|
||||
(!strcasecmp(ext, ".sfd")) ||
|
||||
(!strcasecmp(ext, ".snf")) ||
|
||||
(!strcasecmp(ext, ".otf")) ||
|
||||
(!strcasecmp(ext, ".psf")) ||
|
||||
(!strcasecmp(ext, ".ttc")) ||
|
||||
(!strcasecmp(ext, ".ttx")) ||
|
||||
(!strcasecmp(ext, ".gsf")) ||
|
||||
(!strcasecmp(ext, ".spd"))
|
||||
))
|
||||
{
|
||||
Evas_Coord tx = 0, ty = 0, tw = 0, th = 0;
|
||||
ww = eth->w;
|
||||
hh = eth->h;
|
||||
alpha = 0;
|
||||
|
||||
bg = evas_object_rectangle_add(evas);
|
||||
evas_object_color_set(bg, 96, 96, 96, 255);
|
||||
evas_object_move(bg, 0, 0);
|
||||
evas_object_resize(bg, ww, hh);
|
||||
evas_object_show(bg);
|
||||
|
||||
im = evas_object_text_add(evas);
|
||||
evas_object_text_font_set(im, eth->file, hh / 4);
|
||||
evas_object_color_set(im, 192, 192, 192, 255);
|
||||
evas_object_text_ellipsis_set(im, 0.0);
|
||||
evas_object_text_text_set(im, "ABCabc");
|
||||
evas_object_geometry_get(im, NULL, NULL, &tw, &th);
|
||||
if (tw > ww) tw = ww;
|
||||
tx = 0 + ((ww - tw) / 2);
|
||||
ty = 0 + (((hh / 2) - th) / 2);
|
||||
evas_object_move(im, tx, ty);
|
||||
evas_object_resize(im, tw, th);
|
||||
evas_object_show(im);
|
||||
|
||||
im2 = evas_object_text_add(evas);
|
||||
evas_object_text_font_set(im2, eth->file, hh / 4);
|
||||
evas_object_color_set(im2, 255, 255, 255, 255);
|
||||
evas_object_text_ellipsis_set(im2, 0.0);
|
||||
evas_object_text_text_set(im2, "123!@?");
|
||||
evas_object_geometry_get(im2, NULL, NULL, &tw, &th);
|
||||
if (tw > ww) tw = ww;
|
||||
tx = 0 + ((ww - tw) / 2);
|
||||
ty = (hh / 2) + (((hh / 2) - th) / 2);
|
||||
evas_object_move(im2, tx, ty);
|
||||
evas_object_resize(im2, tw, th);
|
||||
evas_object_show(im2);
|
||||
}
|
||||
else if (evas_object_image_extension_can_load_get(ext))
|
||||
{
|
||||
im = evas_object_image_add(evas);
|
||||
evas_object_image_load_orientation_set(im, EINA_TRUE);
|
||||
evas_object_image_load_size_set(im, eth->w, eth->h);
|
||||
evas_object_image_file_set(im, eth->file, NULL);
|
||||
iw = 0; ih = 0;
|
||||
evas_object_image_size_get(im, &iw, &ih);
|
||||
alpha = evas_object_image_alpha_get(im);
|
||||
if ((iw > 0) && (ih > 0))
|
||||
{
|
||||
ww = eth->w;
|
||||
hh = (eth->w * ih) / iw;
|
||||
if (hh > eth->h)
|
||||
{
|
||||
hh = eth->h;
|
||||
ww = (eth->h * iw) / ih;
|
||||
}
|
||||
evas_object_image_fill_set(im, 0, 0, ww, hh);
|
||||
}
|
||||
evas_object_move(im, 0, 0);
|
||||
evas_object_resize(im, ww, hh);
|
||||
sortkey = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
goto end;
|
||||
|
||||
ecore_evas_alpha_set(ee, alpha);
|
||||
ecore_evas_resize(ee, ww, hh);
|
||||
evas_object_show(im);
|
||||
if (ww <= 0) goto end;
|
||||
data = ecore_evas_buffer_pixels_get(ee);
|
||||
if (!data) goto end;
|
||||
ef = eet_open(buf, EET_FILE_MODE_WRITE);
|
||||
if (!ef) goto end;
|
||||
eet_write(ef, "/thumbnail/orig_file",
|
||||
eth->file, strlen(eth->file), 1);
|
||||
if (eth->key)
|
||||
eet_write(ef, "/thumbnail/orig_key",
|
||||
eth->key, strlen(eth->key), 1);
|
||||
eet_data_image_write(ef, "/thumbnail/data",
|
||||
(void *)data, ww, hh, alpha,
|
||||
0, 91, 1);
|
||||
if (sortkey)
|
||||
{
|
||||
ww = 4; hh = 4;
|
||||
evas_object_image_fill_set(im, 0, 0, ww, hh);
|
||||
evas_object_resize(im, ww, hh);
|
||||
ecore_evas_resize(ee, ww, hh);
|
||||
data = ecore_evas_buffer_pixels_get(ee);
|
||||
if (!data) goto end;
|
||||
|
||||
data1 = malloc(ww * hh * sizeof(unsigned int));
|
||||
memcpy(data1, data, ww * hh * sizeof(unsigned int));
|
||||
ww = 2; hh = 2;
|
||||
evas_object_image_fill_set(im, 0, 0, ww, hh);
|
||||
evas_object_resize(im, ww, hh);
|
||||
ecore_evas_resize(ee, ww, hh);
|
||||
data = ecore_evas_buffer_pixels_get(ee);
|
||||
if (data)
|
||||
{
|
||||
unsigned int *data2;
|
||||
|
||||
data2 = malloc(ww * hh * sizeof(unsigned int));
|
||||
memcpy(data2, data, ww * hh * sizeof(unsigned int));
|
||||
ww = 1; hh = 1;
|
||||
evas_object_image_fill_set(im, 0, 0, ww, hh);
|
||||
evas_object_resize(im, ww, hh);
|
||||
ecore_evas_resize(ee, ww, hh);
|
||||
data = ecore_evas_buffer_pixels_get(ee);
|
||||
if (data)
|
||||
{
|
||||
unsigned int *data3;
|
||||
unsigned char id2[(21 * 4) + 1];
|
||||
int n, i;
|
||||
int hi, si, vi;
|
||||
float h, s, v;
|
||||
const int pat2[4] =
|
||||
{
|
||||
0, 3, 1, 2
|
||||
};
|
||||
const int pat1[16] =
|
||||
{
|
||||
5, 10, 6, 9,
|
||||
0, 15, 3, 12,
|
||||
1, 14, 7, 8,
|
||||
4, 11, 2, 13
|
||||
};
|
||||
|
||||
/* ww = hh = 1 here */
|
||||
data3 = malloc(sizeof(unsigned int));
|
||||
memcpy(data3, data, sizeof(unsigned int));
|
||||
// sort_id
|
||||
n = 0;
|
||||
#define A(v) (((v) >> 24) & 0xff)
|
||||
#define R(v) (((v) >> 16) & 0xff)
|
||||
#define G(v) (((v) >> 8) & 0xff)
|
||||
#define B(v) (((v)) & 0xff)
|
||||
#define HSV(p) \
|
||||
evas_color_rgb_to_hsv(R(p), G(p), B(p), &h, &s, &v); \
|
||||
hi = 20 * (h / 360.0); \
|
||||
si = 20 * s; \
|
||||
vi = 20 * v; \
|
||||
if (si < 2) hi = 25;
|
||||
#define SAVEHSV(h, s, v) \
|
||||
id2[n++] = 'a' + h; \
|
||||
id2[n++] = 'a' + v; \
|
||||
id2[n++] = 'a' + s;
|
||||
#define SAVEX(x) \
|
||||
id2[n++] = 'a' + x;
|
||||
#if 0
|
||||
HSV(data3[0]);
|
||||
SAVEHSV(hi, si, vi);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
HSV(data2[pat2[i]]);
|
||||
SAVEHSV(hi, si, vi);
|
||||
}
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
HSV(data1[pat1[i]]);
|
||||
SAVEHSV(hi, si, vi);
|
||||
}
|
||||
#else
|
||||
HSV(data3[0]);
|
||||
SAVEX(hi);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
HSV(data2[pat2[i]]);
|
||||
SAVEX(hi);
|
||||
}
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
HSV(data1[pat1[i]]);
|
||||
SAVEX(hi);
|
||||
}
|
||||
HSV(data3[0]);
|
||||
SAVEX(vi);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
HSV(data2[pat2[i]]);
|
||||
SAVEX(vi);
|
||||
}
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
HSV(data1[pat1[i]]);
|
||||
SAVEX(vi);
|
||||
}
|
||||
HSV(data3[0]);
|
||||
SAVEX(si);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
HSV(data2[pat2[i]]);
|
||||
SAVEX(si);
|
||||
}
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
HSV(data1[pat1[i]]);
|
||||
SAVEX(si);
|
||||
}
|
||||
#endif
|
||||
id2[n++] = 0;
|
||||
eet_write(ef, "/thumbnail/sort_id", id2, n, 1);
|
||||
free(data3);
|
||||
}
|
||||
free(data2);
|
||||
}
|
||||
free(data1);
|
||||
}
|
||||
end:
|
||||
if (ef) eet_close(ef);
|
||||
|
||||
/* will free all */
|
||||
if (edje) evas_object_del(edje);
|
||||
if (ee_im) ecore_evas_free(ee_im);
|
||||
else if (im) evas_object_del(im);
|
||||
if (im2) evas_object_del(im2);
|
||||
if (bg) evas_object_del(bg);
|
||||
ecore_evas_free(ee);
|
||||
eet_clearcache();
|
||||
break;
|
||||
}
|
||||
/* send back path to thumb */
|
||||
ecore_ipc_server_send(_e_ipc_server, EPHOTO_IPC_DOMAIN_THUMB, 2, eth->objid, 0, 0, buf, strlen(buf) + 1);
|
||||
}
|
||||
|
||||
static int
|
||||
e_sha1_sum(unsigned char *data, int size, unsigned char *dst)
|
||||
{
|
||||
unsigned int digest[5], word[80], wa, wb, wc, wd, we, t;
|
||||
unsigned char buf[64], *d;
|
||||
int idx, left, i;
|
||||
const unsigned int magic[4] =
|
||||
{
|
||||
0x5a827999,
|
||||
0x6ed9eba1,
|
||||
0x8f1bbcdc,
|
||||
0xca62c1d6
|
||||
};
|
||||
|
||||
idx = 0;
|
||||
digest[0] = 0x67452301;
|
||||
digest[1] = 0xefcdab89;
|
||||
digest[2] = 0x98badcfe;
|
||||
digest[3] = 0x10325476;
|
||||
digest[4] = 0xc3d2e1f0;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
for (left = size, d = data; left > 0; left--, d++)
|
||||
{
|
||||
if ((idx == 0) && (left < 64))
|
||||
{
|
||||
memset(buf, 0, 60);
|
||||
buf[60] = (size >> 24) & 0xff;
|
||||
buf[61] = (size >> 16) & 0xff;
|
||||
buf[62] = (size >> 8) & 0xff;
|
||||
buf[63] = (size) & 0xff;
|
||||
}
|
||||
buf[idx] = *d;
|
||||
idx++;;
|
||||
if ((idx == 64) || (left == 1))
|
||||
{
|
||||
if ((left == 1) && (idx < 64)) buf[idx] = 0x80;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
word[i] = (unsigned int)buf[(i * 4) ] << 24;
|
||||
word[i] |= (unsigned int)buf[(i * 4) + 1] << 16;
|
||||
word[i] |= (unsigned int)buf[(i * 4) + 2] << 8;
|
||||
word[i] |= (unsigned int)buf[(i * 4) + 3];
|
||||
}
|
||||
for (i = 16; i < 80; i++)
|
||||
word[i] = SHSH(1,
|
||||
word[i - 3 ] ^ word[i - 8 ] ^
|
||||
word[i - 14] ^ word[i - 16]);
|
||||
wa = digest[0];
|
||||
wb = digest[1];
|
||||
wc = digest[2];
|
||||
wd = digest[3];
|
||||
we = digest[4];
|
||||
for (i = 0; i < 80; i++)
|
||||
{
|
||||
if (i < 20)
|
||||
t = SHSH(5, wa) + ((wb & wc) | ((~wb) & wd)) +
|
||||
we + word[i] + magic[0];
|
||||
else if (i < 40)
|
||||
t = SHSH(5, wa) + (wb ^ wc ^ wd) +
|
||||
we + word[i] + magic[1];
|
||||
else if (i < 60)
|
||||
t = SHSH(5, wa) + ((wb & wc) | (wb & wd) | (wc & wd)) +
|
||||
we + word[i] + magic[2];
|
||||
else if (i < 80)
|
||||
t = SHSH(5, wa) + (wb ^ wc ^ wd) +
|
||||
we + word[i] + magic[3];
|
||||
we = wd;
|
||||
wd = wc;
|
||||
wc = SHSH(30, wb);
|
||||
wb = wa;
|
||||
wa = t;
|
||||
}
|
||||
digest[0] += wa;
|
||||
digest[1] += wb;
|
||||
digest[2] += wc;
|
||||
digest[3] += wd;
|
||||
digest[4] += we;
|
||||
idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
t = htonl(digest[0]); digest[0] = t;
|
||||
t = htonl(digest[1]); digest[1] = t;
|
||||
t = htonl(digest[2]); digest[2] = t;
|
||||
t = htonl(digest[3]); digest[3] = t;
|
||||
t = htonl(digest[4]); digest[4] = t;
|
||||
|
||||
memcpy(dst, digest, 5 * 4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *
|
||||
_e_thumb_file_id(char *file,
|
||||
char *key)
|
||||
{
|
||||
char s[64];
|
||||
const char *chmap = "0123456789abcdef";
|
||||
unsigned char *buf, id[20];
|
||||
int i, len, lenf;
|
||||
|
||||
len = 0;
|
||||
lenf = strlen(file);
|
||||
len += lenf;
|
||||
len++;
|
||||
if (key)
|
||||
{
|
||||
key += strlen(key);
|
||||
len++;
|
||||
}
|
||||
buf = alloca(len);
|
||||
|
||||
strcpy((char *)buf, file);
|
||||
if (key) strcpy((char *)(buf + lenf + 1), key);
|
||||
|
||||
e_sha1_sum(buf, len, id);
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
s[(i * 2) + 0] = chmap[(id[i] >> 4) & 0xf];
|
||||
s[(i * 2) + 1] = chmap[(id[i]) & 0xf];
|
||||
}
|
||||
s[(i * 2)] = 0;
|
||||
return strdup(s);
|
||||
}
|
||||
|
Loading…
Reference in New Issue