summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/evas/Evas_Eo.h15
-rw-r--r--src/lib/evas/Evas_Legacy.h17
-rw-r--r--src/lib/evas/cache/evas_cache.h19
-rw-r--r--src/lib/evas/cache/evas_cache_image.c258
-rw-r--r--src/lib/evas/canvas/evas_object_image.c176
-rw-r--r--src/lib/evas/common/evas_image.h1
-rw-r--r--src/lib/evas/common/evas_image_load.c50
-rw-r--r--src/lib/evas/common/evas_image_main.c32
-rw-r--r--src/lib/evas/include/evas_common.h1
-rw-r--r--src/lib/evas/include/evas_private.h1
-rw-r--r--src/modules/evas/engines/gl_cocoa/evas_engine.c12
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_common.h1
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_image.c36
-rw-r--r--src/modules/evas/engines/gl_sdl/evas_engine.c10
-rw-r--r--src/modules/evas/engines/gl_x11/evas_engine.c12
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c21
16 files changed, 493 insertions, 169 deletions
diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h
index 83c6540c6b..8345981973 100644
--- a/src/lib/evas/Evas_Eo.h
+++ b/src/lib/evas/Evas_Eo.h
@@ -5474,6 +5474,7 @@ enum
5474{ 5474{
5475 EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET, 5475 EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET,
5476 EVAS_OBJ_IMAGE_SUB_ID_FILE_SET, 5476 EVAS_OBJ_IMAGE_SUB_ID_FILE_SET,
5477 EVAS_OBJ_IMAGE_SUB_ID_MMAP_SET,
5477 EVAS_OBJ_IMAGE_SUB_ID_FILE_GET, 5478 EVAS_OBJ_IMAGE_SUB_ID_FILE_GET,
5478 EVAS_OBJ_IMAGE_SUB_ID_SOURCE_SET, 5479 EVAS_OBJ_IMAGE_SUB_ID_SOURCE_SET,
5479 EVAS_OBJ_IMAGE_SUB_ID_SOURCE_GET, 5480 EVAS_OBJ_IMAGE_SUB_ID_SOURCE_GET,
@@ -5584,6 +5585,20 @@ enum
5584#define evas_obj_image_file_set(file, key) EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_FILE_SET), EO_TYPECHECK(const char *, file), EO_TYPECHECK(const char*, key) 5585#define evas_obj_image_file_set(file, key) EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_FILE_SET), EO_TYPECHECK(const char *, file), EO_TYPECHECK(const char*, key)
5585 5586
5586/** 5587/**
5588 * @def evas_obj_image_mmap_set
5589 * @since 1.8
5590 *
5591 * Set the source mmaped file from where an image object must fetch the real
5592 * image data (it may be any Eina_File).
5593 *
5594 * @param[in] file in
5595 * @param[in] key in
5596 *
5597 * @see evas_obj_image_file_set
5598 */
5599#define evas_obj_image_mmap_set(f, key) EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_MMAP_SET), EO_TYPECHECK(Eina_File *, f), EO_TYPECHECK(const char*, key)
5600
5601/**
5587 * @def evas_obj_image_file_get 5602 * @def evas_obj_image_file_get
5588 * @since 1.8 5603 * @since 1.8
5589 * 5604 *
diff --git a/src/lib/evas/Evas_Legacy.h b/src/lib/evas/Evas_Legacy.h
index fd69a83079..8456900aca 100644
--- a/src/lib/evas/Evas_Legacy.h
+++ b/src/lib/evas/Evas_Legacy.h
@@ -3913,6 +3913,23 @@ EAPI void evas_object_image_memfile_set(Evas_Object *ob
3913EAPI void evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key) EINA_ARG_NONNULL(1); 3913EAPI void evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key) EINA_ARG_NONNULL(1);
3914 3914
3915/** 3915/**
3916 * Set the source mmaped file from where an image object must fetch the real
3917 * image data (it must be an Eina_File).
3918 *
3919 * @param obj The given image object.
3920 * @param f The mmaped file
3921 * @param key The image key in @p file (if its an Eet one), or @c
3922 * NULL, otherwise.
3923 *
3924 * If the file supports multiple data stored in it (as Eet files do),
3925 * you can specify the key to be used as the index of the image in
3926 * this file.
3927 *
3928 * @since 1.8
3929 */
3930EAPI void evas_object_image_mmap_set(Evas_Object *eo_obj, Eina_File *f, const char *key);
3931
3932/**
3916 * Retrieve the source file from where an image object is to fetch the 3933 * Retrieve the source file from where an image object is to fetch the
3917 * real image data (it may be an Eet file, besides pure image ones). 3934 * real image data (it may be an Eet file, besides pure image ones).
3918 * 3935 *
diff --git a/src/lib/evas/cache/evas_cache.h b/src/lib/evas/cache/evas_cache.h
index 8fca866f1f..b7756aef6c 100644
--- a/src/lib/evas/cache/evas_cache.h
+++ b/src/lib/evas/cache/evas_cache.h
@@ -55,6 +55,12 @@ struct _Evas_Cache_Image
55 Eina_Inlist *lru_nodata; 55 Eina_Inlist *lru_nodata;
56 Eina_Hash *inactiv; 56 Eina_Hash *inactiv;
57 Eina_Hash *activ; 57 Eina_Hash *activ;
58
59 Eina_Hash *mmap_activ;
60 Eina_Hash *mmap_inactiv;
61 Eina_Inlist *mmap_lru;
62 Eina_Inlist *mmap_lru_nodata;
63
58 void *data; 64 void *data;
59 65
60 int usage; 66 int usage;
@@ -90,14 +96,14 @@ struct _Evas_Cache_Engine_Image
90{ 96{
91 Evas_Cache_Engine_Image_Func func; 97 Evas_Cache_Engine_Image_Func func;
92 98
93 Eina_Inlist* dirty; 99 Eina_Inlist *dirty;
94 100
95 Eina_Hash* activ; 101 Eina_Hash *activ;
96 Eina_Hash* inactiv; 102 Eina_Hash *inactiv;
97 Eina_Inlist* lru; 103 Eina_Inlist *lru;
98 104
99 Evas_Cache_Image* parent; 105 Evas_Cache_Image *parent;
100 Evas_Cache_Engine_Image* brother; 106 Evas_Cache_Engine_Image *brother;
101 107
102 int usage; 108 int usage;
103 int limit; 109 int limit;
@@ -114,6 +120,7 @@ extern "C" {
114EAPI Evas_Cache_Image* evas_cache_image_init(const Evas_Cache_Image_Func *cb); 120EAPI Evas_Cache_Image* evas_cache_image_init(const Evas_Cache_Image_Func *cb);
115EAPI void evas_cache_image_shutdown(Evas_Cache_Image *cache); 121EAPI void evas_cache_image_shutdown(Evas_Cache_Image *cache);
116EAPI Image_Entry* evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error); 122EAPI Image_Entry* evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error);
123EAPI Image_Entry* evas_cache_image_mmap_request(Evas_Cache_Image *cache, Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error);
117EAPI void evas_cache_image_ref(Image_Entry *im); 124EAPI void evas_cache_image_ref(Image_Entry *im);
118EAPI void evas_cache_image_drop(Image_Entry *im); 125EAPI void evas_cache_image_drop(Image_Entry *im);
119EAPI void evas_cache_image_data_not_needed(Image_Entry *im); 126EAPI void evas_cache_image_data_not_needed(Image_Entry *im);
diff --git a/src/lib/evas/cache/evas_cache_image.c b/src/lib/evas/cache/evas_cache_image.c
index 6765f6ba8a..1dc13d9f0f 100644
--- a/src/lib/evas/cache/evas_cache_image.c
+++ b/src/lib/evas/cache/evas_cache_image.c
@@ -72,7 +72,7 @@ _evas_cache_image_dirty_del(Image_Entry *im)
72 if (!im->flags.dirty) return; 72 if (!im->flags.dirty) return;
73 im->flags.dirty = 0; 73 im->flags.dirty = 0;
74 im->flags.cached = 0; 74 im->flags.cached = 0;
75 im->cache->dirty = eina_inlist_remove(im->cache->dirty, EINA_INLIST_GET(im)); 75 im->cache->dirty = eina_inlist_remove(im->cache->dirty, EINA_INLIST_GET(im));
76} 76}
77 77
78static void 78static void
@@ -85,7 +85,10 @@ _evas_cache_image_activ_add(Image_Entry *im)
85 if (!im->cache_key) return; 85 if (!im->cache_key) return;
86 im->flags.activ = 1; 86 im->flags.activ = 1;
87 im->flags.cached = 1; 87 im->flags.cached = 1;
88 eina_hash_direct_add(im->cache->activ, im->cache_key, im); 88 if (im->flags.given_mmap)
89 eina_hash_direct_add(im->cache->mmap_activ, im->cache_key, im);
90 else
91 eina_hash_direct_add(im->cache->activ, im->cache_key, im);
89} 92}
90 93
91static void 94static void
@@ -95,7 +98,10 @@ _evas_cache_image_activ_del(Image_Entry *im)
95 if (!im->cache_key) return; 98 if (!im->cache_key) return;
96 im->flags.activ = 0; 99 im->flags.activ = 0;
97 im->flags.cached = 0; 100 im->flags.cached = 0;
98 eina_hash_del(im->cache->activ, im->cache_key, im); 101 if (im->flags.given_mmap)
102 eina_hash_del(im->cache->mmap_activ, im->cache_key, im);
103 else
104 eina_hash_del(im->cache->activ, im->cache_key, im);
99} 105}
100 106
101static void 107static void
@@ -108,8 +114,16 @@ _evas_cache_image_lru_add(Image_Entry *im)
108 if (!im->cache_key) return; 114 if (!im->cache_key) return;
109 im->flags.lru = 1; 115 im->flags.lru = 1;
110 im->flags.cached = 1; 116 im->flags.cached = 1;
111 eina_hash_direct_add(im->cache->inactiv, im->cache_key, im); 117 if (im->flags.given_mmap)
112 im->cache->lru = eina_inlist_prepend(im->cache->lru, EINA_INLIST_GET(im)); 118 {
119 eina_hash_direct_add(im->cache->mmap_inactiv, im->cache_key, im);
120 im->cache->mmap_lru = eina_inlist_prepend(im->cache->mmap_lru, EINA_INLIST_GET(im));
121 }
122 else
123 {
124 eina_hash_direct_add(im->cache->inactiv, im->cache_key, im);
125 im->cache->lru = eina_inlist_prepend(im->cache->lru, EINA_INLIST_GET(im));
126 }
113 im->cache->usage += im->cache->func.mem_size_get(im); 127 im->cache->usage += im->cache->func.mem_size_get(im);
114} 128}
115 129
@@ -120,8 +134,16 @@ _evas_cache_image_lru_del(Image_Entry *im)
120 if (!im->cache_key) return; 134 if (!im->cache_key) return;
121 im->flags.lru = 0; 135 im->flags.lru = 0;
122 im->flags.cached = 0; 136 im->flags.cached = 0;
123 eina_hash_del(im->cache->inactiv, im->cache_key, im); 137 if (im->flags.given_mmap)
124 im->cache->lru = eina_inlist_remove(im->cache->lru, EINA_INLIST_GET(im)); 138 {
139 eina_hash_del(im->cache->mmap_inactiv, im->cache_key, im);
140 im->cache->mmap_lru = eina_inlist_remove(im->cache->mmap_lru, EINA_INLIST_GET(im));
141 }
142 else
143 {
144 eina_hash_del(im->cache->inactiv, im->cache_key, im);
145 im->cache->lru = eina_inlist_remove(im->cache->lru, EINA_INLIST_GET(im));
146 }
125 im->cache->usage -= im->cache->func.mem_size_get(im); 147 im->cache->usage -= im->cache->func.mem_size_get(im);
126} 148}
127 149
@@ -134,7 +156,10 @@ _evas_cache_image_lru_nodata_add(Image_Entry *im)
134 _evas_cache_image_lru_del(im); 156 _evas_cache_image_lru_del(im);
135 im->flags.lru = 1; 157 im->flags.lru = 1;
136 im->flags.cached = 1; 158 im->flags.cached = 1;
137 im->cache->lru_nodata = eina_inlist_prepend(im->cache->lru_nodata, EINA_INLIST_GET(im)); 159 if (im->flags.given_mmap)
160 im->cache->mmap_lru_nodata = eina_inlist_prepend(im->cache->mmap_lru_nodata, EINA_INLIST_GET(im));
161 else
162 im->cache->lru_nodata = eina_inlist_prepend(im->cache->lru_nodata, EINA_INLIST_GET(im));
138} 163}
139 164
140static void 165static void
@@ -143,7 +168,10 @@ _evas_cache_image_lru_nodata_del(Image_Entry *im)
143 if (!im->flags.lru_nodata) return; 168 if (!im->flags.lru_nodata) return;
144 im->flags.lru = 0; 169 im->flags.lru = 0;
145 im->flags.cached = 0; 170 im->flags.cached = 0;
146 im->cache->lru_nodata = eina_inlist_remove(im->cache->lru_nodata, EINA_INLIST_GET(im)); 171 if (im->flags.given_mmap)
172 im->cache->mmap_lru_nodata = eina_inlist_remove(im->cache->mmap_lru_nodata, EINA_INLIST_GET(im));
173 else
174 im->cache->lru_nodata = eina_inlist_remove(im->cache->lru_nodata, EINA_INLIST_GET(im));
147} 175}
148 176
149static void 177static void
@@ -213,6 +241,7 @@ static Image_Entry *
213_evas_cache_image_entry_new(Evas_Cache_Image *cache, 241_evas_cache_image_entry_new(Evas_Cache_Image *cache,
214 const char *hkey, 242 const char *hkey,
215 Image_Timestamp *tstamp, 243 Image_Timestamp *tstamp,
244 Eina_File *f,
216 const char *file, 245 const char *file,
217 const char *key, 246 const char *key,
218 Evas_Image_Load_Opts *lo, 247 Evas_Image_Load_Opts *lo,
@@ -233,6 +262,9 @@ _evas_cache_image_entry_new(Evas_Cache_Image *cache,
233 ie->w = -1; 262 ie->w = -1;
234 ie->h = -1; 263 ie->h = -1;
235 ie->scale = 1; 264 ie->scale = 1;
265 ie->f = f;
266 ie->loader_data = NULL;
267 if (ie->f) ie->flags.given_mmap = EINA_TRUE;
236 if (file) ie->file = eina_stringshare_add(file); 268 if (file) ie->file = eina_stringshare_add(file);
237 if (key) ie->key = eina_stringshare_add(key); 269 if (key) ie->key = eina_stringshare_add(key);
238 if (tstamp) ie->tstamp = *tstamp; 270 if (tstamp) ie->tstamp = *tstamp;
@@ -242,7 +274,7 @@ _evas_cache_image_entry_new(Evas_Cache_Image *cache,
242 LKI(ie->lock_cancel); 274 LKI(ie->lock_cancel);
243 275
244 if (lo) ie->load_opts = *lo; 276 if (lo) ie->load_opts = *lo;
245 if (ie->file) 277 if (ie->file || ie->f)
246 { 278 {
247 *error = cache->func.constructor(ie); 279 *error = cache->func.constructor(ie);
248 if (*error != EVAS_LOAD_ERROR_NONE) 280 if (*error != EVAS_LOAD_ERROR_NONE)
@@ -485,6 +517,8 @@ evas_cache_image_init(const Evas_Cache_Image_Func *cb)
485 cache->func = *cb; 517 cache->func = *cb;
486 cache->inactiv = eina_hash_string_superfast_new(NULL); 518 cache->inactiv = eina_hash_string_superfast_new(NULL);
487 cache->activ = eina_hash_string_superfast_new(NULL); 519 cache->activ = eina_hash_string_superfast_new(NULL);
520 cache->mmap_activ = eina_hash_string_superfast_new(NULL);
521 cache->mmap_inactiv = eina_hash_string_superfast_new(NULL);
488 cache->references = 1; 522 cache->references = 1;
489 return cache; 523 return cache;
490} 524}
@@ -534,6 +568,9 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
534 } 568 }
535 delete_list = NULL; 569 delete_list = NULL;
536 eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list); 570 eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list);
571 eina_hash_foreach(cache->mmap_activ, _evas_cache_image_free_cb, &delete_list);
572 eina_hash_foreach(cache->inactiv, _evas_cache_image_free_cb, &delete_list);
573 eina_hash_foreach(cache->mmap_inactiv, _evas_cache_image_free_cb, &delete_list);
537 while (delete_list) 574 while (delete_list)
538 { 575 {
539 _evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list)); 576 _evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list));
@@ -553,6 +590,8 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
553 } 590 }
554 eina_hash_free(cache->activ); 591 eina_hash_free(cache->activ);
555 eina_hash_free(cache->inactiv); 592 eina_hash_free(cache->inactiv);
593 eina_hash_free(cache->mmap_activ);
594 eina_hash_free(cache->mmap_inactiv);
556 free(cache); 595 free(cache);
557 596
558 if (--_evas_cache_mutex_init == 0) 597 if (--_evas_cache_mutex_init == 0)
@@ -563,6 +602,140 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
563 } 602 }
564} 603}
565 604
605static const Evas_Image_Load_Opts prevent = {
606 { 0, 0, 0, 0 },
607 {
608 0, 0, 0, 0,
609 0, 0,
610 0,
611 0
612 },
613 0.0,
614 0, 0,
615 0,
616 0,
617
618 EINA_FALSE
619};
620
621static size_t
622_evas_cache_image_loadopts_append(char *hkey, Evas_Image_Load_Opts **plo)
623{
624 Evas_Image_Load_Opts *lo = *plo;
625 size_t offset = 0;
626
627 if ((!lo) ||
628 (lo &&
629 (lo->scale_down_by == 0) &&
630 (lo->dpi == 0.0) &&
631 ((lo->w == 0) || (lo->h == 0)) &&
632 ((lo->region.w == 0) || (lo->region.h == 0)) &&
633 (lo->orientation == 0)
634 ))
635 {
636 *plo = (Evas_Image_Load_Opts*) &prevent;
637 }
638 else
639 {
640 memcpy(hkey, "//@/", 4);
641 offset += 4;
642 offset += eina_convert_xtoa(lo->scale_down_by, hkey + offset);
643 hkey[offset] = '/';
644 offset += 1;
645 offset += eina_convert_dtoa(lo->dpi, hkey + offset);
646 hkey[offset] = '/';
647 offset += 1;
648 offset += eina_convert_xtoa(lo->w, hkey + offset);
649 hkey[offset] = 'x';
650 offset += 1;
651 offset += eina_convert_xtoa(lo->h, hkey + offset);
652 hkey[offset] = '/';
653 offset += 1;
654 offset += eina_convert_xtoa(lo->region.x, hkey + offset);
655 hkey[offset] = '+';
656 offset += 1;
657 offset += eina_convert_xtoa(lo->region.y, hkey + offset);
658 hkey[offset] = '.';
659 offset += 1;
660 offset += eina_convert_xtoa(lo->region.w, hkey + offset);
661 hkey[offset] = 'x';
662 offset += 1;
663 offset += eina_convert_xtoa(lo->region.h, hkey + offset);
664
665 if (lo->orientation)
666 {
667 hkey[offset] = '/';
668 offset += 1;
669 hkey[offset] = 'o';
670 offset += 1;
671 }
672 }
673 hkey[offset] = '\0';
674
675 return offset;
676}
677
678EAPI Image_Entry *
679evas_cache_image_mmap_request(Evas_Cache_Image *cache,
680 Eina_File *f, const char *key,
681 Evas_Image_Load_Opts *lo, int *error)
682{
683 const char *hexcode = "0123456789abcdef";
684 const char *ckey = "(null)";
685 char *hkey;
686 char *pf;
687 Image_Entry *im;
688 size_t size;
689 size_t file_length;
690 size_t key_length;
691 unsigned int i;
692
693 // FIXME: In the long term we should certainly merge both mmap and filename path
694 // by just using the mmap path. But for the time being, let's just have two path
695 // as it is unlikely to really have an impact on real world application
696 if ((!f) || (!f && !key))
697 {
698 *error = EVAS_LOAD_ERROR_GENERIC;
699 return NULL;
700 }
701
702 /* generate hkey from file+key+load opts */
703 file_length = sizeof (Eina_File*) * 2;
704 key_length = key ? strlen(key) : 6;
705 size = file_length + key_length + 132;
706 hkey = alloca(sizeof (char) * size);
707 pf = (char*) &f;
708 for (size = 0, i = 0; i < sizeof (Eina_File*); i++)
709 {
710 hkey[size++] = hexcode[(pf[i] & 0xF0) >> 4];
711 hkey[size++] = hexcode[(pf[i] & 0x0F)];
712 }
713 memcpy(hkey + size, "//://", 5);
714 size += 5;
715 if (key) ckey = key;
716 memcpy(hkey + size, ckey, key_length);
717 size += key_length;
718 size += _evas_cache_image_loadopts_append(hkey + size, &lo);
719
720
721 /* find image by key in active mmap hash */
722 im = eina_hash_find(cache->mmap_activ, hkey);
723 if (im) goto on_ok;
724
725 /* find image by key in inactive/lru hash */
726 im = eina_hash_find(cache->mmap_inactiv, hkey);
727 if (im) goto on_ok;
728
729 im = _evas_cache_image_entry_new(cache, hkey, NULL, f, NULL, key, lo, error);
730 if (!im) return NULL;
731
732 on_ok:
733 *error = EVAS_LOAD_ERROR_NONE;
734 im->references++;
735 return im;
736}
737
738
566EAPI Image_Entry * 739EAPI Image_Entry *
567evas_cache_image_request(Evas_Cache_Image *cache, const char *file, 740evas_cache_image_request(Evas_Cache_Image *cache, const char *file,
568 const char *key, Evas_Image_Load_Opts *lo, int *error) 741 const char *key, Evas_Image_Load_Opts *lo, int *error)
@@ -570,7 +743,6 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file,
570 const char *ckey = "(null)"; 743 const char *ckey = "(null)";
571 char *hkey; 744 char *hkey;
572 Image_Entry *im; 745 Image_Entry *im;
573 Evas_Image_Load_Opts prevent;
574 size_t size; 746 size_t size;
575 int stat_done = 0, stat_failed = 0; 747 int stat_done = 0, stat_failed = 0;
576 size_t file_length; 748 size_t file_length;
@@ -584,8 +756,6 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file,
584 return NULL; 756 return NULL;
585 } 757 }
586 758
587 memset(&prevent, 0, sizeof prevent);
588
589 /* generate hkey from file+key+load opts */ 759 /* generate hkey from file+key+load opts */
590 file_length = strlen(file); 760 file_length = strlen(file);
591 key_length = key ? strlen(key) : 6; 761 key_length = key ? strlen(key) : 6;
@@ -598,53 +768,7 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file,
598 if (key) ckey = key; 768 if (key) ckey = key;
599 memcpy(hkey + size, ckey, key_length); 769 memcpy(hkey + size, ckey, key_length);
600 size += key_length; 770 size += key_length;
601 if ((!lo) || 771 size += _evas_cache_image_loadopts_append(hkey + size, &lo);
602 (lo &&
603 (lo->scale_down_by == 0) &&
604 (lo->dpi == 0.0) &&
605 ((lo->w == 0) || (lo->h == 0)) &&
606 ((lo->region.w == 0) || (lo->region.h == 0)) &&
607 (lo->orientation == 0)
608 ))
609 {
610 lo = &prevent;
611 }
612 else
613 {
614 memcpy(hkey + size, "//@/", 4);
615 size += 4;
616 size += eina_convert_xtoa(lo->scale_down_by, hkey + size);
617 hkey[size] = '/';
618 size += 1;
619 size += eina_convert_dtoa(lo->dpi, hkey + size);
620 hkey[size] = '/';
621 size += 1;
622 size += eina_convert_xtoa(lo->w, hkey + size);
623 hkey[size] = 'x';
624 size += 1;
625 size += eina_convert_xtoa(lo->h, hkey + size);
626 hkey[size] = '/';
627 size += 1;
628 size += eina_convert_xtoa(lo->region.x, hkey + size);
629 hkey[size] = '+';
630 size += 1;
631 size += eina_convert_xtoa(lo->region.y, hkey + size);
632 hkey[size] = '.';
633 size += 1;
634 size += eina_convert_xtoa(lo->region.w, hkey + size);
635 hkey[size] = 'x';
636 size += 1;
637 size += eina_convert_xtoa(lo->region.h, hkey + size);
638
639 if (lo->orientation)
640 {
641 hkey[size] = '/';
642 size += 1;
643 hkey[size] = 'o';
644 size += 1;
645 }
646 }
647 hkey[size] = '\0';
648 772
649 /* find image by key in active hash */ 773 /* find image by key in active hash */
650 im = eina_hash_find(cache->activ, hkey); 774 im = eina_hash_find(cache->activ, hkey);
@@ -707,7 +831,7 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file,
707 if (stat(file, &st) < 0) goto on_stat_error; 831 if (stat(file, &st) < 0) goto on_stat_error;
708 } 832 }
709 _timestamp_build(&tstamp, &st); 833 _timestamp_build(&tstamp, &st);
710 im = _evas_cache_image_entry_new(cache, hkey, &tstamp, file, key, 834 im = _evas_cache_image_entry_new(cache, hkey, &tstamp, NULL, file, key,
711 lo, error); 835 lo, error);
712 if (!im) goto on_stat_error; 836 if (!im) goto on_stat_error;
713 if (cache->func.debug) cache->func.debug("request", im); 837 if (cache->func.debug) cache->func.debug("request", im);
@@ -866,7 +990,7 @@ evas_cache_image_copied_data(Evas_Cache_Image *cache,
866 (cspace == EVAS_COLORSPACE_YCBCR422601_PL)) 990 (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
867 w &= ~0x1; 991 w &= ~0x1;
868 992
869 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL); 993 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
870 if (!im) return NULL; 994 if (!im) return NULL;
871 im->space = cspace; 995 im->space = cspace;
872 im->flags.alpha = alpha; 996 im->flags.alpha = alpha;
@@ -892,7 +1016,7 @@ evas_cache_image_data(Evas_Cache_Image *cache, unsigned int w, unsigned int h, D
892 (cspace == EVAS_COLORSPACE_YCBCR422601_PL)) 1016 (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
893 w &= ~0x1; 1017 w &= ~0x1;
894 1018
895 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL); 1019 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
896 if (!im) return NULL; 1020 if (!im) return NULL;
897 im->w = w; 1021 im->w = w;
898 im->h = h; 1022 im->h = h;
@@ -936,7 +1060,7 @@ evas_cache_image_size_set(Image_Entry *im, unsigned int w, unsigned int h)
936 if ((im->w == w) && (im->h == h)) return im; 1060 if ((im->w == w) && (im->h == h)) return im;
937 1061
938 cache = im->cache; 1062 cache = im->cache;
939 im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, &error); 1063 im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &error);
940 if (!im2) goto on_error; 1064 if (!im2) goto on_error;
941 1065
942 im2->flags.alpha = im->flags.alpha; 1066 im2->flags.alpha = im->flags.alpha;
@@ -1021,7 +1145,7 @@ evas_cache_image_unload_data(Image_Entry *im)
1021 } 1145 }
1022 LKU(im->lock_cancel); 1146 LKU(im->lock_cancel);
1023 1147
1024 if ((!im->flags.loaded) || (!im->file) || (!im->info.module) || 1148 if ((!im->flags.loaded) || (!im->file && !im->f) || (!im->info.module) ||
1025 (im->flags.dirty)) 1149 (im->flags.dirty))
1026 { 1150 {
1027 LKU(im->lock); 1151 LKU(im->lock);
@@ -1091,7 +1215,7 @@ _dump_img(Image_Entry *im, const char *type)
1091 im->references, 1215 im->references,
1092 im->cache->func.mem_size_get(im), 1216 im->cache->func.mem_size_get(im),
1093 im->w, im->h, im->allocated.w, im->allocated.h, 1217 im->w, im->h, im->allocated.w, im->allocated.h,
1094 im->file, im->key); 1218 im->f ? eina_file_filename_get(im->f) : im->file, im->key);
1095} 1219}
1096 1220
1097static Eina_Bool 1221static Eina_Bool
@@ -1159,7 +1283,7 @@ evas_cache_image_empty(Evas_Cache_Image *cache)
1159{ 1283{
1160 Image_Entry *im; 1284 Image_Entry *im;
1161 1285
1162 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL); 1286 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1163 if (!im) return NULL; 1287 if (!im) return NULL;
1164 im->references = 1; 1288 im->references = 1;
1165 return im; 1289 return im;
diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c
index 3bc4cef32a..864d5f2466 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -85,6 +85,7 @@ struct _Evas_Object_Image_State
85 Evas_Map *defmap; 85 Evas_Map *defmap;
86 const char *file; 86 const char *file;
87 const char *key; 87 const char *key;
88 Eina_File *f;
88 int frame; 89 int frame;
89 int spread; 90 int spread;
90 91
@@ -196,7 +197,7 @@ static const Evas_Object_Image_State default_state = {
196 { 0, 0, 0 }, // image 197 { 0, 0, 0 }, // image
197 { 1.0, 0, 0, 0, 0, 1 }, // border 198 { 1.0, 0, 0, 0, 0, 1 }, // border
198 199
199 NULL, NULL, NULL, NULL, 200 NULL, NULL, NULL, NULL, NULL,
200 0, 201 0,
201 EVAS_TEXTURE_REPEAT, 202 EVAS_TEXTURE_REPEAT,
202 EVAS_COLORSPACE_ARGB8888, 203 EVAS_COLORSPACE_ARGB8888,
@@ -483,51 +484,18 @@ _image_memfile_set(Eo *eo_obj, void *_pd, va_list *list)
483 } 484 }
484} 485}
485 486
486EAPI void
487evas_object_image_file_set(Evas_Object *eo_obj, const char *file, const char *key)
488{
489 MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);
490 return;
491 MAGIC_CHECK_END();
492 eo_do(eo_obj, evas_obj_image_file_set(file, key));
493}
494
495static void 487static void
496_image_file_set(Eo *eo_obj, void *_pd, va_list *list) 488_image_init_set(Eina_File *f, const char *file, const char *key,
489 Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Object_Image *o,
490 Evas_Image_Load_Opts *lo)
497{ 491{
498 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJ_CLASS);
499 Evas_Object_Image *o = _pd;
500 Evas_Image_Load_Opts lo;
501 Eina_Bool resize_call = EINA_FALSE;
502
503 const char *file = va_arg(*list, const char*);
504 const char *key = va_arg(*list, const char*);
505
506 if ((o->pixels->tmpf) && (file != o->pixels->tmpf)) _cleanup_tmpf(eo_obj);
507 if ((o->cur->file) && (file) && (!strcmp(o->cur->file, file)))
508 {
509 if ((!o->cur->key) && (!key))
510 return;
511 if ((o->cur->key) && (key) && (!strcmp(o->cur->key, key)))
512 return;
513 }
514 /*
515 * WTF? why cancel a null image preload? this is just silly (tm)
516 if (!o->engine_data)
517 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
518 o->engine_data,
519 eo_obj);
520 */
521 if (o->cur->source) _proxy_unset(eo_obj, obj, o); 492 if (o->cur->source) _proxy_unset(eo_obj, obj, o);
522 493
523 EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) 494 EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
524 { 495 {
525 if (o->cur->file) eina_stringshare_del(state_write->file); 496 eina_stringshare_replace(&state_write->file, file);
526 if (o->cur->key) eina_stringshare_del(o->cur->key); 497 eina_stringshare_replace(&state_write->key, key);
527 if (file) state_write->file = eina_stringshare_add(file); 498 state_write->f = f;
528 else state_write->file = NULL;
529 if (key) state_write->key = eina_stringshare_add(key);
530 else state_write->key = NULL;
531 } 499 }
532 EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); 500 EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
533 501
@@ -535,9 +503,10 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list)
535 { 503 {
536 state_write->file = NULL; 504 state_write->file = NULL;
537 state_write->key = NULL; 505 state_write->key = NULL;
506 state_write->f = NULL;
538 } 507 }
539 EINA_COW_WRITE_END(evas_object_image_state_cow, o->prev, state_write); 508 EINA_COW_WRITE_END(evas_object_image_state_cow, o->prev, state_write);
540 509
541 if (o->engine_data) 510 if (o->engine_data)
542 { 511 {
543 if (o->preloading) 512 if (o->preloading)
@@ -548,28 +517,30 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list)
548 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output, o->engine_data); 517 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output, o->engine_data);
549 } 518 }
550 o->load_error = EVAS_LOAD_ERROR_NONE; 519 o->load_error = EVAS_LOAD_ERROR_NONE;
551 lo.scale_down_by = o->load_opts->scale_down_by; 520 lo->scale_down_by = o->load_opts->scale_down_by;
552 lo.dpi = o->load_opts->dpi; 521 lo->dpi = o->load_opts->dpi;
553 lo.w = o->load_opts->w; 522 lo->w = o->load_opts->w;
554 lo.h = o->load_opts->h; 523 lo->h = o->load_opts->h;
555 lo.region.x = o->load_opts->region.x; 524 lo->region.x = o->load_opts->region.x;
556 lo.region.y = o->load_opts->region.y; 525 lo->region.y = o->load_opts->region.y;
557 lo.region.w = o->load_opts->region.w; 526 lo->region.w = o->load_opts->region.w;
558 lo.region.h = o->load_opts->region.h; 527 lo->region.h = o->load_opts->region.h;
559 lo.scale_load.src_x = o->load_opts->scale_load.src_x; 528 lo->scale_load.src_x = o->load_opts->scale_load.src_x;
560 lo.scale_load.src_y = o->load_opts->scale_load.src_y; 529 lo->scale_load.src_y = o->load_opts->scale_load.src_y;
561 lo.scale_load.src_w = o->load_opts->scale_load.src_w; 530 lo->scale_load.src_w = o->load_opts->scale_load.src_w;
562 lo.scale_load.src_h = o->load_opts->scale_load.src_h; 531 lo->scale_load.src_h = o->load_opts->scale_load.src_h;
563 lo.scale_load.dst_w = o->load_opts->scale_load.dst_w; 532 lo->scale_load.dst_w = o->load_opts->scale_load.dst_w;
564 lo.scale_load.dst_h = o->load_opts->scale_load.dst_h; 533 lo->scale_load.dst_h = o->load_opts->scale_load.dst_h;
565 lo.scale_load.smooth = o->load_opts->scale_load.smooth; 534 lo->scale_load.smooth = o->load_opts->scale_load.smooth;
566 lo.scale_load.scale_hint = o->load_opts->scale_load.scale_hint; 535 lo->scale_load.scale_hint = o->load_opts->scale_load.scale_hint;
567 lo.orientation = o->load_opts->orientation; 536 lo->orientation = o->load_opts->orientation;
568 o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output, 537}
569 o->cur->file, 538
570 o->cur->key, 539static void
571 &o->load_error, 540_image_done_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Object_Image *o)
572 &lo); 541{
542 Eina_Bool resize_call = EINA_FALSE;
543
573 if (o->engine_data) 544 if (o->engine_data)
574 { 545 {
575 int w, h; 546 int w, h;
@@ -620,6 +591,83 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list)
620} 591}
621 592
622EAPI void 593EAPI void
594evas_object_image_mmap_set(Evas_Object *eo_obj, Eina_File *f, const char *key)
595{
596 eo_do(eo_obj, evas_obj_image_mmap_set(f, key));
597}
598
599static void
600_image_mmap_set(Eo *eo_obj, void *_pd, va_list *list)
601{
602 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJ_CLASS);
603 Evas_Object_Image *o = _pd;
604 Evas_Image_Load_Opts lo;
605
606 Eina_File *f = va_arg(*list, Eina_File *);
607 const char *key = va_arg(*list, const char*);
608
609 if (o->pixels->tmpf) _cleanup_tmpf(eo_obj);
610 if (o->cur->f == f)
611 {
612 if ((!o->cur->key) && (!key))
613 return;
614 if ((o->cur->key) && (key) && (!strcmp(o->cur->key, key)))
615 return;
616 }
617
618 _image_init_set(f, NULL, key, eo_obj, obj, o, &lo);
619 o->engine_data = obj->layer->evas->engine.func->image_mmap(obj->layer->evas->engine.data.output,
620 o->cur->f,
621 o->cur->key,
622 &o->load_error,
623 &lo);
624 _image_done_set(eo_obj, obj, o);
625}
626
627EAPI void
628evas_object_image_file_set(Evas_Object *eo_obj, const char *file, const char *key)
629{
630 MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);
631 return;
632 MAGIC_CHECK_END();
633 eo_do(eo_obj, evas_obj_image_file_set(file, key));
634}
635
636static void
637_image_file_set(Eo *eo_obj, void *_pd, va_list *list)
638{
639 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJ_CLASS);
640 Evas_Object_Image *o = _pd;
641 Evas_Image_Load_Opts lo;
642
643 const char *file = va_arg(*list, const char*);
644 const char *key = va_arg(*list, const char*);
645
646 if ((o->pixels->tmpf) && (file != o->pixels->tmpf)) _cleanup_tmpf(eo_obj);
647 if ((o->cur->file) && (file) && (!strcmp(o->cur->file, file)))
648 {
649 if ((!o->cur->key) && (!key))
650 return;
651 if ((o->cur->key) && (key) && (!strcmp(o->cur->key, key)))
652 return;
653 }
654 /*
655 * WTF? why cancel a null image preload? this is just silly (tm)
656 if (!o->engine_data)
657 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
658 o->engine_data,
659 eo_obj);
660 */
661 _image_init_set(NULL, file, key, eo_obj, obj, o, &lo);
662 o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output,
663 o->cur->file,
664 o->cur->key,
665 &o->load_error,
666 &lo);
667 _image_done_set(eo_obj, obj, o);
668}
669
670EAPI void
623evas_object_image_file_get(const Evas_Object *eo_obj, const char **file, const char **key) 671evas_object_image_file_get(const Evas_Object *eo_obj, const char **file, const char **key)
624{ 672{
625 MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ); 673 MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);
@@ -5146,6 +5194,7 @@ _class_constructor(Eo_Class *klass)
5146 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DBG_INFO_GET), _dbg_info_get), 5194 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DBG_INFO_GET), _dbg_info_get),
5147 EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET), _image_memfile_set), 5195 EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET), _image_memfile_set),
5148 EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_FILE_SET), _image_file_set), 5196 EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_FILE_SET), _image_file_set),
5197 EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_MMAP_SET), _image_mmap_set),
5149 EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_FILE_GET), _image_file_get), 5198 EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_FILE_GET), _image_file_get),
5150 EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_SOURCE_SET), _image_source_set), 5199 EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_SOURCE_SET), _image_source_set),
5151 EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_SOURCE_GET), _image_source_get), 5200 EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_SOURCE_GET), _image_source_get),
@@ -5224,6 +5273,7 @@ _class_constructor(Eo_Class *klass)
5224static const Eo_Op_Description op_desc[] = { 5273static const Eo_Op_Description op_desc[] = {
5225 EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET, "Sets the data for an image from memory to be loaded"), 5274 EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET, "Sets the data for an image from memory to be loaded"),
5226 EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_FILE_SET, "Set the source file from where an image object must fetch the real"), 5275 EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_FILE_SET, "Set the source file from where an image object must fetch the real"),
5276 EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_MMAP_SET, "Set the source mmaped file from where an image object must fetch the real"),
5227 EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_FILE_GET, "Retrieve the source file from where an image object is to fetch the"), 5277 EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_FILE_GET, "Retrieve the source file from where an image object is to fetch the"),
5228 EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_SOURCE_SET, "Set the source object on an image object to used as a @b proxy."), 5278 EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_SOURCE_SET, "Set the source object on an image object to used as a @b proxy."),
5229 EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_SOURCE_GET, "Get the current source object of an image object."), 5279 EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_SOURCE_GET, "Get the current source object of an image object."),
diff --git a/src/lib/evas/common/evas_image.h b/src/lib/evas/common/evas_image.h
index 79f1a29c33..3ea2f22a49 100644
--- a/src/lib/evas/common/evas_image.h
+++ b/src/lib/evas/common/evas_image.h
@@ -33,6 +33,7 @@ EAPI void evas_common_image_alpha_line_buffer_release (RGBA_Image *
33EAPI void evas_common_image_alpha_line_buffer_free (RGBA_Image *im); 33EAPI void evas_common_image_alpha_line_buffer_free (RGBA_Image *im);
34 34
35EAPI RGBA_Image *evas_common_load_image_from_file (const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error); 35EAPI RGBA_Image *evas_common_load_image_from_file (const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error);
36EAPI RGBA_Image *evas_common_load_image_from_mmap (Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error);
36EAPI int evas_common_save_image_to_file (RGBA_Image *im, const char *file, const char *key, int quality, int compress); 37EAPI int evas_common_save_image_to_file (RGBA_Image *im, const char *file, const char *key, int quality, int compress);
37 38
38EAPI void evas_common_rgba_image_scalecache_init(Image_Entry *ie); 39EAPI void evas_common_rgba_image_scalecache_init(Image_Entry *ie);
diff --git a/src/lib/evas/common/evas_image_load.c b/src/lib/evas/common/evas_image_load.c
index a505bc99f6..cb03c7ab76 100644
--- a/src/lib/evas/common/evas_image_load.c
+++ b/src/lib/evas/common/evas_image_load.c
@@ -150,8 +150,17 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error)
150 if (evas_image_load_func) 150 if (evas_image_load_func)
151 { 151 {
152 Evas_Image_Property property; 152 Evas_Image_Property property;
153 const char *file;
153 154
154 if (!ie->f) ie->f = eina_file_open(ie->file, EINA_FALSE); 155 if (!ie->f)
156 {
157 ie->f = eina_file_open(ie->file, EINA_FALSE);
158 file = ie->file;
159 }
160 else
161 {
162 file = eina_file_filename_get(ie->f);
163 }
155 if (!ie->f) 164 if (!ie->f)
156 { 165 {
157 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; 166 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
@@ -173,7 +182,7 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error)
173 (*error == EVAS_LOAD_ERROR_NONE)) 182 (*error == EVAS_LOAD_ERROR_NONE))
174 { 183 {
175 DBG("loaded file head using module '%s' (%p): %s", 184 DBG("loaded file head using module '%s' (%p): %s",
176 em->definition->name, em, ie->file); 185 em->definition->name, em, file);
177 186
178 ie->w = property.w; 187 ie->w = property.w;
179 ie->h = property.h; 188 ie->h = property.h;
@@ -189,7 +198,7 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error)
189 evas_module_unload(em); 198 evas_module_unload(em);
190 INF("failed to load file head using module '%s' (%p): " 199 INF("failed to load file head using module '%s' (%p): "
191 "%s (%s)", 200 "%s (%s)",
192 em->definition->name, em, ie->file, evas_load_error_str(*error)); 201 em->definition->name, em, file, evas_load_error_str(*error));
193 } 202 }
194 } 203 }
195 else 204 else
@@ -221,8 +230,8 @@ EAPI int
221evas_common_load_rgba_image_module_from_file(Image_Entry *ie) 230evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
222{ 231{
223 const char *loader = NULL, *end; 232 const char *loader = NULL, *end;
233 const char *file;
224 Evas_Module *em; 234 Evas_Module *em;
225 struct stat st;
226 unsigned int i; 235 unsigned int i;
227 int len, ret = EVAS_LOAD_ERROR_NONE; 236 int len, ret = EVAS_LOAD_ERROR_NONE;
228 struct evas_image_foreach_loader_data fdata; 237 struct evas_image_foreach_loader_data fdata;
@@ -240,14 +249,27 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
240 // } 249 // }
241 } 250 }
242#endif 251#endif
243 if (stat(ie->file, &st) != 0 || S_ISDIR(st.st_mode)) 252 if (ie->f)
244 { 253 {
245 DBG("trying to open directory '%s' !", ie->file); 254 len = strlen(eina_file_filename_get(ie->f));
246 return EVAS_LOAD_ERROR_DOES_NOT_EXIST; 255 end = eina_file_filename_get(ie->f) + len;
256 file = eina_file_filename_get(ie->f);
257 }
258 else
259 {
260 struct stat st;
261
262 if (stat(ie->file, &st) != 0 || S_ISDIR(st.st_mode))
263 {
264 DBG("trying to open directory '%s' !", ie->file);
265 return EVAS_LOAD_ERROR_DOES_NOT_EXIST;
266 }
267
268 len = strlen(ie->file);
269 end = ie->file + len;
270 file = ie->file;
247 } 271 }
248 272
249 len = strlen(ie->file);
250 end = ie->file + len;
251 for (i = 0; i < (sizeof (loaders) / sizeof(struct ext_loader_s)); i++) 273 for (i = 0; i < (sizeof (loaders) / sizeof(struct ext_loader_s)); i++)
252 { 274 {
253 int len2 = strlen(loaders[i].extension); 275 int len2 = strlen(loaders[i].extension);
@@ -256,7 +278,7 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
256 { 278 {
257 loader = loaders[i].loader; 279 loader = loaders[i].loader;
258 DBG("known loader '%s' handles extension '%s' of file '%s'", 280 DBG("known loader '%s' handles extension '%s' of file '%s'",
259 loader, end - len2, ie->file); 281 loader, end - len2, file);
260 break; 282 break;
261 } 283 }
262 } 284 }
@@ -296,10 +318,10 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
296 DBG("could not find module '%s'", loaders_name[i]); 318 DBG("could not find module '%s'", loaders_name[i]);
297 } 319 }
298 320
299 INF("exhausted all means to load image '%s'", ie->file); 321 INF("exhausted all means to load image '%s'", file);
300 return EVAS_LOAD_ERROR_UNKNOWN_FORMAT; 322 return EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
301 323
302 end: 324 end:
303 325
304 if (ret != EVAS_LOAD_ERROR_NONE) 326 if (ret != EVAS_LOAD_ERROR_NONE)
305 { 327 {
@@ -313,7 +335,7 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
313 WRN("loader '%s' (version %d) " 335 WRN("loader '%s' (version %d) "
314 "handled file '%s', key '%s' with errors: %s", 336 "handled file '%s', key '%s' with errors: %s",
315 modname ? modname : "<UNKNOWN>", modversion, 337 modname ? modname : "<UNKNOWN>", modversion,
316 ie->file, ie->key ? ie->key : "", 338 file, ie->key ? ie->key : "",
317 evas_load_error_str(ret)); 339 evas_load_error_str(ret));
318 goto end; 340 goto end;
319 } 341 }
@@ -321,7 +343,7 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
321 DBG("loader '%s' used for file %s", 343 DBG("loader '%s' used for file %s",
322 (em && em->definition && em->definition->name) ? 344 (em && em->definition && em->definition->name) ?
323 em->definition->name : "<UNKNOWN>", 345 em->definition->name : "<UNKNOWN>",
324 ie->file); 346 file);
325 347
326 ie->info.module = (void*) em; 348 ie->info.module = (void*) em;
327 ie->info.loader = (void*) em ? em->functions : NULL; 349 ie->info.loader = (void*) em ? em->functions : NULL;
diff --git a/src/lib/evas/common/evas_image_main.c b/src/lib/evas/common/evas_image_main.c
index 8a7e21fd59..3d9972a64e 100644
--- a/src/lib/evas/common/evas_image_main.c
+++ b/src/lib/evas/common/evas_image_main.c
@@ -187,6 +187,15 @@ _evas_common_rgba_image_delete(Image_Entry *ie)
187#ifdef BUILD_PIPE_RENDER 187#ifdef BUILD_PIPE_RENDER
188 evas_common_pipe_free(im); 188 evas_common_pipe_free(im);
189#endif 189#endif
190 if (ie->loader_data)
191 {
192 Evas_Image_Load_Func *evas_image_load_func = NULL;
193
194 evas_image_load_func = ie->info.loader;
195 if (evas_image_load_func)
196 evas_image_load_func->file_close(ie->loader_data);
197 ie->loader_data = NULL;
198 }
190 evas_common_rgba_image_scalecache_shutdown(&im->cache_entry); 199 evas_common_rgba_image_scalecache_shutdown(&im->cache_entry);
191 if (ie->info.module) evas_module_unref((Evas_Module *)ie->info.module); 200 if (ie->info.module) evas_module_unref((Evas_Module *)ie->info.module);
192 /* memset the image to 0x99 because i recently saw a segv where an 201 /* memset the image to 0x99 because i recently saw a segv where an
@@ -217,15 +226,7 @@ _evas_common_rgba_image_delete(Image_Entry *ie)
217 } 226 }
218 } 227 }
219 } 228 }
220 if (ie->loader_data) 229 if (ie->f && !ie->flags.given_mmap) eina_file_close(ie->f);
221 {
222 Evas_Image_Load_Func *evas_image_load_func = NULL;
223
224 evas_image_load_func = ie->info.loader;
225 if (evas_image_load_func)
226 evas_image_load_func->file_close(ie->loader_data);
227 }
228 if (ie->f) eina_file_close(ie->f);
229 free(im); 230 free(im);
230} 231}
231 232
@@ -269,7 +270,7 @@ evas_common_rgba_image_unload(Image_Entry *ie)
269 270
270 if (!ie->flags.loaded) return; 271 if (!ie->flags.loaded) return;
271 if ((!ie->info.module) && (!ie->data1)) return; 272 if ((!ie->info.module) && (!ie->data1)) return;
272 if (!ie->file) return; 273 if (!ie->file && !ie->f) return;
273 if (ie->references > 0) return; 274 if (ie->references > 0) return;
274 275
275 ie->flags.loaded = 0; 276 ie->flags.loaded = 0;
@@ -765,6 +766,17 @@ evas_common_load_image_from_file(const char *file, const char *key, Evas_Image_L
765 return (RGBA_Image *) evas_cache_image_request(eci, file, key, lo, error); 766 return (RGBA_Image *) evas_cache_image_request(eci, file, key, lo, error);
766} 767}
767 768
769EAPI RGBA_Image *
770evas_common_load_image_from_mmap(Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error)
771{
772 if (!f)
773 {
774 *error = EVAS_LOAD_ERROR_GENERIC;
775 return NULL;
776 }
777 return (RGBA_Image *) evas_cache_image_mmap_request(eci, f, key, lo, error);
778}
779
768EAPI void 780EAPI void
769evas_common_image_cache_free(void) 781evas_common_image_cache_free(void)
770{ 782{
diff --git a/src/lib/evas/include/evas_common.h b/src/lib/evas/include/evas_common.h
index 03a2777d58..4d930dddc9 100644
--- a/src/lib/evas/include/evas_common.h
+++ b/src/lib/evas/include/evas_common.h
@@ -513,6 +513,7 @@ struct _Image_Entry_Flags
513 Eina_Bool pending : 1; 513 Eina_Bool pending : 1;
514 Eina_Bool rotated : 1; 514 Eina_Bool rotated : 1;
515 Eina_Bool unload_cancel : 1; 515 Eina_Bool unload_cancel : 1;
516 Eina_Bool given_mmap : 1;
516}; 517};
517 518
518struct _Image_Entry_Frame 519struct _Image_Entry_Frame
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 82a0211833..01a556e335 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -795,6 +795,7 @@ struct _Evas_Func
795 void (*polygon_draw) (void *data, void *context, void *surface, void *polygon, int x, int y, Eina_Bool do_async); 795 void (*polygon_draw) (void *data, void *context, void *surface, void *polygon, int x, int y, Eina_Bool do_async);
796 796
797 void *(*image_load) (void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo); 797 void *(*image_load) (void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo);
798 void *(*image_mmap) (void *data, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo);
798 void *(*image_new_from_data) (void *data, int w, int h, DATA32 *image_data, int alpha, int cspace); 799 void *(*image_new_from_data) (void *data, int w, int h, DATA32 *image_data, int alpha, int cspace);
799 void *(*image_new_from_copied_data) (void *data, int w, int h, DATA32 *image_data, int alpha, int cspace); 800 void *(*image_new_from_copied_data) (void *data, int w, int h, DATA32 *image_data, int alpha, int cspace);
800 void (*image_free) (void *data, void *image); 801 void (*image_free) (void *data, void *image);
diff --git a/src/modules/evas/engines/gl_cocoa/evas_engine.c b/src/modules/evas/engines/gl_cocoa/evas_engine.c
index 36148889b7..b5fc778442 100644
--- a/src/modules/evas/engines/gl_cocoa/evas_engine.c
+++ b/src/modules/evas/engines/gl_cocoa/evas_engine.c
@@ -585,6 +585,17 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I
585} 585}
586 586
587static void * 587static void *
588eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo)
589{
590 Render_Engine *re;
591
592 re = (Render_Engine *)data;
593 *error = EVAS_LOAD_ERROR_NONE;
594 eng_window_use(re->win);
595 return evas_gl_common_image_mmap(re->win->gl_context, f, key, lo, error);
596}
597
598static void *
588eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) 599eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
589{ 600{
590 Render_Engine *re; 601 Render_Engine *re;
@@ -1372,6 +1383,7 @@ module_open(Evas_Module *em)
1372 ORD(polygon_draw); 1383 ORD(polygon_draw);
1373 1384
1374 ORD(image_load); 1385 ORD(image_load);
1386 ORD(image_mmap);
1375 ORD(image_new_from_data); 1387 ORD(image_new_from_data);
1376 ORD(image_new_from_copied_data); 1388 ORD(image_new_from_copied_data);
1377 ORD(image_free); 1389 ORD(image_free);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h
index e7603203de..452ab2848d 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -655,6 +655,7 @@ void evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc);
655void evas_gl_common_image_ref(Evas_GL_Image *im); 655void evas_gl_common_image_ref(Evas_GL_Image *im);
656void evas_gl_common_image_unref(Evas_GL_Image *im); 656void evas_gl_common_image_unref(Evas_GL_Image *im);
657Evas_GL_Image *evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error); 657Evas_GL_Image *evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error);
658Evas_GL_Image *evas_gl_common_image_mmap(Evas_Engine_GL_Context *gc, Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error);
658Evas_GL_Image *evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace); 659Evas_GL_Image *evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace);
659Evas_GL_Image *evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace); 660Evas_GL_Image *evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace);
660Evas_GL_Image *evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, int cspace); 661Evas_GL_Image *evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, int cspace);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c
index b605b7534c..a8036ad874 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_image.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_image.c
@@ -96,15 +96,11 @@ evas_gl_common_image_unref(Evas_GL_Image *im)
96 } 96 }
97} 97}
98 98
99Evas_GL_Image * 99static Evas_GL_Image *
100evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error) 100_evas_gl_common_image(Evas_Engine_GL_Context *gc, RGBA_Image *im_im, Evas_Image_Load_Opts *lo, int *error)
101{ 101{
102 Evas_GL_Image *im; 102 Evas_GL_Image *im;
103 RGBA_Image *im_im; 103 Eina_List *l;
104 Eina_List *l;
105
106 im_im = evas_common_load_image_from_file(file, key, lo, error);
107 if (!im_im) return NULL;
108 104
109 /* i'd LOVe to do this, but we can't because we load to load header 105 /* i'd LOVe to do this, but we can't because we load to load header
110 * to get image size to know if its too big or not! so this disallows 106 * to get image size to know if its too big or not! so this disallows
@@ -151,7 +147,29 @@ evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const ch
151 im->h = im->im->cache_entry.h; 147 im->h = im->im->cache_entry.h;
152 if (lo) im->load_opts = *lo; 148 if (lo) im->load_opts = *lo;
153 gc->shared->images = eina_list_prepend(gc->shared->images, im); 149 gc->shared->images = eina_list_prepend(gc->shared->images, im);
154 return im; 150 return im;
151}
152
153Evas_GL_Image *
154evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error)
155{
156 RGBA_Image *im_im;
157
158 im_im = evas_common_load_image_from_file(file, key, lo, error);
159 if (!im_im) return NULL;
160
161 return _evas_gl_common_image(gc, im_im, lo, error);
162}
163
164Evas_GL_Image *
165evas_gl_common_image_mmap(Evas_Engine_GL_Context *gc, Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error)
166{
167 RGBA_Image *im_im;
168
169 im_im = evas_common_load_image_from_mmap(f, key, lo, error);
170 if (!im_im) return NULL;
171
172 return _evas_gl_common_image(gc, im_im, lo, error);
155} 173}
156 174
157Evas_GL_Image * 175Evas_GL_Image *
diff --git a/src/modules/evas/engines/gl_sdl/evas_engine.c b/src/modules/evas/engines/gl_sdl/evas_engine.c
index 18813ee35b..f0553063de 100644
--- a/src/modules/evas/engines/gl_sdl/evas_engine.c
+++ b/src/modules/evas/engines/gl_sdl/evas_engine.c
@@ -486,6 +486,15 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I
486} 486}
487 487
488static void * 488static void *
489eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo)
490{
491 Render_Engine *re = data;
492
493 *error = EVAS_LOAD_ERROR_NONE;
494 return evas_gl_common_image_mmap(re->gl_context, f, key, lo, error);
495}
496
497static void *
489eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) 498eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
490{ 499{
491 Render_Engine *re = data; 500 Render_Engine *re = data;
@@ -916,6 +925,7 @@ module_open(Evas_Module *em)
916 ORD(polygon_draw); 925 ORD(polygon_draw);
917 926
918 ORD(image_load); 927 ORD(image_load);
928 ORD(image_mmap);
919 ORD(image_new_from_data); 929 ORD(image_new_from_data);
920 ORD(image_new_from_copied_data); 930 ORD(image_new_from_copied_data);
921 ORD(image_free); 931 ORD(image_free);
diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c
index 21f73151d8..8f374e4e71 100644
--- a/src/modules/evas/engines/gl_x11/evas_engine.c
+++ b/src/modules/evas/engines/gl_x11/evas_engine.c
@@ -2438,6 +2438,17 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I
2438} 2438}
2439 2439
2440static void * 2440static void *
2441eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo)
2442{
2443 Render_Engine *re;
2444
2445 re = (Render_Engine *)data;
2446 *error = EVAS_LOAD_ERROR_NONE;
2447 eng_window_use(re->win);
2448 return evas_gl_common_image_mmap(re->win->gl_context, f, key, lo, error);
2449}
2450
2451static void *
2441eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) 2452eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
2442{ 2453{
2443 Render_Engine *re; 2454 Render_Engine *re;
@@ -3335,6 +3346,7 @@ module_open(Evas_Module *em)
3335 ORD(polygon_draw); 3346 ORD(polygon_draw);
3336 3347
3337 ORD(image_load); 3348 ORD(image_load);
3349 ORD(image_mmap);
3338 ORD(image_new_from_data); 3350 ORD(image_new_from_data);
3339 ORD(image_new_from_copied_data); 3351 ORD(image_new_from_copied_data);
3340 ORD(image_free); 3352 ORD(image_free);
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c
index 45aae29d8b..3e36dd0dee 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -958,6 +958,26 @@ eng_image_load(void *data EINA_UNUSED, const char *file, const char *key, int *e
958} 958}
959 959
960static void * 960static void *
961eng_image_mmap(void *data EINA_UNUSED, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo)
962{
963 *error = EVAS_LOAD_ERROR_NONE;
964#ifdef EVAS_CSERVE2
965 // FIXME: Need to pass fd to make that useful, so just get the filename for now.
966 if (evas_cserve2_use_get())
967 {
968 Image_Entry *ie;
969 ie = evas_cache2_image_open(evas_common_image_cache2_get(),
970 eina_file_filename_get(f), key, lo, error);
971 if (ie)
972 evas_cache2_image_open_wait(ie);
973
974 return ie;
975 }
976#endif
977 return evas_common_load_image_from_mmap(f, key, lo, error);
978}
979
980static void *
961eng_image_new_from_data(void *data EINA_UNUSED, int w, int h, DATA32 *image_data, int alpha, int cspace) 981eng_image_new_from_data(void *data EINA_UNUSED, int w, int h, DATA32 *image_data, int alpha, int cspace)
962{ 982{
963#ifdef EVAS_CSERVE2 983#ifdef EVAS_CSERVE2
@@ -2568,6 +2588,7 @@ static Evas_Func func =
2568 eng_polygon_draw, 2588 eng_polygon_draw,
2569 /* image draw funcs */ 2589 /* image draw funcs */
2570 eng_image_load, 2590 eng_image_load,
2591 eng_image_mmap,
2571 eng_image_new_from_data, 2592 eng_image_new_from_data,
2572 eng_image_new_from_copied_data, 2593 eng_image_new_from_copied_data,
2573 eng_image_free, 2594 eng_image_free,