#include "evas_cs2.h"
#ifndef CSERVE2_LOG_LEVEL
-#define CSERVE2_LOG_LEVEL 2
+#define CSERVE2_LOG_LEVEL 4
#endif
#ifdef CRIT
} Slave_Command;
struct _Slave_Msg_Image_Open {
- Eina_Bool has_loader_data : 1;
- // Optionally followed by:
+ struct {
+ struct {
+ unsigned int x, y, w, h;
+ } region;
+ double dpi;
+ unsigned int w, h;
+ int scale_down_by;
+ Eina_Bool orientation;
+ } lo;
+ // const char path[];
+ // const char key[];
// const char loader[];
};
void cserve2_cache_shutdown(void);
void cserve2_cache_client_new(Client *client);
void cserve2_cache_client_del(Client *client);
-int cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char *path, const char *key, unsigned int rid);
+int cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char *path, const char *key, unsigned int rid, Evas_Image_Load_Opts *lo);
void cserve2_cache_file_close(Client *client, unsigned int client_file_id);
int cserve2_cache_image_entry_create(Client *client, int rid, unsigned int client_file_id, unsigned int image_id, Evas_Image_Load_Opts *opts);
void cserve2_rgba_image_scale_do(void *src_data, void *dst_data, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int alpha, int smooth);
typedef struct _Font_Source Font_Source;
typedef struct _Font_Entry Font_Entry;
+static const Evas_Image_Load_Opts empty_lo = {
+ { 0, 0, 0, 0 },
+ {
+ 0, 0, 0, 0,
+ 0, 0,
+ 0,
+ 0
+ },
+ 0.0,
+ 0, 0,
+ 0,
+ 0,
+
+ EINA_FALSE
+};
+
typedef enum {
CSERVE2_IMAGE_FILE,
CSERVE2_IMAGE_DATA,
static void *
_open_request_build(Entry *entry, int *bufsize)
{
+ Slave_Msg_Image_Open msg = { { { 0,0,0,0}, 0,0,0,0,0, } };
const char *loader_data, *key, *path;
- char *buf;
- int size, pathlen, keylen, loaderlen;
- Slave_Msg_Image_Open msg;
+ void *buf;
+ size_t pathlen, keylen, loaderlen;
File_Data *fd;
+ Eina_Binbuf *bb;
if (!entry || entry->type != CSERVE2_IMAGE_FILE)
return NULL;
path = cserve2_shared_string_get(fd->path);
key = cserve2_shared_string_get(fd->key);
+ loader_data = cserve2_shared_string_get(fd->loader_data);
if (!path) path = "";
if (!key) key = "";
+ if (!loader_data) loader_data = "";
pathlen = strlen(path) + 1;
keylen = strlen(key) + 1;
-
- memset(&msg, 0, sizeof(msg));
- loader_data = cserve2_shared_string_get(fd->loader_data);
- msg.has_loader_data = !!loader_data;
- loaderlen = msg.has_loader_data ? (strlen(loader_data) + 1) : 0;
-
- size = sizeof(msg) + pathlen + keylen + loaderlen;
- buf = malloc(size);
- if (!buf) return NULL;
-
- memcpy(buf, &msg, sizeof(msg));
- memcpy(buf + sizeof(msg), path, pathlen);
- memcpy(buf + sizeof(msg) + pathlen, key, keylen);
- if (msg.has_loader_data)
- memcpy(buf + sizeof(msg) + pathlen + keylen, loader_data, loaderlen);
-
- *bufsize = size;
-
- _entry_load_start(entry);
-
+ loaderlen = strlen(loader_data) + 1;
+
+ msg.lo.region.x = fd->lo.region.x;
+ msg.lo.region.y = fd->lo.region.y;
+ msg.lo.region.w = fd->lo.region.w;
+ msg.lo.region.h = fd->lo.region.h;
+ msg.lo.dpi = fd->lo.dpi;
+ msg.lo.w = fd->lo.w;
+ msg.lo.h = fd->lo.h;
+ msg.lo.scale_down_by = fd->lo.scale_down_by;
+ msg.lo.orientation = fd->lo.orientation;
+
+ bb = eina_binbuf_new();
+ eina_binbuf_append_length(bb, (unsigned char *) &msg, sizeof(msg));
+ eina_binbuf_append_length(bb, (unsigned char *) path, pathlen);
+ eina_binbuf_append_length(bb, (unsigned char *) key, keylen);
+ eina_binbuf_append_length(bb, (unsigned char *) loader_data, loaderlen);
+
+ *bufsize = eina_binbuf_length_get(bb);
+ buf = eina_binbuf_string_steal(bb);
+ eina_binbuf_free(bb);
return buf;
}
return size / 1024;
}
+static Eina_Bool
+_evas_image_load_opts_empty(Evas_Image_Load_Opts *lo)
+{
+ if (!lo) return EINA_TRUE;
+
+ return ((lo->scale_down_by == 0)
+ && (lo->dpi == 0.0)
+ && (lo->w == 0) && (lo->h == 0)
+ && (lo->region.x == 0) && (lo->region.y == 0)
+ && (lo->region.w == 0) && (lo->region.h == 0)
+ && (lo->orientation == 0));
+}
+
+static void
+_file_hkey_get(char *buf, size_t sz, const char *path, const char *key,
+ Evas_Image_Load_Opts *lo)
+{
+ // Same as _evas_cache_image_loadopts_append() but not optimized :)
+ if (lo && _evas_image_load_opts_empty(lo))
+ lo = NULL;
+
+ if (!lo)
+ snprintf(buf, sz, "%s:%s", path, key);
+ else
+ {
+ if (lo->orientation)
+ {
+ snprintf(buf, sz, "%s:%s//@/%d/%f/%dx%d/%d+%d.%dx%d",
+ path, key, lo->scale_down_by, lo->dpi, lo->w, lo->h,
+ lo->region.x, lo->region.y, lo->region.w, lo->region.h);
+ }
+ else
+ {
+ snprintf(buf, sz, "%s:%s//@/%d/%f/%dx%d/%d+%d.%dx%d/o",
+ path, key, lo->scale_down_by, lo->dpi, lo->w, lo->h,
+ lo->region.x, lo->region.y, lo->region.w, lo->region.h);
+ }
+ }
+}
+
static void
_file_id_free(File_Data *fd)
{
+ Evas_Image_Load_Opts lo = empty_lo;
char buf[4096];
- DBG("Removing entry file id: %d, file: \"%s:%s\"",
- fd->id, cserve2_shared_string_get(fd->path),
- cserve2_shared_string_get(fd->key));
- snprintf(buf, sizeof(buf), "%s:%s",
- cserve2_shared_string_get(fd->path),
- cserve2_shared_string_get(fd->key));
+ lo.region.x = fd->lo.region.x;
+ lo.region.y = fd->lo.region.y;
+ lo.region.w = fd->lo.region.w;
+ lo.region.h = fd->lo.region.h;
+ lo.dpi = fd->lo.dpi;
+ lo.w = fd->lo.w;
+ lo.h = fd->lo.h;
+ lo.scale_down_by = fd->lo.scale_down_by;
+ lo.orientation = fd->lo.orientation;
+
+ _file_hkey_get(buf, sizeof(buf), cserve2_shared_string_get(fd->path),
+ cserve2_shared_string_get(fd->key), &lo);
+
+ DBG("Removing entry file id: %u, file: \"%s\"", fd->id, buf);
eina_hash_del_by_key(file_ids, buf);
}
int
cserve2_cache_file_open(Client *client, unsigned int client_file_id,
- const char *path, const char *key, unsigned int rid)
+ const char *path, const char *key, unsigned int rid,
+ Evas_Image_Load_Opts *lo)
{
unsigned int file_id;
File_Data *fd;
File_Entry *fentry;
int idx;
+#if 0
// look for this file on client references
ref = eina_hash_find(client->files.referencing, &client_file_id);
if (ref)
_image_opened_send(client, fd, rid);
return 0;
}
+#endif
// search whether the file is already opened by another client
- snprintf(buf, sizeof(buf), "%s:%s", path, key);
+ _file_hkey_get(buf, sizeof(buf), path, key, lo);
file_id = (unsigned int)(uintptr_t)eina_hash_find(file_ids, buf);
if (file_id)
{
return -1;
}
fd->valid = EINA_FALSE;
- fd->refcount = 1;
fd->path = cserve2_shared_string_add(path);
fd->key = cserve2_shared_string_add(key);
+ if (!lo) lo = (Evas_Image_Load_Opts *) &empty_lo;
+ fd->lo.region.x = lo->region.x;
+ fd->lo.region.y = lo->region.y;
+ fd->lo.region.w = lo->region.w;
+ fd->lo.region.h = lo->region.h;
+ fd->lo.dpi = lo->dpi;
+ fd->lo.w = lo->w;
+ fd->lo.h = lo->h;
+ fd->lo.scale_down_by = lo->scale_down_by;
+ fd->lo.orientation = lo->orientation;
+ fd->refcount = 1;
fd->id = file_id;
fentry = calloc(1, sizeof(File_Entry));
{
Msg_Open *msg = (Msg_Open *)client->msg.buf;
const char *path, *key, *end;
+ Evas_Image_Load_Opts *opts = NULL;
+ Evas_Image_Load_Opts opts_copy;
path = ((const char *)msg) + sizeof(*msg) + msg->path_offset;
key = ((const char *)msg) + sizeof(*msg) + msg->key_offset;
msg->file_id, path, key, (int) msg->has_load_opts);
if (!key[0]) key = NULL;
- cserve2_cache_file_open(client, msg->file_id, path, key, msg->base.rid);
+ if (msg->has_load_opts)
+ {
+ opts = &opts_copy;
+ memcpy(&opts_copy, end, sizeof(opts_copy));
+ }
+
+ cserve2_cache_file_open(client, msg->file_id, path, key, msg->base.rid,
+ opts);
if (!msg->has_load_opts)
cserve2_cache_image_entry_create(client, msg->base.rid,
else
{
// FIXME: Check message size first?
- Evas_Image_Load_Opts *opts = (Evas_Image_Load_Opts *) end;
DBG("Load Options:");
DBG("\tdpi: %03.1f", opts->dpi);
}
static void
-_files_all_print(Eina_Bool full)
+_files_all_print_short()
{
int k;
fd = _shared_array_item_get(sf_files, k);
if (!fd) break;
- if (!fd->id || (!full && !fd->refcount)) continue;
+ if (!fd->id || !fd->refcount) continue;
printf("%7d %7d %5dx%-6d %d %d %6.6s %6d %6d '%s':'%s'\n",
k, fd->id, fd->w, fd->h, !!fd->alpha, !!fd->invalid,
}
static void
+_files_all_print_all(void)
+{
+ int k;
+
+ if (!sf_files) return;
+
+ printf("List of opened image files: %s\n", eina_file_filename_get(sf_files->f));
+ printf_newline(0);
+
+ for (k = 0; k < sf_files->header->count; k++)
+ {
+ File_Data *fd;
+
+ fd = _shared_array_item_get(sf_files, k);
+ if (!fd) break;
+ if (!fd->id) continue;
+
+ printf("File #%-8d %d\n", k, fd->id);
+ printf("Path:Key: '%s':'%s'\n",
+ _shared_string_get(fd->path), _shared_string_get(fd->key));
+ printf("LoadOpts: Region: %d,%d-%dx%d\n",
+ fd->lo.region.x, fd->lo.region.y, fd->lo.region.w, fd->lo.region.h);
+ if (fd->lo.dpi != 0)
+ printf(" DPI: %f\n");
+ else
+ printf(" DPI: 0\n");
+ printf(" Requested: %dx%d\n", fd->lo.w, fd->lo.h);
+ printf(" Scale down: %d\n", fd->lo.scale_down_by);
+ printf(" Orientation: %s\n", fd->lo.orientation ? "YES" : "NO");
+ printf("Loader: %s\n", _shared_string_get(fd->loader_data));
+ printf("Geometry: %dx%d\n", fd->w, fd->h);
+ printf("Animation: anim: %s, frames: %d, loop: %d, hint: %d\n",
+ fd->animated ? "YES" : "NO",
+ fd->frame_count, fd->loop_count, fd->loop_hint);
+ printf("Alpha: %s\n", fd->alpha ? "YES" : "NO");
+ printf("Invalid: %s\n", fd->invalid ? "YES" : "NO");
+
+ printf_newline(0);
+ }
+
+ printf("\n\n");
+ fflush(stdout);
+}
+
+static void
_images_all_print_short(void)
{
int k;
_index_tables_summary_print();
_strings_all_print(full);
- _files_all_print(full);
+ _files_all_print_short();
+ if (full) _files_all_print_all();
_images_all_print_short();
if (full) _images_all_print_full();
_fonts_all_print_short();
static Error_Type
image_open(const char *file, const char *key,
- Slave_Msg_Image_Opened *result, const char **use_loader)
+ Slave_Msg_Image_Opened *result, const char **use_loader,
+ Evas_Image_Load_Opts *load_opts)
{
Evas_Module *module;
Eina_File *fd;
unsigned int i;
Error_Type ret = CSERVE2_NONE;
Eina_Stringshare *skey = eina_stringshare_add(key);
- Evas_Image_Load_Opts load_opts;
-
- memset(&load_opts, 0, sizeof(load_opts));
fd = eina_file_open(file, EINA_FALSE);
if (!fd)
module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
if (module)
{
- if (_image_file_header(fd, skey, &load_opts, result, module))
+ if (_image_file_header(fd, skey, load_opts, result, module))
goto success;
}
if (loader)
{
module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
- if (module && _image_file_header(fd, skey, &load_opts, result, module))
+ if (module && _image_file_header(fd, skey, load_opts, result, module))
goto success;
loader = NULL;
module = NULL;
loader = loaders_name[i];
module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
if (!module) continue;
- if (_image_file_header(fd, skey, &load_opts, result, module))
+ if (_image_file_header(fd, skey, load_opts, result, module))
goto success;
}
static void
handle_image_open(int wfd, void *params)
{
- Slave_Msg_Image_Open *p;
+ Slave_Msg_Image_Open *msg = params;
Slave_Msg_Image_Opened result;
+ Evas_Image_Load_Opts load_opts;
Error_Type err;
const char *loader = NULL, *file, *key, *ptr;
char *resp;
size_t resp_size;
- p = params;
- file = (const char *)(p + sizeof(Slave_Msg_Image_Open));
+ memset(&load_opts, 0, sizeof(load_opts));
+ load_opts.region.x = msg->lo.region.x;
+ load_opts.region.y = msg->lo.region.y;
+ load_opts.region.w = msg->lo.region.w;
+ load_opts.region.h = msg->lo.region.h;
+ load_opts.dpi = msg->lo.dpi;
+ load_opts.w = msg->lo.w;
+ load_opts.h = msg->lo.h;
+ load_opts.scale_down_by = msg->lo.scale_down_by;
+ load_opts.orientation = msg->lo.orientation;
+
+ file = (const char *) (msg + 1);
key = file + strlen(file) + 1;
ptr = key + strlen(key) + 1;
- if (p->has_loader_data)
- loader = ptr;
+ loader = ptr;
memset(&result, 0, sizeof(result));
- if ((err = image_open(file, key, &result, &loader))
+ if ((err = image_open(file, key, &result, &loader, &load_opts))
!= CSERVE2_NONE)
{
printf("OPEN failed at %s:%d\n", __FUNCTION__, __LINE__);
#define FILE_DATA_ARRAY_TAG ('F' | 'I' << 8 | 'L' << 16 | 'E' << 24)
struct _File_Data {
SHMOBJECT;
+ // Hash entry elements (see Evas_Image_Load_Opts)
string_t path;
string_t key;
- string_t loader_data;
+ struct {
+ struct {
+ unsigned int x, y, w, h;
+ } region;
+ double dpi;
+ unsigned int w, h;
+ int scale_down_by;
+ Eina_Bool orientation;
+ } lo;
+ // Properties set after opening the file
+ string_t loader_data; // Can also be set during open (force this loader)
int w, h;
int frame_count;
int loop_count;
#define HKEY_LOAD_OPTS_STR_LEN 215
typedef void (*Op_Callback)(void *data, const void *msg, int size);
+static const Evas_Image_Load_Opts empty_lo = {
+ { 0, 0, 0, 0 },
+ {
+ 0, 0, 0, 0,
+ 0, 0,
+ 0,
+ 0
+ },
+ 0.0,
+ 0, 0,
+ 0,
+ 0,
+
+ EINA_FALSE
+};
+
struct _File_Entry {
unsigned int file_id;
unsigned int server_file_id;
do { if (!_shared_index_remap_check(&(si), sizeof(typ))) { \
CRIT("Failed to remap index"); return NULL; } } while (0)
-static const char *
-_shared_file_data_hkey_get(char *hkey, const char *file, const char *key,
- size_t hkey_size)
+
+static Eina_Bool
+_evas_image_load_opts_empty(Evas_Image_Load_Opts *lo)
{
- size_t keylen = 0, filelen;
+ if (!lo) return EINA_TRUE;
- if (key) keylen = strlen(key) + 1;
- filelen = strlen(file);
+ return ((lo->scale_down_by == 0)
+ && (lo->dpi == 0.0)
+ && (lo->w == 0) && (lo->h == 0)
+ && (lo->region.x == 0) && (lo->region.y == 0)
+ && (lo->region.w == 0) && (lo->region.h == 0)
+ && (lo->orientation == 0));
+}
- if (filelen + keylen + 1 > hkey_size)
- return NULL;
+static void
+_file_hkey_get(char *buf, size_t sz, const char *path, const char *key,
+ Evas_Image_Load_Opts *lo)
+{
+ // Same as _evas_cache_image_loadopts_append() but not optimized :)
+ if (lo && _evas_image_load_opts_empty(lo))
+ lo = NULL;
- memcpy(hkey, file, filelen);
- hkey[filelen] = ':';
- if (key)
- memcpy(hkey + filelen + 1, key, keylen);
+ if (!lo)
+ snprintf(buf, sz, "%s:%s", path, key);
else
- memcpy(hkey + filelen + 1, "(null)", 7);
-
- return hkey;
+ {
+ if (lo->orientation)
+ {
+ snprintf(buf, sz, "%s:%s//@/%d/%f/%dx%d/%d+%d.%dx%d",
+ path, key, lo->scale_down_by, lo->dpi, lo->w, lo->h,
+ lo->region.x, lo->region.y, lo->region.w, lo->region.h);
+ }
+ else
+ {
+ snprintf(buf, sz, "%s:%s//@/%d/%f/%dx%d/%d+%d.%dx%d/o",
+ path, key, lo->scale_down_by, lo->dpi, lo->w, lo->h,
+ lo->region.x, lo->region.y, lo->region.w, lo->region.h);
+ }
+ }
}
static const File_Data *
}
// Check hash
- _shared_file_data_hkey_get(hkey, ie->file, ie->key, PATH_MAX);
+ _file_hkey_get(hkey, sizeof(hkey), ie->file, ie->key, &ie->load_opts);
fdata = eina_hash_find(_index.files.entries_by_hkey, hkey);
if (fdata)
return fdata;
const char *file, *key;
const File_Data *fd;
char fd_hkey[PATH_MAX];
+ Evas_Image_Load_Opts lo = empty_lo;
fd = &(_index.files.entries.filedata[k]);
if (!fd->id) break;
(key > _index.strings_entries.data + _index.strings_entries.size))
key = _shared_string_get(fd->key);
- _shared_file_data_hkey_get(fd_hkey, file, key, PATH_MAX);
+ lo.region.x = fd->lo.region.x;
+ lo.region.y = fd->lo.region.y;
+ lo.region.w = fd->lo.region.w;
+ lo.region.h = fd->lo.region.h;
+ lo.dpi = fd->lo.dpi;
+ lo.w = fd->lo.w;
+ lo.h = fd->lo.h;
+ lo.scale_down_by = fd->lo.scale_down_by;
+ lo.orientation = fd->lo.orientation;
+
+ _file_hkey_get(fd_hkey, sizeof(fd_hkey), file, key, &lo);
if (add_to_hash)
{