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