Evas image: reset error after setting a proxy.
[framework/uifw/evas.git] / src / lib / canvas / evas_object_image.c
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"  /* so that EAPI in Evas.h is correctly defined */
3 #endif
4
5 #include <sys/types.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #ifdef HAVE_SYS_MMAN_H
9 # include <sys/mman.h>
10 #endif
11 #include <math.h>
12
13 #include "evas_common.h"
14 #include "evas_private.h"
15 #include "../engines/common/evas_convert_color.h"
16 #include "../engines/common/evas_convert_colorspace.h"
17 #include "../engines/common/evas_convert_yuv.h"
18
19 #define VERBOSE_PROXY_ERROR 1
20
21 /* private magic number for image objects */
22 static const char o_type[] = "image";
23
24 /* private struct for rectangle object internal data */
25 typedef struct _Evas_Object_Image      Evas_Object_Image;
26
27 struct _Evas_Object_Image
28 {
29    DATA32            magic;
30
31    struct {
32       int                  spread;
33       Evas_Coord_Rectangle fill;
34       struct {
35          short         w, h, stride;
36       } image;
37       struct {
38          short         l, r, t, b;
39          unsigned char fill;
40          double        scale;
41       } border;
42
43       Evas_Object   *source;
44       Evas_Map      *defmap;
45       const char    *file;
46       const char    *key;
47       int            frame;
48       Evas_Colorspace cspace;
49
50       unsigned char  smooth_scale : 1;
51       unsigned char  has_alpha :1;
52       unsigned char  opaque :1;
53       unsigned char  opaque_valid :1;
54    } cur, prev;
55
56    int               pixels_checked_out;
57    int               load_error;
58    Eina_List        *pixel_updates;
59
60    struct {
61       unsigned char  scale_down_by;
62       double         dpi;
63       short          w, h;
64       struct {
65          short       x, y, w, h;
66       } region;
67       Eina_Bool  orientation : 1;
68    } load_opts;
69
70    struct {
71       Evas_Object_Image_Pixels_Get_Cb  get_pixels;
72       void                            *get_pixels_data;
73    } func;
74
75    Evas_Video_Surface video;
76
77    const char             *tmpf;
78    int                     tmpf_fd;
79
80    Evas_Image_Scale_Hint   scale_hint;
81    Evas_Image_Content_Hint content_hint;
82
83    void             *engine_data;
84
85    unsigned char     changed : 1;
86    unsigned char     dirty_pixels : 1;
87    unsigned char     filled : 1;
88    unsigned char     proxyrendering : 1;
89    unsigned char     preloading : 1;
90    unsigned char     video_rendering : 1;
91    unsigned char     video_surface : 1;
92    unsigned char     video_visible : 1;
93    unsigned char     created : 1;
94 };
95
96 /* private methods for image objects */
97 static void evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty);
98 static void evas_object_image_load(Evas_Object *obj);
99 static Evas_Coord evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret);
100 static Evas_Coord evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret);
101
102 static void evas_object_image_init(Evas_Object *obj);
103 static void *evas_object_image_new(void);
104 static void evas_object_image_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y);
105 static void evas_object_image_free(Evas_Object *obj);
106 static void evas_object_image_render_pre(Evas_Object *obj);
107 static void evas_object_image_render_post(Evas_Object *obj);
108
109 static unsigned int evas_object_image_id_get(Evas_Object *obj);
110 static unsigned int evas_object_image_visual_id_get(Evas_Object *obj);
111 static void *evas_object_image_engine_data_get(Evas_Object *obj);
112
113 static int evas_object_image_is_opaque(Evas_Object *obj);
114 static int evas_object_image_was_opaque(Evas_Object *obj);
115 static int evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
116 static int evas_object_image_has_opaque_rect(Evas_Object *obj);
117 static int evas_object_image_get_opaque_rect(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
118 static int evas_object_image_can_map(Evas_Object *obj);
119
120 static void *evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace);
121 static void evas_object_image_filled_resize_listener(void *data, Evas *e, Evas_Object *obj, void *einfo);
122
123 static void _proxy_unset(Evas_Object *proxy);
124 static void _proxy_set(Evas_Object *proxy, Evas_Object *src);
125 static void _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface, int x, int y);
126
127 static void _cleanup_tmpf(Evas_Object *obj);
128
129 static const Evas_Object_Func object_func =
130 {
131    /* methods (compulsory) */
132    evas_object_image_free,
133      evas_object_image_render,
134      evas_object_image_render_pre,
135      evas_object_image_render_post,
136      evas_object_image_id_get,
137      evas_object_image_visual_id_get,
138      evas_object_image_engine_data_get,
139      /* these are optional. NULL = nothing */
140      NULL,
141      NULL,
142      NULL,
143      NULL,
144      evas_object_image_is_opaque,
145      evas_object_image_was_opaque,
146      evas_object_image_is_inside,
147      NULL,
148      NULL,
149      NULL,
150      evas_object_image_has_opaque_rect,
151      evas_object_image_get_opaque_rect,
152      evas_object_image_can_map
153 };
154
155 EVAS_MEMPOOL(_mp_obj);
156
157 static void
158 _evas_object_image_cleanup(Evas_Object *obj, Evas_Object_Image *o)
159 {
160    if ((o->preloading) && (o->engine_data))
161      {
162         o->preloading = 0;
163         obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
164                                                                  o->engine_data,
165                                                                  obj);
166      }
167    if (o->tmpf) _cleanup_tmpf(obj);
168    if (o->cur.source) _proxy_unset(obj);
169 }
170
171 EAPI Evas_Object *
172 evas_object_image_add(Evas *e)
173 {
174    Evas_Object *obj;
175    Evas_Object_Image *o;
176
177    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
178    return NULL;
179    MAGIC_CHECK_END();
180    EINA_SAFETY_ON_NULL_RETURN_VAL(e->engine.func, NULL);
181    obj = evas_object_new(e);
182    evas_object_image_init(obj);
183    evas_object_inject(obj, e);
184    o = (Evas_Object_Image *)(obj->object_data);
185    o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
186                                                                        o->engine_data);
187    return obj;
188 }
189
190 EAPI Evas_Object *
191 evas_object_image_filled_add(Evas *e)
192 {
193    Evas_Object *obj;
194    obj = evas_object_image_add(e);
195    evas_object_image_filled_set(obj, 1);
196    return obj;
197 }
198
199 static void
200 _cleanup_tmpf(Evas_Object *obj)
201 {
202 #ifdef HAVE_SYS_MMAN_H
203    Evas_Object_Image *o;
204
205    o = (Evas_Object_Image *)(obj->object_data);
206    if (!o->tmpf) return;
207 #ifdef __linux__
208 #else
209    unlink(o->tmpf);
210 #endif
211    if (o->tmpf_fd >= 0) close(o->tmpf_fd);
212    eina_stringshare_del(o->tmpf);
213    o->tmpf_fd = -1;
214    o->tmpf = NULL;
215 #else
216    (void) obj;
217 #endif
218 }
219
220 static void
221 _create_tmpf(Evas_Object *obj, void *data, int size, char *format __UNUSED__)
222 {
223 #ifdef HAVE_SYS_MMAN_H
224    Evas_Object_Image *o;
225    char buf[PATH_MAX];
226    void *dst;
227    int fd = -1;
228    
229    o = (Evas_Object_Image *)(obj->object_data);
230 #ifdef __linux__
231    snprintf(buf, sizeof(buf), "/dev/shm/.evas-tmpf-%i-%p-%i-XXXXXX", 
232             (int)getpid(), data, (int)size);
233    fd = mkstemp(buf);
234 #endif   
235    if (fd < 0)
236      {
237         const char *tmpdir = getenv("TMPDIR");
238         
239         if (!tmpdir)
240           {
241              tmpdir = getenv("TMP");
242              if (!tmpdir)
243                {
244                   tmpdir = getenv("TEMP");
245                   if (!tmpdir) tmpdir = "/tmp";
246                }
247           }
248         snprintf(buf, sizeof(buf), "%s/.evas-tmpf-%i-%p-%i-XXXXXX", 
249                  tmpdir, (int)getpid(), data, (int)size);
250         fd = mkstemp(buf);
251         if (fd < 0) return;
252      }
253    if (ftruncate(fd, size) < 0)
254      {
255         unlink(buf);
256         close(fd);
257         return;
258      }
259 #ifdef __linux__
260    unlink(buf);
261 #endif
262    
263    eina_mmap_safety_enabled_set(EINA_TRUE);
264    
265    dst = mmap(NULL, size, 
266               PROT_READ | PROT_WRITE, 
267               MAP_SHARED, 
268               fd, 0);
269    if (dst == MAP_FAILED)
270      {
271         close(fd);
272         return;
273      }
274    o->tmpf_fd = fd;
275 #ifdef __linux__
276    snprintf(buf, sizeof(buf), "/proc/%li/fd/%i", (long)getpid(), fd);
277 #endif
278    o->tmpf = eina_stringshare_add(buf);
279    memcpy(dst, data, size);
280    munmap(dst, size);
281 #else
282    (void) obj;
283    (void) data;
284    (void) size;
285    (void) format;
286 #endif
287 }
288
289 EAPI void
290 evas_object_image_memfile_set(Evas_Object *obj, void *data, int size, char *format, char *key)
291 {
292    Evas_Object_Image *o;
293
294    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
295    return;
296    MAGIC_CHECK_END();
297    o = (Evas_Object_Image *)(obj->object_data);
298    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
299    return;
300    MAGIC_CHECK_END();
301    _cleanup_tmpf(obj);
302    evas_object_image_file_set(obj, NULL, NULL);
303    // invalidate the cache effectively
304    evas_object_image_alpha_set(obj, !o->cur.has_alpha);
305    evas_object_image_alpha_set(obj, !o->cur.has_alpha);
306
307    if ((size < 1) || (!data)) return;
308
309    _create_tmpf(obj, data, size, format);
310    evas_object_image_file_set(obj, o->tmpf, key);
311    if (!o->engine_data)
312      {
313         ERR("unable to load '%s' from memory", o->tmpf);
314         _cleanup_tmpf(obj);
315         return;
316      }
317 }
318
319 EAPI void
320 evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
321 {
322    Evas_Object_Image *o;
323    Evas_Image_Load_Opts lo;
324
325    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
326    return;
327    MAGIC_CHECK_END();
328    o = (Evas_Object_Image *)(obj->object_data);
329    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
330    return;
331    MAGIC_CHECK_END();
332    if ((o->tmpf) && (file != o->tmpf)) _cleanup_tmpf(obj);
333    if ((o->cur.file) && (file) && (!strcmp(o->cur.file, file)))
334      {
335         if ((!o->cur.key) && (!key))
336           return;
337         if ((o->cur.key) && (key) && (!strcmp(o->cur.key, key)))
338           return;
339      }
340 /*
341  * WTF? why cancel a null image preload? this is just silly (tm)
342    if (!o->engine_data)
343      obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
344                                                               o->engine_data,
345                                                               obj);
346  */
347    if (o->cur.source) _proxy_unset(obj);
348    if (o->cur.file) eina_stringshare_del(o->cur.file);
349    if (o->cur.key) eina_stringshare_del(o->cur.key);
350    if (file) o->cur.file = eina_stringshare_add(file);
351    else o->cur.file = NULL;
352    if (key) o->cur.key = eina_stringshare_add(key);
353    else o->cur.key = NULL;
354    o->prev.file = NULL;
355    o->prev.key = NULL;
356    if (o->engine_data)
357      {
358         if (o->preloading)
359           {
360              o->preloading = 0;
361              obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
362                                                                       o->engine_data,
363                                                                       obj);
364           }
365         obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
366                                                   o->engine_data);
367      }
368    o->load_error = EVAS_LOAD_ERROR_NONE;
369    lo.scale_down_by = o->load_opts.scale_down_by;
370    lo.dpi = o->load_opts.dpi;
371    lo.w = o->load_opts.w;
372    lo.h = o->load_opts.h;
373    lo.region.x = o->load_opts.region.x;
374    lo.region.y = o->load_opts.region.y;
375    lo.region.w = o->load_opts.region.w;
376    lo.region.h = o->load_opts.region.h;
377    lo.orientation = o->load_opts.orientation;
378    o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output,
379                                                               o->cur.file,
380                                                               o->cur.key,
381                                                               &o->load_error,
382                                                               &lo);
383    if (o->engine_data)
384      {
385         int w, h;
386         int stride;
387
388         obj->layer->evas->engine.func->image_size_get(obj->layer->evas->engine.data.output,
389                                                       o->engine_data, &w, &h);
390         if (obj->layer->evas->engine.func->image_stride_get)
391           obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output,
392                                                           o->engine_data, &stride);
393         else
394           stride = w * 4;
395         o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output,
396                                                                           o->engine_data);
397         o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
398                                                                             o->engine_data);
399         o->cur.image.w = w;
400         o->cur.image.h = h;
401         o->cur.image.stride = stride;
402      }
403    else
404      {
405         if (o->load_error == EVAS_LOAD_ERROR_NONE)
406           o->load_error = EVAS_LOAD_ERROR_GENERIC;
407         o->cur.has_alpha = 1;
408         o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
409         o->cur.image.w = 0;
410         o->cur.image.h = 0;
411         o->cur.image.stride = 0;
412      }
413    o->changed = 1;
414    evas_object_change(obj);
415 }
416
417 EAPI void
418 evas_object_image_file_get(const Evas_Object *obj, const char **file, const char **key)
419 {
420    Evas_Object_Image *o;
421
422    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
423    if (file) *file = NULL;
424    if (key) *key = NULL;
425    return;
426    MAGIC_CHECK_END();
427    o = (Evas_Object_Image *)(obj->object_data);
428    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
429    if (file) *file = NULL;
430    if (key) *key = NULL;
431    return;
432    MAGIC_CHECK_END();
433    if (file) *file = o->cur.file;
434    if (key) *key = o->cur.key;
435 }
436
437 EAPI Eina_Bool
438 evas_object_image_source_set(Evas_Object *obj, Evas_Object *src)
439 {
440    Evas_Object_Image *o;
441
442    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
443    return EINA_FALSE;
444    MAGIC_CHECK_END();
445    o = obj->object_data;
446    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
447    return EINA_FALSE;
448    MAGIC_CHECK_END();
449
450    if (src == obj) return EINA_FALSE;
451    if (o->cur.source == src) return EINA_TRUE;
452
453    _evas_object_image_cleanup(obj, o);
454    /* Kill the image if any */
455    if (o->cur.file || o->cur.key)
456       evas_object_image_file_set(obj, NULL, NULL);
457
458    if (src)
459      {
460         _proxy_set(obj, src);
461      }
462
463    return EINA_TRUE;
464 }
465
466
467 EAPI Evas_Object *
468 evas_object_image_source_get(const Evas_Object *obj)
469 {
470    Evas_Object_Image *o;
471
472    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
473    return NULL;
474    MAGIC_CHECK_END();
475    o = obj->object_data;
476    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
477    return NULL;
478    MAGIC_CHECK_END();
479
480    return o->cur.source;
481 }
482
483 EAPI Eina_Bool
484 evas_object_image_source_unset(Evas_Object *obj)
485 {
486    return evas_object_image_source_set(obj, NULL);
487 }
488
489 EAPI void
490 evas_object_image_border_set(Evas_Object *obj, int l, int r, int t, int b)
491 {
492    Evas_Object_Image *o;
493
494    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
495    return;
496    MAGIC_CHECK_END();
497    o = (Evas_Object_Image *)(obj->object_data);
498    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
499    return;
500    MAGIC_CHECK_END();
501    if (l < 0) l = 0;
502    if (r < 0) r = 0;
503    if (t < 0) t = 0;
504    if (b < 0) b = 0;
505    if ((o->cur.border.l == l) &&
506        (o->cur.border.r == r) &&
507        (o->cur.border.t == t) &&
508        (o->cur.border.b == b)) return;
509    o->cur.border.l = l;
510    o->cur.border.r = r;
511    o->cur.border.t = t;
512    o->cur.border.b = b;
513    o->cur.opaque_valid = 0;
514    o->changed = 1;
515    evas_object_change(obj);
516 }
517
518 EAPI void
519 evas_object_image_border_get(const Evas_Object *obj, int *l, int *r, int *t, int *b)
520 {
521    Evas_Object_Image *o;
522
523    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
524    if (l) *l = 0;
525    if (r) *r = 0;
526    if (t) *t = 0;
527    if (b) *b = 0;
528    return;
529    MAGIC_CHECK_END();
530    o = (Evas_Object_Image *)(obj->object_data);
531    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
532    if (l) *l = 0;
533    if (r) *r = 0;
534    if (t) *t = 0;
535    if (b) *b = 0;
536    return;
537    MAGIC_CHECK_END();
538    if (l) *l = o->cur.border.l;
539    if (r) *r = o->cur.border.r;
540    if (t) *t = o->cur.border.t;
541    if (b) *b = o->cur.border.b;
542 }
543
544 EAPI void
545 evas_object_image_border_center_fill_set(Evas_Object *obj, Evas_Border_Fill_Mode fill)
546 {
547    Evas_Object_Image *o;
548
549    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
550    return;
551    MAGIC_CHECK_END();
552    o = (Evas_Object_Image *)(obj->object_data);
553    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
554    return;
555    MAGIC_CHECK_END();
556    if (fill == o->cur.border.fill) return;
557    o->cur.border.fill = fill;
558    o->changed = 1;
559    evas_object_change(obj);
560 }
561
562 EAPI Evas_Border_Fill_Mode
563 evas_object_image_border_center_fill_get(const Evas_Object *obj)
564 {
565    Evas_Object_Image *o;
566
567    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
568    return 0;
569    MAGIC_CHECK_END();
570    o = (Evas_Object_Image *)(obj->object_data);
571    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
572    return 0;
573    MAGIC_CHECK_END();
574    return o->cur.border.fill;
575 }
576
577 EAPI void
578 evas_object_image_filled_set(Evas_Object *obj, Eina_Bool setting)
579 {
580    Evas_Object_Image *o;
581
582    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
583    return;
584    MAGIC_CHECK_END();
585    o = (Evas_Object_Image *)(obj->object_data);
586    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
587    return;
588    MAGIC_CHECK_END();
589
590    setting = !!setting;
591    if (o->filled == setting) return;
592
593    o->filled = setting;
594    if (!o->filled)
595      evas_object_event_callback_del(obj, EVAS_CALLBACK_RESIZE, evas_object_image_filled_resize_listener);
596    else
597      {
598         Evas_Coord w, h;
599
600         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
601         evas_object_image_fill_set(obj, 0, 0, w, h);
602
603         evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, evas_object_image_filled_resize_listener, NULL);
604      }
605 }
606
607 EAPI Eina_Bool
608 evas_object_image_filled_get(const Evas_Object *obj)
609 {
610    Evas_Object_Image *o;
611
612    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
613    return 0;
614    MAGIC_CHECK_END();
615    o = (Evas_Object_Image *)(obj->object_data);
616    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
617    return 0;
618    MAGIC_CHECK_END();
619
620    return o->filled;
621 }
622
623 EAPI void
624 evas_object_image_border_scale_set(Evas_Object *obj, double scale)
625 {
626    Evas_Object_Image *o;
627
628    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
629    return;
630    MAGIC_CHECK_END();
631    o = (Evas_Object_Image *)(obj->object_data);
632    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
633    return;
634    MAGIC_CHECK_END();
635    if (scale == o->cur.border.scale) return;
636    o->cur.border.scale = scale;
637    o->changed = 1;
638    evas_object_change(obj);
639 }
640
641 EAPI double
642 evas_object_image_border_scale_get(const Evas_Object *obj)
643 {
644    Evas_Object_Image *o;
645
646    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
647    return 1.0;
648    MAGIC_CHECK_END();
649    o = (Evas_Object_Image *)(obj->object_data);
650    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
651    return 1.0;
652    MAGIC_CHECK_END();
653    return o->cur.border.scale;
654 }
655
656 EAPI void
657 evas_object_image_fill_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
658 {
659    Evas_Object_Image *o;
660
661    if (w < 0) w = -w;
662    if (h < 0) h = -h;
663    if (w == 0) return;
664    if (h == 0) return;
665    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
666    return;
667    MAGIC_CHECK_END();
668    o = (Evas_Object_Image *)(obj->object_data);
669    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
670    return;
671    MAGIC_CHECK_END();
672    if ((o->cur.fill.x == x) &&
673        (o->cur.fill.y == y) &&
674        (o->cur.fill.w == w) &&
675        (o->cur.fill.h == h)) return;
676    o->cur.fill.x = x;
677    o->cur.fill.y = y;
678    o->cur.fill.w = w;
679    o->cur.fill.h = h;
680    o->cur.opaque_valid = 0;   
681    o->changed = 1;
682    evas_object_change(obj);
683 }
684
685 EAPI void
686 evas_object_image_fill_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
687 {
688    Evas_Object_Image *o;
689
690    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
691    if (x) *x = 0;
692    if (y) *y = 0;
693    if (w) *w = 0;
694    if (h) *h = 0;
695    return;
696    MAGIC_CHECK_END();
697    o = (Evas_Object_Image *)(obj->object_data);
698    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
699    if (x) *x = 0;
700    if (y) *y = 0;
701    if (w) *w = 0;
702    if (h) *h = 0;
703    return;
704    MAGIC_CHECK_END();
705    if (x) *x = o->cur.fill.x;
706    if (y) *y = o->cur.fill.y;
707    if (w) *w = o->cur.fill.w;
708    if (h) *h = o->cur.fill.h;
709 }
710
711
712 EAPI void
713 evas_object_image_fill_spread_set(Evas_Object *obj, Evas_Fill_Spread spread)
714 {
715    Evas_Object_Image *o;
716
717    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
718    return;
719    MAGIC_CHECK_END();
720    o = (Evas_Object_Image *)(obj->object_data);
721    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
722    return;
723    MAGIC_CHECK_END();
724    if (spread == (Evas_Fill_Spread)o->cur.spread) return;
725    o->cur.spread = spread;
726    o->changed = 1;
727    evas_object_change(obj);
728 }
729
730 EAPI Evas_Fill_Spread
731 evas_object_image_fill_spread_get(const Evas_Object *obj)
732 {
733    Evas_Object_Image *o;
734
735    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
736    return EVAS_TEXTURE_REPEAT;
737    MAGIC_CHECK_END();
738    o = (Evas_Object_Image *)(obj->object_data);
739    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
740    return EVAS_TEXTURE_REPEAT;
741    MAGIC_CHECK_END();
742    return (Evas_Fill_Spread)o->cur.spread;
743 }
744
745 EAPI void
746 evas_object_image_size_set(Evas_Object *obj, int w, int h)
747 {
748    Evas_Object_Image *o;
749    int stride = 0;
750
751    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
752    return;
753    MAGIC_CHECK_END();
754    o = (Evas_Object_Image *)(obj->object_data);
755    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
756    return;
757    MAGIC_CHECK_END();
758    _evas_object_image_cleanup(obj, o);
759    if (w < 1) w = 1;
760    if (h < 1) h = 1;
761    if (w > 32768) return;
762    if (h > 32768) return;
763    if ((w == o->cur.image.w) &&
764        (h == o->cur.image.h)) return;
765    o->cur.image.w = w;
766    o->cur.image.h = h;
767    if (o->engine_data)
768       o->engine_data = obj->layer->evas->engine.func->image_size_set(obj->layer->evas->engine.data.output,
769                                                                      o->engine_data,
770                                                                      w, h);
771    else
772       o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data
773       (obj->layer->evas->engine.data.output, w, h, NULL, o->cur.has_alpha,
774           o->cur.cspace);
775
776    if (o->engine_data)
777      {
778         if (obj->layer->evas->engine.func->image_scale_hint_set)
779            obj->layer->evas->engine.func->image_scale_hint_set
780            (obj->layer->evas->engine.data.output,
781                o->engine_data, o->scale_hint);
782         if (obj->layer->evas->engine.func->image_content_hint_set)
783            obj->layer->evas->engine.func->image_content_hint_set
784            (obj->layer->evas->engine.data.output,
785                o->engine_data, o->content_hint);
786         if (obj->layer->evas->engine.func->image_stride_get)
787            obj->layer->evas->engine.func->image_stride_get
788            (obj->layer->evas->engine.data.output,
789                o->engine_data, &stride);
790         else
791            stride = w * 4;
792      }
793    else
794       stride = w * 4;
795    o->cur.image.stride = stride;
796
797 /* FIXME - in engine call above
798    if (o->engine_data)
799      o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
800                                                                      o->engine_data,
801                                                                      o->cur.has_alpha);
802 */
803    EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
804    o->changed = 1;
805    evas_object_change(obj);
806 }
807
808 EAPI void
809 evas_object_image_size_get(const Evas_Object *obj, int *w, int *h)
810 {
811    Evas_Object_Image *o;
812
813    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
814    if (w) *w = 0;
815    if (h) *h = 0;
816    return;
817    MAGIC_CHECK_END();
818    o = (Evas_Object_Image *)(obj->object_data);
819    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
820    if (w) *w = 0;
821    if (h) *h = 0;
822    return;
823    MAGIC_CHECK_END();
824    if (w) *w = o->cur.image.w;
825    if (h) *h = o->cur.image.h;
826 }
827
828 EAPI int
829 evas_object_image_stride_get(const Evas_Object *obj)
830 {
831    Evas_Object_Image *o;
832
833    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
834    return 0;
835    MAGIC_CHECK_END();
836    o = (Evas_Object_Image *)(obj->object_data);
837    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
838    return 0;
839    MAGIC_CHECK_END();
840    return o->cur.image.stride;
841 }
842
843 EAPI Evas_Load_Error
844 evas_object_image_load_error_get(const Evas_Object *obj)
845 {
846    Evas_Object_Image *o;
847
848    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
849    return 0;
850    MAGIC_CHECK_END();
851    o = (Evas_Object_Image *)(obj->object_data);
852    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
853    return 0;
854    MAGIC_CHECK_END();
855    return o->load_error;
856 }
857
858 EAPI void *
859 evas_object_image_data_convert(Evas_Object *obj, Evas_Colorspace to_cspace)
860 {
861    Evas_Object_Image *o;
862    DATA32 *data;
863    void* result = NULL;
864
865    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
866    return NULL;
867    MAGIC_CHECK_END();
868    o = (Evas_Object_Image *)(obj->object_data);
869    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
870    return NULL;
871    MAGIC_CHECK_END();
872    if ((o->preloading) && (o->engine_data))
873      {
874         o->preloading = 0;
875         obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
876                                                                  o->engine_data,
877                                                                  obj);
878      }
879    if (!o->engine_data) return NULL;
880    if (o->video_surface)
881      o->video.update_pixels(o->video.data, obj, &o->video);
882    if (o->cur.cspace == to_cspace) return NULL;
883    data = NULL;
884    o->engine_data = 
885      obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
886                                                    o->engine_data, 0, &data,
887                                                    &o->load_error);
888    result = evas_object_image_data_convert_internal(o, data, to_cspace);
889    if (o->engine_data)
890      {
891         o->engine_data = 
892           obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
893                                                         o->engine_data, data);
894      }
895
896   return result;
897 }
898 EAPI void
899 evas_object_image_data_set(Evas_Object *obj, void *data)
900 {
901    Evas_Object_Image *o;
902    void *p_data;
903
904    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
905    return;
906    MAGIC_CHECK_END();
907    o = (Evas_Object_Image *)(obj->object_data);
908    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
909    return;
910    MAGIC_CHECK_END();
911    _evas_object_image_cleanup(obj, o);
912    p_data = o->engine_data;
913    if (data)
914      {
915         if (o->engine_data)
916           {
917              o->engine_data = 
918                obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
919                                                              o->engine_data,
920                                                              data);
921           }
922         else
923           {
924              o->engine_data = 
925                obj->layer->evas->engine.func->image_new_from_data(obj->layer->evas->engine.data.output,
926                                                                   o->cur.image.w,
927                                                                   o->cur.image.h,
928                                                                   data,
929                                                                   o->cur.has_alpha,
930                                                                   o->cur.cspace);
931           }
932         if (o->engine_data)
933           {
934              int stride = 0;
935              
936              if (obj->layer->evas->engine.func->image_scale_hint_set)
937                 obj->layer->evas->engine.func->image_scale_hint_set
938                 (obj->layer->evas->engine.data.output,
939                     o->engine_data, o->scale_hint);
940              if (obj->layer->evas->engine.func->image_content_hint_set)
941                 obj->layer->evas->engine.func->image_content_hint_set
942                 (obj->layer->evas->engine.data.output,
943                     o->engine_data, o->content_hint); 
944              if (obj->layer->evas->engine.func->image_stride_get)
945                 obj->layer->evas->engine.func->image_stride_get
946                 (obj->layer->evas->engine.data.output,
947                     o->engine_data, &stride);
948              else
949                 stride = o->cur.image.w * 4;
950              o->cur.image.stride = stride;
951          }
952      }
953    else
954      {
955         if (o->engine_data)
956           obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
957                                                     o->engine_data);
958         o->load_error = EVAS_LOAD_ERROR_NONE;
959         o->cur.image.w = 0;
960         o->cur.image.h = 0;
961         o->cur.image.stride = 0;
962         o->engine_data = NULL;
963      }
964 /* FIXME - in engine call above
965    if (o->engine_data)
966      o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
967                                                                      o->engine_data,
968                                                                      o->cur.has_alpha);
969 */
970    if (o->pixels_checked_out > 0) o->pixels_checked_out--;
971    if (p_data != o->engine_data)
972      {
973         EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
974         o->pixels_checked_out = 0;
975      }
976    o->changed = 1;
977    evas_object_change(obj);
978 }
979
980 EAPI void *
981 evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing)
982 {
983    Evas_Object_Image *o;
984    DATA32 *data;
985
986    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
987    return NULL;
988    MAGIC_CHECK_END();
989    o = (Evas_Object_Image *)(obj->object_data);
990    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
991    return NULL;
992    MAGIC_CHECK_END();
993    if (!o->engine_data) return NULL;
994
995    data = NULL;
996    if (obj->layer->evas->engine.func->image_scale_hint_set)
997       obj->layer->evas->engine.func->image_scale_hint_set
998       (obj->layer->evas->engine.data.output,
999           o->engine_data, o->scale_hint);
1000    if (obj->layer->evas->engine.func->image_content_hint_set)
1001       obj->layer->evas->engine.func->image_content_hint_set
1002       (obj->layer->evas->engine.data.output,
1003           o->engine_data, o->content_hint);
1004    o->engine_data = 
1005      obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1006                                                    o->engine_data,
1007                                                    for_writing, &data,
1008                                                    &o->load_error);
1009
1010    /* if we fail to get engine_data, we have to return NULL */
1011    if (!o->engine_data) return NULL;
1012
1013    if (o->engine_data)
1014      {
1015         int stride = 0;
1016
1017         if (obj->layer->evas->engine.func->image_stride_get)
1018            obj->layer->evas->engine.func->image_stride_get
1019            (obj->layer->evas->engine.data.output,
1020                o->engine_data, &stride);
1021         else
1022            stride = o->cur.image.w * 4;
1023         o->cur.image.stride = stride;
1024      }
1025    o->pixels_checked_out++;
1026    if (for_writing)
1027      {
1028         EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1029      }
1030
1031    return data;
1032 }
1033
1034 EAPI void
1035 evas_object_image_preload(Evas_Object *obj, Eina_Bool cancel)
1036 {
1037    Evas_Object_Image *o;
1038
1039    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1040    return ;
1041    MAGIC_CHECK_END();
1042    o = (Evas_Object_Image *)(obj->object_data);
1043    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1044    return ;
1045    MAGIC_CHECK_END();
1046    if (!o->engine_data)
1047      {
1048         o->preloading = 1;
1049         evas_object_inform_call_image_preloaded(obj);
1050         return;
1051      }
1052    // FIXME: if already busy preloading, then dont request again until
1053    // preload done
1054    if (cancel)
1055      {
1056         if (o->preloading)
1057           {
1058              o->preloading = 0;
1059              obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1060                                                                       o->engine_data,
1061                                                                       obj);
1062           }
1063      }
1064    else
1065      {
1066         if (!o->preloading)
1067           {
1068              o->preloading = 1;
1069              obj->layer->evas->engine.func->image_data_preload_request(obj->layer->evas->engine.data.output,
1070                                                                        o->engine_data,
1071                                                                        obj);
1072           }
1073      }
1074 }
1075
1076 EAPI void
1077 evas_object_image_data_copy_set(Evas_Object *obj, void *data)
1078 {
1079    Evas_Object_Image *o;
1080
1081    if (!data) return;
1082    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1083    return;
1084    MAGIC_CHECK_END();
1085    o = (Evas_Object_Image *)(obj->object_data);
1086    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1087    return;
1088    MAGIC_CHECK_END();
1089    _evas_object_image_cleanup(obj, o);
1090    if ((o->cur.image.w <= 0) ||
1091        (o->cur.image.h <= 0)) return;
1092    if (o->engine_data)
1093      obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
1094                                                o->engine_data);
1095    o->engine_data = 
1096      obj->layer->evas->engine.func->image_new_from_copied_data(obj->layer->evas->engine.data.output,
1097                                                                o->cur.image.w,
1098                                                                o->cur.image.h,
1099                                                                data,
1100                                                                o->cur.has_alpha,
1101                                                                o->cur.cspace);
1102    if (o->engine_data)
1103      {
1104         int stride = 0;
1105
1106         o->engine_data = 
1107           obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1108                                                          o->engine_data,
1109                                                          o->cur.has_alpha);
1110         if (obj->layer->evas->engine.func->image_scale_hint_set)
1111            obj->layer->evas->engine.func->image_scale_hint_set
1112            (obj->layer->evas->engine.data.output,
1113                o->engine_data, o->scale_hint);
1114         if (obj->layer->evas->engine.func->image_content_hint_set)
1115            obj->layer->evas->engine.func->image_content_hint_set
1116            (obj->layer->evas->engine.data.output,
1117                o->engine_data, o->content_hint);
1118         if (obj->layer->evas->engine.func->image_stride_get)
1119            obj->layer->evas->engine.func->image_stride_get
1120            (obj->layer->evas->engine.data.output,
1121                o->engine_data, &stride);
1122         else
1123            stride = o->cur.image.w * 4;
1124         o->cur.image.stride = stride;
1125      }
1126    o->pixels_checked_out = 0;
1127    EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1128 }
1129
1130 EAPI void
1131 evas_object_image_data_update_add(Evas_Object *obj, int x, int y, int w, int h)
1132 {
1133    Evas_Object_Image *o;
1134    Eina_Rectangle *r;
1135
1136    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1137    return;
1138    MAGIC_CHECK_END();
1139    o = (Evas_Object_Image *)(obj->object_data);
1140    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1141    return;
1142    MAGIC_CHECK_END();
1143    RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, o->cur.image.w, o->cur.image.h);
1144    if ((w <= 0)  || (h <= 0)) return;
1145    NEW_RECT(r, x, y, w, h);
1146    if (r) o->pixel_updates = eina_list_append(o->pixel_updates, r);
1147    o->changed = 1;
1148    evas_object_change(obj);
1149 }
1150
1151 EAPI void
1152 evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha)
1153 {
1154    Evas_Object_Image *o;
1155
1156    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1157    return;
1158    MAGIC_CHECK_END();
1159    o = (Evas_Object_Image *)(obj->object_data);
1160    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1161    return;
1162    MAGIC_CHECK_END();
1163    if ((o->preloading) && (o->engine_data))
1164      {
1165         o->preloading = 0;
1166         obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1167                                                                  o->engine_data,
1168                                                                  obj);
1169      }
1170    if (((has_alpha) && (o->cur.has_alpha)) ||
1171        ((!has_alpha) && (!o->cur.has_alpha)))
1172      return;
1173    o->cur.has_alpha = has_alpha;
1174    if (o->engine_data)
1175      {
1176         int stride = 0;
1177
1178         o->engine_data = 
1179           obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1180                                                          o->engine_data,
1181                                                          o->cur.has_alpha);
1182         if (obj->layer->evas->engine.func->image_scale_hint_set)
1183            obj->layer->evas->engine.func->image_scale_hint_set
1184            (obj->layer->evas->engine.data.output,
1185                o->engine_data, o->scale_hint);
1186         if (obj->layer->evas->engine.func->image_content_hint_set)
1187            obj->layer->evas->engine.func->image_content_hint_set
1188            (obj->layer->evas->engine.data.output,
1189                o->engine_data, o->content_hint);
1190         if (obj->layer->evas->engine.func->image_stride_get)
1191            obj->layer->evas->engine.func->image_stride_get
1192            (obj->layer->evas->engine.data.output,
1193                o->engine_data, &stride);
1194         else
1195            stride = o->cur.image.w * 4;
1196         o->cur.image.stride = stride;
1197      }
1198    evas_object_image_data_update_add(obj, 0, 0, o->cur.image.w, o->cur.image.h);
1199    EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1200 }
1201
1202
1203 EAPI Eina_Bool
1204 evas_object_image_alpha_get(const Evas_Object *obj)
1205 {
1206    Evas_Object_Image *o;
1207
1208    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1209    return 0;
1210    MAGIC_CHECK_END();
1211    o = (Evas_Object_Image *)(obj->object_data);
1212    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1213    return 0;
1214    MAGIC_CHECK_END();
1215    return o->cur.has_alpha;
1216 }
1217
1218 EAPI void
1219 evas_object_image_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth_scale)
1220 {
1221    Evas_Object_Image *o;
1222
1223    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1224    return;
1225    MAGIC_CHECK_END();
1226    o = (Evas_Object_Image *)(obj->object_data);
1227    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1228    return;
1229    MAGIC_CHECK_END();
1230    if (((smooth_scale) && (o->cur.smooth_scale)) ||
1231        ((!smooth_scale) && (!o->cur.smooth_scale)))
1232      return;
1233    o->cur.smooth_scale = smooth_scale;
1234    o->changed = 1;
1235    evas_object_change(obj);
1236 }
1237
1238 EAPI Eina_Bool
1239 evas_object_image_smooth_scale_get(const Evas_Object *obj)
1240 {
1241    Evas_Object_Image *o;
1242
1243    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1244    return 0;
1245    MAGIC_CHECK_END();
1246    o = (Evas_Object_Image *)(obj->object_data);
1247    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1248    return 0;
1249    MAGIC_CHECK_END();
1250    return o->cur.smooth_scale;
1251 }
1252
1253 EAPI void
1254 evas_object_image_reload(Evas_Object *obj)
1255 {
1256    Evas_Object_Image *o;
1257
1258    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1259    return;
1260    MAGIC_CHECK_END();
1261    o = (Evas_Object_Image *)(obj->object_data);
1262    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1263    return;
1264    MAGIC_CHECK_END();
1265    if ((o->preloading) && (o->engine_data))
1266      {
1267         o->preloading = 0;
1268         obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1269                                                                  o->engine_data,
1270                                                                  obj);
1271      }
1272    if ((!o->cur.file) ||
1273        (o->pixels_checked_out > 0)) return;
1274    if (o->engine_data)
1275      o->engine_data = obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h);
1276    evas_object_image_unload(obj, 1);
1277    evas_object_inform_call_image_unloaded(obj);
1278    evas_object_image_load(obj);
1279    o->prev.file = NULL;
1280    o->prev.key = NULL;
1281    o->changed = 1;
1282    evas_object_change(obj);
1283 }
1284
1285 EAPI Eina_Bool
1286 evas_object_image_save(const Evas_Object *obj, const char *file, const char *key, const char *flags)
1287 {
1288    Evas_Object_Image *o;
1289    DATA32 *data = NULL;
1290    int quality = 80, compress = 9, ok = 0;
1291    RGBA_Image *im;
1292
1293    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1294    return 0;
1295    MAGIC_CHECK_END();
1296    o = (Evas_Object_Image *)(obj->object_data);
1297    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1298    return 0;
1299    MAGIC_CHECK_END();
1300
1301    if (!o->engine_data) return 0;
1302    o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1303                                                                   o->engine_data,
1304                                                                   0,
1305                                                                   &data,
1306                                                                   &o->load_error);
1307    if (flags)
1308      {
1309         char *p, *pp;
1310         char *tflags;
1311
1312         tflags = alloca(strlen(flags) + 1);
1313         strcpy(tflags, flags);
1314         p = tflags;
1315         while (p)
1316           {
1317              pp = strchr(p, ' ');
1318              if (pp) *pp = 0;
1319              sscanf(p, "quality=%i", &quality);
1320              sscanf(p, "compress=%i", &compress);
1321              if (pp) p = pp + 1;
1322              else break;
1323           }
1324      }
1325    im = (RGBA_Image*) evas_cache_image_data(evas_common_image_cache_get(),
1326                                             o->cur.image.w,
1327                                             o->cur.image.h,
1328                                             data,
1329                                             o->cur.has_alpha,
1330                                             EVAS_COLORSPACE_ARGB8888);
1331    if (im)
1332      {
1333         if (o->cur.cspace == EVAS_COLORSPACE_ARGB8888)
1334           im->image.data = data;
1335         else
1336           im->image.data = evas_object_image_data_convert_internal(o,
1337                                                                    data,
1338                                                                    EVAS_COLORSPACE_ARGB8888);
1339         if (im->image.data)
1340           {
1341              ok = evas_common_save_image_to_file(im, file, key, quality, compress);
1342
1343              if (o->cur.cspace != EVAS_COLORSPACE_ARGB8888)
1344                free(im->image.data);
1345           }
1346
1347         evas_cache_image_drop(&im->cache_entry);
1348      }
1349    o->engine_data = obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1350                                                                   o->engine_data,
1351                                                                   data);
1352    return ok;
1353 }
1354
1355 EAPI Eina_Bool
1356 evas_object_image_pixels_import(Evas_Object *obj, Evas_Pixel_Import_Source *pixels)
1357 {
1358    Evas_Object_Image *o;
1359
1360    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1361    return 0;
1362    MAGIC_CHECK_END();
1363    o = (Evas_Object_Image *)(obj->object_data);
1364    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1365    return 0;
1366    MAGIC_CHECK_END();
1367    _evas_object_image_cleanup(obj, o);
1368    if ((pixels->w != o->cur.image.w) || (pixels->h != o->cur.image.h)) return 0;
1369    switch (pixels->format)
1370      {
1371 #if 0
1372       case EVAS_PIXEL_FORMAT_ARGB32:
1373           {
1374              if (o->engine_data)
1375                {
1376                   DATA32 *image_pixels = NULL;
1377
1378                   o->engine_data =
1379                     obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1380                                                                   o->engine_data,
1381                                                                   1,
1382                                                                   &image_pixels,
1383                                                                   &o->load_error);
1384 /* FIXME: need to actualyl support this */
1385 /*                memcpy(image_pixels, pixels->rows, o->cur.image.w * o->cur.image.h * 4);*/
1386                   if (o->engine_data)
1387                     o->engine_data =
1388                     obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1389                                                                   o->engine_data,
1390                                                                   image_pixels);
1391                   if (o->engine_data)
1392                     o->engine_data =
1393                     obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1394                                                                    o->engine_data,
1395                                                                    o->cur.has_alpha);
1396                   o->changed = 1;
1397                   evas_object_change(obj);
1398                }
1399           }
1400         break;
1401 #endif
1402 #ifdef BUILD_CONVERT_YUV
1403       case EVAS_PIXEL_FORMAT_YUV420P_601:
1404           {
1405              if (o->engine_data)
1406                {
1407                   DATA32 *image_pixels = NULL;
1408
1409                   o->engine_data =
1410                     obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1411                                                                   o->engine_data,
1412                                                                   1,
1413                                                                   &image_pixels,
1414                                                                   &o->load_error);
1415                   if (image_pixels)
1416                     evas_common_convert_yuv_420p_601_rgba((DATA8 **) pixels->rows,
1417                                                           (DATA8 *) image_pixels,
1418                                                           o->cur.image.w,
1419                                                           o->cur.image.h);
1420                   if (o->engine_data)
1421                     o->engine_data =
1422                     obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1423                                                                   o->engine_data,
1424                                                                   image_pixels);
1425                   if (o->engine_data)
1426                     o->engine_data =
1427                     obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1428                                                                    o->engine_data,
1429                                                                    o->cur.has_alpha);
1430                   o->changed = 1;
1431                   evas_object_change(obj);
1432                }
1433           }
1434         break;
1435 #endif
1436       default:
1437         return 0;
1438         break;
1439      }
1440    return 1;
1441 }
1442
1443 EAPI void
1444 evas_object_image_pixels_get_callback_set(Evas_Object *obj, Evas_Object_Image_Pixels_Get_Cb func, void *data)
1445 {
1446    Evas_Object_Image *o;
1447
1448    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1449    return;
1450    MAGIC_CHECK_END();
1451    o = (Evas_Object_Image *)(obj->object_data);
1452    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1453    return;
1454    MAGIC_CHECK_END();
1455    o->func.get_pixels = func;
1456    o->func.get_pixels_data = data;
1457 }
1458
1459 EAPI void
1460 evas_object_image_pixels_dirty_set(Evas_Object *obj, Eina_Bool dirty)
1461 {
1462    Evas_Object_Image *o;
1463
1464    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1465    return;
1466    MAGIC_CHECK_END();
1467    o = (Evas_Object_Image *)(obj->object_data);
1468    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1469    return;
1470    MAGIC_CHECK_END();
1471    if (dirty) o->dirty_pixels = 1;
1472    else o->dirty_pixels = 0;
1473    o->changed = 1;
1474    evas_object_change(obj);
1475 }
1476
1477 EAPI Eina_Bool
1478 evas_object_image_pixels_dirty_get(const Evas_Object *obj)
1479 {
1480    Evas_Object_Image *o;
1481
1482    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1483    return 0;
1484    MAGIC_CHECK_END();
1485    o = (Evas_Object_Image *)(obj->object_data);
1486    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1487    return 0;
1488    MAGIC_CHECK_END();
1489    if (o->dirty_pixels) return 1;
1490    return 0;
1491 }
1492
1493 EAPI void
1494 evas_object_image_load_dpi_set(Evas_Object *obj, double dpi)
1495 {
1496    Evas_Object_Image *o;
1497
1498    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1499    return;
1500    MAGIC_CHECK_END();
1501    o = (Evas_Object_Image *)(obj->object_data);
1502    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1503    return;
1504    MAGIC_CHECK_END();
1505    if (dpi == o->load_opts.dpi) return;
1506    o->load_opts.dpi = dpi;
1507    if (o->cur.file)
1508      {
1509         evas_object_image_unload(obj, 0);
1510         evas_object_inform_call_image_unloaded(obj);
1511         evas_object_image_load(obj);
1512         o->changed = 1;
1513         evas_object_change(obj);
1514      }
1515 }
1516
1517 EAPI double
1518 evas_object_image_load_dpi_get(const Evas_Object *obj)
1519 {
1520    Evas_Object_Image *o;
1521
1522    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1523    return 0.0;
1524    MAGIC_CHECK_END();
1525    o = (Evas_Object_Image *)(obj->object_data);
1526    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1527    return 0.0;
1528    MAGIC_CHECK_END();
1529    return o->load_opts.dpi;
1530 }
1531
1532 EAPI void
1533 evas_object_image_load_size_set(Evas_Object *obj, int w, int h)
1534 {
1535    Evas_Object_Image *o;
1536
1537    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1538    return;
1539    MAGIC_CHECK_END();
1540    o = (Evas_Object_Image *)(obj->object_data);
1541    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1542    return;
1543    MAGIC_CHECK_END();
1544    if ((o->load_opts.w == w) && (o->load_opts.h == h)) return;
1545    o->load_opts.w = w;
1546    o->load_opts.h = h;
1547    if (o->cur.file)
1548      {
1549         evas_object_image_unload(obj, 0);
1550         evas_object_inform_call_image_unloaded(obj);
1551         evas_object_image_load(obj);
1552         o->changed = 1;
1553         evas_object_change(obj);
1554      }
1555 }
1556
1557 EAPI void
1558 evas_object_image_load_size_get(const Evas_Object *obj, int *w, int *h)
1559 {
1560    Evas_Object_Image *o;
1561
1562    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1563    return;
1564    MAGIC_CHECK_END();
1565    o = (Evas_Object_Image *)(obj->object_data);
1566    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1567    return;
1568    MAGIC_CHECK_END();
1569    if (w) *w = o->load_opts.w;
1570    if (h) *h = o->load_opts.h;
1571 }
1572
1573 EAPI void
1574 evas_object_image_load_scale_down_set(Evas_Object *obj, int scale_down)
1575 {
1576    Evas_Object_Image *o;
1577
1578    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1579    return;
1580    MAGIC_CHECK_END();
1581    o = (Evas_Object_Image *)(obj->object_data);
1582    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1583    return;
1584    MAGIC_CHECK_END();
1585    if (o->load_opts.scale_down_by == scale_down) return;
1586    o->load_opts.scale_down_by = scale_down;
1587    if (o->cur.file)
1588      {
1589         evas_object_image_unload(obj, 0);
1590         evas_object_inform_call_image_unloaded(obj);
1591         evas_object_image_load(obj);
1592         o->changed = 1;
1593         evas_object_change(obj);
1594      }
1595 }
1596
1597 EAPI int
1598 evas_object_image_load_scale_down_get(const Evas_Object *obj)
1599 {
1600    Evas_Object_Image *o;
1601
1602    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1603    return 0;
1604    MAGIC_CHECK_END();
1605    o = (Evas_Object_Image *)(obj->object_data);
1606    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1607    return 0;
1608    MAGIC_CHECK_END();
1609    return o->load_opts.scale_down_by;
1610 }
1611
1612 EAPI void
1613 evas_object_image_load_region_set(Evas_Object *obj, int x, int y, int w, int h)
1614 {
1615    Evas_Object_Image *o;
1616
1617    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1618    return;
1619    MAGIC_CHECK_END();
1620    o = (Evas_Object_Image *)(obj->object_data);
1621    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1622    return;
1623    MAGIC_CHECK_END();
1624    if ((o->load_opts.region.x == x) && (o->load_opts.region.y == y) &&
1625        (o->load_opts.region.w == w) && (o->load_opts.region.h == h)) return;
1626    o->load_opts.region.x = x;
1627    o->load_opts.region.y = y;
1628    o->load_opts.region.w = w;
1629    o->load_opts.region.h = h;
1630    if (o->cur.file)
1631      {
1632         evas_object_image_unload(obj, 0);
1633         evas_object_inform_call_image_unloaded(obj);
1634         evas_object_image_load(obj);
1635         o->changed = 1;
1636         evas_object_change(obj);
1637      }
1638 }
1639
1640 EAPI void
1641 evas_object_image_load_region_get(const Evas_Object *obj, int *x, int *y, int *w, int *h)
1642 {
1643    Evas_Object_Image *o;
1644
1645    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1646    return;
1647    MAGIC_CHECK_END();
1648    o = (Evas_Object_Image *)(obj->object_data);
1649    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1650    return;
1651    MAGIC_CHECK_END();
1652    if (x) *x = o->load_opts.region.x;
1653    if (y) *y = o->load_opts.region.y;
1654    if (w) *w = o->load_opts.region.w;
1655    if (h) *h = o->load_opts.region.h;
1656 }
1657
1658 EAPI void
1659 evas_object_image_load_orientation_set(Evas_Object *obj, Eina_Bool enable)
1660 {
1661    Evas_Object_Image *o;
1662
1663    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1664    return;
1665    MAGIC_CHECK_END();
1666    o = (Evas_Object_Image *)(obj->object_data);
1667    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1668    return;
1669    MAGIC_CHECK_END();
1670    o->load_opts.orientation = !!enable;
1671 }
1672
1673 EAPI Eina_Bool
1674 evas_object_image_load_orientation_get(const Evas_Object *obj)
1675 {
1676    Evas_Object_Image *o;
1677
1678    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1679    return EINA_FALSE;
1680    MAGIC_CHECK_END();
1681    o = (Evas_Object_Image *)(obj->object_data);
1682    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1683    return EINA_FALSE;
1684    MAGIC_CHECK_END();
1685    return o->load_opts.orientation;
1686 }
1687
1688 EAPI void
1689 evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace)
1690 {
1691    Evas_Object_Image *o;
1692
1693    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1694    return;
1695    MAGIC_CHECK_END();
1696    o = (Evas_Object_Image *)(obj->object_data);
1697    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1698    return;
1699    MAGIC_CHECK_END();
1700
1701    _evas_object_image_cleanup(obj, o);
1702
1703    o->cur.cspace = cspace;
1704    if (o->engine_data)
1705      obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output,
1706                                                          o->engine_data,
1707                                                          cspace);
1708 }
1709
1710 EAPI Evas_Colorspace
1711 evas_object_image_colorspace_get(const Evas_Object *obj)
1712 {
1713    Evas_Object_Image *o;
1714
1715    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1716    return EVAS_COLORSPACE_ARGB8888;
1717    MAGIC_CHECK_END();
1718    o = (Evas_Object_Image *)(obj->object_data);
1719    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1720    return EVAS_COLORSPACE_ARGB8888;
1721    MAGIC_CHECK_END();
1722    return o->cur.cspace;
1723 }
1724
1725 EAPI void
1726 evas_object_image_video_surface_set(Evas_Object *obj, Evas_Video_Surface *surf)
1727 {
1728    Evas_Object_Image *o;
1729
1730    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1731    return;
1732    MAGIC_CHECK_END();
1733    o = (Evas_Object_Image *)(obj->object_data);
1734    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1735    return;
1736    MAGIC_CHECK_END();
1737    _evas_object_image_cleanup(obj, o);
1738    if (o->video_surface)
1739      {
1740         o->video_surface = 0;
1741         obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
1742      }
1743
1744    if (surf)
1745      {
1746         if (surf->version != EVAS_VIDEO_SURFACE_VERSION) return ;
1747
1748         if (!surf->update_pixels ||
1749             !surf->move ||
1750             !surf->resize ||
1751             !surf->hide ||
1752             !surf->show)
1753           return ;
1754
1755         o->created = EINA_TRUE;
1756         o->video_surface = 1;
1757         o->video = *surf;
1758
1759         obj->layer->evas->video_objects = eina_list_append(obj->layer->evas->video_objects, obj);
1760      }
1761    else
1762      {
1763         o->video_surface = 0;
1764         o->video.update_pixels = NULL;
1765         o->video.move = NULL;
1766         o->video.resize = NULL;
1767         o->video.hide = NULL;
1768         o->video.show = NULL;
1769         o->video.data = NULL;
1770      }
1771 }
1772
1773 EAPI const Evas_Video_Surface *
1774 evas_object_image_video_surface_get(const Evas_Object *obj)
1775 {
1776    Evas_Object_Image *o;
1777
1778    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1779    return NULL;
1780    MAGIC_CHECK_END();
1781    o = (Evas_Object_Image *)(obj->object_data);
1782    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1783    return NULL;
1784    MAGIC_CHECK_END();
1785    if (!o->video_surface) return NULL;
1786    return &o->video;
1787 }
1788
1789 EAPI void
1790 evas_object_image_native_surface_set(Evas_Object *obj, Evas_Native_Surface *surf)
1791 {
1792    Evas_Object_Image *o;
1793
1794    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1795    return;
1796    MAGIC_CHECK_END();
1797    o = (Evas_Object_Image *)(obj->object_data);
1798    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1799    return;
1800    MAGIC_CHECK_END();
1801    _evas_object_image_cleanup(obj, o);
1802    if (!obj->layer->evas->engine.func->image_native_set) return;
1803    if ((surf) &&
1804        ((surf->version < 2) ||
1805         (surf->version > EVAS_NATIVE_SURFACE_VERSION))) return;
1806    o->engine_data = 
1807       obj->layer->evas->engine.func->image_native_set(obj->layer->evas->engine.data.output,
1808                                                       o->engine_data,
1809                                                       surf);
1810 }
1811
1812 EAPI Evas_Native_Surface *
1813 evas_object_image_native_surface_get(const Evas_Object *obj)
1814 {
1815    Evas_Object_Image *o;
1816
1817    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1818    return NULL;
1819    MAGIC_CHECK_END();
1820    o = (Evas_Object_Image *)(obj->object_data);
1821    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1822    return NULL;
1823    MAGIC_CHECK_END();
1824    if (!obj->layer->evas->engine.func->image_native_get) return NULL;
1825    return obj->layer->evas->engine.func->image_native_get(obj->layer->evas->engine.data.output,
1826                                                           o->engine_data);
1827 }
1828
1829 EAPI void
1830 evas_object_image_scale_hint_set(Evas_Object *obj, Evas_Image_Scale_Hint hint)
1831 {
1832    Evas_Object_Image *o;
1833
1834    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1835    return;
1836    MAGIC_CHECK_END();
1837    o = (Evas_Object_Image *)(obj->object_data);
1838    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1839    return;
1840    MAGIC_CHECK_END();
1841    if (o->scale_hint == hint) return;
1842    o->scale_hint = hint;
1843    if (o->engine_data)
1844      {
1845         int stride = 0;
1846         
1847         if (obj->layer->evas->engine.func->image_scale_hint_set)
1848            obj->layer->evas->engine.func->image_scale_hint_set
1849            (obj->layer->evas->engine.data.output,
1850                o->engine_data, o->scale_hint);
1851         if (obj->layer->evas->engine.func->image_stride_get)
1852            obj->layer->evas->engine.func->image_stride_get
1853            (obj->layer->evas->engine.data.output,
1854                o->engine_data, &stride);
1855         else
1856            stride = o->cur.image.w * 4;
1857         o->cur.image.stride = stride;
1858      }
1859 }
1860
1861 EAPI Evas_Image_Scale_Hint
1862 evas_object_image_scale_hint_get(const Evas_Object *obj)
1863 {
1864    Evas_Object_Image *o;
1865
1866    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1867    return EVAS_IMAGE_SCALE_HINT_NONE;
1868    MAGIC_CHECK_END();
1869    o = (Evas_Object_Image *)(obj->object_data);
1870    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1871    return EVAS_IMAGE_SCALE_HINT_NONE;
1872    MAGIC_CHECK_END();
1873    return o->scale_hint;
1874 }
1875
1876 EAPI void
1877 evas_object_image_content_hint_set(Evas_Object *obj, Evas_Image_Content_Hint hint)
1878 {
1879    Evas_Object_Image *o;
1880
1881    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1882    return;
1883    MAGIC_CHECK_END();
1884    o = (Evas_Object_Image *)(obj->object_data);
1885    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1886    return;
1887    MAGIC_CHECK_END();
1888    if (o->content_hint == hint) return;
1889    o->content_hint = hint;
1890    if (o->engine_data)
1891      {
1892         int stride = 0;
1893         
1894         if (obj->layer->evas->engine.func->image_content_hint_set)
1895            obj->layer->evas->engine.func->image_content_hint_set
1896            (obj->layer->evas->engine.data.output,
1897                o->engine_data, o->content_hint);
1898         if (obj->layer->evas->engine.func->image_stride_get)
1899            obj->layer->evas->engine.func->image_stride_get
1900            (obj->layer->evas->engine.data.output,
1901                o->engine_data, &stride);
1902         else
1903            stride = o->cur.image.w * 4;
1904         o->cur.image.stride = stride;
1905      }
1906 }
1907
1908 EAPI void
1909 evas_object_image_alpha_mask_set(Evas_Object *obj, Eina_Bool ismask)
1910 {
1911    Evas_Object_Image *o;
1912
1913    if (!ismask) return;
1914
1915    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1916    return;
1917    MAGIC_CHECK_END();
1918    o = (Evas_Object_Image *)(obj->object_data);
1919    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1920    return;
1921    MAGIC_CHECK_END();
1922
1923    /* Convert to A8 if not already */
1924
1925    /* done */
1926
1927 }
1928
1929 #define FRAME_MAX 1024
1930 EAPI Evas_Image_Content_Hint
1931 evas_object_image_content_hint_get(const Evas_Object *obj)
1932 {
1933    Evas_Object_Image *o;
1934
1935    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1936    return EVAS_IMAGE_CONTENT_HINT_NONE;
1937    MAGIC_CHECK_END();
1938    o = (Evas_Object_Image *)(obj->object_data);
1939    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1940    return EVAS_IMAGE_CONTENT_HINT_NONE;
1941    MAGIC_CHECK_END();
1942    return o->content_hint;
1943 }
1944
1945 EAPI Eina_Bool
1946 evas_object_image_region_support_get(const Evas_Object *obj)
1947 {
1948    Evas_Object_Image *o;
1949
1950    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1951    return EINA_FALSE;
1952    MAGIC_CHECK_END();
1953    o = (Evas_Object_Image *) (obj->object_data);
1954    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1955    return EINA_FALSE;
1956    MAGIC_CHECK_END();
1957
1958    return obj->layer->evas->engine.func->image_can_region_get(
1959       obj->layer->evas->engine.data.output,
1960       o->engine_data);
1961 }
1962
1963 /* animated feature */
1964 EAPI Eina_Bool
1965 evas_object_image_animated_get(const Evas_Object *obj)
1966 {
1967    Evas_Object_Image *o;
1968
1969    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1970    return EINA_FALSE;
1971    MAGIC_CHECK_END();
1972    o = (Evas_Object_Image *)(obj->object_data);
1973    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1974    return EINA_FALSE;
1975    MAGIC_CHECK_END();
1976
1977    if (obj->layer->evas->engine.func->image_animated_get)
1978      return obj->layer->evas->engine.func->image_animated_get(obj->layer->evas->engine.data.output, o->engine_data);
1979    return EINA_FALSE;
1980 }
1981
1982 EAPI int
1983 evas_object_image_animated_frame_count_get(const Evas_Object *obj)
1984 {
1985    Evas_Object_Image *o;
1986
1987    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1988    return -1;
1989    MAGIC_CHECK_END();
1990    o = (Evas_Object_Image *)(obj->object_data);
1991    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1992    return -1;
1993    MAGIC_CHECK_END();
1994
1995    if (!evas_object_image_animated_get(obj)) return -1;
1996    if (obj->layer->evas->engine.func->image_animated_frame_count_get)
1997      return obj->layer->evas->engine.func->image_animated_frame_count_get(obj->layer->evas->engine.data.output, o->engine_data);
1998    return -1;
1999 }
2000
2001 EAPI Evas_Image_Animated_Loop_Hint
2002 evas_object_image_animated_loop_type_get(const Evas_Object *obj)
2003 {
2004    Evas_Object_Image *o;
2005
2006    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2007    return EVAS_IMAGE_ANIMATED_HINT_NONE;
2008    MAGIC_CHECK_END();
2009    o = (Evas_Object_Image *)(obj->object_data);
2010    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2011    return EVAS_IMAGE_ANIMATED_HINT_NONE;
2012    MAGIC_CHECK_END();
2013
2014    if (!evas_object_image_animated_get(obj)) return EVAS_IMAGE_ANIMATED_HINT_NONE;
2015
2016    if (obj->layer->evas->engine.func->image_animated_loop_type_get)
2017      return obj->layer->evas->engine.func->image_animated_loop_type_get(obj->layer->evas->engine.data.output, o->engine_data);
2018    return EVAS_IMAGE_ANIMATED_HINT_NONE;
2019 }
2020
2021 EAPI int
2022 evas_object_image_animated_loop_count_get(const Evas_Object *obj)
2023 {
2024    Evas_Object_Image *o;
2025
2026    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2027    return -1;
2028    MAGIC_CHECK_END();
2029    o = (Evas_Object_Image *)(obj->object_data);
2030    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2031    return -1;
2032    MAGIC_CHECK_END();
2033
2034    if (!evas_object_image_animated_get(obj)) return -1;
2035
2036    if (obj->layer->evas->engine.func->image_animated_loop_count_get)
2037      return obj->layer->evas->engine.func->image_animated_loop_count_get(obj->layer->evas->engine.data.output, o->engine_data);
2038    return -1;
2039 }
2040
2041 EAPI double
2042 evas_object_image_animated_frame_duration_get(const Evas_Object *obj, int start_frame, int frame_num)
2043 {
2044    Evas_Object_Image *o;
2045    int frame_count = 0;
2046
2047    if (start_frame < 1) return -1;
2048    if (frame_num < 0) return -1;
2049
2050    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2051    return -1;
2052    MAGIC_CHECK_END();
2053    o = (Evas_Object_Image *)(obj->object_data);
2054    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2055    return -1;
2056    MAGIC_CHECK_END();
2057
2058    if (!evas_object_image_animated_get(obj)) return -1;
2059
2060    if (!obj->layer->evas->engine.func->image_animated_frame_count_get) return -1;
2061
2062    frame_count = obj->layer->evas->engine.func->image_animated_frame_count_get(obj->layer->evas->engine.data.output, o->engine_data);
2063
2064    if ((start_frame + frame_num) > frame_count) return -1;
2065    if (obj->layer->evas->engine.func->image_animated_frame_duration_get)
2066      return obj->layer->evas->engine.func->image_animated_frame_duration_get(obj->layer->evas->engine.data.output, o->engine_data, start_frame, frame_num);
2067    return -1;
2068 }
2069
2070 EAPI void
2071 evas_object_image_animated_frame_set(Evas_Object *obj, int frame_index)
2072 {
2073    Evas_Object_Image *o;
2074    int frame_count = 0;
2075
2076    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2077    return;
2078    MAGIC_CHECK_END();
2079    o = (Evas_Object_Image *)(obj->object_data);
2080    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2081    return;
2082    MAGIC_CHECK_END();
2083
2084    if (!o->cur.file) return;
2085    if (o->cur.frame == frame_index) return;
2086
2087    if (!evas_object_image_animated_get(obj)) return;
2088
2089    frame_count = evas_object_image_animated_frame_count_get(obj);
2090
2091    /* limit the size of frame to FRAME_MAX */
2092    if ((frame_count > FRAME_MAX) || (frame_count < 0) || (frame_index > frame_count))
2093      return;
2094
2095    if (!obj->layer->evas->engine.func->image_animated_frame_set) return;
2096    if (!obj->layer->evas->engine.func->image_animated_frame_set(obj->layer->evas->engine.data.output, o->engine_data, frame_index))
2097      return;
2098
2099    o->prev.frame = o->cur.frame;
2100    o->cur.frame = frame_index;
2101
2102    o->changed = 1;
2103    evas_object_change(obj);
2104
2105 }
2106
2107 EAPI void
2108 evas_image_cache_flush(Evas *e)
2109 {
2110    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2111    return;
2112    MAGIC_CHECK_END();
2113
2114    e->engine.func->image_cache_flush(e->engine.data.output);
2115 }
2116
2117 EAPI void
2118 evas_image_cache_reload(Evas *e)
2119 {
2120    Evas_Layer *layer;
2121
2122    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2123    return;
2124    MAGIC_CHECK_END();
2125
2126    evas_image_cache_flush(e);
2127    EINA_INLIST_FOREACH(e->layers, layer)
2128      {
2129         Evas_Object *obj;
2130
2131         EINA_INLIST_FOREACH(layer->objects, obj)
2132           {
2133              Evas_Object_Image *o;
2134
2135              o = (Evas_Object_Image *)(obj->object_data);
2136              if (o->magic == MAGIC_OBJ_IMAGE)
2137                {
2138                   evas_object_image_unload(obj, 1);
2139                   evas_object_inform_call_image_unloaded(obj);
2140                }
2141           }
2142      }
2143    evas_image_cache_flush(e);
2144    EINA_INLIST_FOREACH(e->layers, layer)
2145      {
2146         Evas_Object *obj;
2147
2148         EINA_INLIST_FOREACH(layer->objects, obj)
2149           {
2150              Evas_Object_Image *o;
2151
2152              o = (Evas_Object_Image *)(obj->object_data);
2153              if (o->magic == MAGIC_OBJ_IMAGE)
2154                {
2155                   evas_object_image_load(obj);
2156                   o->changed = 1;
2157                   evas_object_change(obj);
2158                }
2159           }
2160      }
2161    evas_image_cache_flush(e);
2162 }
2163
2164 EAPI void
2165 evas_image_cache_set(Evas *e, int size)
2166 {
2167    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2168    return;
2169    MAGIC_CHECK_END();
2170
2171    if (size < 0) size = 0;
2172    e->engine.func->image_cache_set(e->engine.data.output, size);
2173 }
2174
2175 EAPI int
2176 evas_image_cache_get(const Evas *e)
2177 {
2178    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2179    return 0;
2180    MAGIC_CHECK_END();
2181
2182    return e->engine.func->image_cache_get(e->engine.data.output);
2183 }
2184
2185 EAPI Eina_Bool
2186 evas_image_max_size_get(const Evas *e, int *maxw, int *maxh)
2187 {
2188    int w = 0, h = 0;
2189    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2190    return EINA_FALSE;
2191    MAGIC_CHECK_END();
2192    
2193    if (maxw) *maxw = 0xffff;
2194    if (maxh) *maxh = 0xffff;
2195    if (!e->engine.func->image_max_size_get) return EINA_FALSE;
2196    e->engine.func->image_max_size_get(e->engine.data.output, &w, &h);
2197    if (maxw) *maxw = w;
2198    if (maxh) *maxh = h;
2199    return EINA_TRUE;
2200 }
2201
2202 /* all nice and private */
2203 static void
2204 _proxy_unset(Evas_Object *proxy)
2205 {
2206    Evas_Object_Image *o;
2207
2208    o = proxy->object_data;
2209    if (!o->cur.source) return;
2210
2211    o->cur.source->proxy.proxies = eina_list_remove(o->cur.source->proxy.proxies, proxy);
2212
2213    o->cur.source = NULL;
2214    if (o->cur.defmap)
2215      {
2216         evas_map_free(o->cur.defmap);
2217         o->cur.defmap = NULL;
2218      }
2219 }
2220
2221
2222 static void
2223 _proxy_set(Evas_Object *proxy, Evas_Object *src)
2224 {
2225    Evas_Object_Image *o;
2226
2227    o = proxy->object_data;
2228
2229    evas_object_image_file_set(proxy, NULL, NULL);
2230
2231    o->cur.source = src;
2232    o->load_error = EVAS_LOAD_ERROR_NONE;
2233
2234    src->proxy.proxies = eina_list_append(src->proxy.proxies, proxy);
2235    src->proxy.redraw = EINA_TRUE;
2236 }
2237
2238 /* Some moron just set a proxy on a proxy.
2239  * Give them some pixels.  A random color
2240  */
2241 static void
2242 _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface,
2243              int x, int y)
2244 {
2245    Evas_Func *func;
2246    int r = rand() % 255;
2247    int g = rand() % 255;
2248    int b = rand() % 255;
2249    
2250    /* XXX: Eina log error or something I'm sure
2251     * If it bugs you, just fix it.  Don't tell me */
2252    if (VERBOSE_PROXY_ERROR) printf("Err: Argh! Recursive proxies.\n");
2253    
2254    func = proxy->layer->evas->engine.func;
2255    func->context_color_set(output, context, r, g, b, 255);
2256    func->context_multiplier_unset(output, context);
2257    func->context_render_op_set(output, context, proxy->cur.render_op);
2258    func->rectangle_draw(output, context, surface, proxy->cur.geometry.x + x,
2259                         proxy->cur.geometry.y + y,
2260                         proxy->cur.geometry.w,
2261                         proxy->cur.geometry.h);
2262    return;
2263 }
2264
2265 /*
2266 static void
2267 _proxy_subrender_recurse(Evas_Object *obj, Evas_Object *clip, void *output, void *surface, void *ctx, int x, int y)
2268 {
2269    Evas_Object *obj2;
2270    Evas *e = obj->layer->evas;
2271    
2272    if (obj->clip.clipees) return;
2273    if (!obj->cur.visible) return;
2274    if ((!clip) || (clip != obj->cur.clipper))
2275      {
2276         if (!obj->cur.cache.clip.visible) return;
2277         if ((obj->cur.cache.clip.a == 0) &&
2278             (obj->cur.render_op == EVAS_RENDER_BLEND)) return;
2279      }
2280    if ((obj->func->is_visible) && (!obj->func->is_visible(obj))) return;
2281    
2282    if (!obj->pre_render_done)
2283       obj->func->render_pre(obj);
2284    ctx = e->engine.func->context_new(output);
2285    if (obj->smart.smart)
2286      {
2287         EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
2288           {
2289              _proxy_subrender_recurse(obj2, clip, output, surface, ctx, x, y);
2290           }
2291      }
2292    else
2293      {
2294         obj->func->render(obj, output, ctx, surface, x, y);
2295      }
2296    e->engine.func->context_free(output, ctx);
2297 }
2298 */
2299
2300 /**
2301  * Render the source object when a proxy is set.
2302  *
2303  * Used to force a draw if necessary, else just makes sures it's available.
2304  */
2305 static void
2306 _proxy_subrender(Evas *e, Evas_Object *source)
2307 {
2308    void *ctx;
2309 /*   Evas_Object *obj2, *clip;*/
2310    int w, h;
2311
2312    if (!source) return;
2313
2314    w = source->cur.geometry.w;
2315    h = source->cur.geometry.h;
2316
2317    source->proxy.redraw = EINA_FALSE;
2318
2319    /* We need to redraw surface then */
2320    if ((source->proxy.surface) && 
2321        ((source->proxy.w != w) || (source->proxy.h != h)))
2322      {
2323         e->engine.func->image_map_surface_free(e->engine.data.output,
2324                                                source->proxy.surface);
2325         source->proxy.surface = NULL;
2326      }
2327    
2328    /* FIXME: Hardcoded alpha 'on' */
2329    /* FIXME (cont): Should see if the object has alpha */
2330    if (!source->proxy.surface)
2331      {
2332         source->proxy.surface = e->engine.func->image_map_surface_new
2333            (e->engine.data.output, w, h, 1);
2334         source->proxy.w = w;
2335         source->proxy.h = h;
2336      }
2337
2338    ctx = e->engine.func->context_new(e->engine.data.output);
2339    e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 0, 0, 0);
2340    e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY);
2341    e->engine.func->rectangle_draw(e->engine.data.output, ctx,
2342                                   source->proxy.surface, 0, 0, w, h);
2343    e->engine.func->context_free(e->engine.data.output, ctx);
2344    
2345    ctx = e->engine.func->context_new(e->engine.data.output);
2346    evas_render_mapped(e, source, ctx, source->proxy.surface,
2347                       -source->cur.geometry.x,
2348                       -source->cur.geometry.y,
2349                       1, 0, 0, e->output.w, e->output.h);
2350    e->engine.func->context_free(e->engine.data.output, ctx);
2351    source->proxy.surface = e->engine.func->image_dirty_region
2352       (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
2353 /*   
2354    ctx = e->engine.func->context_new(e->engine.data.output);
2355    if (source->smart.smart)
2356      {
2357         clip = evas_object_smart_clipped_clipper_get(source);
2358         EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(source), obj2)
2359           {
2360              _proxy_subrender_recurse(obj2, clip, e->engine.data.output,
2361                                       source->proxy.surface,
2362                                       ctx,
2363                                       -source->cur.geometry.x,
2364                                       -source->cur.geometry.y);
2365           }
2366      }
2367    else
2368      {
2369         if (!source->pre_render_done)
2370            source->func->render_pre(source);
2371         source->func->render(source, e->engine.data.output, ctx,
2372                              source->proxy.surface,
2373                              -source->cur.geometry.x,
2374                              -source->cur.geometry.y);
2375      }
2376    
2377    e->engine.func->context_free(e->engine.data.output, ctx);
2378    source->proxy.surface = e->engine.func->image_dirty_region
2379       (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
2380  */
2381 }
2382
2383 #if 0 // filtering disabled
2384 /*
2385  *
2386  * Note that this is similar to proxy_subrender_recurse.  It should be
2387  * possible to merge I guess
2388  */
2389 static void
2390 image_filter_draw_under_recurse(Evas *e, Evas_Object *obj, Evas_Object *stop,
2391                                 void *output, void *ctx, void *surface,
2392                                 int x, int y)
2393 {
2394    Evas_Object *obj2;
2395    
2396    if (obj->clip.clipees) return;
2397    /* FIXME: Doing bounding box test */
2398    if (!evas_object_is_in_output_rect(obj, stop->cur.geometry.x,
2399                                       stop->cur.geometry.y,
2400                                       stop->cur.geometry.w,
2401                                       stop->cur.geometry.h))
2402       return;
2403    
2404    if (!evas_object_is_visible(obj)) return;
2405    obj->pre_render_done = 1;
2406    ctx = e->engine.func->context_new(output);
2407    
2408    if (obj->smart.smart)
2409      {
2410         EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
2411           {
2412              if (obj2 == stop) return;
2413              image_filter_draw_under_recurse(e, obj2, stop, output, surface, 
2414                                              ctx, x, y);
2415           }
2416      }
2417    else
2418       obj->func->render(obj, output, ctx, surface, x ,y);
2419    e->engine.func->context_free(output, ctx);
2420 }
2421
2422 /*
2423  * Draw all visible objects intersecting an object which are _beneath_ it.
2424  */
2425 static void
2426 image_filter_draw_under(Evas *e, Evas_Object *stop, void *output, void *ctx, void *surface, int dx, int dy)
2427 {
2428    Evas_Layer *lay;
2429    int x, y;
2430    
2431    x = stop->cur.geometry.x - dx;
2432    y = stop->cur.geometry.y - dy;
2433    
2434    EINA_INLIST_FOREACH(e->layers, lay)
2435      {
2436         Evas_Object *obj;
2437         EINA_INLIST_FOREACH(lay->objects, obj)
2438           {
2439              if (obj->delete_me) continue;
2440              if (obj == stop) return;
2441              /* FIXME: Do bounding box check */
2442              image_filter_draw_under_recurse(e, obj, stop, output, ctx, 
2443                                              surface, -x, -y);
2444           }
2445      }
2446    e->engine.func->image_dirty_region(output, surface, 0, 0, 300, 300);
2447    e->engine.func->output_flush(output);
2448 }
2449
2450 /*
2451  * Update the filtered object.
2452  *
2453  * Creates a new context, and renders stuff (filtered) onto that.
2454  */
2455 Filtered_Image *
2456 image_filter_update(Evas *e, Evas_Object *obj, void *src, int imagew, int imageh, int *outw, int *outh)
2457 {
2458    int w, h;
2459    void *ctx;
2460    Evas_Filter_Info *info;
2461    void *surface;
2462    Eina_Bool alpha;
2463    
2464    info = obj->filter;
2465    
2466    if (info->mode == EVAS_FILTER_MODE_BELOW)
2467      {
2468         w = obj->cur.geometry.w;
2469         h = obj->cur.geometry.h;
2470         evas_filter_get_size(info, w, h, &imagew, &imageh, EINA_TRUE);
2471         alpha = EINA_FALSE;
2472      }
2473    else
2474      {
2475         evas_filter_get_size(info, imagew, imageh, &w, &h, EINA_FALSE);
2476         alpha = e->engine.func->image_alpha_get(e->engine.data.output, src);
2477      }
2478    
2479    /* Certain filters may make alpha images anyway */
2480    if (alpha == EINA_FALSE) alpha = evas_filter_always_alpha(info);
2481    
2482    surface = e->engine.func->image_map_surface_new(e->engine.data.output, w, h,
2483                                                    alpha);
2484    
2485    if (info->mode == EVAS_FILTER_MODE_BELOW)
2486      {
2487         void *subsurface;
2488         int disw, dish;
2489         int dx, dy;
2490         disw = obj->cur.geometry.w;
2491         dish = obj->cur.geometry.h;
2492         dx = (imagew - w) >> 1;
2493         dy = (imageh - h) >> 1;
2494         subsurface = e->engine.func->image_map_surface_new
2495            (e->engine.data.output, imagew, imageh, 1);
2496         ctx = e->engine.func->context_new(e->engine.data.output);
2497         e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 255, 0, 255);
2498         e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY);
2499         e->engine.func->rectangle_draw(e->engine.data.output, ctx,
2500                                        subsurface, 0, 0, imagew, imageh);
2501         
2502         image_filter_draw_under(e, obj, e->engine.data.output, ctx,
2503                                 subsurface, dx, dy);
2504         
2505         e->engine.func->context_free(e->engine.data.output, ctx);
2506         
2507         ctx = e->engine.func->context_new(e->engine.data.output);
2508         
2509         e->engine.func->image_draw_filtered(e->engine.data.output,
2510                                             ctx, surface, subsurface, info);
2511         
2512         e->engine.func->context_free(e->engine.data.output, ctx);
2513         
2514         e->engine.func->image_map_surface_free(e->engine.data.output,
2515                                                subsurface);
2516      }
2517    else
2518      {
2519         ctx = e->engine.func->context_new(e->engine.data.output);
2520         e->engine.func->image_draw_filtered(e->engine.data.output,
2521                                             ctx, surface, src, info);
2522         e->engine.func->context_free(e->engine.data.output, ctx);
2523      }
2524    
2525    e->engine.func->image_dirty_region(e->engine.data.output, surface, 
2526                                       0, 0, w, h);
2527    if (outw) *outw = w;
2528    if (outh) *outh = h;
2529    return e->engine.func->image_filtered_save(src, surface,
2530                                               obj->filter->key,
2531                                               obj->filter->len);
2532 }
2533 #endif
2534
2535 static void
2536 evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty)
2537 {
2538    Evas_Object_Image *o;
2539    
2540    o = (Evas_Object_Image *)(obj->object_data);
2541    
2542    if ((!o->cur.file) ||
2543        (o->pixels_checked_out > 0)) return;
2544    if (dirty)
2545      {
2546         if (o->engine_data)
2547            o->engine_data = obj->layer->evas->engine.func->image_dirty_region
2548            (obj->layer->evas->engine.data.output,
2549                o->engine_data,
2550                0, 0,
2551                o->cur.image.w, o->cur.image.h);
2552      }
2553    if (o->engine_data)
2554      {
2555         if (o->preloading)
2556           {
2557              o->preloading = 0;
2558              obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
2559                                                                       o->engine_data,
2560                                                                       obj);
2561           }
2562         obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
2563                                                   o->engine_data);
2564      }
2565    o->engine_data = NULL;
2566    o->load_error = EVAS_LOAD_ERROR_NONE;
2567    o->cur.has_alpha = 1;
2568    o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
2569    o->cur.image.w = 0;
2570    o->cur.image.h = 0;
2571    o->cur.image.stride = 0;
2572 }
2573
2574 static void
2575 evas_object_image_load(Evas_Object *obj)
2576 {
2577    Evas_Object_Image *o;
2578    Evas_Image_Load_Opts lo;
2579
2580    o = (Evas_Object_Image *)(obj->object_data);
2581    if (o->engine_data) return;
2582
2583    lo.scale_down_by = o->load_opts.scale_down_by;
2584    lo.dpi = o->load_opts.dpi;
2585    lo.w = o->load_opts.w;
2586    lo.h = o->load_opts.h;
2587    lo.region.x = o->load_opts.region.x;
2588    lo.region.y = o->load_opts.region.y;
2589    lo.region.w = o->load_opts.region.w;
2590    lo.region.h = o->load_opts.region.h;
2591    lo.orientation = o->load_opts.orientation;
2592    o->engine_data = obj->layer->evas->engine.func->image_load
2593       (obj->layer->evas->engine.data.output,
2594           o->cur.file,
2595           o->cur.key,
2596           &o->load_error,
2597           &lo);
2598    if (o->engine_data)
2599      {
2600         int w, h;
2601         int stride = 0;
2602
2603         obj->layer->evas->engine.func->image_size_get
2604            (obj->layer->evas->engine.data.output,
2605                o->engine_data, &w, &h);
2606         if (obj->layer->evas->engine.func->image_stride_get)
2607           obj->layer->evas->engine.func->image_stride_get
2608            (obj->layer->evas->engine.data.output,
2609                o->engine_data, &stride);
2610         else
2611           stride = w * 4;
2612         o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get
2613            (obj->layer->evas->engine.data.output,
2614                o->engine_data);
2615         o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get
2616            (obj->layer->evas->engine.data.output,
2617                o->engine_data);
2618         o->cur.image.w = w;
2619         o->cur.image.h = h;
2620         o->cur.image.stride = stride;
2621      }
2622    else
2623      {
2624         o->load_error = EVAS_LOAD_ERROR_GENERIC;
2625      }
2626 }
2627
2628 static Evas_Coord
2629 evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
2630 {
2631    Evas_Coord w;
2632
2633    w = ((size * obj->layer->evas->output.w) /
2634         (Evas_Coord)obj->layer->evas->viewport.w);
2635    if (size <= 0) size = 1;
2636    if (start > 0)
2637      {
2638         while (start - size > 0) start -= size;
2639      }
2640    else if (start < 0)
2641      {
2642         while (start < 0) start += size;
2643      }
2644    start = ((start * obj->layer->evas->output.w) /
2645             (Evas_Coord)obj->layer->evas->viewport.w);
2646    *size_ret = w;
2647    return start;
2648 }
2649
2650 static Evas_Coord
2651 evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
2652 {
2653    Evas_Coord h;
2654
2655    h = ((size * obj->layer->evas->output.h) /
2656         (Evas_Coord)obj->layer->evas->viewport.h);
2657    if (size <= 0) size = 1;
2658    if (start > 0)
2659      {
2660         while (start - size > 0) start -= size;
2661      }
2662    else if (start < 0)
2663      {
2664         while (start < 0) start += size;
2665      }
2666    start = ((start * obj->layer->evas->output.h) /
2667             (Evas_Coord)obj->layer->evas->viewport.h);
2668    *size_ret = h;
2669    return start;
2670 }
2671
2672 static void
2673 evas_object_image_init(Evas_Object *obj)
2674 {
2675    /* alloc image ob, setup methods and default values */
2676    obj->object_data = evas_object_image_new();
2677    /* set up default settings for this kind of object */
2678    obj->cur.color.r = 255;
2679    obj->cur.color.g = 255;
2680    obj->cur.color.b = 255;
2681    obj->cur.color.a = 255;
2682    obj->cur.geometry.x = 0;
2683    obj->cur.geometry.y = 0;
2684    obj->cur.geometry.w = 0;
2685    obj->cur.geometry.h = 0;
2686    obj->cur.layer = 0;
2687    obj->cur.anti_alias = 0;
2688    obj->cur.render_op = EVAS_RENDER_BLEND;
2689    /* set up object-specific settings */
2690    obj->prev = obj->cur;
2691    /* set up methods (compulsory) */
2692    obj->func = &object_func;
2693    obj->type = o_type;
2694 }
2695
2696 static void *
2697 evas_object_image_new(void)
2698 {
2699    Evas_Object_Image *o;
2700
2701    /* alloc obj private data */
2702    EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_image", Evas_Object_Image, 16, NULL);
2703    o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Image);
2704    if (!o) return NULL;
2705    EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Image);
2706    o->magic = MAGIC_OBJ_IMAGE;
2707    o->cur.fill.w = 0;
2708    o->cur.fill.h = 0;
2709    o->cur.smooth_scale = 1;
2710    o->cur.border.fill = 1;
2711    o->cur.border.scale = 1.0;
2712    o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
2713    o->cur.spread = EVAS_TEXTURE_REPEAT;
2714    o->cur.opaque_valid = 0;
2715    o->cur.source = NULL;
2716    o->prev = o->cur;
2717    o->tmpf_fd = -1;
2718    return o;
2719 }
2720
2721 static void
2722 evas_object_image_free(Evas_Object *obj)
2723 {
2724    Evas_Object_Image *o;
2725    Eina_Rectangle *r;
2726
2727    /* frees private object data. very simple here */
2728    o = (Evas_Object_Image *)(obj->object_data);
2729    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2730    return;
2731    MAGIC_CHECK_END();
2732    /* free obj */
2733    _cleanup_tmpf(obj);
2734    if (o->cur.file) eina_stringshare_del(o->cur.file);
2735    if (o->cur.key) eina_stringshare_del(o->cur.key);
2736    if (o->cur.source) _proxy_unset(obj);
2737    if (o->engine_data)
2738      {
2739         if (o->preloading)
2740           {
2741              o->preloading = 0;
2742              obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
2743                                                                       o->engine_data,
2744                                                                       obj);
2745           }
2746         obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
2747                                                   o->engine_data);
2748      }
2749    if (o->video_surface)
2750      {
2751         o->video_surface = 0;
2752         obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
2753      }
2754    o->engine_data = NULL;
2755    o->magic = 0;
2756    EINA_LIST_FREE(o->pixel_updates, r)
2757      eina_rectangle_free(r);
2758    EVAS_MEMPOOL_FREE(_mp_obj, o);
2759 }
2760
2761 static void
2762 evas_object_image_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
2763 {
2764    Evas_Object_Image *o;
2765    int imagew, imageh, uvw, uvh;
2766    void *pixels;
2767
2768    /* render object to surface with context, and offset by x,y */
2769    o = (Evas_Object_Image *)(obj->object_data);
2770
2771    if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
2772      return; /* no error message, already printed in pre_render */
2773
2774    /* Proxy sanity */
2775    if (o->proxyrendering)
2776      {
2777         _proxy_error(obj, context, output, surface, x, y);
2778         return;
2779      }
2780
2781    /* We are displaying the overlay */
2782    if (o->video_visible)
2783      {
2784         /* Create a transparent rectangle */
2785         obj->layer->evas->engine.func->context_color_set(output,
2786                                                          context,
2787                                                          0, 0, 0, 0);
2788         obj->layer->evas->engine.func->context_multiplier_unset(output,
2789                                                                 context);
2790         obj->layer->evas->engine.func->context_render_op_set(output, context,
2791                                                              EVAS_RENDER_COPY);
2792         obj->layer->evas->engine.func->rectangle_draw(output,
2793                                                       context,
2794                                                       surface,
2795                                                       obj->cur.geometry.x + x,
2796                                                       obj->cur.geometry.y + y,
2797                                                       obj->cur.geometry.w,
2798                                                       obj->cur.geometry.h);
2799
2800         return ;
2801      }
2802
2803    obj->layer->evas->engine.func->context_color_set(output,
2804                                                     context,
2805                                                     255, 255, 255, 255);
2806
2807    if ((obj->cur.cache.clip.r == 255) &&
2808        (obj->cur.cache.clip.g == 255) &&
2809        (obj->cur.cache.clip.b == 255) &&
2810        (obj->cur.cache.clip.a == 255))
2811      {
2812         obj->layer->evas->engine.func->context_multiplier_unset(output,
2813                                                                 context);
2814      }
2815    else
2816      obj->layer->evas->engine.func->context_multiplier_set(output,
2817                                                            context,
2818                                                            obj->cur.cache.clip.r,
2819                                                            obj->cur.cache.clip.g,
2820                                                            obj->cur.cache.clip.b,
2821                                                            obj->cur.cache.clip.a);
2822
2823    obj->layer->evas->engine.func->context_render_op_set(output, context,
2824                                                         obj->cur.render_op);
2825
2826    if (!o->cur.source)
2827      {
2828         pixels = o->engine_data;
2829         imagew = o->cur.image.w;
2830         imageh = o->cur.image.h;
2831         uvw = imagew;
2832         uvh = imageh;
2833      }
2834    else if (o->cur.source->proxy.surface && !o->cur.source->proxy.redraw)
2835      {
2836         pixels = o->cur.source->proxy.surface;
2837         imagew = o->cur.source->proxy.w;
2838         imageh = o->cur.source->proxy.h;
2839         uvw = imagew;
2840         uvh = imageh;
2841      }
2842    else if (o->cur.source->type == o_type &&
2843             ((Evas_Object_Image *)o->cur.source->object_data)->engine_data)
2844      {
2845         Evas_Object_Image *oi;
2846         oi = o->cur.source->object_data;
2847         pixels = oi->engine_data;
2848         imagew = oi->cur.image.w;
2849         imageh = oi->cur.image.h;
2850         uvw = o->cur.source->cur.geometry.w;
2851         uvh = o->cur.source->cur.geometry.h;
2852      }
2853    else
2854      {
2855         o->proxyrendering = 1;
2856         _proxy_subrender(obj->layer->evas, o->cur.source);
2857         pixels = o->cur.source->proxy.surface;
2858         imagew = o->cur.source->proxy.w;
2859         imageh = o->cur.source->proxy.h;
2860         uvw = imagew;
2861         uvh = imageh;
2862         o->proxyrendering = 0;
2863      }
2864
2865 #if 0 // filtering disabled
2866    /* Now check/update filter */
2867    if (obj->filter && obj->filter->filter)
2868      {
2869         Filtered_Image *fi = NULL;
2870         //printf("%p has filter: %s\n", obj,obj->filter->dirty?"dirty":"clean");
2871         if (obj->filter->dirty)
2872           {
2873              if (obj->filter->mode != EVAS_FILTER_MODE_BELOW)
2874                {
2875                   uint32_t len;
2876                   uint8_t *key;
2877                   
2878                   if (obj->filter->key) free(obj->filter->key);
2879                   obj->filter->key = NULL;
2880                   obj->filter->len = 0;
2881                   key = evas_filter_key_get(obj->filter, &len);
2882                   if (key)
2883                     {
2884                        obj->filter->key = key;
2885                        obj->filter->len = len;
2886                        fi = obj->layer->evas->engine.func->image_filtered_get
2887                           (o->engine_data, key, len);
2888                        if (obj->filter->cached && fi != obj->filter->cached)
2889                          {
2890                             obj->layer->evas->engine.func->image_filtered_free
2891                                (o->engine_data, obj->filter->cached);
2892                             obj->filter->cached = NULL;
2893                          }
2894                     }
2895                }
2896              else if (obj->filter->cached)
2897                {
2898                   obj->layer->evas->engine.func->image_filtered_free
2899                      (o->engine_data, obj->filter->cached);
2900                }
2901              if (!fi)
2902                 fi = image_filter_update(obj->layer->evas, obj, pixels, 
2903                                          imagew, imageh, &imagew, &imageh);
2904              pixels = fi->image;
2905              obj->filter->dirty = 0;
2906              obj->filter->cached = fi;
2907           }
2908         else
2909           {
2910              fi = obj->filter->cached;
2911              pixels = fi->image;
2912           }
2913      }
2914 #endif
2915    
2916    if (pixels)
2917      {
2918         Evas_Coord idw, idh, idx, idy;
2919         int ix, iy, iw, ih;
2920         int img_set = 0;
2921
2922         if (o->dirty_pixels)
2923           {
2924              if (o->func.get_pixels)
2925                {
2926                   // Set img object for direct rendering optimization
2927                   // Check for image w/h against image geometry w/h
2928                   // Check for image color r,g,b,a = {255,255,255,255}
2929                   // Check and make sure that there are no maps.
2930                   if ( (obj->cur.geometry.w == o->cur.image.w) &&
2931                        (obj->cur.geometry.h == o->cur.image.h) &&
2932                        (obj->cur.color.r == 255) &&
2933                        (obj->cur.color.g == 255) &&
2934                        (obj->cur.color.b == 255) &&
2935                        (obj->cur.color.a == 255) && 
2936                        (!obj->cur.map) )
2937                     {
2938                        if (obj->layer->evas->engine.func->gl_img_obj_set)
2939                          {
2940                             obj->layer->evas->engine.func->gl_img_obj_set(output, obj, o->cur.has_alpha);
2941                             img_set = 1;
2942                          }
2943                     }
2944
2945                   o->func.get_pixels(o->func.get_pixels_data, obj);
2946                   if (o->engine_data != pixels)
2947                     pixels = o->engine_data;
2948                   o->engine_data = obj->layer->evas->engine.func->image_dirty_region
2949                      (obj->layer->evas->engine.data.output, o->engine_data,
2950                          0, 0, o->cur.image.w, o->cur.image.h);
2951                }
2952              o->dirty_pixels = 0;
2953           }
2954         if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))
2955           {
2956              evas_object_map_update(obj, x, y, imagew, imageh, uvw, uvh);
2957
2958              obj->layer->evas->engine.func->image_map_draw
2959                (output, context, surface, pixels, obj->spans,
2960                 o->cur.smooth_scale | obj->cur.map->smooth, 0);
2961           }
2962         else
2963           {
2964              obj->layer->evas->engine.func->image_scale_hint_set(output,
2965                                                                  pixels,
2966                                                                  o->scale_hint);
2967              /* This is technically a bug here: If the value is recreated
2968               * (which is returned)it may be a new object, however exactly 0
2969               * of all the evas engines do this. */
2970              obj->layer->evas->engine.func->image_border_set(output, pixels,
2971                                                              o->cur.border.l, o->cur.border.r,
2972                                                              o->cur.border.t, o->cur.border.b);
2973              idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
2974              idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
2975              if (idw < 1) idw = 1;
2976              if (idh < 1) idh = 1;
2977              if (idx > 0) idx -= idw;
2978              if (idy > 0) idy -= idh;
2979              while ((int)idx < obj->cur.geometry.w)
2980                {
2981                   Evas_Coord ydy;
2982                   int dobreak_w = 0;
2983                   
2984                   ydy = idy;
2985                   ix = idx;
2986                   if ((o->cur.fill.w == obj->cur.geometry.w) &&
2987                       (o->cur.fill.x == 0))
2988                     {
2989                        dobreak_w = 1;
2990                        iw = obj->cur.geometry.w;
2991                     }
2992                   else
2993                     iw = ((int)(idx + idw)) - ix;
2994                   while ((int)idy < obj->cur.geometry.h)
2995                     {
2996                        int dobreak_h = 0;
2997                        
2998                        iy = idy;
2999                        if ((o->cur.fill.h == obj->cur.geometry.h) &&
3000                            (o->cur.fill.y == 0))
3001                          {
3002                             ih = obj->cur.geometry.h;
3003                             dobreak_h = 1;
3004                          }
3005                        else
3006                          ih = ((int)(idy + idh)) - iy;
3007                        if ((o->cur.border.l == 0) &&
3008                            (o->cur.border.r == 0) &&
3009                            (o->cur.border.t == 0) &&
3010                            (o->cur.border.b == 0) &&
3011                            (o->cur.border.fill != 0))
3012                          obj->layer->evas->engine.func->image_draw(output,
3013                                                                    context,
3014                                                                    surface,
3015                                                                    pixels,
3016                                                                    0, 0,
3017                                                                    imagew,
3018                                                                    imageh,
3019                                                                    obj->cur.geometry.x + ix + x,
3020                                                                    obj->cur.geometry.y + iy + y,
3021                                                                    iw, ih,
3022                                                                    o->cur.smooth_scale);
3023                        else
3024                          {
3025                             int inx, iny, inw, inh, outx, outy, outw, outh;
3026                             int bl, br, bt, bb, bsl, bsr, bst, bsb;
3027                             int imw, imh, ox, oy;
3028                             
3029                             ox = obj->cur.geometry.x + ix + x;
3030                             oy = obj->cur.geometry.y + iy + y;
3031                             imw = imagew;
3032                             imh = imageh;
3033                             bl = o->cur.border.l;
3034                             br = o->cur.border.r;
3035                             bt = o->cur.border.t;
3036                             bb = o->cur.border.b;
3037                             if ((bl + br) > iw)
3038                               {
3039                                  bl = iw / 2;
3040                                  br = iw - bl;
3041                               }
3042                             if ((bl + br) > imw)
3043                               {
3044                                  bl = imw / 2;
3045                                  br = imw - bl;
3046                               }
3047                             if ((bt + bb) > ih)
3048                               {
3049                                  bt = ih / 2;
3050                                  bb = ih - bt;
3051                               }
3052                             if ((bt + bb) > imh)
3053                               {
3054                                  bt = imh / 2;
3055                                  bb = imh - bt;
3056                               }
3057                             if (o->cur.border.scale != 1.0)
3058                               {
3059                                  bsl = ((double)bl * o->cur.border.scale);
3060                                  bsr = ((double)br * o->cur.border.scale);
3061                                  bst = ((double)bt * o->cur.border.scale);
3062                                  bsb = ((double)bb * o->cur.border.scale);
3063                               }
3064                             else
3065                               {
3066                                   bsl = bl; bsr = br; bst = bt; bsb = bb;
3067                               }
3068                             // #--
3069                             // |
3070                             inx = 0; iny = 0;
3071                             inw = bl; inh = bt;
3072                             outx = ox; outy = oy;
3073                             outw = bsl; outh = bst;
3074                             obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3075                             // .##
3076                             // |
3077                             inx = bl; iny = 0;
3078                             inw = imw - bl - br; inh = bt;
3079                             outx = ox + bsl; outy = oy;
3080                             outw = iw - bsl - bsr; outh = bst;
3081                             obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3082                             // --#
3083                             //   |
3084                             inx = imw - br; iny = 0;
3085                             inw = br; inh = bt;
3086                             outx = ox + iw - bsr; outy = oy;
3087                             outw = bsr; outh = bst;
3088                             obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3089                             // .--
3090                             // #  
3091                             inx = 0; iny = bt;
3092                             inw = bl; inh = imh - bt - bb;
3093                             outx = ox; outy = oy + bst;
3094                             outw = bsl; outh = ih - bst - bsb;
3095                             obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3096                             // .--.
3097                             // |##|
3098                             if (o->cur.border.fill > EVAS_BORDER_FILL_NONE)
3099                               {
3100                                  inx = bl; iny = bt;
3101                                  inw = imw - bl - br; inh = imh - bt - bb;
3102                                  outx = ox + bsl; outy = oy + bst;
3103                                  outw = iw - bsl - bsr; outh = ih - bst - bsb;
3104                                  if ((o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
3105                                      (obj->cur.cache.clip.a == 255) &&
3106                                      (obj->cur.render_op == EVAS_RENDER_BLEND))
3107                                    {
3108                                       obj->layer->evas->engine.func->context_render_op_set(output, context,
3109                                                                                            EVAS_RENDER_COPY);
3110                                       obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3111                                       obj->layer->evas->engine.func->context_render_op_set(output, context,
3112                                                                                            obj->cur.render_op);
3113                                    }
3114                                  else
3115                                    obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3116                               }
3117                             // --.
3118                             //   #
3119                             inx = imw - br; iny = bt;
3120                             inw = br; inh = imh - bt - bb;
3121                             outx = ox + iw - bsr; outy = oy + bst;
3122                             outw = bsr; outh = ih - bst - bsb;
3123                             obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3124                             // |
3125                             // #--
3126                             inx = 0; iny = imh - bb;
3127                             inw = bl; inh = bb;
3128                             outx = ox; outy = oy + ih - bsb;
3129                             outw = bsl; outh = bsb;
3130                             obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3131                             // |
3132                             // .## 
3133                             inx = bl; iny = imh - bb;
3134                             inw = imw - bl - br; inh = bb;
3135                             outx = ox + bsl; outy = oy + ih - bsb;
3136                             outw = iw - bsl - bsr; outh = bsb;
3137                             obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3138                             //   |
3139                             // --#
3140                             inx = imw - br; iny = imh - bb;
3141                             inw = br; inh = bb;
3142                             outx = ox + iw - bsr; outy = oy + ih - bsb;
3143                             outw = bsr; outh = bsb;
3144                             obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3145                          }
3146                        idy += idh;
3147                        if (dobreak_h) break;
3148                     }
3149                   idx += idw;
3150                   idy = ydy;
3151                   if (dobreak_w) break;
3152                }
3153           }
3154
3155         // Unset img object 
3156         if (img_set)
3157           {
3158              if (obj->layer->evas->engine.func->gl_img_obj_set)
3159                {
3160                   obj->layer->evas->engine.func->gl_img_obj_set(output, NULL, 0);
3161                   img_set = 0;
3162                }
3163           }        
3164      }
3165 }
3166
3167 static void
3168 evas_object_image_render_pre(Evas_Object *obj)
3169 {
3170    Evas_Object_Image *o;
3171    int is_v = 0, was_v = 0;
3172    Evas *e;
3173
3174    /* dont pre-render the obj twice! */
3175    if (obj->pre_render_done) return;
3176    obj->pre_render_done = 1;
3177    /* pre-render phase. this does anything an object needs to do just before */
3178    /* rendering. this could mean loading the image data, retrieving it from */
3179    /* elsewhere, decoding video etc. */
3180    /* then when this is done the object needs to figure if it changed and */
3181    /* if so what and where and add the appropriate redraw rectangles */
3182    o = (Evas_Object_Image *)(obj->object_data);
3183    e = obj->layer->evas;
3184
3185    if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
3186      {
3187         ERR("%p has invalid fill size: %dx%d. Ignored",
3188             obj, o->cur.fill.w, o->cur.fill.h);
3189         return;
3190      }
3191
3192    /* if someone is clipping this obj - go calculate the clipper */
3193    if (obj->cur.clipper)
3194      {
3195         if (obj->cur.cache.clip.dirty)
3196           evas_object_clip_recalc(obj->cur.clipper);
3197         obj->cur.clipper->func->render_pre(obj->cur.clipper);
3198      }
3199    /* Proxy: Do it early */
3200    if (o->cur.source && 
3201        (o->cur.source->proxy.redraw || o->cur.source->changed))
3202      {
3203         /* XXX: Do I need to sort out the map here? */
3204         evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3205         goto done;
3206      }
3207
3208    /* now figure what changed and add draw rects */
3209    /* if it just became visible or invisible */
3210    is_v = evas_object_is_visible(obj);
3211    was_v = evas_object_was_visible(obj);
3212    if (is_v != was_v)
3213      {
3214         evas_object_render_pre_visible_change(&e->clip_changes, obj, is_v, was_v);
3215         if (!o->pixel_updates) goto done;
3216      }
3217    if (obj->changed_map)
3218      {
3219         evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3220         goto done;
3221      }
3222    /* it's not visible - we accounted for it appearing or not so just abort */
3223    if (!is_v) goto done;
3224    /* clipper changed this is in addition to anything else for obj */
3225    evas_object_render_pre_clipper_change(&e->clip_changes, obj);
3226    /* if we restacked (layer or just within a layer) and don't clip anyone */
3227    if (obj->restack)
3228      {
3229         evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3230         if (!o->pixel_updates) goto done;
3231      }
3232    /* if it changed color */
3233    if ((obj->cur.color.r != obj->prev.color.r) ||
3234        (obj->cur.color.g != obj->prev.color.g) ||
3235        (obj->cur.color.b != obj->prev.color.b) ||
3236        (obj->cur.color.a != obj->prev.color.a))
3237      {
3238         evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3239         if (!o->pixel_updates) goto done;
3240      }
3241    /* if it changed render op */
3242    if (obj->cur.render_op != obj->prev.render_op)
3243      {
3244         evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3245         if (!o->pixel_updates) goto done;
3246      }
3247    /* if it changed anti_alias */
3248    if (obj->cur.anti_alias != obj->prev.anti_alias)
3249      {
3250         evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3251         if (!o->pixel_updates) goto done;
3252      }
3253    if (o->changed)
3254      {
3255         if (((o->cur.file) && (!o->prev.file)) ||
3256             ((!o->cur.file) && (o->prev.file)) ||
3257             ((o->cur.key) && (!o->prev.key)) ||
3258             ((!o->cur.key) && (o->prev.key))
3259             )
3260           {
3261              evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3262              if (!o->pixel_updates) goto done;
3263           }
3264         if ((o->cur.image.w != o->prev.image.w) ||
3265             (o->cur.image.h != o->prev.image.h) ||
3266             (o->cur.has_alpha != o->prev.has_alpha) ||
3267             (o->cur.cspace != o->prev.cspace) ||
3268             (o->cur.smooth_scale != o->prev.smooth_scale))
3269           {
3270              evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3271              if (!o->pixel_updates) goto done;
3272           }
3273         if ((o->cur.border.l != o->prev.border.l) ||
3274             (o->cur.border.r != o->prev.border.r) ||
3275             (o->cur.border.t != o->prev.border.t) ||
3276             (o->cur.border.b != o->prev.border.b) ||
3277             (o->cur.border.fill != o->prev.border.fill) ||
3278             (o->cur.border.scale != o->prev.border.scale))
3279           {
3280              evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3281              if (!o->pixel_updates) goto done;
3282           }
3283         if (o->dirty_pixels)
3284           {
3285              evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3286              if (!o->pixel_updates) goto done;
3287           }
3288         if (o->cur.frame != o->prev.frame)
3289           {
3290              evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3291              if (!o->pixel_updates) goto done;
3292           }
3293         
3294      }
3295    /* if it changed geometry - and obviously not visibility or color */
3296    /* calculate differences since we have a constant color fill */
3297    /* we really only need to update the differences */
3298 #if 0 // XXX: maybe buggy?
3299    if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
3300         (obj->cur.geometry.y != obj->prev.geometry.y) ||
3301         (obj->cur.geometry.w != obj->prev.geometry.w) ||
3302         (obj->cur.geometry.h != obj->prev.geometry.h)) &&
3303        (o->cur.fill.w == o->prev.fill.w) &&
3304        (o->cur.fill.h == o->prev.fill.h) &&
3305        ((o->cur.fill.x + obj->cur.geometry.x) == (o->prev.fill.x + obj->prev.geometry.x)) &&
3306        ((o->cur.fill.y + obj->cur.geometry.y) == (o->prev.fill.y + obj->prev.geometry.y)) &&
3307        (!o->pixel_updates)
3308        )
3309      {
3310         evas_rects_return_difference_rects(&e->clip_changes,
3311                                            obj->cur.geometry.x,
3312                                            obj->cur.geometry.y,
3313                                            obj->cur.geometry.w,
3314                                            obj->cur.geometry.h,
3315                                            obj->prev.geometry.x,
3316                                            obj->prev.geometry.y,
3317                                            obj->prev.geometry.w,
3318                                            obj->prev.geometry.h);
3319         if (!o->pixel_updates) goto done;
3320      }
3321 #endif   
3322    if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
3323         (obj->cur.geometry.y != obj->prev.geometry.y) ||
3324         (obj->cur.geometry.w != obj->prev.geometry.w) ||
3325         (obj->cur.geometry.h != obj->prev.geometry.h))
3326        )
3327      {
3328         evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3329         if (!o->pixel_updates) goto done;
3330      }
3331    if (o->changed)
3332      {
3333         if ((o->cur.fill.x != o->prev.fill.x) ||
3334             (o->cur.fill.y != o->prev.fill.y) ||
3335             (o->cur.fill.w != o->prev.fill.w) ||
3336             (o->cur.fill.h != o->prev.fill.h))
3337           {
3338              evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3339              if (!o->pixel_updates) goto done;
3340           }
3341         if (o->pixel_updates)
3342           {
3343              if ((o->cur.border.l == 0) &&
3344                  (o->cur.border.r == 0) &&
3345                  (o->cur.border.t == 0) &&
3346                  (o->cur.border.b == 0) &&
3347                  (o->cur.image.w > 0) &&
3348                  (o->cur.image.h > 0) &&
3349                 (!((obj->cur.map) && (obj->cur.usemap))))
3350                {
3351                   Eina_Rectangle *rr;
3352                   
3353                   EINA_LIST_FREE(o->pixel_updates, rr)
3354                     {
3355                        Evas_Coord idw, idh, idx, idy;
3356                        int x, y, w, h;
3357                        
3358                        e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, rr->x, rr->y, rr->w, rr->h);
3359                        
3360                        idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
3361                        idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
3362                        
3363                        if (idw < 1) idw = 1;
3364                        if (idh < 1) idh = 1;
3365                        if (idx > 0) idx -= idw;
3366                        if (idy > 0) idy -= idh;
3367                        while (idx < obj->cur.geometry.w)
3368                          {
3369                             Evas_Coord ydy;
3370                             
3371                             ydy = idy;
3372                             x = idx;
3373                             w = ((int)(idx + idw)) - x;
3374                             while (idy < obj->cur.geometry.h)
3375                               {
3376                                  Eina_Rectangle r;
3377                                  
3378                                  y = idy;
3379                                  h = ((int)(idy + idh)) - y;
3380                                  
3381                                  r.x = (rr->x * w) / o->cur.image.w;
3382                                  r.y = (rr->y * h) / o->cur.image.h;
3383                                  r.w = ((rr->w * w) + (o->cur.image.w * 2) - 1) / o->cur.image.w;
3384                                  r.h = ((rr->h * h) + (o->cur.image.h * 2) - 1) / o->cur.image.h;
3385                                  r.x += obj->cur.geometry.x + x;
3386                                  r.y += obj->cur.geometry.y + y;
3387                                  RECTS_CLIP_TO_RECT(r.x, r.y, r.w, r.h,
3388                                                     obj->cur.cache.clip.x, obj->cur.cache.clip.y,
3389                                                     obj->cur.cache.clip.w, obj->cur.cache.clip.h);
3390                                  evas_add_rect(&e->clip_changes, r.x, r.y, r.w, r.h);
3391                                  idy += h;
3392                               }
3393                             idx += idw;
3394                             idy = ydy;
3395                          }
3396                        eina_rectangle_free(rr);
3397                     }
3398                   goto done;
3399                }
3400              else
3401                {
3402                   Eina_Rectangle *r;
3403                   
3404                   EINA_LIST_FREE(o->pixel_updates, r)
3405                      eina_rectangle_free(r);
3406                   e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h);
3407                   evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3408                   goto done;
3409                }
3410           }
3411      }
3412 #if 0 // filtering disabled
3413    if (obj->filter && obj->filter->dirty)
3414      {
3415         evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3416      }
3417 #endif   
3418    /* it obviously didn't change - add a NO obscure - this "unupdates"  this */
3419    /* area so if there were updates for it they get wiped. don't do it if we */
3420    /* aren't fully opaque and we are visible */
3421    if (evas_object_is_visible(obj) &&
3422        evas_object_is_opaque(obj))
3423      {
3424         Evas_Coord x, y, w, h;
3425         
3426         x = obj->cur.cache.clip.x;
3427         y = obj->cur.cache.clip.y;
3428         w = obj->cur.cache.clip.w;
3429         h = obj->cur.cache.clip.h;
3430         if (obj->cur.clipper)
3431           {
3432              RECTS_CLIP_TO_RECT(x, y, w, h,
3433                                 obj->cur.clipper->cur.cache.clip.x,
3434                                 obj->cur.clipper->cur.cache.clip.y,
3435                                 obj->cur.clipper->cur.cache.clip.w,
3436                                 obj->cur.clipper->cur.cache.clip.h);
3437           }
3438         e->engine.func->output_redraws_rect_del(e->engine.data.output,
3439                                                 x, y, w, h);
3440      }
3441    done:
3442    evas_object_render_pre_effect_updates(&e->clip_changes, obj, is_v, was_v);
3443 }
3444
3445 static void
3446 evas_object_image_render_post(Evas_Object *obj)
3447 {
3448    Evas_Object_Image *o;
3449    Eina_Rectangle *r;
3450
3451    /* this moves the current data to the previous state parts of the object */
3452    /* in whatever way is safest for the object. also if we don't need object */
3453    /* data anymore we can free it if the object deems this is a good idea */
3454    o = (Evas_Object_Image *)(obj->object_data);
3455    /* remove those pesky changes */
3456    evas_object_clip_changes_clean(obj);
3457    EINA_LIST_FREE(o->pixel_updates, r)
3458      eina_rectangle_free(r);
3459    /* move cur to prev safely for object data */
3460    evas_object_cur_prev(obj);
3461    o->prev = o->cur;
3462    o->changed = 0;
3463    /* FIXME: copy strings across */
3464 }
3465
3466 static unsigned int evas_object_image_id_get(Evas_Object *obj)
3467 {
3468    Evas_Object_Image *o;
3469
3470    o = (Evas_Object_Image *)(obj->object_data);
3471    if (!o) return 0;
3472    return MAGIC_OBJ_IMAGE;
3473 }
3474
3475 static unsigned int evas_object_image_visual_id_get(Evas_Object *obj)
3476 {
3477    Evas_Object_Image *o;
3478
3479    o = (Evas_Object_Image *)(obj->object_data);
3480    if (!o) return 0;
3481    return MAGIC_OBJ_IMAGE;
3482 }
3483
3484 static void *evas_object_image_engine_data_get(Evas_Object *obj)
3485 {
3486    Evas_Object_Image *o;
3487
3488    o = (Evas_Object_Image *)(obj->object_data);
3489    if (!o) return NULL;
3490    return o->engine_data;
3491 }
3492
3493 static int
3494 evas_object_image_is_opaque(Evas_Object *obj)
3495 {
3496    Evas_Object_Image *o;
3497
3498    /* this returns 1 if the internal object data implies that the object is */
3499    /* currently fully opaque over the entire rectangle it occupies */
3500    o = (Evas_Object_Image *)(obj->object_data);
3501 /*  disable caching due tyo maps screwing with this
3502    o->cur.opaque_valid = 0;
3503    if (o->cur.opaque_valid)
3504      {
3505         if (!o->cur.opaque) return 0;
3506      }
3507    else
3508 */
3509      {
3510         o->cur.opaque = 0;
3511 /* disable caching */
3512 /*        o->cur.opaque_valid = 1; */
3513         if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
3514            return o->cur.opaque;
3515         if (((o->cur.border.l != 0) ||
3516              (o->cur.border.r != 0) ||
3517              (o->cur.border.t != 0) ||
3518              (o->cur.border.b != 0)) &&
3519             (!o->cur.border.fill)) return o->cur.opaque;
3520         if (!o->engine_data) return o->cur.opaque;
3521         o->cur.opaque = 1;
3522      }
3523    // FIXME: use proxy
3524    if (o->cur.source)
3525      {
3526         o->cur.opaque = evas_object_is_opaque(o->cur.source);
3527         return o->cur.opaque; /* FIXME: Should go poke at the object */
3528      }
3529    if (o->cur.has_alpha)
3530      {
3531         o->cur.opaque = 0;
3532         return o->cur.opaque;
3533      }
3534    if ((obj->cur.map) && (obj->cur.usemap))
3535      {
3536         Evas_Map *m = obj->cur.map;
3537         
3538         if ((m->points[0].a == 255) &&
3539             (m->points[1].a == 255) &&
3540             (m->points[2].a == 255) &&
3541             (m->points[3].a == 255))
3542           {
3543              if (
3544                  ((m->points[0].x == m->points[3].x) &&
3545                      (m->points[1].x == m->points[2].x) &&
3546                      (m->points[0].y == m->points[1].y) &&
3547                      (m->points[2].y == m->points[3].y))
3548                  ||
3549                  ((m->points[0].x == m->points[1].x) &&
3550                      (m->points[2].x == m->points[3].x) &&
3551                      (m->points[0].y == m->points[3].y) &&
3552                      (m->points[1].y == m->points[2].y))
3553                 )
3554                {
3555                   if ((m->points[0].x == obj->cur.geometry.x) &&
3556                       (m->points[0].y == obj->cur.geometry.y) &&
3557                       (m->points[2].x == (obj->cur.geometry.x + obj->cur.geometry.w)) &&
3558                       (m->points[2].y == (obj->cur.geometry.y + obj->cur.geometry.h)))
3559                     return o->cur.opaque;
3560                }
3561           }
3562         o->cur.opaque = 0;
3563         return o->cur.opaque;
3564      }
3565    if (obj->cur.render_op == EVAS_RENDER_COPY) return o->cur.opaque;
3566    return o->cur.opaque;
3567 }
3568
3569 static int
3570 evas_object_image_was_opaque(Evas_Object *obj)
3571 {
3572    Evas_Object_Image *o;
3573
3574    /* this returns 1 if the internal object data implies that the object was */
3575    /* previously fully opaque over the entire rectangle it occupies */
3576    o = (Evas_Object_Image *)(obj->object_data);
3577    if (o->prev.opaque_valid)
3578      {
3579         if (!o->prev.opaque) return 0;
3580      }
3581    else
3582      {
3583         o->prev.opaque = 0;
3584         o->prev.opaque_valid = 1;
3585         if ((o->prev.fill.w < 1) || (o->prev.fill.h < 1))
3586            return 0;
3587         if (((o->prev.border.l != 0) ||
3588              (o->prev.border.r != 0) ||
3589              (o->prev.border.t != 0) ||
3590              (o->prev.border.b != 0)) &&
3591             (!o->prev.border.fill)) return 0;
3592         if (!o->engine_data) return 0;
3593         o->prev.opaque = 1;
3594      }
3595    // FIXME: use proxy
3596    if (o->prev.source) return 0; /* FIXME: Should go poke at the object */
3597    if (obj->prev.usemap) return 0;
3598    if (obj->prev.render_op == EVAS_RENDER_COPY) return 1;
3599    if (o->prev.has_alpha) return 0;
3600    if (obj->prev.render_op != EVAS_RENDER_BLEND) return 0;
3601    return 1;
3602 }
3603
3604 static int
3605 evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
3606 {
3607    Evas_Object_Image *o;
3608    DATA32 *data;
3609    int w, h, stride, iw, ih;
3610    int a;
3611    int return_value;
3612
3613    o = (Evas_Object_Image *)(obj->object_data);
3614
3615    x -= obj->cur.cache.clip.x;
3616    y -= obj->cur.cache.clip.y;
3617    w = obj->cur.cache.clip.w;
3618    h = obj->cur.cache.clip.h;
3619    iw = o->cur.image.w;
3620    ih = o->cur.image.h;
3621
3622    if ((x < 0) || (y < 0) || (x >= w) || (y >= h)) return 0;
3623    if (!o->cur.has_alpha) return 1;
3624
3625    // FIXME: proxy needs to be honored
3626    if (obj->cur.map)
3627      {
3628         x = obj->cur.map->mx;
3629         y = obj->cur.map->my;
3630      }
3631    else
3632      {
3633         int bl, br, bt, bb, bsl, bsr, bst, bsb;
3634         
3635         bl = o->cur.border.l;
3636         br = o->cur.border.r;
3637         bt = o->cur.border.t;
3638         bb = o->cur.border.b;
3639         if ((bl + br) > iw)
3640           {
3641              bl = iw / 2;
3642              br = iw - bl;
3643           }
3644         if ((bl + br) > iw)
3645           {
3646              bl = iw / 2;
3647              br = iw - bl;
3648           }
3649         if ((bt + bb) > ih)
3650           {
3651              bt = ih / 2;
3652              bb = ih - bt;
3653           }
3654         if ((bt + bb) > ih)
3655           {
3656              bt = ih / 2;
3657              bb = ih - bt;
3658           }
3659         if (o->cur.border.scale != 1.0)
3660           {
3661              bsl = ((double)bl * o->cur.border.scale);
3662              bsr = ((double)br * o->cur.border.scale);
3663              bst = ((double)bt * o->cur.border.scale);
3664              bsb = ((double)bb * o->cur.border.scale);
3665           }
3666         else
3667           {
3668              bsl = bl; bsr = br; bst = bt; bsb = bb;
3669           }
3670         
3671         w = o->cur.fill.w;
3672         h = o->cur.fill.h;
3673         x -= o->cur.fill.x;
3674         y -= o->cur.fill.y;
3675         x %= w;
3676         y %= h;
3677         
3678         if (x < 0) x += w;
3679         if (y < 0) y += h;
3680         
3681         if (o->cur.border.fill != EVAS_BORDER_FILL_DEFAULT)
3682           {
3683              if ((x > bsl) && (x < (w - bsr)) &&
3684                  (y > bst) && (y < (h - bsb)))
3685                {
3686                   if (o->cur.border.fill == EVAS_BORDER_FILL_SOLID) return 1;
3687                   return 0;
3688                }
3689           }
3690         
3691         if (x < bsl) x = (x * bl) / bsl;
3692         else if (x > (w - bsr)) x = iw - (((w - x) * br) / bsr);
3693         else if ((bsl + bsr) < w) x = bl + (((x - bsl) * (iw - bl - br)) / (w - bsl - bsr));
3694         else return 1;
3695         
3696         if (y < bst) y = (y * bt) / bst;
3697         else if (y > (h - bsb)) y = ih - (((h - y) * bb) / bsb);
3698         else if ((bst + bsb) < h) y = bt + (((y - bst) * (ih - bt - bb)) / (h - bst - bsb));
3699         else return 1;
3700      }
3701    
3702    if (x < 0) x = 0;
3703    if (y < 0) y = 0;
3704    if (x >= iw) x = iw - 1;
3705    if (y >= ih) y = ih - 1;
3706    
3707    stride = o->cur.image.stride;
3708    
3709    o->engine_data = obj->layer->evas->engine.func->image_data_get
3710       (obj->layer->evas->engine.data.output,
3711           o->engine_data,
3712           0,
3713           &data,
3714           &o->load_error);
3715
3716    if (!data)
3717      {
3718         return_value = 0;
3719         goto finish;
3720      }
3721
3722    switch (o->cur.cspace)
3723      {
3724      case EVAS_COLORSPACE_ARGB8888:
3725         data = ((DATA32*)(data) + ((y * (stride >> 2)) + x));
3726         a = (*((DATA32*)(data)) >> 24) & 0xff;
3727         break;
3728      case EVAS_COLORSPACE_RGB565_A5P:
3729         data = (void*) ((DATA16*)(data) + (h * (stride >> 1)));
3730         data = (void*) ((DATA8*)(data) + ((y * (stride >> 1)) + x));
3731         a = (*((DATA8*)(data))) & 0x1f;
3732         break;
3733      default:
3734         return_value = 1;
3735         goto finish;
3736         break;
3737      }
3738
3739    return_value = (a != 0);
3740    goto finish;
3741
3742    finish:
3743
3744    obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
3745                                   o->engine_data,
3746                                   data);
3747    return return_value;
3748 }
3749
3750 static int
3751 evas_object_image_has_opaque_rect(Evas_Object *obj)
3752 {
3753    Evas_Object_Image *o;
3754
3755    o = (Evas_Object_Image *)(obj->object_data);
3756    if ((obj->cur.map) && (obj->cur.usemap)) return 0;
3757    if (((o->cur.border.l | o->cur.border.r | o->cur.border.t | o->cur.border.b) != 0) &&
3758        (o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
3759        (obj->cur.render_op == EVAS_RENDER_BLEND) &&
3760        (obj->cur.cache.clip.a == 255) &&
3761        (o->cur.fill.x == 0) &&
3762        (o->cur.fill.y == 0) &&
3763        (o->cur.fill.w == obj->cur.geometry.w) &&
3764        (o->cur.fill.h == obj->cur.geometry.h)
3765        ) return 1;
3766    return 0;
3767 }
3768
3769 static int
3770 evas_object_image_get_opaque_rect(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
3771 {
3772    Evas_Object_Image *o;
3773
3774    o = (Evas_Object_Image *)(obj->object_data);
3775    if (o->cur.border.scale == 1.0)
3776      {
3777         *x = obj->cur.geometry.x + o->cur.border.l;
3778         *y = obj->cur.geometry.y + o->cur.border.t;
3779         *w = obj->cur.geometry.w - (o->cur.border.l + o->cur.border.r);
3780         if (*w < 0) *w = 0;
3781         *h = obj->cur.geometry.h - (o->cur.border.t + o->cur.border.b);
3782         if (*h < 0) *h = 0;
3783      }
3784    else
3785      {
3786         *x = obj->cur.geometry.x + (o->cur.border.l * o->cur.border.scale);
3787         *y = obj->cur.geometry.y + (o->cur.border.t * o->cur.border.scale);
3788         *w = obj->cur.geometry.w - ((o->cur.border.l * o->cur.border.scale) + (o->cur.border.r * o->cur.border.scale));
3789         if (*w < 0) *w = 0;
3790         *h = obj->cur.geometry.h - ((o->cur.border.t * o->cur.border.scale) + (o->cur.border.b * o->cur.border.scale));
3791         if (*h < 0) *h = 0;
3792      }
3793    return 1;
3794 }
3795
3796 static int
3797 evas_object_image_can_map(Evas_Object *obj __UNUSED__)
3798 {
3799    return 1;
3800 }
3801
3802 static void *
3803 evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace)
3804 {
3805    void *out = NULL;
3806
3807    if (!data)
3808      return NULL;
3809
3810    switch (o->cur.cspace)
3811      {
3812         case EVAS_COLORSPACE_ARGB8888:
3813           out = evas_common_convert_argb8888_to(data,
3814                                                 o->cur.image.w,
3815                                                 o->cur.image.h,
3816                                                 o->cur.image.stride >> 2,
3817                                                 o->cur.has_alpha,
3818                                                 to_cspace);
3819           break;
3820         case EVAS_COLORSPACE_RGB565_A5P:
3821           out = evas_common_convert_rgb565_a5p_to(data,
3822                                                   o->cur.image.w,
3823                                                   o->cur.image.h,
3824                                                   o->cur.image.stride >> 1,
3825                                                   o->cur.has_alpha,
3826                                                   to_cspace);
3827           break;
3828         case EVAS_COLORSPACE_YCBCR422601_PL:
3829            out = evas_common_convert_yuv_422_601_to(data,
3830                                                    o->cur.image.w,
3831                                                    o->cur.image.h,
3832                                                    to_cspace);
3833           break;
3834         case EVAS_COLORSPACE_YCBCR422P601_PL:
3835           out = evas_common_convert_yuv_422P_601_to(data,
3836                                                     o->cur.image.w,
3837                                                     o->cur.image.h,
3838                                                     to_cspace);
3839           break;
3840         case EVAS_COLORSPACE_YCBCR420NV12601_PL:
3841           out = evas_common_convert_yuv_420_601_to(data,
3842                                                    o->cur.image.w,
3843                                                    o->cur.image.h,
3844                                                    to_cspace);
3845           break;
3846         case EVAS_COLORSPACE_YCBCR420TM12601_PL:
3847           out = evas_common_convert_yuv_420T_601_to(data,
3848                                                     o->cur.image.w,
3849                                                     o->cur.image.h,
3850                                                     to_cspace);
3851           break;
3852         default:
3853           WRN("unknow colorspace: %i\n", o->cur.cspace);
3854           break;
3855      }
3856
3857    return out;
3858 }
3859
3860 static void
3861 evas_object_image_filled_resize_listener(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *einfo __UNUSED__)
3862 {
3863    Evas_Coord w, h;
3864
3865    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3866    evas_object_image_fill_set(obj, 0, 0, w, h);
3867 }
3868
3869
3870 Eina_Bool
3871 _evas_object_image_preloading_get(const Evas_Object *obj)
3872 {
3873    Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3874    if (!o) return EINA_FALSE;
3875    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
3876    return EINA_FALSE;
3877    MAGIC_CHECK_END();
3878    return o->preloading;
3879 }
3880
3881 void
3882 _evas_object_image_preloading_set(Evas_Object *obj, Eina_Bool preloading)
3883 {
3884    Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3885    o->preloading = preloading;
3886 }
3887
3888 void
3889 _evas_object_image_preloading_check(Evas_Object *obj)
3890 {
3891    Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3892    if (obj->layer->evas->engine.func->image_load_error_get)
3893       o->load_error = obj->layer->evas->engine.func->image_load_error_get
3894       (obj->layer->evas->engine.data.output, o->engine_data);
3895 }
3896
3897 Evas_Object *
3898 _evas_object_image_video_parent_get(Evas_Object *obj)
3899 {
3900    Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3901
3902    return o->video_surface ? o->video.parent : NULL;
3903 }
3904
3905 void
3906 _evas_object_image_video_overlay_show(Evas_Object *obj)
3907 {
3908    Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3909
3910    if (obj->cur.cache.clip.x != obj->prev.cache.clip.x ||
3911        obj->cur.cache.clip.y != obj->prev.cache.clip.y ||
3912        o->created || !o->video_visible)
3913      o->video.move(o->video.data, obj, &o->video, obj->cur.cache.clip.x, obj->cur.cache.clip.y);
3914    if (obj->cur.cache.clip.w != obj->prev.cache.clip.w ||
3915        obj->cur.cache.clip.h != obj->prev.cache.clip.h ||
3916        o->created || !o->video_visible)
3917      o->video.resize(o->video.data, obj, &o->video, obj->cur.cache.clip.w, obj->cur.cache.clip.h);
3918    if (!o->video_visible || o->created)
3919      {
3920         o->video.show(o->video.data, obj, &o->video);
3921      }
3922    else
3923      {
3924         /* Cancel dirty on the image */
3925         Eina_Rectangle *r;
3926
3927         o->dirty_pixels = 0;
3928         EINA_LIST_FREE(o->pixel_updates, r)
3929           eina_rectangle_free(r);
3930      }
3931    o->video_visible = EINA_TRUE;
3932    o->created = EINA_FALSE;
3933 }
3934
3935 void
3936 _evas_object_image_video_overlay_hide(Evas_Object *obj)
3937 {
3938    Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3939
3940    if (o->video_visible || o->created)
3941      o->video.hide(o->video.data, obj, &o->video);
3942    if (evas_object_is_visible(obj))
3943      o->video.update_pixels(o->video.data, obj, &o->video);
3944    o->video_visible = EINA_FALSE;
3945    o->created = EINA_FALSE;
3946 }
3947
3948 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/