forked from enlightenment/efl
evas: add memory image loader api. ask not how it works or i shall
disembowel you. ktnxbi. SVN revision: 57736
This commit is contained in:
parent
6317f922e5
commit
3d26ace1c7
|
@ -166,3 +166,9 @@
|
||||||
2011-03-11 Carsten Haitzler (The Rasterman)
|
2011-03-11 Carsten Haitzler (The Rasterman)
|
||||||
|
|
||||||
* Add ICO loader to evas (also can load CUR cursor files in theory)
|
* Add ICO loader to evas (also can load CUR cursor files in theory)
|
||||||
|
|
||||||
|
2011-03-14 Carsten Haitzler (The Rasterman)
|
||||||
|
|
||||||
|
* Add "load from memory" API: evas_object_image_memfile_set() by
|
||||||
|
popular demand. Can load an image format from a memory address.
|
||||||
|
|
||||||
|
|
|
@ -1245,6 +1245,7 @@ typedef void (*Evas_Object_Image_Pixels_Get_Cb) (void *data, Evas_Object *o);
|
||||||
EAPI Evas_Object *evas_object_image_add (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
|
EAPI Evas_Object *evas_object_image_add (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
|
||||||
EAPI Evas_Object *evas_object_image_filled_add (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
|
EAPI Evas_Object *evas_object_image_filled_add (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
|
||||||
|
|
||||||
|
EAPI void evas_object_image_memfile_set (Evas_Object *obj, void *data, int size, char *format, char *key) EINA_ARG_NONNULL(1, 2);
|
||||||
EAPI void evas_object_image_file_set (Evas_Object *obj, const char *file, const char *key) EINA_ARG_NONNULL(1);
|
EAPI void evas_object_image_file_set (Evas_Object *obj, const char *file, const char *key) EINA_ARG_NONNULL(1);
|
||||||
EAPI void evas_object_image_file_get (const Evas_Object *obj, const char **file, const char **key) EINA_ARG_NONNULL(1, 2);
|
EAPI void evas_object_image_file_get (const Evas_Object *obj, const char **file, const char **key) EINA_ARG_NONNULL(1, 2);
|
||||||
EAPI void evas_object_image_border_set (Evas_Object *obj, int l, int r, int t, int b) EINA_ARG_NONNULL(1);
|
EAPI void evas_object_image_border_set (Evas_Object *obj, int l, int r, int t, int b) EINA_ARG_NONNULL(1);
|
||||||
|
|
|
@ -964,6 +964,7 @@ evas_cache_image_drop(Image_Entry *im)
|
||||||
LKL(im->lock_references);
|
LKL(im->lock_references);
|
||||||
#endif
|
#endif
|
||||||
im->references--;
|
im->references--;
|
||||||
|
if (im->references < 0) im->references = 0;
|
||||||
references = im->references;
|
references = im->references;
|
||||||
#ifdef EVAS_FRAME_QUEUING
|
#ifdef EVAS_FRAME_QUEUING
|
||||||
LKU(im->lock_references);
|
LKU(im->lock_references);
|
||||||
|
@ -1129,7 +1130,7 @@ evas_cache_image_alone(Image_Entry *im)
|
||||||
LKU(im->lock_references);
|
LKU(im->lock_references);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (references == 1)
|
if (references <= 1)
|
||||||
{
|
{
|
||||||
if (!(im->flags.dirty))
|
if (!(im->flags.dirty))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#include "evas_common.h"
|
#include "evas_common.h"
|
||||||
#include "evas_private.h"
|
#include "evas_private.h"
|
||||||
#include "../engines/common/evas_convert_color.h"
|
#include "../engines/common/evas_convert_color.h"
|
||||||
|
@ -58,6 +63,9 @@ struct _Evas_Object_Image
|
||||||
void *get_pixels_data;
|
void *get_pixels_data;
|
||||||
} func;
|
} func;
|
||||||
|
|
||||||
|
const char *tmpf;
|
||||||
|
int tmpf_fd;
|
||||||
|
|
||||||
Evas_Image_Scale_Hint scale_hint;
|
Evas_Image_Scale_Hint scale_hint;
|
||||||
Evas_Image_Content_Hint content_hint;
|
Evas_Image_Content_Hint content_hint;
|
||||||
|
|
||||||
|
@ -100,6 +108,7 @@ static void _proxy_unset(Evas_Object *proxy);
|
||||||
static void _proxy_set(Evas_Object *proxy, Evas_Object *src);
|
static void _proxy_set(Evas_Object *proxy, Evas_Object *src);
|
||||||
static void _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface, int x, int y);
|
static void _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface, int x, int y);
|
||||||
|
|
||||||
|
static void _cleanup_tmpf(Evas_Object *obj);
|
||||||
|
|
||||||
static const Evas_Object_Func object_func =
|
static const Evas_Object_Func object_func =
|
||||||
{
|
{
|
||||||
|
@ -179,6 +188,120 @@ evas_object_image_filled_add(Evas *e)
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cleanup_tmpf(Evas_Object *obj)
|
||||||
|
{
|
||||||
|
Evas_Object_Image *o;
|
||||||
|
|
||||||
|
o = (Evas_Object_Image *)(obj->object_data);
|
||||||
|
if (!o->tmpf) return;
|
||||||
|
#ifdef __linux__
|
||||||
|
#else
|
||||||
|
unlink(o->tmpf);
|
||||||
|
#endif
|
||||||
|
if (o->tmpf_fd >= 0) close(o->tmpf_fd);
|
||||||
|
eina_stringshare_del(o->tmpf);
|
||||||
|
o->tmpf_fd = -1;
|
||||||
|
o->tmpf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_create_tmpf(Evas_Object *obj, void *data, int size, char *format __UNUSED__)
|
||||||
|
{
|
||||||
|
Evas_Object_Image *o;
|
||||||
|
char buf[4096];
|
||||||
|
void *dst;
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
o = (Evas_Object_Image *)(obj->object_data);
|
||||||
|
#ifdef __linux__
|
||||||
|
snprintf(buf, sizeof(buf), "/dev/shm/.evas-tmpf-%i-%p-%i-XXXXXX",
|
||||||
|
(int)getpid(), data, (int)size);
|
||||||
|
fd = mkstemp(buf);
|
||||||
|
#endif
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), "/tmp/.evas-tmpf-%i-%p-%i-XXXXXX",
|
||||||
|
(int)getpid(), data, (int)size);
|
||||||
|
fd = mkstemp(buf);
|
||||||
|
}
|
||||||
|
if (fd < 0) return;
|
||||||
|
if (ftruncate(fd, size) < 0)
|
||||||
|
{
|
||||||
|
unlink(buf);
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unlink(buf);
|
||||||
|
dst = mmap(NULL, size,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
MAP_SHARED,
|
||||||
|
fd, 0);
|
||||||
|
if (dst == MAP_FAILED)
|
||||||
|
{
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
o->tmpf_fd = fd;
|
||||||
|
#ifdef __linux__
|
||||||
|
snprintf(buf, sizeof(buf), "/proc/%li/fd/%i", (long)getpid(), fd);
|
||||||
|
#endif
|
||||||
|
o->tmpf = eina_stringshare_add(buf);
|
||||||
|
memcpy(dst, data, size);
|
||||||
|
munmap(dst, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the data for an image from memory to be loaded
|
||||||
|
*
|
||||||
|
* This is the same as evas_object_image_file_set() but the file to be loaded
|
||||||
|
* may exist at an address in memory (the data for the file, not the filename
|
||||||
|
* itself). The @p data at the address is copied and stored for future use, so
|
||||||
|
* no @p data needs to be kept after this call is made. It will be managed and
|
||||||
|
* freed for you when no longer needed. The @p size is limited to 2 gigabytes
|
||||||
|
* in size, and must be greater than 0. A NULL @p data pointer is also invalid.
|
||||||
|
* Set the filename to NULL to reset to empty state and have the image file
|
||||||
|
* data freed from memory using evas_object_image_file_set().
|
||||||
|
*
|
||||||
|
* The @p format is optional (pass NULL if you don't need/use it). It is used
|
||||||
|
* to help Evas guess better which loader to use for the data. It may simply
|
||||||
|
* be the "extension" of the file as it would normally be on disk such as
|
||||||
|
* "jpg" or "png" or "gif" etc.
|
||||||
|
*
|
||||||
|
* @param obj The given image object.
|
||||||
|
* @param data The image file data address
|
||||||
|
* @param size The size of the image file data in bytes
|
||||||
|
* @param format The format of the file (optional), or NULL if not needed
|
||||||
|
* @param key The image key in file, or NULL.
|
||||||
|
*/
|
||||||
|
EAPI void
|
||||||
|
evas_object_image_memfile_set(Evas_Object *obj, void *data, int size, char *format, char *key)
|
||||||
|
{
|
||||||
|
Evas_Object_Image *o;
|
||||||
|
|
||||||
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
||||||
|
return;
|
||||||
|
MAGIC_CHECK_END();
|
||||||
|
o = (Evas_Object_Image *)(obj->object_data);
|
||||||
|
MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
|
||||||
|
return;
|
||||||
|
MAGIC_CHECK_END();
|
||||||
|
_cleanup_tmpf(obj);
|
||||||
|
evas_object_image_file_set(obj, NULL, NULL);
|
||||||
|
if ((size < 1) || (!data)) return;
|
||||||
|
|
||||||
|
_create_tmpf(obj, data, size, format);
|
||||||
|
evas_object_image_file_set(obj, o->tmpf, key);
|
||||||
|
if (!o->engine_data)
|
||||||
|
{
|
||||||
|
_cleanup_tmpf(obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// invalidate the cache effectively
|
||||||
|
evas_object_image_alpha_set(obj, !o->cur.has_alpha);
|
||||||
|
evas_object_image_alpha_set(obj, !o->cur.has_alpha);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the filename and key of the given image object.
|
* Sets the filename and key of the given image object.
|
||||||
*
|
*
|
||||||
|
@ -202,6 +325,7 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
|
||||||
MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
|
MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
|
||||||
return;
|
return;
|
||||||
MAGIC_CHECK_END();
|
MAGIC_CHECK_END();
|
||||||
|
if ((o->tmpf) && (file != o->tmpf)) _cleanup_tmpf(obj);
|
||||||
if ((o->cur.file) && (file) && (!strcmp(o->cur.file, file)))
|
if ((o->cur.file) && (file) && (!strcmp(o->cur.file, file)))
|
||||||
{
|
{
|
||||||
if ((!o->cur.key) && (!key))
|
if ((!o->cur.key) && (!key))
|
||||||
|
@ -2659,6 +2783,7 @@ evas_object_image_new(void)
|
||||||
o->cur.opaque_valid = 0;
|
o->cur.opaque_valid = 0;
|
||||||
o->cur.source = NULL;
|
o->cur.source = NULL;
|
||||||
o->prev = o->cur;
|
o->prev = o->cur;
|
||||||
|
o->tmpf_fd = -1;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2674,6 +2799,7 @@ evas_object_image_free(Evas_Object *obj)
|
||||||
return;
|
return;
|
||||||
MAGIC_CHECK_END();
|
MAGIC_CHECK_END();
|
||||||
/* free obj */
|
/* free obj */
|
||||||
|
_cleanup_tmpf(obj);
|
||||||
if (o->cur.file) eina_stringshare_del(o->cur.file);
|
if (o->cur.file) eina_stringshare_del(o->cur.file);
|
||||||
if (o->cur.key) eina_stringshare_del(o->cur.key);
|
if (o->cur.key) eina_stringshare_del(o->cur.key);
|
||||||
if (o->cur.source) _proxy_unset(obj);
|
if (o->cur.source) _proxy_unset(obj);
|
||||||
|
|
Loading…
Reference in New Issue