move around - flatter.
[profile/ivi/evas.git] / src / lib / canvas / evas_object_image.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #include "evas_common.h"
6 #include "evas_private.h"
7 #include "../engines/common/evas_convert_color.h"
8 #include "../engines/common/evas_convert_colorspace.h"
9 #include "../engines/common/evas_convert_yuv.h"
10
11 /* private magic number for image objects */
12 static const char o_type[] = "image";
13
14 /* private struct for rectangle object internal data */
15 typedef struct _Evas_Object_Image      Evas_Object_Image;
16
17 struct _Evas_Object_Image
18 {
19    DATA32            magic;
20
21    struct {
22       Evas_Coord_Rectangle fill;
23       struct {
24          short       w, h, stride;
25       } image;
26       struct {
27          short         l, r, t, b;
28          unsigned char fill;
29       } border;
30
31       const char    *file;
32       const char    *key;
33       int            cspace;
34
35       unsigned char  smooth_scale : 1;
36       unsigned char  has_alpha :1;
37    } cur, prev;
38
39    int               pixels_checked_out;
40    int               load_error;
41    Evas_List        *pixel_updates;
42
43    struct {
44       unsigned char  scale_down_by;
45       double         dpi;
46       short          w, h;
47    } load_opts;
48
49    struct {
50       void            (*get_pixels) (void *data, Evas_Object *o);
51       void             *get_pixels_data;
52    } func;
53
54    void             *engine_data;
55
56    unsigned char     changed : 1;
57    unsigned char     dirty_pixels : 1;
58 };
59
60 /* private methods for image objects */
61 static void evas_object_image_unload(Evas_Object *obj);
62 static void evas_object_image_load(Evas_Object *obj);
63 static Evas_Coord evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret);
64 static Evas_Coord evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret);
65
66 static void evas_object_image_init(Evas_Object *obj);
67 static void *evas_object_image_new(void);
68 static void evas_object_image_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y);
69 static void evas_object_image_free(Evas_Object *obj);
70 static void evas_object_image_render_pre(Evas_Object *obj);
71 static void evas_object_image_render_post(Evas_Object *obj);
72
73 static int evas_object_image_is_opaque(Evas_Object *obj);
74 static int evas_object_image_was_opaque(Evas_Object *obj);
75 static int evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
76
77 static void *evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace);
78
79 static const Evas_Object_Func object_func =
80 {
81    /* methods (compulsory) */
82    evas_object_image_free,
83    evas_object_image_render,
84    evas_object_image_render_pre,
85    evas_object_image_render_post,
86    /* these are optional. NULL = nothing */
87    NULL,
88    NULL,
89    NULL,
90    NULL,
91    evas_object_image_is_opaque,
92    evas_object_image_was_opaque,
93    evas_object_image_is_inside,
94    NULL,
95    NULL
96 };
97
98 /**
99  * @defgroup Evas_Object_Image Image Object Functions
100  *
101  * Functions used to create and manipulate image objects.
102  *
103  * Note - Image objects may return or accept "image data" in multiple formats.
104  * This is based on the colorspace of an object. Here is a rundown on formats:
105  *
106  * EVAS_COLORSPACE_ARGB8888:
107  *
108  * This pixel format is a linear block of pixels, starting at the top-left row
109  * by row until the bottom right of the image or pixel region. All pixels are
110  * 32-bit unsigned int's with the high-byte being alpha and the low byte being
111  * blue in the format ARGB. Alpha may or may not be used by evas depending on
112  * the alpha flag of the image, but if not used, should be set to 0xff anyway.
113  *
114  * This colorspace uses premultiplied alpha. That means that R, G and B cannot
115  * exceed A in value. The conversion from non-premultiplied colorspace is:
116  *
117  * R = (r * a) / 255; G = (g * a) / 255; B = (b * a) / 255;
118  *
119  * So 50% transparent blue will be: 0x80000080. This will not be "dark" - just
120  * 50% transparent. Values are 0 == black, 255 == solid or full red, green or
121  * blue.
122  *
123  * EVAS_COLORSPACE_YCBCR422P601_PL:
124  *
125  * This is a pointer-list indirected set of YUV (YCbCr) pixel data. This means
126  * that the data returned or set is not actual pixel data, but pointers TO
127  * lines of pixel data. The list of pointers will first be N rows of pointers
128  * to the Y plane - pointing to the first pixel at the start of each row in
129  * the Y plane. N is the height of the image data in pixels. Each pixel in the
130  * Y, U and V planes is 1 byte exactly, packed. The next N / 2 pointers will
131  * point to rows in the U plane, and the next N / 2 pointers will point to
132  * the V plane rows. U and V planes are half the horizontal and vertical
133  * resolution of the U plane.
134  *
135  * Row order is top to bottom and row pixels are stored left to right.
136  *
137  * There is a limitation that these images MUST be a multiple of 2 pixels in
138  * size horizontally or vertically. This is due to the U and V planes being
139  * half resolution. Also note that this assumes the itu601 YUV colorspace
140  * specification. This is defined for standard television and mpeg streams.
141  * HDTV may use the itu709 specification.
142  *
143  * Values are 0 to 255, indicating full or no signal in that plane
144  * respectively.
145  *
146  * EVAS_COLORSPACE_YCBCR422P709_PL:
147  *
148  * Not implemented yet.
149  *
150  * EVAS_COLORSPACE_RGB565_A5P:
151  *
152  * In the process of being implemented in 1 engine only. This may change.
153  *
154  * This is a pointer to image data for 16-bit half-word pixel data in 16bpp
155  * RGB 565 format (5 bits red, 6 bits green, 5 bits blue), with the high-byte
156  * containing red and the low byte containing blue, per pixel. This data is
157  * packed row by row from the top-left to the bottom right.
158  *
159  * If the image has an alpha channel enabled there will be an extra alpha plane
160  * after the color pixel plane. If not, then this data will not exist and
161  * should not be accessed in any way. This plane is a set of pixels with 1
162  * byte per pixel defining the alpha values of all pixels in the image from
163  * the top-left to the bottom right of the image, row by row. Even though
164  * the values of the alpha pixels can be 0 to 255, only values 0 through to 32
165  * are used, 32 being solid and 0 being transparent.
166  *
167  * RGB values can be 0 to 31 for red and blue and 0 to 63 for green, with 0
168  * being black and 31 or 63 being full red, green or blue respectively. This
169  * colorspace is also pre-multiplied like EVAS_COLORSPACE_ARGB8888 so:
170  *
171  * R = (r * a) / 32; G = (g * a) / 32; B = (b * a) / 32;
172  */
173
174 /**
175  * Creates a new image object on the given evas.
176  *
177  * @param e The given evas.
178  * @return The created image object.
179  * @ingroup Evas_Object_Image
180  */
181 EAPI Evas_Object *
182 evas_object_image_add(Evas *e)
183 {
184    Evas_Object *obj;
185    Evas_Object_Image *o;
186
187    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
188    return NULL;
189    MAGIC_CHECK_END();
190    obj = evas_object_new();
191    evas_object_image_init(obj);
192    evas_object_inject(obj, e);
193    o = (Evas_Object_Image *)(obj->object_data);
194    o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
195                                                                        o->engine_data);
196    return obj;
197 }
198
199 /**
200  * @defgroup Evas_Object_Image_File_Group Image Object File Functions
201  *
202  * Functions that write to or retrieve images from files.
203  */
204
205 /**
206  * Sets the filename and key of the given image object.
207  *
208  * If the file supports multiple data stored in it as eet,
209  * you can specify the key to be used as the index of the
210  * image in this file.
211  *
212  * @param obj The given image object.
213  * @param file The image filename.
214  * @param key The image key in file, or NULL.
215  * @ingroup Evas_Object_Image_File_Group
216  */
217 EAPI void
218 evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
219 {
220    Evas_Object_Image *o;
221    Evas_Image_Load_Opts lo;
222
223    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
224    return;
225    MAGIC_CHECK_END();
226    o = (Evas_Object_Image *)(obj->object_data);
227    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
228    return;
229    MAGIC_CHECK_END();
230    if ((o->cur.file) && (file) && (!strcmp(o->cur.file, file)))
231      {
232         if ((!o->cur.key) && (!key))
233           return;
234         if ((o->cur.key) && (key) && (!strcmp(o->cur.key, key)))
235           return;
236      }
237    if (o->cur.file) evas_stringshare_del(o->cur.file);
238    if (o->cur.key) evas_stringshare_del(o->cur.key);
239    if (file) o->cur.file = evas_stringshare_add(file);
240    else o->cur.file = NULL;
241    if (key) o->cur.key = evas_stringshare_add(key);
242    else o->cur.key = NULL;
243    o->prev.file = NULL;
244    o->prev.key = NULL;
245    if (o->engine_data)
246      obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
247                                                o->engine_data);
248    o->load_error = EVAS_LOAD_ERROR_NONE;
249    lo.scale_down_by = o->load_opts.scale_down_by;
250    lo.dpi = o->load_opts.dpi;
251    lo.w = o->load_opts.w;
252    lo.h = o->load_opts.h;
253    o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output,
254                                                               o->cur.file,
255                                                               o->cur.key,
256                                                               &o->load_error,
257                                                               &lo);
258    if (o->engine_data)
259      {
260         int w, h;
261         int stride;
262
263         obj->layer->evas->engine.func->image_size_get(obj->layer->evas->engine.data.output,
264                                                       o->engine_data, &w, &h);
265         if (obj->layer->evas->engine.func->image_stride_get)
266           obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output,
267                                                           o->engine_data, &stride);
268         else
269           stride = w;
270         o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output,
271                                                                           o->engine_data);
272         o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
273                                                                             o->engine_data);
274         o->cur.image.w = w;
275         o->cur.image.h = h;
276         o->cur.image.stride = stride;
277      }
278    else
279      {
280         o->load_error = EVAS_LOAD_ERROR_GENERIC;
281         o->cur.has_alpha = 1;
282         o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
283         o->cur.image.w = 0;
284         o->cur.image.h = 0;
285         o->cur.image.stride = 0;
286      }
287    o->changed = 1;
288    evas_object_change(obj);
289 }
290
291 /**
292  * Retrieves the filename and key of the given image object.
293  *
294  * @param obj The given image object.
295  * @param file Location to store the image filename, or NULL.
296  * @param key Location to store the image key, or NULL.
297  * @ingroup Evas_Object_Image_File_Group
298  */
299 EAPI void
300 evas_object_image_file_get(const Evas_Object *obj, const char **file, const char **key)
301 {
302    Evas_Object_Image *o;
303
304    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
305    if (file) *file = NULL;
306    if (key) *key = NULL;
307    return;
308    MAGIC_CHECK_END();
309    o = (Evas_Object_Image *)(obj->object_data);
310    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
311    if (file) *file = NULL;
312    if (key) *key = NULL;
313    return;
314    MAGIC_CHECK_END();
315    if (file) *file = o->cur.file;
316    if (key) *key = o->cur.key;
317 }
318
319 /**
320  * @defgroup Evas_Object_Image_Border_Group Image Object Border Functions
321  *
322  * Functions that adjust the unscaled image border of image objects.
323  */
324
325 /**
326  * Sets how much of each border of the given image object is not
327  * to be scaled.
328  *
329  * When rendering, the image may be scaled to fit the size of the
330  * image object. This function sets what area around the border of
331  * the image is not to be scaled. This sort of function is useful for
332  * widget theming, where, for example, buttons may be of varying
333  * sizes, but the border size must remain constant.
334  *
335  * The units used for @p l, @p r, @p t and @p b are output units.
336  *
337  * @param obj The given image object.
338  * @param l Distance of the left border that is not to be stretched.
339  * @param r Distance of the right border that is not to be stretched.
340  * @param t Distance of the top border that is not to be stretched.
341  * @param b Distance of the bottom border that is not to be stretched.
342  * @ingroup Evas_Object_Image_Border_Group
343  */
344 EAPI void
345 evas_object_image_border_set(Evas_Object *obj, int l, int r, int t, int b)
346 {
347    Evas_Object_Image *o;
348
349    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
350    return;
351    MAGIC_CHECK_END();
352    o = (Evas_Object_Image *)(obj->object_data);
353    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
354    return;
355    MAGIC_CHECK_END();
356    if (l < 0) l = 0;
357    if (r < 0) r = 0;
358    if (t < 0) t = 0;
359    if (b < 0) b = 0;
360    if ((o->cur.border.l == l) &&
361        (o->cur.border.r == r) &&
362        (o->cur.border.t == t) &&
363        (o->cur.border.b == b)) return;
364    o->cur.border.l = l;
365    o->cur.border.r = r;
366    o->cur.border.t = t;
367    o->cur.border.b = b;
368    o->changed = 1;
369    evas_object_change(obj);
370 }
371
372 /**
373  * Retrieves how much of each border of the given image object is not to
374  * be scaled.
375  *
376  * See @ref evas_object_image_border_set for more details.
377  *
378  * @param obj The given image object.
379  * @param l Location to store the left border width in, or NULL.
380  * @param r Location to store the right border width in, or NULL.
381  * @param t Location to store the top border width in, or NULL.
382  * @param b Location to store the bottom border width in, or NULL.
383  * @ingroup Evas_Object_Image_Border_Group
384  */
385 EAPI void
386 evas_object_image_border_get(const Evas_Object *obj, int *l, int *r, int *t, int *b)
387 {
388    Evas_Object_Image *o;
389
390    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
391    if (l) *l = 0;
392    if (r) *r = 0;
393    if (t) *t = 0;
394    if (b) *b = 0;
395    return;
396    MAGIC_CHECK_END();
397    o = (Evas_Object_Image *)(obj->object_data);
398    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
399    if (l) *l = 0;
400    if (r) *r = 0;
401    if (t) *t = 0;
402    if (b) *b = 0;
403    return;
404    MAGIC_CHECK_END();
405    if (l) *l = o->cur.border.l;
406    if (r) *r = o->cur.border.r;
407    if (t) *t = o->cur.border.t;
408    if (b) *b = o->cur.border.b;
409 }
410
411 /**
412  * @defgroup Evas_Object_Image_Fill_Group Image Object Fill Rectangle Functions
413  *
414  * Functions that deal with what areas of the image object are to be
415  * tiled with the given image.
416  */
417
418 /**
419  * Sets if the center part of the given image object (not the border)
420  * should be drawn.
421  *
422  * When rendering, the image may be scaled to fit the size of the
423  * image object. This function sets if the center part of the scaled image
424  * is to be drawn or left completely blank. Very useful for frames and
425  * decorations.
426  *
427  * @param obj The given image object.
428  * @param fill Whether the center should be drawn.
429  * @ingroup Evas_Object_Image_Fill_Group
430  */
431 EAPI void
432 evas_object_image_border_center_fill_set(Evas_Object *obj, Evas_Bool fill)
433 {
434    Evas_Object_Image *o;
435
436    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
437    return;
438    MAGIC_CHECK_END();
439    o = (Evas_Object_Image *)(obj->object_data);
440    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
441    return;
442    MAGIC_CHECK_END();
443    if (((o->cur.border.fill) && (fill)) ||
444        ((!o->cur.border.fill) && (!fill)))
445      return;
446    o->cur.border.fill = fill;
447    o->changed = 1;
448    evas_object_change(obj);
449 }
450
451 /**
452  * Retrieves if the center of the given image object is to be drawn
453  * or not.
454  *
455  * See @ref evas_object_image_fill_set for more details.
456  *
457  * @param obj The given image object.
458  * @return If the center is to be drawn or not.
459  * @ingroup Evas_Object_Image_Fill_Group
460  */
461 EAPI Evas_Bool
462 evas_object_image_border_center_fill_get(const Evas_Object *obj)
463 {
464    Evas_Object_Image *o;
465
466    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
467    return 0;
468    MAGIC_CHECK_END();
469    o = (Evas_Object_Image *)(obj->object_data);
470    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
471    return 0;
472    MAGIC_CHECK_END();
473    return o->cur.border.fill;
474 }
475
476 /**
477  * Sets the rectangle of the given image object that the image will
478  * be drawn to.
479  *
480  * Note that the image will be tiled around this one rectangle. To have
481  * only one copy of the image drawn, @p x and @p y must be 0 and @p w
482  * and @p h need to be the width and height of the image object
483  * respectively.
484  *
485  * The default values for the fill parameters is @p x = 0, @p y = 0,
486  * @p w = 32 and @p h = 32.
487  *
488  * @param obj The given image object.
489  * @param x The X coordinate for the top left corner of the image.
490  * @param y The Y coordinate for the top left corner of the image.
491  * @param w The width of the image.
492  * @param h The height of the image.
493  * @ingroup Evas_Object_Image_Fill_Group
494  */
495 EAPI void
496 evas_object_image_fill_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
497 {
498    Evas_Object_Image *o;
499
500    if (w < 0) w = -w;
501    if (h < 0) h = -h;
502    if (w == 0.0) return;
503    if (h == 0.0) return;
504    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
505    return;
506    MAGIC_CHECK_END();
507    o = (Evas_Object_Image *)(obj->object_data);
508    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
509    return;
510    MAGIC_CHECK_END();
511    if ((o->cur.fill.x == x) &&
512        (o->cur.fill.y == y) &&
513        (o->cur.fill.w == w) &&
514        (o->cur.fill.h == h)) return;
515    o->cur.fill.x = x;
516    o->cur.fill.y = y;
517    o->cur.fill.w = w;
518    o->cur.fill.h = h;
519    o->changed = 1;
520    evas_object_change(obj);
521 }
522
523 /**
524  * Retrieves the dimensions of the rectangle of the given image object
525  * that the image will be drawn to.
526  *
527  * See @ref evas_object_image_fill_set for more details.
528  *
529  * @param obj The given image object.
530  * @param x Location to store the X coordinate for the top left corner of the image in, or NULL.
531  * @param y Location to store the Y coordinate for the top left corner of the image in, or NULL.
532  * @param w Location to store the width of the image in, or NULL.
533  * @param h Location to store the height of the image in, or NULL.
534  * @ingroup Evas_Object_Image_Fill_Group
535  */
536 EAPI void
537 evas_object_image_fill_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
538 {
539    Evas_Object_Image *o;
540
541    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
542    if (x) *x = 0;
543    if (y) *y = 0;
544    if (w) *w = 0;
545    if (h) *h = 0;
546    return;
547    MAGIC_CHECK_END();
548    o = (Evas_Object_Image *)(obj->object_data);
549    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
550    if (x) *x = 0;
551    if (y) *y = 0;
552    if (w) *w = 0;
553    if (h) *h = 0;
554    return;
555    MAGIC_CHECK_END();
556    if (x) *x = o->cur.fill.x;
557    if (y) *y = o->cur.fill.y;
558    if (w) *w = o->cur.fill.w;
559    if (h) *h = o->cur.fill.h;
560 }
561
562 /**
563  * @defgroup Evas_Object_Image_Size Image Object Image Size Functions
564  *
565  * Functions that change the size of the image used by an image object.
566  */
567
568 /**
569  * Sets the size of the given image object.
570  *
571  * This function will scale down or crop the image so that it is
572  * treated as if it were at the given size. If the size given is
573  * smaller than the image, it will be cropped. If the size given is
574  * larger, then the image will be treated as if it were in the upper
575  * left hand corner of a larger image that is otherwise transparent.
576  *
577  * @param obj The given image object.
578  * @param w The new width of the image.
579  * @param h The new height of the image.
580  * @ingroup Evas_Object_Image_Size
581  */
582 EAPI void
583 evas_object_image_size_set(Evas_Object *obj, int w, int h)
584 {
585    Evas_Object_Image *o;
586    int stride;
587
588    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
589    return;
590    MAGIC_CHECK_END();
591    o = (Evas_Object_Image *)(obj->object_data);
592    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
593    return;
594    MAGIC_CHECK_END();
595    if (w < 1) w = 1;
596    if (h < 1) h = 1;
597    if (w > 32768) return;
598    if (h > 32768) return;
599    if ((w == o->cur.image.w) &&
600        (h == o->cur.image.h)) return;
601    o->cur.image.w = w;
602    o->cur.image.h = h;
603    if (o->engine_data)
604      o->engine_data = obj->layer->evas->engine.func->image_size_set(obj->layer->evas->engine.data.output,
605                                                                     o->engine_data,
606                                                                     w, h);
607    else
608      o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data
609      (obj->layer->evas->engine.data.output, w, h, NULL, o->cur.has_alpha,
610       o->cur.cspace);
611
612    if (obj->layer->evas->engine.func->image_stride_get)
613      obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output,
614                                                      o->engine_data, &stride);
615    else
616      stride = w;
617    o->cur.image.stride = stride;
618
619 /* FIXME - in engine call above
620    if (o->engine_data)
621      o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
622                                                                      o->engine_data,
623                                                                      o->cur.has_alpha);
624 */
625    EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
626    o->changed = 1;
627    evas_object_change(obj);
628 }
629
630 /**
631  * Retrieves the size of the given image object.
632  *
633  * See @ref evas_object_image_size_set for more details.
634  *
635  * @param obj The given image object.
636  * @param w Location to store the width of the image in, or NULL.
637  * @param h Location to store the height of the image in, or NULL.
638  * @ingroup Evas_Object_Image_Size
639  */
640 EAPI void
641 evas_object_image_size_get(const Evas_Object *obj, int *w, int *h)
642 {
643    Evas_Object_Image *o;
644
645    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
646    if (w) *w = 0;
647    if (h) *h = 0;
648    return;
649    MAGIC_CHECK_END();
650    o = (Evas_Object_Image *)(obj->object_data);
651    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
652    if (w) *w = 0;
653    if (h) *h = 0;
654    return;
655    MAGIC_CHECK_END();
656    if (w) *w = o->cur.image.w;
657    if (h) *h = o->cur.image.h;
658 }
659
660 /**
661  * Retrieves the row stride of the given image object,
662  *
663  * The row stride is the number of units between the start of a
664  * row and the start of the next row.
665  *
666  * @param obj The given image object.
667  * @return The stride of the image.
668  * @ingroup Evas_Object_Image_Size
669  */
670 EAPI int
671 evas_object_image_stride_get(const Evas_Object *obj)
672 {
673    Evas_Object_Image *o;
674
675    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
676    return 0;
677    MAGIC_CHECK_END();
678    o = (Evas_Object_Image *)(obj->object_data);
679    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
680    return 0;
681    MAGIC_CHECK_END();
682    return o->cur.image.stride;
683 }
684
685 /**
686  * Retrieves a number representing any error that occurred during the last
687  * load of the given image object.
688  *
689  * @param obj The given image object.
690  * @return A value giving the last error that occurred. It should be one of
691  *         the @c EVAS_LOAD_ERROR_* values.  @c EVAS_LOAD_ERROR_NONE is
692  *         returned if there was no error.
693  * @ingroup Evas_Object_Image
694  */
695 EAPI int
696 evas_object_image_load_error_get(const Evas_Object *obj)
697 {
698    Evas_Object_Image *o;
699
700    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
701    return 0;
702    MAGIC_CHECK_END();
703    o = (Evas_Object_Image *)(obj->object_data);
704    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
705    return 0;
706    MAGIC_CHECK_END();
707    return o->load_error;
708 }
709
710 /**
711  * @defgroup Evas_Object_Image_Data Image Object Image Data Functions
712  *
713  * Functions that allow you to access or modify the image pixel data of an
714  * image object.
715  */
716
717 /**
718  * Converts the raw image data of the given image object to the
719  * specified colorspace.
720  *
721  * Note that this function does not modify the raw image data.
722  * If the requested colorspace is the same as the image colorspace
723  * nothing is done and NULL is returned. You should use
724  * evas_object_image_colorspace_get() to check the current image
725  * colorspace.
726  *
727  * See @ref evas_object_image_colorspace_get.
728  *
729  * @param obj The given image object.
730  * @param to_cspace The colorspace to which the image raw data will be converted.
731  * @return data A newly allocated data in the format specified by to_cspace.
732  * @ingroup Evas_Object_Image_Data
733  */
734 EAPI void *
735 evas_object_image_data_convert(Evas_Object *obj, Evas_Colorspace to_cspace)
736 {
737    Evas_Object_Image *o;
738    DATA32 *data;
739
740    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
741    return NULL;
742    MAGIC_CHECK_END();
743    o = (Evas_Object_Image *)(obj->object_data);
744    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
745    return NULL;
746    MAGIC_CHECK_END();
747    if (!o->engine_data) return NULL;
748    if (!o->cur.cspace == to_cspace) return NULL;
749    data = NULL;
750    o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
751                                                                   o->engine_data,
752                                                                   0,
753                                                                   &data);
754    return evas_object_image_data_convert_internal(o, data, to_cspace);
755 }
756
757 /**
758  * Sets the raw image data of the given image object.
759  *
760  * Note that the raw data must be of the same size and colorspace
761  * of the image. If data is NULL the current image data will be freed.
762  *
763  * @param obj The given image object.
764  * @param data The raw data, or NULL.
765  * @ingroup Evas_Object_Image_Data
766  */
767 EAPI void
768 evas_object_image_data_set(Evas_Object *obj, void *data)
769 {
770    Evas_Object_Image *o;
771    void *p_data;
772
773    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
774    return;
775    MAGIC_CHECK_END();
776    o = (Evas_Object_Image *)(obj->object_data);
777    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
778    return;
779    MAGIC_CHECK_END();
780    p_data = o->engine_data;
781    if (data)
782      {
783         if (o->engine_data)
784           o->engine_data = obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
785                                                                          o->engine_data,
786                                                                          data);
787         else
788           o->engine_data = obj->layer->evas->engine.func->image_new_from_data(obj->layer->evas->engine.data.output,
789                                                                               o->cur.image.w,
790                                                                               o->cur.image.h,
791                                                                               data,
792                                                                               o->cur.has_alpha,
793                                                                               o->cur.cspace);
794      }
795    else
796      {
797         if (o->engine_data)
798           obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
799                                                     o->engine_data);
800         o->load_error = EVAS_LOAD_ERROR_NONE;
801         o->cur.image.w = 0;
802         o->cur.image.h = 0;
803         o->cur.image.stride = 0;
804         o->engine_data = NULL;
805      }
806 /* FIXME - in engine call above
807    if (o->engine_data)
808      o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
809                                                                      o->engine_data,
810                                                                      o->cur.has_alpha);
811 */
812    if (o->pixels_checked_out > 0) o->pixels_checked_out--;
813    if (p_data != o->engine_data)
814      {
815         EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
816         o->pixels_checked_out = 0;
817      }
818    o->changed = 1;
819    evas_object_change(obj);
820 }
821
822 /**
823  * Get a pointer to the raw image data of the given image object.
824  *
825  * This function returns a pointer to an image object's internal pixel buffer,
826  * for reading only or read/write. If you request it for writing, the image
827  * will be marked dirty so that it gets redrawn at the next update.
828  *
829  * This is best suited when you want to modify an existing image,
830  * without changing its dimensions.
831  *
832  * @param obj The given image object.
833  * @param for_writing Whether the data being retrieved will be modified.
834  * @return The raw image data.
835  * @ingroup Evas_Object_Image_Data
836  */
837 EAPI void *
838 evas_object_image_data_get(const Evas_Object *obj, Evas_Bool for_writing)
839 {
840    Evas_Object_Image *o;
841    DATA32 *data;
842
843    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
844    return NULL;
845    MAGIC_CHECK_END();
846    o = (Evas_Object_Image *)(obj->object_data);
847    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
848    return NULL;
849    MAGIC_CHECK_END();
850    if (!o->engine_data) return NULL;
851    data = NULL;
852    o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
853                                                                   o->engine_data,
854                                                                   for_writing,
855                                                                   &data);
856    o->pixels_checked_out++;
857    if (for_writing)
858      {
859         EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
860      }
861
862    return data;
863 }
864
865 /**
866  * Replaces the raw image data of the given image object.
867  *
868  * This function lets the application replace an image object's internal pixel
869  * buffer with a user-allocated one. For best results, you should generally
870  * first call evas_object_image_size_set() with the width and height for the
871  * new buffer.
872  *
873  * This call is best suited for when you will be using image data with
874  * different dimensions than the existing image data, if any. If you only need
875  * to modify the existing image in some fashion, then using
876  * evas_object_image_data_get() is probably what you are after.
877  *
878  * Note that the caller is responsible for freeing the buffer when finished
879  * with it, as user-set image data will not be automatically freed when the
880  * image object is deleted.
881  *
882  * See @ref evas_object_image_data_get for more details.
883  *
884  * @param obj The given image object.
885  * @param data The raw data.
886  * @ingroup Evas_Object_Image_Data
887  */
888 EAPI void
889 evas_object_image_data_copy_set(Evas_Object *obj, void *data)
890 {
891    Evas_Object_Image *o;
892
893    if (!data) return;
894    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
895    return;
896    MAGIC_CHECK_END();
897    o = (Evas_Object_Image *)(obj->object_data);
898    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
899    return;
900    MAGIC_CHECK_END();
901    if ((o->cur.image.w <= 0) ||
902        (o->cur.image.h <= 0)) return;
903    if (o->engine_data)
904      obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
905                                                o->engine_data);
906    o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data(obj->layer->evas->engine.data.output,
907                                                                               o->cur.image.w,
908                                                                               o->cur.image.h,
909                                                                               data,
910                                                                               o->cur.has_alpha,
911                                                                               o->cur.cspace);
912    if (o->engine_data)
913      o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
914                                                                      o->engine_data,
915                                                                      o->cur.has_alpha);
916    o->pixels_checked_out = 0;
917    EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
918 }
919
920 /**
921  * Mark a sub-region of the given image object to be redrawn.
922  *
923  * This function schedules a particular rectangular region of an image
924  * object to be updated (redrawn) at the next render.
925  *
926  * @param obj The given image object.
927  * @param x X-offset of the region to be updated.
928  * @param y Y-offset of the region to be updated.
929  * @param w Width of the region to be updated.
930  * @param h Height of the region to be updated.
931  * @ingroup Evas_Object_Image_Data
932  */
933 EAPI void
934 evas_object_image_data_update_add(Evas_Object *obj, int x, int y, int w, int h)
935 {
936    Evas_Object_Image *o;
937    Evas_Rectangle *r;
938
939    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
940    return;
941    MAGIC_CHECK_END();
942    o = (Evas_Object_Image *)(obj->object_data);
943    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
944    return;
945    MAGIC_CHECK_END();
946    RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, o->cur.image.w, o->cur.image.h);
947    if ((w <= 0)  || (h <= 0)) return;
948    NEW_RECT(r, x, y, w, h);
949    if (r) o->pixel_updates = evas_list_append(o->pixel_updates, r);
950    o->changed = 1;
951    evas_object_change(obj);
952 }
953
954 /**
955  * @defgroup Evas_Object_Image_Alpha Image Object Image Alpha Functions
956  *
957  * Functions that change the alpha of an image object.
958  */
959
960 /**
961  * Enable or disable alpha channel of the given image object.
962  *
963  * This function sets a flag on an image object indicating whether or not to
964  * use alpha channel data. A value of 1 indicates to use alpha channel data,
965  * and 0 indicates to ignore any alpha channel data. Note that this has
966  * nothing to do with an object's color as manipulated by
967  * evas_object_color_set().
968  *
969  * @param obj The given image object.
970  * @param has_alpha Whether to use alpha channel data or not.
971  * @ingroup Evas_Object_Image_Alpha
972  */
973 EAPI void
974 evas_object_image_alpha_set(Evas_Object *obj, Evas_Bool has_alpha)
975 {
976    Evas_Object_Image *o;
977
978    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
979    return;
980    MAGIC_CHECK_END();
981    o = (Evas_Object_Image *)(obj->object_data);
982    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
983    return;
984    MAGIC_CHECK_END();
985    if (((has_alpha) && (o->cur.has_alpha)) ||
986        ((!has_alpha) && (!o->cur.has_alpha)))
987      return;
988    o->cur.has_alpha = has_alpha;
989    if (o->engine_data)
990      o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
991                                                                      o->engine_data,
992                                                                      o->cur.has_alpha);
993    evas_object_image_data_update_add(obj, 0, 0, o->cur.image.w, o->cur.image.h);
994    EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
995 }
996
997
998 /**
999  * Retrieves the alpha channel setting of the given image object.
1000  *
1001  * This function returns 1 if the image object's alpha channel is being used,
1002  * or 0 otherwise.
1003  *
1004  * See @ref evas_object_image_alpha_set for more details.
1005  *
1006  * @param obj The given image object.
1007  * @return Whether the alpha channel data is being used.
1008  * @ingroup Evas_Object_Image_Alpha
1009  */
1010 EAPI Evas_Bool
1011 evas_object_image_alpha_get(const Evas_Object *obj)
1012 {
1013    Evas_Object_Image *o;
1014
1015    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1016    return 0;
1017    MAGIC_CHECK_END();
1018    o = (Evas_Object_Image *)(obj->object_data);
1019    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1020    return 0;
1021    MAGIC_CHECK_END();
1022    return o->cur.has_alpha;
1023 }
1024
1025 /**
1026  * @defgroup Evas_Object_Image_Scale Image Object Image Scaling Functions
1027  *
1028  * Functions that change the scaling quality of an image object.
1029  */
1030
1031 /**
1032  * Sets whether to use of high-quality image scaling algorithm
1033  * of the given image object.
1034  *
1035  * When enabled, a higher quality image scaling algorithm is used when scaling
1036  * images to sizes other than the source image. This gives better results but
1037  * is more computationally expensive.
1038  *
1039  * @param obj The given image object.
1040  * @param smooth_scale Whether to use smooth scale or not.
1041  * @ingroup Evas_Object_Image_Scale
1042  */
1043 EAPI void
1044 evas_object_image_smooth_scale_set(Evas_Object *obj, Evas_Bool smooth_scale)
1045 {
1046    Evas_Object_Image *o;
1047
1048    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1049    return;
1050    MAGIC_CHECK_END();
1051    o = (Evas_Object_Image *)(obj->object_data);
1052    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1053    return;
1054    MAGIC_CHECK_END();
1055    if (((smooth_scale) && (o->cur.smooth_scale)) ||
1056        ((!smooth_scale) && (!o->cur.smooth_scale)))
1057      return;
1058    o->cur.smooth_scale = smooth_scale;
1059 }
1060
1061 /**
1062  * Retrieves whether the given image object is using use a high-quality
1063  * image scaling algorithm.
1064  *
1065  * See @ref evas_object_image_smooth_scale_set for more details.
1066  *
1067  * @param obj The given image object.
1068  * @return Whether smooth scale is being used.
1069  * @ingroup Evas_Object_Image_Scale
1070  */
1071 EAPI Evas_Bool
1072 evas_object_image_smooth_scale_get(const Evas_Object *obj)
1073 {
1074    Evas_Object_Image *o;
1075
1076    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1077    return 0;
1078    MAGIC_CHECK_END();
1079    o = (Evas_Object_Image *)(obj->object_data);
1080    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1081    return 0;
1082    MAGIC_CHECK_END();
1083    return o->cur.smooth_scale;
1084 }
1085
1086 /**
1087  * To be documented.
1088  *
1089  * FIXME: To be fixed.
1090  *
1091  */
1092 EAPI void
1093 evas_object_image_reload(Evas_Object *obj)
1094 {
1095    Evas_Object_Image *o;
1096
1097    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1098    return;
1099    MAGIC_CHECK_END();
1100    o = (Evas_Object_Image *)(obj->object_data);
1101    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1102    return;
1103    MAGIC_CHECK_END();
1104    if ((!o->cur.file) ||
1105        (o->pixels_checked_out > 0)) return;
1106    if (o->engine_data)
1107      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);
1108    evas_object_image_unload(obj);
1109    evas_object_image_load(obj);
1110    o->changed = 1;
1111    evas_object_change(obj);
1112 }
1113
1114 /**
1115  * Save the given image object to a file.
1116  *
1117  * Note that you should pass the filename extension when saving.
1118  * If the file supports multiple data stored in it as eet,
1119  * you can specify the key to be used as the index of the
1120  * image in this file.
1121  *
1122  * You can specify some flags when saving the image.
1123  * Currently acceptable flags are quality and compress.
1124  * Eg.: "quality=100 compress=9"
1125  *
1126  * @param obj The given image object.
1127  * @param file The filename to be used to save the image.
1128  * @param key The image key in file, or NULL.
1129  * @param flags String containing the flags to be used.
1130  * @ingroup Evas_Object_Image
1131  */
1132 EAPI Evas_Bool
1133 evas_object_image_save(const Evas_Object *obj, const char *file, const char *key, const char *flags)
1134 {
1135    Evas_Object_Image *o;
1136    DATA32 *data = NULL;
1137    int quality = 80, compress = 9, ok = 0;
1138    RGBA_Image *im;
1139
1140    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1141    return 0;
1142    MAGIC_CHECK_END();
1143    o = (Evas_Object_Image *)(obj->object_data);
1144    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1145    return 0;
1146    MAGIC_CHECK_END();
1147
1148    if (!o->engine_data) return 0;
1149    o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1150                                                                   o->engine_data,
1151                                                                   0,
1152                                                                   &data);
1153    if (flags)
1154      {
1155         char *p, *pp;
1156         char *tflags;
1157         
1158         tflags = alloca(strlen(flags) + 1);
1159         strcpy(tflags, flags);
1160         p = tflags;
1161         while (p)
1162           {
1163              pp = strchr(p, ' ');
1164              if (pp) *pp = 0;
1165              sscanf(p, "quality=%i", &quality);
1166              sscanf(p, "compress=%i", &compress);
1167              if (pp) p = pp + 1;
1168              else break;
1169           }
1170      }
1171    im = (RGBA_Image*) evas_cache_image_data(evas_common_image_cache_get(),
1172                                             o->cur.image.w,
1173                                             o->cur.image.h,
1174                                             data,
1175                                             o->cur.has_alpha,
1176                                             EVAS_COLORSPACE_ARGB8888);
1177    if (im)
1178      {
1179         if (o->cur.cspace == EVAS_COLORSPACE_ARGB8888)
1180           im->image.data = data;
1181         else
1182           im->image.data = evas_object_image_data_convert_internal(o,
1183                                                                    data,
1184                                                                    EVAS_COLORSPACE_ARGB8888);
1185         if (im->image.data)
1186           {
1187              ok = evas_common_save_image_to_file(im, file, key, quality, compress);
1188
1189              if (o->cur.cspace != EVAS_COLORSPACE_ARGB8888)
1190                free(im->image.data);
1191           }
1192
1193         evas_cache_image_drop(&im->cache_entry);
1194      }
1195    return ok;
1196 }
1197
1198 /**
1199  * To be documented.
1200  *
1201  * FIXME: To be fixed.
1202  *
1203  */
1204 EAPI Evas_Bool
1205 evas_object_image_pixels_import(Evas_Object *obj, Evas_Pixel_Import_Source *pixels)
1206 {
1207    Evas_Object_Image *o;
1208
1209    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1210    return 0;
1211    MAGIC_CHECK_END();
1212    o = (Evas_Object_Image *)(obj->object_data);
1213    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1214    return 0;
1215    MAGIC_CHECK_END();
1216
1217    if ((pixels->w != o->cur.image.w) || (pixels->h != o->cur.image.h)) return 0;
1218    switch (pixels->format)
1219      {
1220 #if 0
1221       case EVAS_PIXEL_FORMAT_ARGB32:
1222           {
1223              if (o->engine_data)
1224                {
1225                   DATA32 *image_pixels = NULL;
1226
1227                   o->engine_data =
1228                     obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1229                                                                   o->engine_data,
1230                                                                   1,
1231                                                                   &image_pixels);
1232 /* FIXME: need to actualyl support this */
1233 /*                memcpy(image_pixels, pixels->rows, o->cur.image.w * o->cur.image.h * 4);*/
1234                   if (o->engine_data)
1235                     o->engine_data =
1236                     obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1237                                                                   o->engine_data,
1238                                                                   image_pixels);
1239                   if (o->engine_data)
1240                     o->engine_data =
1241                     obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1242                                                                    o->engine_data,
1243                                                                    o->cur.has_alpha);
1244                   o->changed = 1;
1245                   evas_object_change(obj);
1246                }
1247           }
1248         break;
1249 #endif
1250 #ifdef BUILD_CONVERT_YUV
1251       case EVAS_PIXEL_FORMAT_YUV420P_601:
1252           {
1253              if (o->engine_data)
1254                {
1255                   DATA32 *image_pixels = NULL;
1256
1257                   o->engine_data =
1258                     obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1259                                                                   o->engine_data,
1260                                                                   1,
1261                                                                   &image_pixels);
1262                   if (image_pixels)
1263                     evas_common_convert_yuv_420p_601_rgba((DATA8 **) pixels->rows,
1264                                                           (DATA8 *) image_pixels,
1265                                                           o->cur.image.w,
1266                                                           o->cur.image.h);
1267                   if (o->engine_data)
1268                     o->engine_data =
1269                     obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1270                                                                   o->engine_data,
1271                                                                   image_pixels);
1272                   if (o->engine_data)
1273                     o->engine_data =
1274                     obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1275                                                                    o->engine_data,
1276                                                                    o->cur.has_alpha);
1277                   o->changed = 1;
1278                   evas_object_change(obj);
1279                }
1280           }
1281         break;
1282 #endif
1283       default:
1284         return 0;
1285         break;
1286      }
1287    return 1;
1288 }
1289
1290 /**
1291  * To be documented.
1292  *
1293  * FIXME: To be fixed.
1294  *
1295  */
1296 EAPI void
1297 evas_object_image_pixels_get_callback_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *o), void *data)
1298 {
1299    Evas_Object_Image *o;
1300
1301    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1302    return;
1303    MAGIC_CHECK_END();
1304    o = (Evas_Object_Image *)(obj->object_data);
1305    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1306    return;
1307    MAGIC_CHECK_END();
1308    o->func.get_pixels = func;
1309    o->func.get_pixels_data = data;
1310 }
1311
1312 /**
1313  * Mark whether the given image object is dirty (needs to be redrawn).
1314  *
1315  * @param obj The given image object.
1316  * @param dirty Whether the image is dirty.
1317  * @ingroup Evas_Object_Image
1318  */
1319 EAPI void
1320 evas_object_image_pixels_dirty_set(Evas_Object *obj, Evas_Bool dirty)
1321 {
1322    Evas_Object_Image *o;
1323
1324    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1325    return;
1326    MAGIC_CHECK_END();
1327    o = (Evas_Object_Image *)(obj->object_data);
1328    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1329    return;
1330    MAGIC_CHECK_END();
1331    if (dirty) o->dirty_pixels = 1;
1332    else o->dirty_pixels = 0;
1333    o->changed = 1;
1334    evas_object_change(obj);
1335 }
1336
1337 /**
1338  * Retrieves whether the given image object is dirty (needs to be redrawn).
1339  *
1340  * @param obj The given image object.
1341  * @return Whether the image is dirty.
1342  * @ingroup Evas_Object_Image
1343  */
1344 EAPI Evas_Bool
1345 evas_object_image_pixels_dirty_get(const Evas_Object *obj)
1346 {
1347    Evas_Object_Image *o;
1348
1349    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1350    return 0;
1351    MAGIC_CHECK_END();
1352    o = (Evas_Object_Image *)(obj->object_data);
1353    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1354    return 0;
1355    MAGIC_CHECK_END();
1356    if (o->dirty_pixels) return 1;
1357    return 0;
1358 }
1359
1360 /**
1361  * To be documented.
1362  *
1363  * FIXME: To be fixed.
1364  *
1365  */
1366 EAPI void
1367 evas_object_image_load_dpi_set(Evas_Object *obj, double dpi)
1368 {
1369    Evas_Object_Image *o;
1370
1371    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1372    return;
1373    MAGIC_CHECK_END();
1374    o = (Evas_Object_Image *)(obj->object_data);
1375    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1376    return;
1377    MAGIC_CHECK_END();
1378    o->load_opts.dpi = dpi;
1379    if (o->cur.file)
1380      {
1381         evas_object_image_unload(obj);
1382         evas_object_image_load(obj);
1383         o->changed = 1;
1384         evas_object_change(obj);
1385      }
1386 }
1387
1388 /**
1389  * To be documented.
1390  *
1391  * FIXME: To be fixed.
1392  *
1393  */
1394 EAPI double
1395 evas_object_image_load_dpi_get(const Evas_Object *obj)
1396 {
1397    Evas_Object_Image *o;
1398
1399    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1400    return 0.0;
1401    MAGIC_CHECK_END();
1402    o = (Evas_Object_Image *)(obj->object_data);
1403    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1404    return 0.0;
1405    MAGIC_CHECK_END();
1406    return o->load_opts.dpi;
1407 }
1408
1409 /**
1410  * To be documented.
1411  *
1412  * FIXME: To be fixed.
1413  *
1414  */
1415 EAPI void
1416 evas_object_image_load_size_set(Evas_Object *obj, int w, int h)
1417 {
1418    Evas_Object_Image *o;
1419
1420    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1421    return;
1422    MAGIC_CHECK_END();
1423    o = (Evas_Object_Image *)(obj->object_data);
1424    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1425    return;
1426    MAGIC_CHECK_END();
1427    o->load_opts.w = w;
1428    o->load_opts.h = h;
1429    if (o->cur.file)
1430      {
1431         evas_object_image_unload(obj);
1432         evas_object_image_load(obj);
1433         o->changed = 1;
1434         evas_object_change(obj);
1435      }
1436 }
1437
1438 EAPI void
1439 evas_object_image_load_size_get(const Evas_Object *obj, int *w, int *h)
1440 {
1441    Evas_Object_Image *o;
1442
1443    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1444    return;
1445    MAGIC_CHECK_END();
1446    o = (Evas_Object_Image *)(obj->object_data);
1447    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1448    return;
1449    MAGIC_CHECK_END();
1450    if (w) *w = o->load_opts.w;
1451    if (h) *h = o->load_opts.h;
1452 }
1453
1454 /**
1455  * To be documented.
1456  *
1457  * FIXME: To be fixed.
1458  *
1459  */
1460 EAPI void
1461 evas_object_image_load_scale_down_set(Evas_Object *obj, int scale_down)
1462 {
1463    Evas_Object_Image *o;
1464
1465    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1466    return;
1467    MAGIC_CHECK_END();
1468    o = (Evas_Object_Image *)(obj->object_data);
1469    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1470    return;
1471    MAGIC_CHECK_END();
1472    o->load_opts.scale_down_by = scale_down;
1473    if (o->cur.file)
1474      {
1475         evas_object_image_unload(obj);
1476         evas_object_image_load(obj);
1477         o->changed = 1;
1478         evas_object_change(obj);
1479      }
1480 }
1481
1482 /**
1483  * To be documented.
1484  *
1485  * FIXME: To be fixed.
1486  *
1487  */
1488 EAPI int
1489 evas_object_image_load_scale_down_get(const Evas_Object *obj)
1490 {
1491    Evas_Object_Image *o;
1492
1493    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1494    return 0;
1495    MAGIC_CHECK_END();
1496    o = (Evas_Object_Image *)(obj->object_data);
1497    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1498    return 0;
1499    MAGIC_CHECK_END();
1500    return o->load_opts.scale_down_by;
1501 }
1502
1503 /**
1504  * To be documented.
1505  *
1506  * FIXME: To be fixed.
1507  *
1508  */
1509 EAPI void
1510 evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace)
1511 {
1512    Evas_Object_Image *o;
1513
1514    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1515    return;
1516    MAGIC_CHECK_END();
1517    o = (Evas_Object_Image *)(obj->object_data);
1518    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1519    return;
1520    MAGIC_CHECK_END();
1521    o->cur.cspace = cspace;
1522    if (o->engine_data)
1523      obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output,
1524                                                          o->engine_data,
1525                                                          cspace);
1526 }
1527
1528 /**
1529  * To be documented.
1530  *
1531  * FIXME: To be fixed.
1532  *
1533  */
1534 EAPI Evas_Colorspace
1535 evas_object_image_colorspace_get(const Evas_Object *obj)
1536 {
1537    Evas_Object_Image *o;
1538
1539    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1540    return EVAS_COLORSPACE_ARGB8888;
1541    MAGIC_CHECK_END();
1542    o = (Evas_Object_Image *)(obj->object_data);
1543    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1544    return EVAS_COLORSPACE_ARGB8888;
1545    MAGIC_CHECK_END();
1546    return o->cur.cspace;
1547 }
1548
1549 /**
1550  * To be documented.
1551  *
1552  * FIXME: To be fixed.
1553  *
1554  */
1555 EAPI void
1556 evas_object_image_native_surface_set(Evas_Object *obj, Evas_Native_Surface *surf)
1557 {
1558    Evas_Object_Image *o;
1559
1560    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1561    return;
1562    MAGIC_CHECK_END();
1563    o = (Evas_Object_Image *)(obj->object_data);
1564    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1565    return;
1566    MAGIC_CHECK_END();
1567    obj->layer->evas->engine.func->image_native_set(obj->layer->evas->engine.data.output,
1568                                                    o->engine_data,
1569                                                    surf);
1570 }
1571
1572 /**
1573  * To be documented.
1574  *
1575  * FIXME: To be fixed.
1576  *
1577  */
1578 EAPI Evas_Native_Surface *
1579 evas_object_image_native_surface_get(const Evas_Object *obj)
1580 {
1581    Evas_Object_Image *o;
1582
1583    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1584    return NULL;
1585    MAGIC_CHECK_END();
1586    o = (Evas_Object_Image *)(obj->object_data);
1587    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1588    return NULL;
1589    MAGIC_CHECK_END();
1590    return obj->layer->evas->engine.func->image_native_get(obj->layer->evas->engine.data.output,
1591                                                           o->engine_data);
1592 }
1593
1594 /**
1595  * To be documented.
1596  *
1597  * FIXME: To be fixed.
1598  *
1599  */
1600 EAPI void
1601 evas_image_cache_flush(Evas *e)
1602 {
1603    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
1604    return;
1605    MAGIC_CHECK_END();
1606
1607    e->engine.func->image_cache_flush(e->engine.data.output);
1608 }
1609
1610 /**
1611  * To be documented.
1612  *
1613  * FIXME: To be fixed.
1614  *
1615  */
1616 EAPI void
1617 evas_image_cache_reload(Evas *e)
1618 {
1619    Evas_Object_List *l;
1620
1621    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
1622    return;
1623    MAGIC_CHECK_END();
1624
1625    evas_image_cache_flush(e);
1626    for (l = (Evas_Object_List *)e->layers; l; l = l->next)
1627      {
1628         Evas_Layer *layer;
1629         Evas_Object_List *l2;
1630
1631         layer = (Evas_Layer *)l;
1632         for (l2 = (Evas_Object_List *)layer->objects; l2; l2 = l2->next)
1633           {
1634              Evas_Object *obj;
1635              Evas_Object_Image *o;
1636
1637              obj = (Evas_Object *)l2;
1638              o = (Evas_Object_Image *)(obj->object_data);
1639              if (o->magic == MAGIC_OBJ_IMAGE)
1640                {
1641                   evas_object_image_unload(obj);
1642                }
1643           }
1644      }
1645    evas_image_cache_flush(e);
1646    for (l = (Evas_Object_List *)e->layers; l; l = l->next)
1647      {
1648         Evas_Layer *layer;
1649         Evas_Object_List *l2;
1650
1651         layer = (Evas_Layer *)l;
1652         for (l2 = (Evas_Object_List *)layer->objects; l2; l2 = l2->next)
1653           {
1654              Evas_Object *obj;
1655              Evas_Object_Image *o;
1656
1657              obj = (Evas_Object *)l2;
1658              o = (Evas_Object_Image *)(obj->object_data);
1659              if (o->magic == MAGIC_OBJ_IMAGE)
1660                {
1661                   evas_object_image_load(obj);
1662                   o->changed = 1;
1663                   evas_object_change(obj);
1664                }
1665           }
1666      }
1667    evas_image_cache_flush(e);
1668 }
1669
1670 /**
1671  * To be documented.
1672  *
1673  * FIXME: To be fixed.
1674  *
1675  */
1676 EAPI void
1677 evas_image_cache_set(Evas *e, int size)
1678 {
1679    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
1680    return;
1681    MAGIC_CHECK_END();
1682
1683    if (size < 0) size = 0;
1684    e->engine.func->image_cache_set(e->engine.data.output, size);
1685 }
1686
1687 /**
1688  * To be documented.
1689  *
1690  * FIXME: To be fixed.
1691  *
1692  */
1693 EAPI int
1694 evas_image_cache_get(const Evas *e)
1695 {
1696    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
1697    return 0;
1698    MAGIC_CHECK_END();
1699
1700    return e->engine.func->image_cache_get(e->engine.data.output);
1701 }
1702
1703 /* all nice and private */
1704
1705 static void
1706 evas_object_image_unload(Evas_Object *obj)
1707 {
1708    Evas_Object_Image *o;
1709
1710    o = (Evas_Object_Image *)(obj->object_data);
1711
1712    if ((!o->cur.file) ||
1713        (o->pixels_checked_out > 0)) return;
1714    if (o->engine_data)
1715      o->engine_data = obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output,
1716                                                                         o->engine_data,
1717                                                                         0, 0,
1718                                                                         o->cur.image.w, o->cur.image.h);
1719    if (o->engine_data)
1720      obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
1721                                                o->engine_data);
1722    o->engine_data = NULL;
1723    o->load_error = EVAS_LOAD_ERROR_NONE;
1724    o->cur.has_alpha = 1;
1725    o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
1726    o->cur.image.w = 0;
1727    o->cur.image.h = 0;
1728    o->cur.image.stride = 0;
1729 }
1730
1731 static void
1732 evas_object_image_load(Evas_Object *obj)
1733 {
1734    Evas_Object_Image *o;
1735    Evas_Image_Load_Opts lo;
1736
1737    o = (Evas_Object_Image *)(obj->object_data);
1738    if (o->engine_data) return;
1739
1740    lo.scale_down_by = o->load_opts.scale_down_by;
1741    lo.dpi = o->load_opts.dpi;
1742    lo.w = o->load_opts.w;
1743    lo.h = o->load_opts.h;
1744    o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output,
1745                                                               o->cur.file,
1746                                                               o->cur.key,
1747                                                               &o->load_error,
1748                                                               &lo);
1749    if (o->engine_data)
1750      {
1751         int w, h;
1752         int stride;
1753
1754         obj->layer->evas->engine.func->image_size_get(obj->layer->evas->engine.data.output,
1755                                                       o->engine_data, &w, &h);
1756         if (obj->layer->evas->engine.func->image_stride_get)
1757           obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output,
1758                                                           o->engine_data, &stride);
1759         else
1760           stride = w;
1761         o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output,
1762                                                                           o->engine_data);
1763         o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
1764                                                                             o->engine_data);
1765         o->cur.image.w = w;
1766         o->cur.image.h = h;
1767         o->cur.image.stride = stride;
1768      }
1769    else
1770      {
1771         o->load_error = EVAS_LOAD_ERROR_GENERIC;
1772      }
1773 }
1774
1775 static Evas_Coord
1776 evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
1777 {
1778    Evas_Coord w;
1779
1780    w = ((size * obj->layer->evas->output.w) /
1781         (Evas_Coord)obj->layer->evas->viewport.w);
1782    if (size <= 0) size = 1;
1783    if (start > 0)
1784      {
1785         while (start - size > 0) start -= size;
1786      }
1787    else if (start < 0)
1788      {
1789         while (start < 0) start += size;
1790      }
1791    start = ((start * obj->layer->evas->output.w) /
1792             (Evas_Coord)obj->layer->evas->viewport.w);
1793    *size_ret = w;
1794    return start;
1795 }
1796
1797 static Evas_Coord
1798 evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
1799 {
1800    Evas_Coord h;
1801
1802    h = ((size * obj->layer->evas->output.h) /
1803         (Evas_Coord)obj->layer->evas->viewport.h);
1804    if (size <= 0) size = 1;
1805    if (start > 0)
1806      {
1807         while (start - size > 0) start -= size;
1808      }
1809    else if (start < 0)
1810      {
1811         while (start < 0) start += size;
1812      }
1813    start = ((start * obj->layer->evas->output.h) /
1814             (Evas_Coord)obj->layer->evas->viewport.h);
1815    *size_ret = h;
1816    return start;
1817 }
1818
1819 static void
1820 evas_object_image_init(Evas_Object *obj)
1821 {
1822    /* alloc image ob, setup methods and default values */
1823    obj->object_data = evas_object_image_new();
1824    /* set up default settings for this kind of object */
1825    obj->cur.color.r = 255;
1826    obj->cur.color.g = 255;
1827    obj->cur.color.b = 255;
1828    obj->cur.color.a = 255;
1829    obj->cur.geometry.x = 0;
1830    obj->cur.geometry.y = 0;
1831    obj->cur.geometry.w = 0;
1832    obj->cur.geometry.h = 0;
1833    obj->cur.layer = 0;
1834    obj->cur.anti_alias = 0;
1835    obj->cur.render_op = EVAS_RENDER_BLEND;
1836    /* set up object-specific settings */
1837    obj->prev = obj->cur;
1838    /* set up methods (compulsory) */
1839    obj->func = &object_func;
1840    obj->type = o_type;
1841 }
1842
1843 static void *
1844 evas_object_image_new(void)
1845 {
1846    Evas_Object_Image *o;
1847
1848    /* alloc obj private data */
1849    o = calloc(1, sizeof(Evas_Object_Image));
1850    o->magic = MAGIC_OBJ_IMAGE;
1851    o->cur.fill.w = 1;
1852    o->cur.fill.h = 1;
1853    o->cur.smooth_scale = 1;
1854    o->cur.border.fill = 1;
1855    o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
1856    o->prev = o->cur;
1857    return o;
1858 }
1859
1860 static void
1861 evas_object_image_free(Evas_Object *obj)
1862 {
1863    Evas_Object_Image *o;
1864
1865    /* frees private object data. very simple here */
1866    o = (Evas_Object_Image *)(obj->object_data);
1867    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1868    return;
1869    MAGIC_CHECK_END();
1870    /* free obj */
1871    if (o->cur.file) evas_stringshare_del(o->cur.file);
1872    if (o->cur.key) evas_stringshare_del(o->cur.key);
1873    if (o->engine_data)
1874      obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
1875                                                o->engine_data);
1876    o->engine_data = NULL;
1877    o->magic = 0;
1878    while (o->pixel_updates)
1879      {
1880         Evas_Rectangle *r;
1881
1882         r = (Evas_Rectangle *)o->pixel_updates->data;
1883         o->pixel_updates = evas_list_remove(o->pixel_updates, r);
1884         free(r);
1885      }
1886    free(o);
1887 }
1888
1889 static void
1890 evas_object_image_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
1891 {
1892    Evas_Object_Image *o;
1893
1894    /* render object to surface with context, and offset by x,y */
1895    o = (Evas_Object_Image *)(obj->object_data);
1896    obj->layer->evas->engine.func->context_color_set(output,
1897                                                     context,
1898                                                     255, 255, 255, 255);
1899
1900    if ((obj->cur.cache.clip.r == 255) &&
1901        (obj->cur.cache.clip.g == 255) &&
1902        (obj->cur.cache.clip.b == 255) &&
1903        (obj->cur.cache.clip.a == 255))
1904      {
1905         obj->layer->evas->engine.func->context_multiplier_unset(output,
1906                                                                 context);
1907      }
1908    else
1909      obj->layer->evas->engine.func->context_multiplier_set(output,
1910                                                            context,
1911                                                            obj->cur.cache.clip.r,
1912                                                            obj->cur.cache.clip.g,
1913                                                            obj->cur.cache.clip.b,
1914                                                            obj->cur.cache.clip.a);
1915
1916    obj->layer->evas->engine.func->context_render_op_set(output, context,
1917                                                         obj->cur.render_op);
1918    if (o->engine_data)
1919      {
1920         Evas_Coord idw, idh, idx, idy;
1921         int ix, iy, iw, ih;
1922
1923         if (o->dirty_pixels)
1924           {
1925              if (o->func.get_pixels)
1926                {
1927                   o->func.get_pixels(o->func.get_pixels_data, obj);
1928                   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);
1929                }
1930              o->dirty_pixels = 0;
1931           }
1932         o->engine_data = obj->layer->evas->engine.func->image_border_set(output, o->engine_data,
1933                                                                          o->cur.border.l, o->cur.border.r,
1934                                                                          o->cur.border.t, o->cur.border.b);
1935         idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
1936         idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
1937         if (idw < 1.0) idw = 1.0;
1938         if (idh < 1.0) idh = 1.0;
1939         if (idx > 0.0) idx -= idw;
1940         if (idy > 0.0) idy -= idh;
1941         while ((int)idx < obj->cur.geometry.w)
1942           {
1943              Evas_Coord ydy;
1944              int dobreak_w = 0;
1945
1946              ydy = idy;
1947              ix = idx;
1948              if ((o->cur.fill.w == obj->cur.geometry.w) &&
1949                  (o->cur.fill.x == 0.0))
1950                {
1951                   dobreak_w = 1;
1952                   iw = obj->cur.geometry.w;
1953                }
1954              else
1955                iw = ((int)(idx + idw)) - ix;
1956              while ((int)idy < obj->cur.geometry.h)
1957                {
1958                   int dobreak_h = 0;
1959
1960                   iy = idy;
1961                   if ((o->cur.fill.h == obj->cur.geometry.h) &&
1962                       (o->cur.fill.y == 0.0))
1963                     {
1964                        ih = obj->cur.geometry.h;
1965                        dobreak_h = 1;
1966                     }
1967                   else
1968                     ih = ((int)(idy + idh)) - iy;
1969                   if ((o->cur.border.l == 0) &&
1970                       (o->cur.border.r == 0) &&
1971                       (o->cur.border.t == 0) &&
1972                       (o->cur.border.b == 0) &&
1973                       (o->cur.border.fill != 0))
1974                     obj->layer->evas->engine.func->image_draw(output,
1975                                                               context,
1976                                                               surface,
1977                                                               o->engine_data,
1978                                                               0, 0,
1979                                                               o->cur.image.w,
1980                                                               o->cur.image.h,
1981                                                               obj->cur.geometry.x + ix + x,
1982                                                               obj->cur.geometry.y + iy + y,
1983                                                               iw, ih,
1984                                                               o->cur.smooth_scale);
1985                   else
1986                     {
1987                        int inx, iny, inw, inh, outx, outy, outw, outh;
1988                        int bl, br, bt, bb;
1989                        int imw, imh, ox, oy;
1990
1991                        ox = obj->cur.geometry.x + ix + x;
1992                        oy = obj->cur.geometry.y + iy + y;
1993                        imw = o->cur.image.w;
1994                        imh = o->cur.image.h;
1995                        bl = o->cur.border.l;
1996                        br = o->cur.border.r;
1997                        bt = o->cur.border.t;
1998                        bb = o->cur.border.b;
1999                        if ((bl + br) > iw)
2000                          {
2001                             bl = iw / 2;
2002                             br = iw - bl;
2003                          }
2004                        if ((bl + br) > imw)
2005                          {
2006                             bl = imw / 2;
2007                             br = imw - bl;
2008                          }
2009                        if ((bt + bb) > ih)
2010                          {
2011                             bt = ih / 2;
2012                             bb = ih - bt;
2013                          }
2014                        if ((bt + bb) > imh)
2015                          {
2016                             bt = imh / 2;
2017                             bb = imh - bt;
2018                          }
2019
2020                        inx = 0; iny = 0;
2021                        inw = bl; inh = bt;
2022                        outx = ox; outy = oy;
2023                        outw = bl; outh = bt;
2024                        obj->layer->evas->engine.func->image_draw(output, context, surface, o->engine_data, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
2025                        inx = bl; iny = 0;
2026                        inw = imw - bl - br; inh = bt;
2027                        outx = ox + bl; outy = oy;
2028                        outw = iw - bl - br; outh = bt;
2029                        obj->layer->evas->engine.func->image_draw(output, context, surface, o->engine_data, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
2030                        inx = imw - br; iny = 0;
2031                        inw = br; inh = bt;
2032                        outx = ox + iw - br; outy = oy;
2033                        outw = br; outh = bt;
2034                        obj->layer->evas->engine.func->image_draw(output, context, surface, o->engine_data, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
2035
2036                        inx = 0; iny = bt;
2037                        inw = bl; inh = imh - bt - bb;
2038                        outx = ox; outy = oy + bt;
2039                        outw = bl; outh = ih - bt - bb;
2040                        obj->layer->evas->engine.func->image_draw(output, context, surface, o->engine_data, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
2041                        if (o->cur.border.fill)
2042                          {
2043                             inx = bl; iny = bt;
2044                             inw = imw - bl - br; inh = imh - bt - bb;
2045                             outx = ox + bl; outy = oy + bt;
2046                             outw = iw - bl - br; outh = ih - bt - bb;
2047                             obj->layer->evas->engine.func->image_draw(output, context, surface, o->engine_data, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
2048                          }
2049                        inx = imw - br; iny = bt;
2050                        inw = br; inh = imh - bt - bb;
2051                        outx = ox + iw - br; outy = oy + bt;
2052                        outw = br; outh = ih - bt - bb;
2053                        obj->layer->evas->engine.func->image_draw(output, context, surface, o->engine_data, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
2054
2055                        inx = 0; iny = imh - bb;
2056                        inw = bl; inh = bb;
2057                        outx = ox; outy = oy + ih - bb;
2058                        outw = bl; outh = bb;
2059                        obj->layer->evas->engine.func->image_draw(output, context, surface, o->engine_data, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
2060                        inx = bl; iny = imh - bb;
2061                        inw = imw - bl - br; inh = bb;
2062                        outx = ox + bl; outy = oy + ih - bb;
2063                        outw = iw - bl - br; outh = bb;
2064                        obj->layer->evas->engine.func->image_draw(output, context, surface, o->engine_data, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
2065                        inx = imw - br; iny = imh - bb;
2066                        inw = br; inh = bb;
2067                        outx = ox + iw - br; outy = oy + ih - bb;
2068                        outw = br; outh = bb;
2069                        obj->layer->evas->engine.func->image_draw(output, context, surface, o->engine_data, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
2070                     }
2071                   idy += idh;
2072                   if (dobreak_h) break;
2073                }
2074              idx += idw;
2075              idy = ydy;
2076              if (dobreak_w) break;
2077           }
2078      }
2079 }
2080
2081 static void
2082 evas_object_image_render_pre(Evas_Object *obj)
2083 {
2084    Evas_Rectangles rects = { 0, 0, NULL };
2085    Evas_Object_Image *o;
2086    int is_v, was_v;
2087
2088    /* dont pre-render the obj twice! */
2089    if (obj->pre_render_done) return;
2090    obj->pre_render_done = 1;
2091    /* pre-render phase. this does anything an object needs to do just before */
2092    /* rendering. this could mean loading the image data, retrieving it from */
2093    /* elsewhere, decoding video etc. */
2094    /* then when this is done the object needs to figure if it changed and */
2095    /* if so what and where and add the appropriate redraw rectangles */
2096    o = (Evas_Object_Image *)(obj->object_data);
2097    /* if someone is clipping this obj - go calculate the clipper */
2098    if (obj->cur.clipper)
2099      {
2100         if (obj->cur.cache.clip.dirty)
2101           evas_object_clip_recalc(obj->cur.clipper);
2102         obj->cur.clipper->func->render_pre(obj->cur.clipper);
2103      }
2104    /* now figure what changed and add draw rects */
2105    /* if it just became visible or invisible */
2106    is_v = evas_object_is_visible(obj);
2107    was_v = evas_object_was_visible(obj);
2108    if (is_v != was_v)
2109      {
2110         evas_object_render_pre_visible_change(&rects, obj, is_v, was_v);
2111         if (!o->pixel_updates) goto done;
2112      }
2113    /* it's not visible - we accounted for it appearing or not so just abort */
2114    if (!is_v) goto done;
2115    /* clipper changed this is in addition to anything else for obj */
2116    evas_object_render_pre_clipper_change(&rects, obj);
2117    /* if we restacked (layer or just within a layer) and don't clip anyone */
2118    if (obj->restack)
2119      {
2120         evas_object_render_pre_prev_cur_add(&rects, obj);
2121         if (!o->pixel_updates) goto done;
2122      }
2123    /* if it changed color */
2124    if ((obj->cur.color.r != obj->prev.color.r) ||
2125        (obj->cur.color.g != obj->prev.color.g) ||
2126        (obj->cur.color.b != obj->prev.color.b) ||
2127        (obj->cur.color.a != obj->prev.color.a))
2128      {
2129         evas_object_render_pre_prev_cur_add(&rects, obj);
2130         if (!o->pixel_updates) goto done;
2131      }
2132    /* if it changed render op */
2133    if (obj->cur.render_op != obj->prev.render_op)
2134      {
2135         evas_object_render_pre_prev_cur_add(&rects, obj);
2136         if (!o->pixel_updates) goto done;
2137      }
2138    /* if it changed anti_alias */
2139    if (obj->cur.anti_alias != obj->prev.anti_alias)
2140      {
2141         evas_object_render_pre_prev_cur_add(&rects, obj);
2142         if (!o->pixel_updates) goto done;
2143      }
2144    if (o->changed)
2145      {
2146         if (((o->cur.file) && (!o->prev.file)) ||
2147             ((!o->cur.file) && (o->prev.file)) ||
2148             ((o->cur.key) && (!o->prev.key)) ||
2149             ((!o->cur.key) && (o->prev.key))
2150             )
2151           {
2152              evas_object_render_pre_prev_cur_add(&rects, obj);
2153              if (!o->pixel_updates) goto done;
2154           }
2155         if ((o->cur.image.w != o->prev.image.w) ||
2156             (o->cur.image.h != o->prev.image.h) ||
2157             (o->cur.has_alpha != o->prev.has_alpha) ||
2158             (o->cur.cspace != o->prev.cspace) ||
2159             (o->cur.smooth_scale != o->prev.smooth_scale))
2160           {
2161              evas_object_render_pre_prev_cur_add(&rects, obj);
2162              if (!o->pixel_updates) goto done;
2163           }
2164         if ((o->cur.border.l != o->prev.border.l) ||
2165             (o->cur.border.r != o->prev.border.r) ||
2166             (o->cur.border.t != o->prev.border.t) ||
2167             (o->cur.border.b != o->prev.border.b))
2168           {
2169              evas_object_render_pre_prev_cur_add(&rects, obj);
2170              if (!o->pixel_updates) goto done;
2171           }
2172         if (o->dirty_pixels)
2173           {
2174              evas_object_render_pre_prev_cur_add(&rects, obj);
2175              if (!o->pixel_updates) goto done;
2176           }
2177      }
2178    /* if it changed geometry - and obviously not visibility or color */
2179    /* caluclate differences since we have a constant color fill */
2180    /* we really only need to update the differences */
2181    if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
2182         (obj->cur.geometry.y != obj->prev.geometry.y) ||
2183         (obj->cur.geometry.w != obj->prev.geometry.w) ||
2184         (obj->cur.geometry.h != obj->prev.geometry.h)) &&
2185        (o->cur.fill.w == o->prev.fill.w) &&
2186        (o->cur.fill.h == o->prev.fill.h) &&
2187        ((o->cur.fill.x + obj->cur.geometry.x) == (o->prev.fill.x + obj->prev.geometry.x)) &&
2188        ((o->cur.fill.y + obj->cur.geometry.y) == (o->prev.fill.y + obj->prev.geometry.y)) &&
2189        (!o->pixel_updates)
2190        )
2191      {
2192         evas_rects_return_difference_rects(&rects,
2193                                            obj->cur.geometry.x,
2194                                            obj->cur.geometry.y,
2195                                            obj->cur.geometry.w,
2196                                            obj->cur.geometry.h,
2197                                            obj->prev.geometry.x,
2198                                            obj->prev.geometry.y,
2199                                            obj->prev.geometry.w,
2200                                            obj->prev.geometry.h);
2201         if (!o->pixel_updates) goto done;
2202      }
2203    if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
2204         (obj->cur.geometry.y != obj->prev.geometry.y) ||
2205         (obj->cur.geometry.w != obj->prev.geometry.w) ||
2206         (obj->cur.geometry.h != obj->prev.geometry.h))
2207        )
2208      {
2209         evas_object_render_pre_prev_cur_add(&rects, obj);
2210         if (!o->pixel_updates) goto done;
2211      }
2212    if (o->changed)
2213      {
2214         if ((o->cur.fill.x != o->prev.fill.x) ||
2215             (o->cur.fill.y != o->prev.fill.y) ||
2216             (o->cur.fill.w != o->prev.fill.w) ||
2217             (o->cur.fill.h != o->prev.fill.h))
2218           {
2219              evas_object_render_pre_prev_cur_add(&rects, obj);
2220              if (!o->pixel_updates) goto done;
2221           }
2222         if ((o->cur.border.l == 0) &&
2223             (o->cur.border.r == 0) &&
2224             (o->cur.border.t == 0) &&
2225             (o->cur.border.b == 0))
2226           {
2227              while (o->pixel_updates)
2228                {
2229                   Evas_Rectangle *rr;
2230                   Evas_Coord idw, idh, idx, idy;
2231                   int x, y, w, h;
2232
2233                   rr = o->pixel_updates->data;
2234                   o->pixel_updates = evas_list_remove(o->pixel_updates, rr);
2235                   obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, o->engine_data, rr->x, rr->y, rr->w, rr->h);
2236                   
2237                   idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
2238                   idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
2239
2240                   if (idw < 1) idw = 1;
2241                   if (idh < 1) idh = 1;
2242                   if (idx > 0) idx -= idw;
2243                   if (idy > 0) idy -= idh;
2244                   while (idx < obj->cur.geometry.w)
2245                     {
2246                        Evas_Coord ydy;
2247
2248                        ydy = idy;
2249                        x = idx;
2250                        w = ((int)(idx + idw)) - x;
2251                        while (idy < obj->cur.geometry.h)
2252                          {
2253                             Evas_Rectangle r;
2254
2255                             y = idy;
2256                             h = ((int)(idy + idh)) - y;
2257
2258                             r.x = ((rr->x - 1) * w) / o->cur.image.w;
2259                             r.y = ((rr->y - 1) * h) / o->cur.image.h;
2260                             r.w = ((rr->w + 2) * w) / o->cur.image.w;
2261                             r.h = ((rr->h + 2) * h) / o->cur.image.h;
2262                             r.x += obj->cur.geometry.x + x;
2263                             r.y += obj->cur.geometry.y + y;
2264                             evas_add_rect(&rects, r.x, r.y, r.w, r.h);
2265                             idy += h;
2266                          }
2267                        idx += idw;
2268                        idy = ydy;
2269                     }
2270                   free(rr);
2271                }
2272              goto done;
2273           }
2274         else
2275           {
2276              if (o->pixel_updates)
2277                {
2278                   while (o->pixel_updates)
2279                     {
2280                        Evas_Rectangle *r;
2281
2282                        r = (Evas_Rectangle *)o->pixel_updates->data;
2283                        o->pixel_updates = evas_list_remove(o->pixel_updates, r);
2284                        free(r);
2285                     }
2286                   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);
2287                   evas_object_render_pre_prev_cur_add(&rects, obj);
2288                   goto done;
2289                }
2290           }
2291      }
2292    /* it obviously didn't change - add a NO obscure - this "unupdates"  this */
2293    /* area so if there were updates for it they get wiped. don't do it if we */
2294    /* aren't fully opaque and we are visible */
2295    if (evas_object_is_visible(obj) &&
2296        evas_object_is_opaque(obj))
2297      obj->layer->evas->engine.func->output_redraws_rect_del(obj->layer->evas->engine.data.output,
2298                                                             obj->cur.cache.clip.x,
2299                                                             obj->cur.cache.clip.y,
2300                                                             obj->cur.cache.clip.w,
2301                                                             obj->cur.cache.clip.h);
2302    done:
2303    evas_object_render_pre_effect_updates(&rects, obj, is_v, was_v);
2304 }
2305
2306 static void
2307 evas_object_image_render_post(Evas_Object *obj)
2308 {
2309    Evas_Object_Image *o;
2310
2311    /* this moves the current data to the previous state parts of the object */
2312    /* in whatever way is safest for the object. also if we don't need object */
2313    /* data anymore we can free it if the object deems this is a good idea */
2314    o = (Evas_Object_Image *)(obj->object_data);
2315    /* remove those pesky changes */
2316    while (obj->clip.changes)
2317      {
2318         Evas_Rectangle *r;
2319
2320         r = (Evas_Rectangle *)obj->clip.changes->data;
2321         obj->clip.changes = evas_list_remove(obj->clip.changes, r);
2322         free(r);
2323      }
2324    while (o->pixel_updates)
2325      {
2326         Evas_Rectangle *r;
2327
2328         r = (Evas_Rectangle *)o->pixel_updates->data;
2329         o->pixel_updates = evas_list_remove(o->pixel_updates, r);
2330         free(r);
2331      }
2332    /* move cur to prev safely for object data */
2333    obj->prev = obj->cur;
2334    o->prev = o->cur;
2335    o->changed = 0;
2336    /* FIXME: copy strings across */
2337 }
2338
2339 static int
2340 evas_object_image_is_opaque(Evas_Object *obj)
2341 {
2342    Evas_Object_Image *o;
2343
2344    /* this returns 1 if the internal object data implies that the object is */
2345    /* currently fully opaque over the entire rectangle it occupies */
2346    o = (Evas_Object_Image *)(obj->object_data);
2347    if (((o->cur.border.l != 0) ||
2348         (o->cur.border.r != 0) ||
2349         (o->cur.border.t != 0) ||
2350         (o->cur.border.b != 0)) &&
2351        (!o->cur.border.fill)) return 0;
2352    if (!o->engine_data) return 0;
2353    if (obj->cur.render_op == EVAS_RENDER_COPY)
2354         return 1;
2355    if (o->cur.has_alpha) return 0;
2356    if (obj->cur.render_op != EVAS_RENDER_BLEND)
2357         return 0;
2358    return 1;
2359 }
2360
2361 static int
2362 evas_object_image_was_opaque(Evas_Object *obj)
2363 {
2364    Evas_Object_Image *o;
2365
2366    /* this returns 1 if the internal object data implies that the object was */
2367    /* previously fully opaque over the entire rectangle it occupies */
2368    o = (Evas_Object_Image *)(obj->object_data);
2369    if (((o->prev.border.l != 0) ||
2370         (o->prev.border.r != 0) ||
2371         (o->prev.border.t != 0) ||
2372         (o->prev.border.b != 0)) &&
2373        (!o->prev.border.fill)) return 0;
2374    if (!o->engine_data) return 0;
2375    if (obj->prev.render_op == EVAS_RENDER_COPY)
2376         return 1;
2377    if (o->prev.has_alpha) return 0;
2378    if (obj->prev.render_op != EVAS_RENDER_BLEND)
2379         return 0;
2380    return 1;
2381 }
2382
2383 static int
2384 evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
2385 {
2386    Evas_Object_Image *o;
2387    DATA32 *data;
2388    int w, h, stride;
2389    int a;
2390
2391    o = (Evas_Object_Image *)(obj->object_data);
2392
2393    x -= obj->cur.cache.clip.x;
2394    y -= obj->cur.cache.clip.y;
2395    w = o->cur.image.w;
2396    h = o->cur.image.h;
2397
2398    if ((x > w) || (y > h))
2399      return 0;
2400
2401    if (!o->cur.has_alpha)
2402      return 1;
2403
2404    stride = o->cur.image.stride;
2405
2406    o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
2407                                                                   o->engine_data,
2408                                                                   0,
2409                                                                   &data);
2410    if (!data)
2411      return 0;
2412
2413    switch (o->cur.cspace)
2414      {
2415         case EVAS_COLORSPACE_ARGB8888:
2416           data = ((DATA32*)(data) + ((y * stride) + x));
2417           a = (*((DATA32*)(data)) >> 24) & 0xff;
2418           break;
2419         case EVAS_COLORSPACE_RGB565_A5P:
2420            data = (void*) ((DATA16*)(data) + (h * stride));
2421           data = (void*) ((DATA8*)(data) + ((y * stride) + x));
2422           a = (*((DATA8*)(data))) & 0x1f;
2423           break;
2424         default:
2425           return 1;
2426           break;
2427      }
2428
2429    return (a != 0);
2430 }
2431
2432 static void *
2433 evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace)
2434 {
2435    void *out = NULL;
2436
2437    if (!data)
2438      return NULL;
2439
2440    switch (o->cur.cspace)
2441      {
2442         case EVAS_COLORSPACE_ARGB8888:
2443           out = evas_common_convert_argb8888_to(data,
2444                                                 o->cur.image.w,
2445                                                 o->cur.image.h,
2446                                                 o->cur.image.stride,
2447                                                 o->cur.has_alpha,
2448                                                 to_cspace);
2449           break;
2450         case EVAS_COLORSPACE_RGB565_A5P:
2451           out = evas_common_convert_rgb565_a5p_to(data,
2452                                                   o->cur.image.w,
2453                                                   o->cur.image.h,
2454                                                   o->cur.image.stride,
2455                                                   o->cur.has_alpha,
2456                                                   to_cspace);
2457           break;
2458         default:
2459           break;
2460      }
2461
2462    return out;
2463 }