forked from enlightenment/efl
evas/cserve2: Fix images indexing (File_Entry stuff)
High-level problem: cserve2 does not support load_opts properly when opening an image. As a result, when (pre)loading a JPEG file with specific load options (eg. w, h, region and orientation), the image buffer might have the wrong dimensions. So, we need to use load_opts when computing file hash key. And, pass these load options to the loader slave, and use them while OPENING the image. This will set properly the geometry. Fixes test "Preload and Prescale" in elementary_test.
This commit is contained in:
parent
85cd382725
commit
0d506a7b73
|
@ -5,7 +5,7 @@
|
||||||
#include "evas_cs2.h"
|
#include "evas_cs2.h"
|
||||||
|
|
||||||
#ifndef CSERVE2_LOG_LEVEL
|
#ifndef CSERVE2_LOG_LEVEL
|
||||||
#define CSERVE2_LOG_LEVEL 2
|
#define CSERVE2_LOG_LEVEL 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CRIT
|
#ifdef CRIT
|
||||||
|
@ -103,8 +103,17 @@ typedef enum {
|
||||||
} Slave_Command;
|
} Slave_Command;
|
||||||
|
|
||||||
struct _Slave_Msg_Image_Open {
|
struct _Slave_Msg_Image_Open {
|
||||||
Eina_Bool has_loader_data : 1;
|
struct {
|
||||||
// Optionally followed by:
|
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[];
|
// const char loader[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -308,7 +317,7 @@ void cserve2_cache_init(void);
|
||||||
void cserve2_cache_shutdown(void);
|
void cserve2_cache_shutdown(void);
|
||||||
void cserve2_cache_client_new(Client *client);
|
void cserve2_cache_client_new(Client *client);
|
||||||
void cserve2_cache_client_del(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);
|
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);
|
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);
|
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);
|
||||||
|
|
|
@ -27,6 +27,22 @@ typedef struct _File_Watch File_Watch;
|
||||||
typedef struct _Font_Source Font_Source;
|
typedef struct _Font_Source Font_Source;
|
||||||
typedef struct _Font_Entry Font_Entry;
|
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 {
|
typedef enum {
|
||||||
CSERVE2_IMAGE_FILE,
|
CSERVE2_IMAGE_FILE,
|
||||||
CSERVE2_IMAGE_DATA,
|
CSERVE2_IMAGE_DATA,
|
||||||
|
@ -550,11 +566,12 @@ _font_loaded_send(Client *client, unsigned int rid)
|
||||||
static void *
|
static void *
|
||||||
_open_request_build(Entry *entry, int *bufsize)
|
_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;
|
const char *loader_data, *key, *path;
|
||||||
char *buf;
|
void *buf;
|
||||||
int size, pathlen, keylen, loaderlen;
|
size_t pathlen, keylen, loaderlen;
|
||||||
Slave_Msg_Image_Open msg;
|
|
||||||
File_Data *fd;
|
File_Data *fd;
|
||||||
|
Eina_Binbuf *bb;
|
||||||
|
|
||||||
if (!entry || entry->type != CSERVE2_IMAGE_FILE)
|
if (!entry || entry->type != CSERVE2_IMAGE_FILE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -568,30 +585,33 @@ _open_request_build(Entry *entry, int *bufsize)
|
||||||
|
|
||||||
path = cserve2_shared_string_get(fd->path);
|
path = cserve2_shared_string_get(fd->path);
|
||||||
key = cserve2_shared_string_get(fd->key);
|
key = cserve2_shared_string_get(fd->key);
|
||||||
|
loader_data = cserve2_shared_string_get(fd->loader_data);
|
||||||
if (!path) path = "";
|
if (!path) path = "";
|
||||||
if (!key) key = "";
|
if (!key) key = "";
|
||||||
|
if (!loader_data) loader_data = "";
|
||||||
pathlen = strlen(path) + 1;
|
pathlen = strlen(path) + 1;
|
||||||
keylen = strlen(key) + 1;
|
keylen = strlen(key) + 1;
|
||||||
|
loaderlen = strlen(loader_data) + 1;
|
||||||
|
|
||||||
memset(&msg, 0, sizeof(msg));
|
msg.lo.region.x = fd->lo.region.x;
|
||||||
loader_data = cserve2_shared_string_get(fd->loader_data);
|
msg.lo.region.y = fd->lo.region.y;
|
||||||
msg.has_loader_data = !!loader_data;
|
msg.lo.region.w = fd->lo.region.w;
|
||||||
loaderlen = msg.has_loader_data ? (strlen(loader_data) + 1) : 0;
|
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;
|
||||||
|
|
||||||
size = sizeof(msg) + pathlen + keylen + loaderlen;
|
bb = eina_binbuf_new();
|
||||||
buf = malloc(size);
|
eina_binbuf_append_length(bb, (unsigned char *) &msg, sizeof(msg));
|
||||||
if (!buf) return NULL;
|
eina_binbuf_append_length(bb, (unsigned char *) path, pathlen);
|
||||||
|
eina_binbuf_append_length(bb, (unsigned char *) key, keylen);
|
||||||
memcpy(buf, &msg, sizeof(msg));
|
eina_binbuf_append_length(bb, (unsigned char *) loader_data, loaderlen);
|
||||||
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);
|
|
||||||
|
|
||||||
|
*bufsize = eina_binbuf_length_get(bb);
|
||||||
|
buf = eina_binbuf_string_steal(bb);
|
||||||
|
eina_binbuf_free(bb);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,17 +960,66 @@ _image_entry_size_get(Image_Entry *ientry)
|
||||||
return size / 1024;
|
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
|
static void
|
||||||
_file_id_free(File_Data *fd)
|
_file_id_free(File_Data *fd)
|
||||||
{
|
{
|
||||||
|
Evas_Image_Load_Opts lo = empty_lo;
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
|
|
||||||
DBG("Removing entry file id: %d, file: \"%s:%s\"",
|
lo.region.x = fd->lo.region.x;
|
||||||
fd->id, cserve2_shared_string_get(fd->path),
|
lo.region.y = fd->lo.region.y;
|
||||||
cserve2_shared_string_get(fd->key));
|
lo.region.w = fd->lo.region.w;
|
||||||
snprintf(buf, sizeof(buf), "%s:%s",
|
lo.region.h = fd->lo.region.h;
|
||||||
cserve2_shared_string_get(fd->path),
|
lo.dpi = fd->lo.dpi;
|
||||||
cserve2_shared_string_get(fd->key));
|
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);
|
eina_hash_del_by_key(file_ids, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2450,7 +2519,8 @@ _cserve2_cache_font_debug(unsigned int rid, unsigned int *size)
|
||||||
|
|
||||||
int
|
int
|
||||||
cserve2_cache_file_open(Client *client, unsigned int client_file_id,
|
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;
|
unsigned int file_id;
|
||||||
File_Data *fd;
|
File_Data *fd;
|
||||||
|
@ -2460,6 +2530,7 @@ cserve2_cache_file_open(Client *client, unsigned int client_file_id,
|
||||||
File_Entry *fentry;
|
File_Entry *fentry;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
|
#if 0
|
||||||
// look for this file on client references
|
// look for this file on client references
|
||||||
ref = eina_hash_find(client->files.referencing, &client_file_id);
|
ref = eina_hash_find(client->files.referencing, &client_file_id);
|
||||||
if (ref)
|
if (ref)
|
||||||
|
@ -2483,9 +2554,10 @@ cserve2_cache_file_open(Client *client, unsigned int client_file_id,
|
||||||
_image_opened_send(client, fd, rid);
|
_image_opened_send(client, fd, rid);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// search whether the file is already opened by another client
|
// 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);
|
file_id = (unsigned int)(uintptr_t)eina_hash_find(file_ids, buf);
|
||||||
if (file_id)
|
if (file_id)
|
||||||
{
|
{
|
||||||
|
@ -2527,9 +2599,19 @@ cserve2_cache_file_open(Client *client, unsigned int client_file_id,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fd->valid = EINA_FALSE;
|
fd->valid = EINA_FALSE;
|
||||||
fd->refcount = 1;
|
|
||||||
fd->path = cserve2_shared_string_add(path);
|
fd->path = cserve2_shared_string_add(path);
|
||||||
fd->key = cserve2_shared_string_add(key);
|
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;
|
fd->id = file_id;
|
||||||
|
|
||||||
fentry = calloc(1, sizeof(File_Entry));
|
fentry = calloc(1, sizeof(File_Entry));
|
||||||
|
|
|
@ -136,6 +136,8 @@ _cserve2_client_open(Client *client)
|
||||||
{
|
{
|
||||||
Msg_Open *msg = (Msg_Open *)client->msg.buf;
|
Msg_Open *msg = (Msg_Open *)client->msg.buf;
|
||||||
const char *path, *key, *end;
|
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;
|
path = ((const char *)msg) + sizeof(*msg) + msg->path_offset;
|
||||||
key = ((const char *)msg) + sizeof(*msg) + msg->key_offset;
|
key = ((const char *)msg) + sizeof(*msg) + msg->key_offset;
|
||||||
|
@ -146,7 +148,14 @@ _cserve2_client_open(Client *client)
|
||||||
msg->file_id, path, key, (int) msg->has_load_opts);
|
msg->file_id, path, key, (int) msg->has_load_opts);
|
||||||
|
|
||||||
if (!key[0]) key = NULL;
|
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)
|
if (!msg->has_load_opts)
|
||||||
cserve2_cache_image_entry_create(client, msg->base.rid,
|
cserve2_cache_image_entry_create(client, msg->base.rid,
|
||||||
|
@ -154,7 +163,6 @@ _cserve2_client_open(Client *client)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// FIXME: Check message size first?
|
// FIXME: Check message size first?
|
||||||
Evas_Image_Load_Opts *opts = (Evas_Image_Load_Opts *) end;
|
|
||||||
|
|
||||||
DBG("Load Options:");
|
DBG("Load Options:");
|
||||||
DBG("\tdpi: %03.1f", opts->dpi);
|
DBG("\tdpi: %03.1f", opts->dpi);
|
||||||
|
|
|
@ -384,7 +384,7 @@ _strings_all_print(Eina_Bool full)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_files_all_print(Eina_Bool full)
|
_files_all_print_short()
|
||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
|
@ -401,7 +401,7 @@ _files_all_print(Eina_Bool full)
|
||||||
|
|
||||||
fd = _shared_array_item_get(sf_files, k);
|
fd = _shared_array_item_get(sf_files, k);
|
||||||
if (!fd) break;
|
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",
|
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,
|
k, fd->id, fd->w, fd->h, !!fd->alpha, !!fd->invalid,
|
||||||
|
@ -413,6 +413,51 @@ _files_all_print(Eina_Bool full)
|
||||||
printf_newline(1);
|
printf_newline(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static void
|
||||||
_images_all_print_short(void)
|
_images_all_print_short(void)
|
||||||
{
|
{
|
||||||
|
@ -752,7 +797,8 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
|
||||||
|
|
||||||
_index_tables_summary_print();
|
_index_tables_summary_print();
|
||||||
_strings_all_print(full);
|
_strings_all_print(full);
|
||||||
_files_all_print(full);
|
_files_all_print_short();
|
||||||
|
if (full) _files_all_print_all();
|
||||||
_images_all_print_short();
|
_images_all_print_short();
|
||||||
if (full) _images_all_print_full();
|
if (full) _images_all_print_full();
|
||||||
_fonts_all_print_short();
|
_fonts_all_print_short();
|
||||||
|
|
|
@ -318,7 +318,8 @@ _image_file_header(Eina_File *fd, Eina_Stringshare *key, Evas_Image_Load_Opts *l
|
||||||
|
|
||||||
static Error_Type
|
static Error_Type
|
||||||
image_open(const char *file, const char *key,
|
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;
|
Evas_Module *module;
|
||||||
Eina_File *fd;
|
Eina_File *fd;
|
||||||
|
@ -327,9 +328,6 @@ image_open(const char *file, const char *key,
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
Error_Type ret = CSERVE2_NONE;
|
Error_Type ret = CSERVE2_NONE;
|
||||||
Eina_Stringshare *skey = eina_stringshare_add(key);
|
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);
|
fd = eina_file_open(file, EINA_FALSE);
|
||||||
if (!fd)
|
if (!fd)
|
||||||
|
@ -344,7 +342,7 @@ image_open(const char *file, const char *key,
|
||||||
module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
|
module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
|
||||||
if (module)
|
if (module)
|
||||||
{
|
{
|
||||||
if (_image_file_header(fd, skey, &load_opts, result, module))
|
if (_image_file_header(fd, skey, load_opts, result, module))
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +362,7 @@ try_extension:
|
||||||
if (loader)
|
if (loader)
|
||||||
{
|
{
|
||||||
module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, 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;
|
goto success;
|
||||||
loader = NULL;
|
loader = NULL;
|
||||||
module = NULL;
|
module = NULL;
|
||||||
|
@ -376,7 +374,7 @@ try_extension:
|
||||||
loader = loaders_name[i];
|
loader = loaders_name[i];
|
||||||
module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
|
module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
|
||||||
if (!module) continue;
|
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;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,22 +485,32 @@ done:
|
||||||
static void
|
static void
|
||||||
handle_image_open(int wfd, void *params)
|
handle_image_open(int wfd, void *params)
|
||||||
{
|
{
|
||||||
Slave_Msg_Image_Open *p;
|
Slave_Msg_Image_Open *msg = params;
|
||||||
Slave_Msg_Image_Opened result;
|
Slave_Msg_Image_Opened result;
|
||||||
|
Evas_Image_Load_Opts load_opts;
|
||||||
Error_Type err;
|
Error_Type err;
|
||||||
const char *loader = NULL, *file, *key, *ptr;
|
const char *loader = NULL, *file, *key, *ptr;
|
||||||
char *resp;
|
char *resp;
|
||||||
size_t resp_size;
|
size_t resp_size;
|
||||||
|
|
||||||
p = params;
|
memset(&load_opts, 0, sizeof(load_opts));
|
||||||
file = (const char *)(p + sizeof(Slave_Msg_Image_Open));
|
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;
|
key = file + strlen(file) + 1;
|
||||||
ptr = key + strlen(key) + 1;
|
ptr = key + strlen(key) + 1;
|
||||||
if (p->has_loader_data)
|
loader = ptr;
|
||||||
loader = ptr;
|
|
||||||
|
|
||||||
memset(&result, 0, sizeof(result));
|
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)
|
!= CSERVE2_NONE)
|
||||||
{
|
{
|
||||||
printf("OPEN failed at %s:%d\n", __FUNCTION__, __LINE__);
|
printf("OPEN failed at %s:%d\n", __FUNCTION__, __LINE__);
|
||||||
|
|
|
@ -324,9 +324,20 @@ struct _Index_Entry {
|
||||||
#define FILE_DATA_ARRAY_TAG ('F' | 'I' << 8 | 'L' << 16 | 'E' << 24)
|
#define FILE_DATA_ARRAY_TAG ('F' | 'I' << 8 | 'L' << 16 | 'E' << 24)
|
||||||
struct _File_Data {
|
struct _File_Data {
|
||||||
SHMOBJECT;
|
SHMOBJECT;
|
||||||
|
// Hash entry elements (see Evas_Image_Load_Opts)
|
||||||
string_t path;
|
string_t path;
|
||||||
string_t key;
|
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 w, h;
|
||||||
int frame_count;
|
int frame_count;
|
||||||
int loop_count;
|
int loop_count;
|
||||||
|
|
|
@ -23,6 +23,22 @@
|
||||||
#define HKEY_LOAD_OPTS_STR_LEN 215
|
#define HKEY_LOAD_OPTS_STR_LEN 215
|
||||||
typedef void (*Op_Callback)(void *data, const void *msg, int size);
|
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 {
|
struct _File_Entry {
|
||||||
unsigned int file_id;
|
unsigned int file_id;
|
||||||
unsigned int server_file_id;
|
unsigned int server_file_id;
|
||||||
|
@ -2053,26 +2069,45 @@ _shared_string_get(int id)
|
||||||
do { if (!_shared_index_remap_check(&(si), sizeof(typ))) { \
|
do { if (!_shared_index_remap_check(&(si), sizeof(typ))) { \
|
||||||
CRIT("Failed to remap index"); return NULL; } } while (0)
|
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,
|
static Eina_Bool
|
||||||
size_t hkey_size)
|
_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;
|
return ((lo->scale_down_by == 0)
|
||||||
filelen = strlen(file);
|
&& (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)
|
static void
|
||||||
return NULL;
|
_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);
|
if (!lo)
|
||||||
hkey[filelen] = ':';
|
snprintf(buf, sz, "%s:%s", path, key);
|
||||||
if (key)
|
|
||||||
memcpy(hkey + filelen + 1, key, keylen);
|
|
||||||
else
|
else
|
||||||
memcpy(hkey + filelen + 1, "(null)", 7);
|
{
|
||||||
|
if (lo->orientation)
|
||||||
return hkey;
|
{
|
||||||
|
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 *
|
static const File_Data *
|
||||||
|
@ -2104,7 +2139,7 @@ _shared_image_entry_file_data_find(Image_Entry *ie)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check hash
|
// 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);
|
fdata = eina_hash_find(_index.files.entries_by_hkey, hkey);
|
||||||
if (fdata)
|
if (fdata)
|
||||||
return fdata;
|
return fdata;
|
||||||
|
@ -2116,6 +2151,7 @@ _shared_image_entry_file_data_find(Image_Entry *ie)
|
||||||
const char *file, *key;
|
const char *file, *key;
|
||||||
const File_Data *fd;
|
const File_Data *fd;
|
||||||
char fd_hkey[PATH_MAX];
|
char fd_hkey[PATH_MAX];
|
||||||
|
Evas_Image_Load_Opts lo = empty_lo;
|
||||||
|
|
||||||
fd = &(_index.files.entries.filedata[k]);
|
fd = &(_index.files.entries.filedata[k]);
|
||||||
if (!fd->id) break;
|
if (!fd->id) break;
|
||||||
|
@ -2136,7 +2172,17 @@ _shared_image_entry_file_data_find(Image_Entry *ie)
|
||||||
(key > _index.strings_entries.data + _index.strings_entries.size))
|
(key > _index.strings_entries.data + _index.strings_entries.size))
|
||||||
key = _shared_string_get(fd->key);
|
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)
|
if (add_to_hash)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue