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