evas/cserve2: Set image->flags.loaded on loaded_handle.
[profile/ivi/evas.git] / src / lib / cache2 / evas_cache2.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <stdlib.h>
6 #include <assert.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <errno.h>
10
11 #ifdef HAVE_EVIL
12 # include <Evil.h>
13 #endif
14
15 #include "evas_common.h"
16 #include "evas_private.h"
17 #include "evas_cache2.h"
18 #include "evas_cs2.h"
19 #include "evas_cs2_private.h"
20
21 #define FREESTRC(Var)             \
22    if (Var)                       \
23 {                              \
24    eina_stringshare_del(Var);  \
25    Var = NULL;                 \
26 }
27
28 static void _evas_cache_image_dirty_add(Image_Entry *im);
29 static void _evas_cache_image_dirty_del(Image_Entry *im);
30 static void _evas_cache_image_activ_add(Image_Entry *im);
31 static void _evas_cache_image_activ_del(Image_Entry *im);
32 static void _evas_cache_image_lru_add(Image_Entry *im);
33 static void _evas_cache_image_lru_del(Image_Entry *im);
34 static void _evas_cache2_image_entry_preload_remove(Image_Entry *ie, const void *target);
35 // static void _evas_cache_image_lru_nodata_add(Image_Entry *im);
36 // static void _evas_cache_image_lru_nodata_del(Image_Entry *im);
37
38 static void
39 _evas_cache_image_dirty_add(Image_Entry *im)
40 {
41    if (im->flags.dirty) return;
42    _evas_cache_image_activ_del(im);
43    _evas_cache_image_lru_del(im);
44    // _evas_cache_image_lru_nodata_del(im);
45    im->flags.dirty = 1;
46    im->flags.cached = 1;
47    im->cache2->dirty = eina_inlist_prepend(im->cache2->dirty, EINA_INLIST_GET(im));
48    if (im->cache_key)
49      {
50         eina_stringshare_del(im->cache_key);
51         im->cache_key = NULL;
52      }
53 }
54
55 static void
56 _evas_cache_image_dirty_del(Image_Entry *im)
57 {
58    if (!im->flags.dirty) return;
59    if (!im->cache2) return;
60    im->flags.dirty = 0;
61    im->flags.cached = 0;
62    im->cache2->dirty = eina_inlist_remove(im->cache2->dirty, EINA_INLIST_GET(im));
63 }
64
65 static void
66 _evas_cache_image_activ_add(Image_Entry *im)
67 {
68    if (im->flags.activ) return;
69    _evas_cache_image_dirty_del(im);
70    _evas_cache_image_lru_del(im);
71    // _evas_cache_image_lru_nodata_del(im);
72    if (!im->cache_key) return;
73    im->flags.activ = 1;
74    im->flags.cached = 1;
75    eina_hash_direct_add(im->cache2->activ, im->cache_key, im);
76 }
77
78 static void
79 _evas_cache_image_activ_del(Image_Entry *im)
80 {
81    if (!im->flags.activ) return;
82    if (!im->cache_key) return;
83    im->flags.activ = 0;
84    im->flags.cached = 0;
85    eina_hash_del(im->cache2->activ, im->cache_key, im);
86 }
87
88 static void
89 _evas_cache_image_lru_add(Image_Entry *im)
90 {
91    if (im->flags.lru) return;
92    _evas_cache_image_dirty_del(im);
93    _evas_cache_image_activ_del(im);
94    // _evas_cache_image_lru_nodata_del(im); 
95    if (!im->cache_key) return;
96    im->flags.lru = 1;
97    im->flags.cached = 1;
98    eina_hash_direct_add(im->cache2->inactiv, im->cache_key, im);
99    im->cache2->lru = eina_inlist_prepend(im->cache2->lru, EINA_INLIST_GET(im));
100    im->cache2->usage += im->cache2->func.mem_size_get(im);
101 }
102
103 static void
104 _evas_cache_image_lru_del(Image_Entry *im)
105 {
106    if (!im->flags.lru) return;
107    if (!im->cache_key) return;
108    im->flags.lru = 0;
109    im->flags.cached = 0;
110    eina_hash_del(im->cache2->inactiv, im->cache_key, im);
111    im->cache2->lru = eina_inlist_remove(im->cache2->lru, EINA_INLIST_GET(im));
112    im->cache2->usage -= im->cache2->func.mem_size_get(im);
113 }
114
115 /*
116 static void
117 _evas_cache_image_lru_nodata_add(Image_Entry *im)
118 {
119    if (im->flags.lru_nodata) return;
120    _evas_cache_image_dirty_del(im);
121    _evas_cache_image_activ_del(im);
122    _evas_cache_image_lru_del(im);
123    im->flags.lru = 1;
124    im->flags.cached = 1;
125    im->cache2->lru_nodata = eina_inlist_prepend(im->cache2->lru_nodata, EINA_INLIST_GET(im));
126 }
127
128 static void
129 _evas_cache_image_lru_nodata_del(Image_Entry *im)
130 {
131    if (!im->flags.lru_nodata) return;
132    im->flags.lru = 0;
133    im->flags.cached = 0;
134    im->cache2->lru_nodata = eina_inlist_remove(im->cache2->lru_nodata, EINA_INLIST_GET(im));
135 }
136 */
137
138 static Eina_Bool
139 _timestamp_compare(Image_Timestamp *tstamp, struct stat *st)
140 {
141    if (tstamp->mtime != st->st_mtime) return EINA_FALSE;
142    if (tstamp->size != st->st_size) return EINA_FALSE;
143    if (tstamp->ino != st->st_ino) return EINA_FALSE;
144 #ifdef _STAT_VER_LINUX
145 #if (defined __USE_MISC && defined st_mtime)
146    if (tstamp->mtime_nsec != (unsigned long int)st->st_mtim.tv_nsec)
147      return EINA_FALSE;
148 #else
149    if (tstamp->mtime_nsec != (unsigned long int)st->st_mtimensec)
150      return EINA_FALSE;
151 #endif
152 #endif
153    return EINA_TRUE;
154 }
155
156 static void
157 _timestamp_build(Image_Timestamp *tstamp, struct stat *st)
158 {
159    tstamp->mtime = st->st_mtime;
160    tstamp->size = st->st_size;
161    tstamp->ino = st->st_ino;
162 #ifdef _STAT_VER_LINUX
163 #if (defined __USE_MISC && defined st_mtime)
164    tstamp->mtime_nsec = (unsigned long int)st->st_mtim.tv_nsec;
165 #else
166    tstamp->mtime_nsec = (unsigned long int)st->st_mtimensec;
167 #endif
168 #endif
169 }
170
171 static void
172 _evas_cache_image_entry_delete(Evas_Cache2 *cache, Image_Entry *ie)
173 {
174    if (!ie) return;
175
176    if (ie->flags.delete_me == 1)
177      return;
178
179    if (ie->preload_rid)
180      {
181         ie->flags.delete_me = 1;
182         _evas_cache2_image_entry_preload_remove(ie, NULL);
183         return;
184      }
185
186    _evas_cache_image_dirty_del(ie);
187    _evas_cache_image_activ_del(ie);
188    _evas_cache_image_lru_del(ie);
189    // _evas_cache_image_lru_nodata_del(ie);
190
191
192    if (ie->data1)
193      {
194         evas_cserve2_image_unload(ie);
195         evas_cache2_image_unload_data(ie);
196         evas_cserve2_image_free(ie);
197      }
198    else
199      {
200         if (cache)
201           cache->func.surface_delete(ie);
202      }
203
204    FREESTRC(ie->cache_key);
205    FREESTRC(ie->file);
206    FREESTRC(ie->key);
207    ie->cache2 = NULL;
208
209    evas_common_rgba_image_scalecache_shutdown(ie);
210
211    free(ie);
212 }
213
214 static Image_Entry *
215 _evas_cache_image_entry_new(Evas_Cache2 *cache,
216                             const char *hkey,
217                             Image_Timestamp *tstamp,
218                             const char *file,
219                             const char *key,
220                             RGBA_Image_Loadopts *lo,
221                             int *error)
222 {
223    Image_Entry  *ie;
224    RGBA_Image *im;
225
226    // ie = cache->func.alloc();
227    im = calloc(1, sizeof(RGBA_Image));
228    if (!im)
229      {
230         *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
231         return NULL;
232      }
233
234    im->flags = RGBA_IMAGE_NOTHING;
235    im->ref = 1;
236    evas_common_rgba_image_scalecache_init(&im->cache_entry);
237
238    ie = &im->cache_entry;
239
240    ie->cache2 = cache;
241    if (hkey) ie->cache_key = eina_stringshare_add(hkey);
242    ie->flags.need_data = 1;
243    ie->space = EVAS_COLORSPACE_ARGB8888;
244    ie->w = -1;
245    ie->h = -1;
246    ie->scale = 1;
247    if (file) ie->file = eina_stringshare_add(file);
248    if (key) ie->key = eina_stringshare_add(key);
249    if (tstamp) ie->tstamp = *tstamp;
250    else memset(&ie->tstamp, 0, sizeof(Image_Timestamp));
251
252    if (lo) ie->load_opts = *lo;
253    if (ie->file)
254      {
255         if (!evas_cserve2_image_load(ie, ie->file, ie->key, &(ie->load_opts)))
256           {
257              ERR("couldn't load '%s' '%s' with cserve2!",
258                  ie->file, ie->key ? ie->key : "");
259              _evas_cache_image_entry_delete(cache, ie);
260              return NULL;
261           }
262      }
263
264    if (ie->cache_key) _evas_cache_image_activ_add(ie);
265    else _evas_cache_image_dirty_add(ie);
266    return ie;
267 }
268
269 EAPI void
270 evas_cache2_image_surface_alloc(Image_Entry *ie, int w, int h)
271 {
272    Evas_Cache2 *cache = ie->cache2;
273    int wmin = w > 0 ? w : 1;
274    int hmin = h > 0 ? h : 1;
275
276    if (cache->func.surface_alloc(ie, wmin, hmin))
277      {
278         wmin = 0;
279         hmin = 0;
280      }
281
282    ie->w = wmin;
283    ie->h = hmin;
284    ie->allocated.w = wmin;
285    ie->allocated.h = hmin;
286    ie->flags.loaded = EINA_TRUE;
287 }
288
289 static void
290 _evas_cache2_image_preloaded_cb(void *data, Eina_Bool success)
291 {
292    Image_Entry *ie = data;
293    Evas_Cache_Target *tmp;
294
295    ie->cache2->preload = eina_list_remove(ie->cache2->preload, ie);
296    ie->flags.preload_done = success;
297
298    while ((tmp = ie->targets))
299      {
300         ie->targets = (Evas_Cache_Target *)
301            eina_inlist_remove(EINA_INLIST_GET(ie->targets),
302                             EINA_INLIST_GET(ie->targets));
303         if (!ie->flags.delete_me)
304             evas_object_inform_call_image_preloaded((Evas_Object *) tmp->target);
305         free(tmp);
306      }
307
308    if (ie->flags.delete_me)
309      _evas_cache_image_entry_delete(ie->cache2, ie);
310 }
311
312 static Eina_Bool
313 _evas_cache2_image_entry_preload_add(Image_Entry *ie, const void *target)
314 {
315    Evas_Cache_Target *tg;
316
317    if (ie->flags.preload_done)
318      return EINA_FALSE;
319
320    tg = malloc(sizeof(Evas_Cache_Target));
321    if (!tg)
322      return EINA_TRUE;
323
324    tg->target = target;
325    ie->targets = (Evas_Cache_Target *)
326       eina_inlist_append(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
327
328    if (!ie->preload_rid)
329      {
330         ie->cache2->preload = eina_list_append(ie->cache2->preload, ie);
331         evas_cserve2_image_preload(ie, _evas_cache2_image_preloaded_cb);
332      }
333
334    return EINA_TRUE;
335 }
336
337 static void
338 _evas_cache2_image_entry_preload_remove(Image_Entry *ie, const void *target)
339 {
340    if (target)
341      {
342         Evas_Cache_Target *tg;
343
344         EINA_INLIST_FOREACH(ie->targets, tg)
345           {
346              if (tg->target == target)
347                {
348                   ie->targets = (Evas_Cache_Target *)
349                      eina_inlist_remove(EINA_INLIST_GET(ie->targets),
350                                         EINA_INLIST_GET(tg));
351                   free(tg);
352                   break;
353                }
354           }
355      }
356    else
357      {
358         Evas_Cache_Target *tg;
359
360         while (ie->targets)
361           {
362              tg = ie->targets;
363              ie->targets = (Evas_Cache_Target *)
364                 eina_inlist_remove(EINA_INLIST_GET(ie->targets),
365                                    EINA_INLIST_GET(tg));
366              free(tg);
367           }
368      }
369
370    // FIXME: Should also send message to the server to cancel the request.
371 }
372
373 EAPI Image_Entry *
374 evas_cache2_image_copied_data(Evas_Cache2 *cache, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace)
375 {
376    Image_Entry *im;
377
378    if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
379        (cspace == EVAS_COLORSPACE_YCBCR422P709_PL) ||
380        (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
381      w &= ~0x1;
382
383    im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
384    if (!im)
385      return NULL;
386
387    im->space = cspace;
388    im->flags.alpha = alpha;
389    evas_cache2_image_surface_alloc(im, w, h);
390    if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0)
391      {
392         _evas_cache_image_entry_delete(cache, im);
393         return NULL;
394      }
395
396    im->references = 1;
397    im->flags.loaded = EINA_TRUE;
398    if (cache->func.debug) cache->func.debug("copied-data", im);
399
400    return im;
401 }
402
403 EAPI Image_Entry *
404 evas_cache2_image_data(Evas_Cache2 *cache, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace)
405 {
406    Image_Entry *im;
407
408    if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
409        (cspace == EVAS_COLORSPACE_YCBCR422P709_PL) ||
410        (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
411      w &= ~0x1;
412
413    im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
414    if (!im) return NULL;
415    im->w = w;
416    im->h = h;
417    im->flags.alpha = alpha;
418    im->flags.loaded = 1;
419    if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0)
420      {
421         _evas_cache_image_entry_delete(cache, im);
422         return NULL;
423      }
424    im->references = 1;
425    if (cache->func.debug) cache->func.debug("data", im);
426    return im;
427 }
428
429 EAPI Image_Entry *
430 evas_cache2_image_empty(Evas_Cache2 *cache)
431 {
432    Image_Entry *im;
433
434    im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
435    if (!im)
436      return NULL;
437
438    im->references = 1;
439    return im;
440 }
441
442 EAPI Image_Entry *
443 evas_cache2_image_size_set(Image_Entry *im, unsigned int w, unsigned h)
444 {
445    Evas_Cache2 *cache;
446    Image_Entry *im2 = NULL;
447    int error;
448
449    if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
450        (im->space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
451        (im->space == EVAS_COLORSPACE_YCBCR422601_PL))
452      w &= ~0x1;
453
454    if ((im->w == w) && (im->h == h)) return im;
455
456    cache = im->cache2;
457    im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL,
458                                      NULL);
459    if (!im2) goto on_error;
460
461    im2->flags.alpha = im->flags.alpha;
462    im2->space = im->space;
463    im2->load_opts = im->load_opts;
464    evas_cache2_image_surface_alloc(im2, w, h);
465    error = cache->func.size_set(im2, im, w, h);
466    if (error != 0) goto on_error;
467
468    im2->references = 1;
469
470    evas_cache2_image_close(im);
471    return im2;
472
473 on_error:
474    if (im2)
475      _evas_cache_image_entry_delete(cache, im2);
476    return NULL;
477 }
478
479 EAPI Evas_Cache2 *
480 evas_cache2_init(const Evas_Cache2_Image_Func *cb)
481 {
482    Evas_Cache2 *cache = calloc(1, sizeof(Evas_Cache2));
483
484    cache->func = *cb;
485    cache->activ = eina_hash_string_superfast_new(NULL);
486    cache->inactiv = eina_hash_string_superfast_new(NULL);
487
488    return cache;
489 }
490
491 static Eina_Bool
492 _evas_cache_image_free_cb(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, void *fdata)
493 {
494    Eina_List **delete_list = fdata;
495    *delete_list = eina_list_prepend(*delete_list, data);
496    return EINA_TRUE;
497 }
498
499 EAPI void
500 evas_cache2_shutdown(Evas_Cache2 *cache)
501 {
502    Eina_List *delete_list;
503    Image_Entry *im;
504
505    while (cache->lru)
506      {
507         im = (Image_Entry *)cache->lru;
508         _evas_cache_image_entry_delete(cache, im);
509      }
510    /* This is mad, I am about to destroy image still alive, but we need to prevent leak. */
511    while (cache->dirty)
512      {
513         im = (Image_Entry *)cache->dirty;
514         _evas_cache_image_entry_delete(cache, im);
515      }
516
517    delete_list = NULL;
518    eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list);
519    while (delete_list)
520      {
521         _evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list));
522         delete_list = eina_list_remove_list(delete_list, delete_list);
523      }
524
525    eina_hash_free(cache->activ);
526    eina_hash_free(cache->inactiv);
527
528    free(cache);
529 }
530
531 static void
532 _create_hash_key(char *hkey, const char *path, size_t pathlen, const char *key, size_t keylen, RGBA_Image_Loadopts *lo)
533 {
534    const char *ckey = "(null)";
535    size_t size;
536
537    /* generate hkey from file+key+load opts */
538    memcpy(hkey, path, pathlen);
539    size = pathlen;
540    memcpy(hkey + size, "//://", 5);
541    size += 5;
542    if (key) ckey = key;
543    memcpy(hkey + size, ckey, keylen);
544    size += keylen;
545    if (lo)
546      {
547         memcpy(hkey + size, "//@/", 4);
548         size += 4;
549         size += eina_convert_xtoa(lo->scale_down_by, hkey + size);
550         hkey[size] = '/';
551         size += 1;
552         size += eina_convert_dtoa(lo->dpi, hkey + size);
553         hkey[size] = '/';
554         size += 1;
555         size += eina_convert_xtoa(lo->w, hkey + size);
556         hkey[size] = 'x';
557         size += 1;
558         size += eina_convert_xtoa(lo->h, hkey + size);
559         hkey[size] = '/';
560         size += 1;
561         size += eina_convert_xtoa(lo->region.x, hkey + size);
562         hkey[size] = '+';
563         size += 1;
564         size += eina_convert_xtoa(lo->region.y, hkey + size);
565         hkey[size] = '.';
566         size += 1;
567         size += eina_convert_xtoa(lo->region.w, hkey + size);
568         hkey[size] = 'x';
569         size += 1;
570         size += eina_convert_xtoa(lo->region.h, hkey + size);
571
572         if (lo->orientation)
573           {
574              hkey[size] = '/';
575              size += 1;
576              hkey[size] = 'o';
577              size += 1;
578           }
579      }
580    hkey[size] = '\0';
581 }
582
583 EAPI Image_Entry *
584 evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, RGBA_Image_Loadopts *lo, int *error)
585 {
586    size_t                size;
587    size_t                pathlen;
588    size_t                keylen;
589    char                 *hkey;
590    Image_Entry          *im;
591    int                   stat_done = 0, stat_failed = 0;
592    struct stat           st;
593    Image_Timestamp       tstamp;
594    Evas_Image_Load_Opts  prevent = { 0, 0.0, 0, 0, 0, { 0, 0, 0, 0 }, EINA_FALSE };
595
596    if ((!path) || ((!path) && (!key)))
597      {
598         *error = EVAS_LOAD_ERROR_GENERIC;
599         return NULL;
600      }
601
602    pathlen = strlen(path);
603    keylen = key ? strlen(key) : 6;
604    size = pathlen + keylen + 132;
605    hkey = alloca(sizeof(char) * size);
606
607    _create_hash_key(hkey, path, pathlen, key, keylen, lo);
608    DBG("Looking at the hash for key '%s'", hkey);
609
610    /* use local var to copy default load options to the image entry */
611    if ((!lo) ||
612        (lo &&
613         (lo->scale_down_by == 0) &&
614         (lo->dpi == 0.0) &&
615         ((lo->w == 0) || (lo->h == 0)) &&
616         ((lo->region.w == 0) || (lo->region.h == 0)) &&
617         (lo->orientation == 0)
618        ))
619      {
620         lo = &prevent;
621      }
622
623    im = eina_hash_find(cache->activ, hkey);
624
625    if (im)
626      {
627         int ok = 1;
628         DBG("Found entry on active hash for key: '%s'", hkey);
629
630         stat_done = 1;
631         if (stat(path, &st) < 0)
632           {
633              stat_failed = 1;
634              ok = 0;
635           }
636         else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
637         if (ok) goto on_ok;
638         /* image we found doesn't match what's on disk (stat info wise)
639          * so dirty the active cache entry so we never find it again. this
640          * also implicitly guarantees that we only have 1 active copy
641          * of an image at a given key. we wither find it and keep re-reffing
642          * it or we dirty it and get it out */
643         DBG("Entry on inactive hash was invalid (file changed or deleted).");
644         _evas_cache_image_dirty_add(im);
645         im = NULL;
646      }
647
648    im = eina_hash_find(cache->inactiv, hkey);
649
650    if (im)
651      {
652         int ok = 1;
653         DBG("Found entry on inactive hash for key: '%s'", hkey);
654
655         if (!stat_done)
656           {
657              stat_done = 1;
658              if (stat(path, &st) < 0)
659                {
660                   stat_failed = 1;
661                   ok = 0;
662                }
663              else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
664           }
665         else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
666
667         if (ok)
668           {
669              /* remove from lru and make it active again */
670              _evas_cache_image_lru_del(im);
671              _evas_cache_image_activ_add(im);
672              goto on_ok;
673           }
674         DBG("Entry on inactive hash was invalid (file changed or deleted).");
675         /* as avtive cache find - if we match in lru and its invalid, dirty */
676         _evas_cache_image_dirty_add(im);
677         /* this image never used, so it have to be deleted */
678         _evas_cache_image_entry_delete(cache, im);
679         im = NULL;
680      }
681    if (stat_failed) goto on_stat_error;
682
683    if (!stat_done)
684      {
685         if (stat(path, &st) < 0) goto on_stat_error;
686      }
687    _timestamp_build(&tstamp, &st);
688    DBG("Creating a new entry for key '%s'.", hkey);
689    im = _evas_cache_image_entry_new(cache, hkey, &tstamp, path, key,
690                                     lo, error);
691    if (!im) goto on_stat_error;
692
693 on_ok:
694    *error = EVAS_LOAD_ERROR_NONE;
695    DBG("Using entry on hash for key '%s'", hkey);
696
697    im->references++;
698
699    return im;
700
701 on_stat_error:
702 #ifndef _WIN32
703    if ((errno == ENOENT) || (errno == ENOTDIR) ||
704        (errno == ENAMETOOLONG) || (errno == ELOOP))
705 #else
706      if (errno == ENOENT)
707 #endif
708        *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
709 #ifndef _WIN32
710      else if ((errno == ENOMEM) || (errno == EOVERFLOW))
711 #else
712      else if (errno == ENOMEM)
713 #endif
714        *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
715      else if (errno == EACCES)
716        *error = EVAS_LOAD_ERROR_PERMISSION_DENIED;
717      else
718        *error = EVAS_LOAD_ERROR_GENERIC;
719
720    if (im) _evas_cache_image_entry_delete(cache, im);
721    return NULL;
722 }
723
724 EAPI int
725 evas_cache2_image_open_wait(Image_Entry *im)
726 {
727    DBG("Wait for open image '%s' '%s'", im->file, im->key);
728    if (evas_cserve2_image_load_wait(im) != CSERVE2_NONE)
729      return EVAS_LOAD_ERROR_GENERIC;
730
731    return EVAS_LOAD_ERROR_NONE;
732 }
733
734 EAPI void
735 evas_cache2_image_close(Image_Entry *im)
736 {
737    Evas_Cache2 *cache;
738    int references;
739
740    im->references--;
741    if (im->references < 0)
742      {
743         ERR("image with negative references: %d", im->references);
744         im->references = 0;
745      }
746
747    references = im->references;
748    cache = im->cache2;
749
750    if (references > 0)
751      return;
752
753    if (im->flags.dirty)
754      {
755         _evas_cache_image_entry_delete(cache, im);
756         return;
757      }
758
759    _evas_cache_image_lru_add(im);
760    if (cache)
761      evas_cache2_flush(cache);
762 }
763
764 EAPI int
765 evas_cache2_image_load_data(Image_Entry *ie)
766 {
767    int error = EVAS_LOAD_ERROR_NONE;
768
769    if ((ie->flags.loaded) && (!ie->flags.animated))
770      return error;
771
772    ie->flags.in_progress = EINA_TRUE;
773
774    DBG("try cserve2 image data '%s' '%s'",
775        ie->file, ie->key ? ie->key : "");
776    if (evas_cserve2_image_data_load(ie))
777      {
778         evas_cserve2_image_load_data_wait(ie);
779         RGBA_Image *im = (RGBA_Image *)ie;
780         DBG("try cserve2 image data '%s' '%s' loaded!",
781             ie->file, ie->key ? ie->key : "");
782         if (im->image.data)
783           {
784              error = EVAS_LOAD_ERROR_NONE;
785           }
786         else
787           {
788              ERR("Failed to load data for image '%s' '%s'.",
789                  ie->file, ie->key ? ie->key : "");
790              error = EVAS_LOAD_ERROR_GENERIC;
791           }
792      }
793    else
794      {
795         ERR("Couldn't send LOAD message to cserve2.");
796         error = EVAS_LOAD_ERROR_GENERIC;
797      }
798
799    ie->flags.in_progress = EINA_FALSE;
800    ie->flags.loaded = 1;
801
802    if (error != EVAS_LOAD_ERROR_NONE)
803      ie->flags.loaded = 0;
804
805    return error;
806 }
807
808 EAPI void
809 evas_cache2_image_unload_data(Image_Entry *im)
810 {
811    // FIXME: This function seems pretty useless, since we always have
812    // to send an UNLOAD message to the server when closing an image,
813    // even if we didn't send a LOAD message before, because the SETOPTS
814    // message increases the image refcount.
815    if (im->flags.in_progress)
816      return;
817
818    if ((!im->file))
819      return;
820
821    if (!im->flags.loaded)
822      return;
823
824 //    if (im->data2)
825    im->flags.loaded = 0;
826 }
827
828 EAPI void
829 evas_cache2_image_preload_data(Image_Entry *im, const void *target)
830 {
831    RGBA_Image *img = (RGBA_Image *)im;
832
833    if ((im->flags.loaded) && (img->image.data))
834      {
835         evas_object_inform_call_image_preloaded((Evas_Object *)target);
836         return;
837      }
838
839    if (!_evas_cache2_image_entry_preload_add(im, target))
840      evas_object_inform_call_image_preloaded((Evas_Object *)target);
841 }
842
843 EAPI void
844 evas_cache2_image_preload_cancel(Image_Entry *im, const void *target)
845 {
846    if (!target)
847      return;
848
849    _evas_cache2_image_entry_preload_remove(im, target);
850 }
851
852 EAPI DATA32 *
853 evas_cache2_image_pixels(Image_Entry *im)
854 {
855    return im->cache2->func.surface_pixels(im);
856 }
857
858 EAPI Image_Entry *
859 evas_cache2_image_writable(Image_Entry *im)
860 {
861    Evas_Cache2 *cache = im->cache2;
862    Image_Entry *im2 = NULL;
863
864    if (!im->cache_key)
865      {
866         if (!im->flags.dirty)
867           _evas_cache_image_dirty_add(im);
868         return im;
869      }
870
871    im2 = evas_cache2_image_copied_data(cache, im->w, im->h,
872                                         evas_cache2_image_pixels(im),
873                                         im->flags.alpha, im->space);
874    if (!im2)
875      goto on_error;
876
877    evas_cache2_image_close(im);
878    return im2;
879
880 on_error:
881    if (im2)
882      _evas_cache_image_entry_delete(cache, im2);
883    return NULL;
884 }
885
886 EAPI Image_Entry *
887 evas_cache2_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
888 {
889    Evas_Cache2 *cache = im->cache2;
890    Image_Entry *im2 = NULL;
891
892    if (!im->cache_key)
893      {
894         if (!im->flags.dirty)
895           _evas_cache_image_dirty_add(im);
896         im2 = im;
897      }
898    else
899      {
900         im2 = evas_cache2_image_copied_data(cache, im->w, im->h,
901                                             evas_cache2_image_pixels(im),
902                                             im->flags.alpha, im->space);
903         if (!im2)
904           goto on_error;
905
906         evas_cache2_image_close(im);
907      }
908
909    if (cache->func.dirty_region)
910      cache->func.dirty_region(im2, x, y, w, h);
911
912    return im2;
913
914 on_error:
915    if (im2)
916      _evas_cache_image_entry_delete(cache, im2);
917    evas_cache2_image_close(im);
918    return NULL;
919 }
920
921 EAPI int
922 evas_cache2_flush(Evas_Cache2 *cache)
923 {
924    if (cache->limit == -1) return -1;
925
926    while ((cache->lru) && (cache->limit < cache->usage))
927      {
928         Image_Entry *im;
929
930         im = (Image_Entry *)cache->lru->last;
931         DBG("Remove unused entry from cache.");
932         _evas_cache_image_entry_delete(cache, im);
933      }
934
935    return cache->usage;
936 }
937
938 EAPI void
939 evas_cache2_limit_set(Evas_Cache2 *cache, int limit)
940 {
941    if (cache->limit == limit)
942      return;
943
944    DBG("Cache2 limit set to %d", limit);
945
946    cache->limit = limit;
947
948    evas_cache2_flush(cache);
949 }
950
951 EAPI int
952 evas_cache2_limit_get(Evas_Cache2 *cache)
953 {
954    return cache->limit;
955 }
956
957 EAPI int
958 evas_cache2_usage_get(Evas_Cache2 *cache)
959 {
960    return cache->usage;
961 }