big patch from Samsung SAIT (Advanced research group) for async multi-frame
[framework/uifw/evas.git] / src / lib / engines / common / evas_image_main.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #ifdef HAVE_CONFIG_H
6 # include "config.h"  /* so that EAPI in Eet.h is correctly defined */
7 #endif
8
9 #ifdef BUILD_LOADER_EET
10 # include <Eet.h>
11 #endif
12
13 #include "evas_common.h"
14 #include "evas_private.h"
15 #include "evas_image_private.h"
16 #include "evas_convert_yuv.h"
17 #include "evas_cs.h"
18
19 #ifdef HAVE_VALGRIND
20 # include <memcheck.h>
21 #endif
22
23 static Evas_Cache_Image * eci = NULL;
24 static int                reference = 0;
25
26 /* static RGBA_Image *evas_rgba_line_buffer = NULL; */
27
28 #define  EVAS_RGBA_LINE_BUFFER_MIN_LEN  256
29 #define  EVAS_RGBA_LINE_BUFFER_MAX_LEN  2048
30
31 /* static RGBA_Image *evas_alpha_line_buffer = NULL; */
32
33 #define  EVAS_ALPHA_LINE_BUFFER_MIN_LEN  256
34 #define  EVAS_ALPHA_LINE_BUFFER_MAX_LEN  2048
35
36
37 static Image_Entry      *_evas_common_rgba_image_new(void);
38 static void              _evas_common_rgba_image_delete(Image_Entry *ie);
39
40 static int               _evas_common_rgba_image_surface_alloc(Image_Entry *ie, int w, int h);
41 static void              _evas_common_rgba_image_surface_delete(Image_Entry *ie);
42 static DATA32           *_evas_common_rgba_image_surface_pixels(Image_Entry *ie);
43
44 static void              _evas_common_rgba_image_unload(Image_Entry *im);
45
46 static void              _evas_common_rgba_image_dirty_region(Image_Entry *im, int x, int y, int w, int h);
47
48 static int               _evas_common_rgba_image_ram_usage(Image_Entry *ie);
49
50 /* Only called when references > 0. Need to provide a fresh copie of im. */
51 /* The destination surface does have a surface, but no allocated pixel data. */
52 static int               _evas_common_rgba_image_dirty(Image_Entry* dst, const Image_Entry* src);
53
54 #if 0
55 static void
56 _evas_common_rgba_image_debug(const char* context, Image_Entry *eim)
57 {
58   DBG("%p = [%s] {%s,%s} %i [%i|%i]", eim, context, eim->file, eim->key, eim->references, eim->w, eim->h);
59 }
60 #endif
61
62 static const Evas_Cache_Image_Func      _evas_common_image_func =
63 {
64   _evas_common_rgba_image_new,
65   _evas_common_rgba_image_delete,
66   _evas_common_rgba_image_surface_alloc,
67   _evas_common_rgba_image_surface_delete,
68   _evas_common_rgba_image_surface_pixels,
69   evas_common_load_rgba_image_module_from_file,
70   _evas_common_rgba_image_unload,
71   _evas_common_rgba_image_dirty_region,
72   _evas_common_rgba_image_dirty,
73   evas_common_rgba_image_size_set,
74   evas_common_rgba_image_from_copied_data,
75   evas_common_rgba_image_from_data,
76   evas_common_rgba_image_colorspace_set,
77   evas_common_load_rgba_image_data_from_file,
78   _evas_common_rgba_image_ram_usage,
79 /*   _evas_common_rgba_image_debug */
80   NULL
81 };
82
83 EAPI void
84 evas_common_image_init(void)
85 {
86    if (!eci)
87      eci = evas_cache_image_init(&_evas_common_image_func);
88    reference++;
89 ////   ERR("REF++=%i", reference);
90
91 #ifdef BUILD_LOADER_EET
92    eet_init();
93 #endif
94    evas_common_scalecache_init();
95 }
96
97 EAPI void
98 evas_common_image_shutdown(void)
99 {
100    if (--reference == 0)
101      {
102 ////    printf("REF--=%i\n", reference);
103 // DISABLE for now - something wrong with cache shutdown freeing things
104 // still in use - rage_thumb segv's now.
105 //
106 // actually - i think i see it. cache ref goes to 0 (and thus gets freed)
107 // because in eng_setup() when a buffer changes size it is FIRST freed
108 // THEN allocated again - thus brignhjing ref to 0 then back to 1 immediately
109 // where it should stay at 1. - see evas_engine.c in the buffer enigne for
110 // example. eng_output_free() is called BEFORE _output_setup(). although this
111 // is only a SIGNE of the problem. we can patch this up with either freeing
112 // after the setup (so we just pt a ref of 2 then back to 1), or just
113 // evas_common_image_init() at the start and evas_common_image_shutdown()
114 // after it all. really ref 0 should only be reached when no more canvases
115 // with no more objects exist anywhere.
116
117 // ENABLE IT AGAIN, hope it is fixed. Gustavo @ January 22nd, 2009.
118        evas_cache_image_shutdown(eci);
119        eci = NULL;
120      }
121
122 #ifdef BUILD_LOADER_EET
123    eet_shutdown();
124 #endif
125    evas_common_scalecache_shutdown();
126 }
127
128 EAPI void
129 evas_common_image_image_all_unload(void)
130 {
131    evas_common_rgba_image_scalecache_flush();
132    evas_cache_image_unload_all(eci);
133 }
134
135 static Image_Entry *
136 _evas_common_rgba_image_new(void)
137 {
138    RGBA_Image *im;
139
140    im = calloc(1, sizeof(RGBA_Image));
141    if (!im) return NULL;
142    im->flags = RGBA_IMAGE_NOTHING;
143    im->ref = 1;
144 #ifdef EVAS_FRAME_QUEUING
145    LKI(im->ref_fq_add);
146    LKI(im->ref_fq_del);
147    pthread_cond_init(&(im->cond_fq_del), NULL);
148 #endif
149
150    evas_common_rgba_image_scalecache_init(&im->cache_entry);
151    return &im->cache_entry;
152 }
153
154 static void
155 _evas_common_rgba_image_delete(Image_Entry *ie)
156 {
157    RGBA_Image   *im = (RGBA_Image *) ie;
158
159 #ifdef BUILD_PIPE_RENDER
160    evas_common_pipe_free(im);
161 # ifdef EVAS_FRAME_QUEUING
162    LKD(im->ref_fq_add);
163    LKD(im->ref_fq_del);
164    pthread_cond_destroy(&(im->cond_fq_del));
165 # endif
166 #endif   
167    evas_common_rgba_image_scalecache_shutdown(&im->cache_entry);
168    if (ie->info.module) evas_module_unref((Evas_Module *)ie->info.module);
169    /* memset the image to 0x99 because i recently saw a segv where an
170     * seemed to be used BUT its contents were wrong - it looks like it was
171     * overwritten by something from efreet - as there was an execute command
172     * for a command there and some other signs - but to make sure, I am
173     * going to empty this struct out in case this happens again so i know
174     * that something else is overwritign this struct - or not */
175 //   memset(im, 0x99, sizeof(im));
176 #ifdef EVAS_CSERVE
177    if (ie->data1) evas_cserve_image_free(ie);
178 #endif   
179    free(im);
180 }
181
182 EAPI void
183 evas_common_rgba_image_free(Image_Entry *ie)
184 {
185    _evas_common_rgba_image_surface_delete(ie);
186    _evas_common_rgba_image_delete(ie);
187 }
188
189 EAPI void
190 evas_common_rgba_image_unload(Image_Entry *ie)
191 {
192    RGBA_Image   *im = (RGBA_Image *) ie;
193
194    evas_cache_image_preload_cancel(ie, NULL);
195
196    if (!ie->flags.loaded) return;
197    if ((!ie->info.module) && (!ie->data1)) return;
198    if (!ie->file) return;
199
200    ie->flags.loaded = 0;
201
202    if ((im->cs.data) && (im->image.data))
203      {
204         if (im->cs.data != im->image.data)
205           {
206              if (!im->cs.no_free) free(im->cs.data);
207           }
208      }
209    else if (im->cs.data)
210      {
211         if (!im->cs.no_free) free(im->cs.data);
212      }
213    im->cs.data = NULL;
214
215 #ifdef EVAS_CSERVE
216    if (ie->data1)
217      {
218         evas_cserve_image_useless(ie);
219         im->image.data = NULL;
220         ie->allocated.w = 0;
221         ie->allocated.h = 0;
222         return;
223      }
224 #endif   
225    
226    if (im->image.data && !im->image.no_free)
227      free(im->image.data);
228    im->image.data = NULL;
229    ie->allocated.w = 0;
230    ie->allocated.h = 0;
231 }
232
233 static int
234 _evas_common_rgba_image_surface_alloc(Image_Entry *ie, int w, int h)
235 {
236    RGBA_Image   *im = (RGBA_Image *) ie;
237    size_t        siz = 0;
238
239 #ifdef EVAS_CSERVE
240    if (ie->data1) return 0;
241 #endif   
242    if (im->image.no_free) return 0;
243
244    if (im->flags & RGBA_IMAGE_ALPHA_ONLY)
245      siz = w * h * sizeof(DATA8);
246    else
247      siz = w * h * sizeof(DATA32);
248
249    if (im->image.data) free(im->image.data);
250    im->image.data = malloc(siz);
251    if (im->image.data == NULL) return -1;
252
253 #ifdef HAVE_VALGRIND
254 # ifdef VALGRIND_MAKE_READABLE
255    VALGRIND_MAKE_READABLE(im->image.data, siz);
256 # else
257 #  ifdef VALGRIND_MAKE_MEM_DEFINED
258    VALGRIND_MAKE_MEM_DEFINED(im->image.data, siz);
259 #  endif
260 # endif
261 #endif
262
263    return 0;
264 }
265
266 static void
267 _evas_common_rgba_image_surface_delete(Image_Entry *ie)
268 {
269    RGBA_Image   *im = (RGBA_Image *) ie;
270
271    if (ie->file)
272      printf("unload: [%p] %s %s\n", ie, ie->file, ie->key);
273    if ((im->cs.data) && (im->image.data))
274      {
275         if (im->cs.data != im->image.data)
276           {
277              if (!im->cs.no_free) free(im->cs.data);
278           }
279      }
280    else if (im->cs.data)
281      {
282         if (!im->cs.no_free) free(im->cs.data);
283      }
284    im->cs.data = NULL;
285
286    if (im->image.data && !im->image.no_free)
287      free(im->image.data);
288 #ifdef EVAS_CSERVE
289    else if (ie->data1)
290      evas_cserve_image_free(ie);
291 #endif   
292    im->image.data = NULL;
293    evas_common_rgba_image_scalecache_dirty(&im->cache_entry);
294 }
295
296 static void
297 _evas_common_rgba_image_unload(Image_Entry *im)
298 {
299 //   printf("unload: [%p] %s %s\n", im, im->file, im->key);
300    evas_common_rgba_image_unload(im);
301 }
302
303 static void
304 _evas_common_rgba_image_dirty_region(Image_Entry* ie, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
305 {
306    RGBA_Image   *im = (RGBA_Image *) ie;
307
308 #ifdef EVAS_CSERVE
309    if (ie->data1) evas_cserve_image_free(ie);
310 #endif   
311    im->flags |= RGBA_IMAGE_IS_DIRTY;
312    evas_common_rgba_image_scalecache_dirty(&im->cache_entry);
313 }
314
315 /* Only called when references > 0. Need to provide a fresh copie of im. */
316 static int
317 _evas_common_rgba_image_dirty(Image_Entry *ie_dst, const Image_Entry *ie_src)
318 {
319    RGBA_Image   *dst = (RGBA_Image *) ie_dst;
320    RGBA_Image   *src = (RGBA_Image *) ie_src;
321
322    evas_common_rgba_image_scalecache_dirty((Image_Entry *)ie_src);
323    evas_common_rgba_image_scalecache_dirty(ie_dst);
324    evas_cache_image_load_data(&src->cache_entry);
325    if (_evas_common_rgba_image_surface_alloc(&dst->cache_entry,
326                                              src->cache_entry.w, src->cache_entry.h))
327      {
328 #ifdef EVAS_CSERVE
329         if (ie_src->data1) evas_cserve_image_free((Image_Entry*) ie_src);
330 #endif        
331         return 1;
332      }
333
334 #ifdef EVAS_CSERVE
335    if (ie_src->data1) evas_cserve_image_free((Image_Entry*) ie_src);
336 #endif   
337    evas_common_image_colorspace_normalize(src);
338    evas_common_image_colorspace_normalize(dst);
339 /*    evas_common_blit_rectangle(src, dst, 0, 0, src->cache_entry.w, src->cache_entry.h, 0, 0); */
340 /*    evas_common_cpu_end_opt(); */
341
342    return 0;
343 }
344
345 static int
346 _evas_common_rgba_image_ram_usage(Image_Entry *ie)
347 {
348    RGBA_Image   *im = (RGBA_Image *) ie;
349    int size = 0;
350
351 //   ram += sizeof(struct _RGBA_Image);
352 //   if (im->info.real_file) ram += strlen(im->info.real_file);
353 //   if (im->info.comment) ram += strlen(im->info.comment);
354    if (im->image.data)
355      {
356 #ifdef EVAS_CSERVE
357         if ((!im->image.no_free) || (ie->data1))
358 #else
359         if ((!im->image.no_free))
360 #endif          
361           size += im->cache_entry.w * im->cache_entry.h * sizeof(DATA32);
362      }
363    size += evas_common_rgba_image_scalecache_usage_get(&im->cache_entry);
364    return size;
365 }
366
367 static DATA32 *
368 _evas_common_rgba_image_surface_pixels(Image_Entry *ie)
369 {
370    RGBA_Image *im = (RGBA_Image *) ie;
371
372    return im->image.data;
373 }
374
375 #if 0
376 void
377 evas_common_image_surface_alpha_tiles_calc(RGBA_Surface *is, int tsize)
378 {
379    int x, y;
380    DATA32 *ptr;
381
382    if (is->spans) return;
383    if (!is->im->cache_entry.flags.alpha) return;
384    /* FIXME: dont handle alpha only images yet */
385    if ((is->im->flags & RGBA_IMAGE_ALPHA_ONLY)) return;
386    if (tsize < 0) tsize = 0;
387    is->spans = calloc(1, sizeof(RGBA_Image_Span *) * is->h);
388    if (!is->spans) return;
389    ptr = is->data;
390    for (y = 0; y < is->h; y++)
391      {
392         RGBA_Image_Span *sp;
393
394         sp = NULL;
395         for (x = 0; x < is->w; x++)
396           {
397              DATA8 a;
398
399              a = A_VAL(ptr);
400              if (sp)
401                {
402                   if (a == 0)
403                     {
404                        is->spans[y] = eina_inlist_append(is->spans[y], sp);
405                        sp = NULL;
406                     }
407                   else
408                     {
409                        sp->w++;
410                        if ((sp->v == 2) && (a != 255)) sp->v = 1;
411                     }
412                }
413              else
414                {
415                   if (a == 255)
416                     {
417                        sp = calloc(1, sizeof(RGBA_Image_Span));
418                        sp->x = x;
419                        sp->w = 1;
420                        sp->v = 2;
421                     }
422                   else if (a > 0)
423                     {
424                        sp = calloc(1, sizeof(RGBA_Image_Span));
425                        sp->x = x;
426                        sp->w = 1;
427                        sp->v = 1;
428                     }
429                }
430              ptr++;
431           }
432         if (sp)
433           {
434              is->spans[y] = eina_inlist_append(is->spans[y], sp);
435              sp = NULL;
436           }
437      }
438 }
439 #endif
440
441 /* EAPI void */
442 /* evas_common_image_surface_dealloc(RGBA_Surface *is) */
443 /* { */
444 /*    if ((is->data) && (!is->no_free)) */
445 /*      { */
446 /*      free(is->data); */
447 /*      is->data = NULL; */
448 /*      } */
449 /* } */
450
451 static RGBA_Image *
452 evas_common_image_create(int w, int h)
453 {
454    RGBA_Image *im;
455
456    im = (RGBA_Image *) _evas_common_rgba_image_new();
457    if (!im) return NULL;
458    im->cache_entry.w = w;
459    im->cache_entry.h = h;
460    if (_evas_common_rgba_image_surface_alloc(&im->cache_entry, w, h))
461      {
462         _evas_common_rgba_image_delete(&im->cache_entry);
463         return NULL;
464      }
465    im->cache_entry.flags.cached = 0;
466    return im;
467 }
468
469 EAPI RGBA_Image *
470 evas_common_image_alpha_create(int w, int h)
471 {
472    RGBA_Image   *im;
473
474    im = (RGBA_Image *) _evas_common_rgba_image_new();
475    if (!im) return NULL;
476    im->cache_entry.w = w;
477    im->cache_entry.h = h;
478    im->cache_entry.flags.alpha = 1;
479    if (_evas_common_rgba_image_surface_alloc(&im->cache_entry, w, h))
480      {
481         _evas_common_rgba_image_delete(&im->cache_entry);
482         return NULL;
483      }
484    im->cache_entry.flags.cached = 0;
485    return im;
486 }
487
488 EAPI RGBA_Image *
489 evas_common_image_new(int w, int h, int alpha)
490 {
491    if (alpha)
492      return evas_common_image_alpha_create(w, h);
493    return evas_common_image_create(w, h);
494 }
495
496 void
497 evas_common_image_colorspace_normalize(RGBA_Image *im)
498 {
499    if ((!im->cs.data) ||
500        ((!im->cs.dirty) && (!(im->flags & RGBA_IMAGE_IS_DIRTY)))) return;
501    switch (im->cache_entry.space)
502      {
503       case EVAS_COLORSPACE_ARGB8888:
504         if (im->image.data != im->cs.data)
505           {
506 #ifdef EVAS_CSERVE
507              if (((Image_Entry *)im)->data1) evas_cserve_image_free(&im->cache_entry);
508 #endif             
509              if (!im->image.no_free) free(im->image.data);
510              im->image.data = im->cs.data;
511              im->cs.no_free = im->image.no_free;
512           }
513         break;
514       case EVAS_COLORSPACE_YCBCR422P601_PL:
515 #ifdef BUILD_CONVERT_YUV
516         if ((im->image.data) && (*((unsigned char **)im->cs.data)))
517           evas_common_convert_yuv_420p_601_rgba(im->cs.data, (DATA8*) im->image.data,
518                                                 im->cache_entry.w, im->cache_entry.h);
519 #endif
520         break;
521       default:
522         break;
523      }
524    im->cs.dirty = 0;
525 }
526
527 EAPI void
528 evas_common_image_colorspace_dirty(RGBA_Image *im)
529 {
530    im->cs.dirty = 1;
531    evas_common_rgba_image_scalecache_dirty(&im->cache_entry);
532 }
533
534 EAPI void
535 evas_common_image_set_cache(int size)
536 {
537    if (eci != NULL)
538      evas_cache_image_set(eci, size);
539 }
540
541 EAPI int
542 evas_common_image_get_cache(void)
543 {
544    return evas_cache_image_get(eci);
545 }
546
547 EAPI RGBA_Image *
548 evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_Loadopts *lo, int *error)
549 {
550    if (file == NULL)
551      {
552         *error = EVAS_LOAD_ERROR_GENERIC;
553         return NULL;
554      }
555    return (RGBA_Image *) evas_cache_image_request(eci, file, key, lo, error);
556 }
557
558 EAPI void
559 evas_common_image_cache_free(void)
560 {
561    evas_common_image_set_cache(0);
562 }
563
564 EAPI Evas_Cache_Image*
565 evas_common_image_cache_get(void)
566 {
567    return eci;
568 }
569
570 EAPI RGBA_Image *
571 evas_common_image_line_buffer_obtain(int len)
572 {
573    if (len < 1) return NULL;
574    if (len < EVAS_RGBA_LINE_BUFFER_MIN_LEN)
575         len = EVAS_RGBA_LINE_BUFFER_MIN_LEN;
576    return evas_common_image_create(len, 1);
577 /*
578    if (evas_rgba_line_buffer)
579      {
580         if (evas_rgba_line_buffer->image->w >= len)
581            return evas_rgba_line_buffer;
582         evas_rgba_line_buffer->image->data = (DATA32 *)realloc(evas_rgba_line_buffer->image->data, len * sizeof(DATA32));
583         if (!evas_rgba_line_buffer->image->data)
584           {
585            evas_common_image_free(evas_rgba_line_buffer);
586            evas_rgba_line_buffer = NULL;
587            return NULL;
588           }
589         evas_rgba_line_buffer->image->w = len;
590         return evas_rgba_line_buffer;
591      }
592    evas_rgba_line_buffer = evas_common_image_create(len, 1);
593    if (!evas_rgba_line_buffer) return NULL;
594    return evas_rgba_line_buffer;
595  */
596 }
597
598 EAPI void
599 evas_common_image_line_buffer_release(RGBA_Image *im)
600 {
601     _evas_common_rgba_image_delete(&im->cache_entry);
602 /*
603    if (!evas_rgba_line_buffer) return;
604    if (EVAS_RGBA_LINE_BUFFER_MAX_LEN < evas_rgba_line_buffer->image->w)
605      {
606         evas_rgba_line_buffer->image->w = EVAS_RGBA_LINE_BUFFER_MAX_LEN;
607         evas_rgba_line_buffer->image->data = (DATA32 *)realloc(evas_rgba_line_buffer->image->data,
608                                  evas_rgba_line_buffer->image->w * sizeof(DATA32));
609         if (!evas_rgba_line_buffer->image->data)
610           {
611            evas_common_image_free(evas_rgba_line_buffer);
612            evas_rgba_line_buffer = NULL;
613           }
614      }
615  */
616 }
617
618 EAPI void
619 evas_common_image_line_buffer_free(RGBA_Image *im)
620 {
621     _evas_common_rgba_image_delete(&im->cache_entry);
622 /*
623    if (!evas_rgba_line_buffer) return;
624    evas_common_image_free(evas_rgba_line_buffer);
625    evas_rgba_line_buffer = NULL;
626  */
627 }
628
629 EAPI RGBA_Image *
630 evas_common_image_alpha_line_buffer_obtain(int len)
631 {
632    if (len < 1) return NULL;
633    if (len < EVAS_ALPHA_LINE_BUFFER_MIN_LEN)
634         len = EVAS_ALPHA_LINE_BUFFER_MIN_LEN;
635    return evas_common_image_alpha_create(len, 1);
636 /*
637    if (evas_alpha_line_buffer)
638      {
639         if (evas_alpha_line_buffer->image->w >= len)
640            return evas_alpha_line_buffer;
641         evas_alpha_line_buffer->image->data = realloc(evas_alpha_line_buffer->image->data, len * sizeof(DATA8));
642         if (!evas_alpha_line_buffer->image->data)
643           {
644            evas_common_image_free(evas_alpha_line_buffer);
645            evas_alpha_line_buffer = NULL;
646            return NULL;
647           }
648         evas_alpha_line_buffer->image->w = len;
649         return evas_alpha_line_buffer;
650      }
651    evas_alpha_line_buffer = evas_common_image_alpha_create(len, 1);
652    return evas_alpha_line_buffer;
653  */
654 }
655
656 EAPI void
657 evas_common_image_alpha_line_buffer_release(RGBA_Image *im)
658 {
659     _evas_common_rgba_image_delete(&im->cache_entry);
660 /*
661    if (!evas_alpha_line_buffer) return;
662    if (EVAS_ALPHA_LINE_BUFFER_MAX_LEN < evas_alpha_line_buffer->image->w)
663      {
664         evas_alpha_line_buffer->image->w = EVAS_ALPHA_LINE_BUFFER_MAX_LEN;
665         evas_alpha_line_buffer->image->data = realloc(evas_alpha_line_buffer->image->data,
666                                  evas_alpha_line_buffer->image->w * sizeof(DATA8));
667         if (!evas_alpha_line_buffer->image->data)
668           {
669            evas_common_image_free(evas_alpha_line_buffer);
670            evas_alpha_line_buffer = NULL;
671           }
672      }
673  */
674 }
675
676 EAPI void
677 evas_common_image_premul(Image_Entry *ie)
678 {
679    DATA32  nas = 0;
680
681    if (!ie) return ;
682    if (!evas_cache_image_pixels(ie)) return ;
683    if (!ie->flags.alpha) return;
684
685    nas = evas_common_convert_argb_premul(evas_cache_image_pixels(ie), ie->w * ie->h);
686    if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (ie->w * ie->h))
687      ie->flags.alpha_sparse = 1;
688 }
689
690 EAPI void
691 evas_common_image_set_alpha_sparse(Image_Entry *ie)
692 {
693    DATA32  *s, *se;
694    DATA32  nas = 0;
695
696    if (!ie) return;
697    if (!evas_cache_image_pixels(ie)) return ;
698    if (!ie->flags.alpha) return;
699
700    s = evas_cache_image_pixels(ie);
701    se = s + (ie->w * ie->h);
702    while (s < se)
703      {
704         DATA32  p = *s & 0xff000000;
705
706         if (!p || (p == 0xff000000))
707            nas++;
708         s++;
709      }
710    if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (ie->w * ie->h))
711      ie->flags.alpha_sparse = 1;
712 }