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