cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=46b9b23144ba6a95d619b1aa21ec326ea92303b6

commit 46b9b23144ba6a95d619b1aa21ec326ea92303b6
Author: kabeer khan <kabeer.k...@samsung.com>
Date:   Wed Feb 11 17:30:49 2015 +0100

    evas: add image orient set/get API in software backend for now.
    
    Summary:
    Added API's to rotate(0, 90, 180, 270), flip(horizontal, vertical, 
transpose, transverse)
    evas image object. Also added example to demonstrate this.
    
    Signed-off-by: kabeer khan <kabeer.k...@samsung.com>
    
    Reviewers: raster, stephenmhouston, cedric
    
    Subscribers: stephenmhouston, cedric
    
    Differential Revision: https://phab.enlightenment.org/D1950
    
    Signed-off-by: Cedric BAIL <ced...@osg.samsung.com>
---
 src/examples/evas/.gitignore                       |   1 +
 src/examples/evas/Makefile.am                      |   6 +
 src/examples/evas/Makefile.examples                |   1 +
 src/examples/evas/evas-images4.c                   | 180 +++++++++++
 src/lib/evas/Evas_Common.h                         |  18 ++
 src/lib/evas/canvas/evas_image.eo                  |  28 ++
 src/lib/evas/canvas/evas_object_image.c            |  64 +++-
 src/lib/evas/include/evas_common_private.h         |   1 +
 src/lib/evas/include/evas_private.h                |   2 +
 .../evas/engines/software_generic/evas_engine.c    | 341 +++++++++++++++++++++
 10 files changed, 641 insertions(+), 1 deletion(-)

diff --git a/src/examples/evas/.gitignore b/src/examples/evas/.gitignore
index 7c29ff5..579d96b 100644
--- a/src/examples/evas/.gitignore
+++ b/src/examples/evas/.gitignore
@@ -5,6 +5,7 @@
 /evas_images
 /evas_images2
 /evas_images3
+/evas_images4
 /evas_init_shutdown
 /evas_object_manipulation
 /evas_object_manipulation-eo
diff --git a/src/examples/evas/Makefile.am b/src/examples/evas/Makefile.am
index fd8e552..b5846f3 100644
--- a/src/examples/evas/Makefile.am
+++ b/src/examples/evas/Makefile.am
@@ -139,6 +139,11 @@ evas_images3_SOURCES = evas-images3.c
 evas_images3_LDADD = $(ECORE_EVAS_COMMON_LDADD)
 evas_images3_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS)
 
+EXTRA_PROGRAMS += evas_images4
+evas_images4_SOURCES = evas-images4.c
+evas_images4_LDADD = $(ECORE_EVAS_COMMON_LDADD)
+evas_images4_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS)
+
 EXTRA_PROGRAMS += evas_text
 evas_text_SOURCES = evas-text.c
 evas_text_LDADD = $(ECORE_EVAS_COMMON_LDADD)
@@ -300,6 +305,7 @@ evas-hints.c \
 evas-images.c \
 evas-images2.c \
 evas-images3.c \
+evas-images4.c \
 evas-init-shutdown.c \
 evas-map-utils.c \
 evas-map-aa.c \
diff --git a/src/examples/evas/Makefile.examples 
b/src/examples/evas/Makefile.examples
index be10cd5..313be1b 100644
--- a/src/examples/evas/Makefile.examples
+++ b/src/examples/evas/Makefile.examples
@@ -14,6 +14,7 @@ EXAMPLES= evas-aspect-hints \
           evas-images \
           evas-images2 \
           evas-images3 \
+          evas-images4 \
           evas-init-shutdown \
           evas-map-utils \
           evas-object-manipulation \
diff --git a/src/examples/evas/evas-images4.c b/src/examples/evas/evas-images4.c
new file mode 100644
index 0000000..391664e
--- /dev/null
+++ b/src/examples/evas/evas-images4.c
@@ -0,0 +1,180 @@
+/**
+ * Simple Evas example illustrating some image objects functions
+ *
+ * You'll need at least one engine built for it (excluding the buffer
+ * one) and the png image loader/saver also built. See stdout/stderr
+ * for output.
+ *
+ * @verbatim
+ * gcc -o evas-images4 evas-images4.c `pkg-config --libs --cflags evas ecore 
ecore-evas`
+ * @endverbatim
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#else
+#define PACKAGE_EXAMPLES_DIR "."
+#endif
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <stdio.h>
+#include <errno.h>
+
+#define WIDTH  (320)
+#define HEIGHT (240)
+
+static const char *img_path = PACKAGE_EXAMPLES_DIR "/im1.png";
+static const char *commands = \
+  "commands are:\n"
+  "\tp - print image fill property\n"
+  "\t0 - rotate by 0\n"
+  "\t1 - rotate by 90\n"
+  "\t2 - rotate by 180\n"
+  "\t3 - rotate by 270\n"
+  "\t4 - flip horizontal\n"
+  "\t5 - flip vertical\n"
+  "\t6 - flip transpose\n"
+  "\t7 - flip transverse\n"
+  "\ts - save noise image to disk (/tmp dir)\n"
+  "\th - print help\n";
+
+const char *file_path = "/tmp/evas-images4-example.png";
+const char *quality_str = "quality=100";
+
+struct test_data
+{
+   Ecore_Evas  *ee;
+   Evas        *evas;
+   Evas_Object *bg, *img;
+};
+
+static struct test_data d = {0};
+
+static void
+_on_destroy(Ecore_Evas *ee EINA_UNUSED)
+{
+   ecore_main_loop_quit();
+}
+
+/* here just to keep our example's window size and background image's
+ * size in synchrony */
+static void
+_canvas_resize_cb(Ecore_Evas *ee)
+{
+   int w, h;
+
+   ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+   evas_object_resize(d.bg, w, h);
+}
+
+static void
+_on_keydown(void        *data EINA_UNUSED,
+            Evas        *evas EINA_UNUSED,
+            Evas_Object *o EINA_UNUSED,
+            void        *einfo)
+{
+   Evas_Event_Key_Down *ev = einfo;
+
+   if (strcmp(ev->key, "h") == 0) /* print help */
+     {
+        fprintf(stdout, commands);
+        return;
+     }
+
+   if (strcmp(ev->key, "s") == 0) /* save noise image to disk */
+     {
+        if (!evas_object_image_save(d.img, file_path, NULL, quality_str))
+          fprintf(stderr, "Cannot save image to '%s' (flags '%s')\n",
+                  file_path, quality_str);
+        else
+          fprintf(stdout, "Image saved to '%s' (flags '%s'), check it out with 
"
+                          "an image viewer\n", file_path, quality_str);
+
+        return;
+     }
+
+   if (strcmp(ev->key, "p") == 0) /* print image size*/
+     {
+        Evas_Coord w, h;
+
+        evas_object_image_size_get(d.img, &w, &h);
+        fprintf(stdout, "Image has size set to: w=%d, h=%d\n", w, h);
+        return;
+     }
+
+   int key_val = ev->key[0] - '0';
+   if (key_val >= 0 && key_val <= 7)
+     {
+        evas_object_image_orient_set(d.img, key_val);
+        fprintf(stdout, "Set %i and got %i\n", key_val,
+                evas_object_image_orient_get(d.img));
+
+        return;
+     }
+}
+
+int
+main(void)
+{
+   int err;
+
+   if (!ecore_evas_init())
+     return EXIT_FAILURE;
+
+   /* this will give you a window with an Evas canvas under the first
+    * engine available */
+   d.ee = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL);
+   if (!d.ee)
+     goto error;
+
+   ecore_evas_callback_destroy_set(d.ee, _on_destroy);
+   ecore_evas_callback_resize_set(d.ee, _canvas_resize_cb);
+   ecore_evas_show(d.ee);
+
+   /* the canvas pointer, de facto */
+   d.evas = ecore_evas_get(d.ee);
+
+   d.bg = evas_object_rectangle_add(d.evas);
+   evas_object_color_set(d.bg, 255, 255, 255, 255); /* white bg */
+   evas_object_move(d.bg, 0, 0); /* at canvas' origin */
+   evas_object_resize(d.bg, WIDTH, HEIGHT); /* covers full canvas */
+   evas_object_show(d.bg);
+
+   d.img = evas_object_image_add(d.evas);
+   evas_object_image_file_set(d.img, img_path, NULL);
+   err = evas_object_image_load_error_get(d.img);
+   if (err != EVAS_LOAD_ERROR_NONE)
+     {
+        fprintf(stderr, "could not load image '%s'. error string is \"%s\"\n",
+                img_path, evas_load_error_str(err));
+     }
+   else
+     {
+        fprintf(stdout, 
+                "loaded image '%s' with succes! error string is \"%s\"\n",
+                img_path, evas_load_error_str(err));
+
+        evas_object_move(d.img, WIDTH / 2, HEIGHT / 2);
+        evas_object_image_fill_set(d.img, 0, 0, WIDTH / 2, HEIGHT / 2);
+        evas_object_resize(d.img, WIDTH / 2, HEIGHT / 2);
+        evas_object_show(d.img);
+
+        evas_object_focus_set(d.bg, EINA_TRUE);
+        evas_object_event_callback_add(
+          d.bg, EVAS_CALLBACK_KEY_DOWN, _on_keydown, NULL);
+     }
+
+   fprintf(stdout, commands);
+   ecore_main_loop_begin();
+
+   ecore_evas_free(d.ee);
+   ecore_evas_shutdown();
+   return 0;
+
+error:
+   fprintf(stderr, "you got to have at least one evas engine built and linked"
+                   " up to ecore-evas for this example to run properly.\n");
+   ecore_evas_shutdown();
+   return -1;
+}
diff --git a/src/lib/evas/Evas_Common.h b/src/lib/evas/Evas_Common.h
index e1ab7d6..27d8dfa 100644
--- a/src/lib/evas/Evas_Common.h
+++ b/src/lib/evas/Evas_Common.h
@@ -631,6 +631,24 @@ typedef enum _Evas_Image_Content_Hint
    EVAS_IMAGE_CONTENT_HINT_STATIC = 2 /**< The contents won't change over time 
*/
 } Evas_Image_Content_Hint; /**< How an image's data is to be treated by Evas, 
for optimization */
 
+/**
+ * Possible orientation options for evas_object_image_orient_set().
+ * @brief Types of orientation available
+ * @since 1.14
+ */
+typedef enum _Evas_Image_Orient
+{
+   EVAS_IMAGE_ORIENT_NONE = 0, /**< no orientation change */
+   EVAS_IMAGE_ORIENT_0 = 0, /**< no orientation change */
+   EVAS_IMAGE_ORIENT_90 = 1, /**< orient 90 degrees clockwise*/
+   EVAS_IMAGE_ORIENT_180 = 2, /**< orient 180 degrees clockwise */
+   EVAS_IMAGE_ORIENT_270 = 3, /**< rotate 90 degrees counter-clockwise (i.e. 
270 degrees clockwise)*/
+   EVAS_IMAGE_FLIP_HORIZONTAL = 4, /**< flip image horizontally */
+   EVAS_IMAGE_FLIP_VERTICAL = 5, /**< flip image vertically */
+   EVAS_IMAGE_FLIP_TRANSPOSE = 6, /**< flip image along the y = (width - x) 
line (bottom-left to top-right) */
+   EVAS_IMAGE_FLIP_TRANSVERSE = 7 /**< flip image along the y = x line 
(top-left to bottom-right) */
+} Evas_Image_Orient;
+
 typedef enum _Evas_Device_Class
 {
    EVAS_DEVICE_CLASS_NONE, /**< Not a device @since 1.8 */
diff --git a/src/lib/evas/canvas/evas_image.eo 
b/src/lib/evas/canvas/evas_image.eo
index 23e563d..df97e32 100644
--- a/src/lib/evas/canvas/evas_image.eo
+++ b/src/lib/evas/canvas/evas_image.eo
@@ -925,6 +925,34 @@ class Evas.Image (Evas.Object, Efl.File, Efl.Image)
             int b; /*@ Bottom padding in pixels */
          }
       }
+      orient {
+         set {
+            /*@
+            Set the image orientation.
+
+            This function allows to rotate or flip the image.
+
+            @see evas_object_image_orient_get()
+            @see @ref Evas_Image_Orient
+
+            @since 1.14*/
+         }
+         get {
+            /*@
+            Get the image orientation.
+
+            @return The image orientation @ref Evas_Image_Orient
+
+            @see evas_object_image_orient_set()
+            @see @ref Evas_Image_Orient
+
+            @since 1.14*/
+         }
+         values {
+            Evas_Image_Orient orient; /*@ The image orientation @ref 
Evas_Image_Orient
+            Default is #EVAS_IMAGE_ORIENT_NONE. */
+         }
+      }
    }
    methods {
       preload_begin {
diff --git a/src/lib/evas/canvas/evas_object_image.c 
b/src/lib/evas/canvas/evas_object_image.c
index 9ec344a..cf43097 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -92,7 +92,8 @@ struct _Evas_Object_Image_State
    int            frame;
    int            spread;
 
-   Evas_Colorspace cspace;
+   Evas_Colorspace    cspace;
+   Evas_Image_Orient  orient;
 
    Eina_Bool      smooth_scale : 1;
    Eina_Bool      has_alpha :1;
@@ -237,6 +238,7 @@ static const Evas_Object_Image_State default_state = {
   0, //frame
   EVAS_TEXTURE_REPEAT,
   EVAS_COLORSPACE_ARGB8888,
+  EVAS_IMAGE_ORIENT_NONE,
 
   // flags
   EINA_TRUE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE
@@ -661,6 +663,61 @@ _evas_image_source_get(Eo *eo_obj EINA_UNUSED, 
Evas_Image_Data *o)
    return o->cur->source;
 }
 
+EOLIAN static void
+_evas_image_orient_set(Eo *eo_obj, Evas_Image_Data *o, Evas_Image_Orient 
orient)
+{
+   Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, 
EVAS_OBJECT_CLASS);
+   int iw, ih;
+
+   if (o->cur->orient == orient) return;
+
+   if ((o->preloading) && (o->engine_data))
+     {
+        o->preloading = EINA_FALSE;
+        ENFN->image_data_preload_cancel(ENDT, o->engine_data, eo_obj);
+     }
+
+   if(o->engine_data)
+     {
+        int stride = 0;
+
+        o->engine_data = ENFN->image_orient_set(ENDT, o->engine_data, orient);
+        if(o->engine_data)
+          {
+             EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
+              state_write->orient = orient;
+             EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
+
+             if (ENFN->image_stride_get)
+               ENFN->image_stride_get(ENDT, o->engine_data, &stride);
+             else
+               stride = o->cur->image.w * 4;
+             if (o->cur->image.stride != stride)
+               {
+                  EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
+                   state_write->image.stride = stride;
+                  EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
+               }
+             o->written = EINA_TRUE;
+          }
+        ENFN->image_size_get(ENDT, o->engine_data, &iw, &ih);
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
+          {
+             state_write->image.w = iw;
+             state_write->image.h = ih;
+          }
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
+     }
+   o->changed = EINA_TRUE;
+   evas_object_change(eo_obj, obj);
+}
+
+EOLIAN static Evas_Image_Orient
+_evas_image_orient_get(Eo *eo_obj EINA_UNUSED, Evas_Image_Data *o)
+{
+   return o->cur->orient;
+}
+
 EAPI Eina_Bool
 evas_object_image_source_unset(Evas_Object *eo_obj)
 {
@@ -3588,6 +3645,11 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
              evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, 
obj);
              if (!o->pixels->pixel_updates) goto done;
           }
+        if (o->cur->orient != o->prev->orient)
+          {
+             evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, 
obj);
+             if (!o->pixels->pixel_updates) goto done;
+          }
 
      }
    if (((obj->cur->geometry.x != obj->prev->geometry.x) ||
diff --git a/src/lib/evas/include/evas_common_private.h 
b/src/lib/evas/include/evas_common_private.h
index 56dc039..0160af5 100644
--- a/src/lib/evas/include/evas_common_private.h
+++ b/src/lib/evas/include/evas_common_private.h
@@ -596,6 +596,7 @@ struct _Image_Entry
    Evas_Image_Load_Opts   load_opts;
    Evas_Colorspace        space;
    const Evas_Colorspace *cspaces; // owned by the loader, live as long as the 
loader
+   Evas_Image_Orient      orient;
 
    unsigned int           w;
    unsigned int           h;
diff --git a/src/lib/evas/include/evas_private.h 
b/src/lib/evas/include/evas_private.h
index 3cd94aa..c07cfa3 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1217,6 +1217,8 @@ struct _Evas_Func
    void  (*image_data_preload_cancel)      (void *data, void *image, const Eo 
*target);
    void *(*image_alpha_set)                (void *data, void *image, int 
has_alpha);
    int  (*image_alpha_get)                 (void *data, void *image);
+   void *(*image_orient_set)               (void *data, void *image, 
Evas_Image_Orient orient);
+   Evas_Image_Orient (*image_orient_get)   (void *data, void *image);
    void *(*image_border_set)               (void *data, void *image, int l, 
int r, int t, int b);
    void  (*image_border_get)               (void *data, void *image, int *l, 
int *r, int *t, int *b);
    Eina_Bool (*image_draw)                 (void *data, void *context, void 
*surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, 
int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async);
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c 
b/src/modules/evas/engines/software_generic/evas_engine.c
index a3b15b4..58cbb23 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -57,6 +57,9 @@
 #define OSMESA_MAX_WIDTH       0x24  /* new in 4.0 */
 #define OSMESA_MAX_HEIGHT      0x25  /* new in 4.0 */
 
+/* Required for orient */
+#define TILE 32
+
 
 typedef void (*OSMESAproc)();
 typedef struct osmesa_context *OSMesaContext;
@@ -1291,6 +1294,342 @@ eng_image_data_put(void *data, void *image, DATA32 
*image_data)
    return im;
 }
 
+static void *
+_image_flip_horizontal(void *data, Image_Entry *im)
+{
+   unsigned int *p1, *p2, tmp;
+   DATA32 *image_data;
+   int x, y, iw, ih;
+   Image_Entry *im2;
+
+   iw = im->w;
+   ih = im->h;
+   image_data = evas_cache_image_pixels(im);
+   for (y = 0; y < ih; y++)
+     {
+        p1 = image_data + (y * iw);
+        p2 = image_data + ((y + 1) * iw) - 1;
+        for (x = 0; x < (iw >> 1); x++)
+          {
+             tmp = *p1;
+             *p1 = *p2;
+             *p2 = tmp;
+             p1++;
+             p2--;
+          }
+     }
+   im2 = eng_image_new_from_data(data, iw, ih, image_data,
+                                           eng_image_alpha_get(data, im),
+                                           eng_image_colorspace_get(data, im));
+   return im2;
+}
+
+static void *
+_image_flip_vertical(void *data, Image_Entry *im)
+{
+   unsigned int *p1, *p2, tmp;
+   DATA32 *image_data;
+   int x, y, iw, ih;
+   Image_Entry *im2;
+
+   iw = im->w;
+   ih = im->h;
+   image_data = evas_cache_image_pixels(im);
+   for (y = 0; y < (ih >> 1); y++)
+     {
+        p1 = image_data + (y * iw);
+        p2 = image_data + ((ih - 1 - y) * iw);
+        for (x = 0; x < iw; x++)
+          {
+             tmp = *p1;
+             *p1 = *p2;
+             *p2 = tmp;
+             p1++;
+             p2++;
+          }
+     }
+   im2 = eng_image_new_from_data(data, iw, ih, image_data,
+                                           eng_image_alpha_get(data, im),
+                                           eng_image_colorspace_get(data, im));
+   return im2;
+}
+
+static void *
+_image_rotate_180(void *data, Image_Entry *im)
+{
+   unsigned int *p1, *p2, tmp;
+   DATA32 *image_data;
+   int x, hw, iw, ih;
+   Image_Entry *im2;
+
+   iw = im->w;
+   ih = im->h;
+   image_data = evas_cache_image_pixels(im);
+   if(!image_data) return im;
+   hw = iw * ih;
+   x = (hw / 2);
+   p1 = image_data;
+   p2 = image_data + hw - 1;
+   for (; --x > 0; )
+     {
+        tmp = *p1;
+        *p1 = *p2;
+        *p2 = tmp;
+        p1++;
+        p2--;
+     }
+   im2 = eng_image_new_from_data(data, iw, ih, image_data,
+                                           eng_image_alpha_get(data, im),
+                                           eng_image_colorspace_get(data, im));
+   return im2;
+}
+
+# define GETDAT(neww, newh) \
+   DATA32 *image_data, *image_data2; \
+   int iw, ih, w, h; \
+   Image_Entry *im2; \
+   iw = im->w; \
+   ih = im->h; \
+   image_data = evas_cache_image_pixels(im); \
+   if (!image_data) return im; \
+   image_data2 = malloc(iw * ih * sizeof(int)); \
+   if (!image_data2) { \
+      return im; \
+   } \
+   memcpy(image_data2, image_data, iw * ih * sizeof(int)); \
+   im = eng_image_new_from_data(data, iw, ih, image_data, \
+                                           eng_image_alpha_get(data, im), \
+                                           eng_image_colorspace_get(data, 
im)); \
+   w = neww; h = newh; \
+   image_data = evas_cache_image_pixels(im); \
+
+# define PUTDAT \
+   im2 = eng_image_new_from_data(data, w, h, image_data, \
+                                           eng_image_alpha_get(data, im), \
+                                           eng_image_colorspace_get(data, 
im)); \
+   im2 = eng_image_size_set(data, im2, w, h); \
+   free(image_data2); \
+   return im2; \
+
+static void *
+_image_rotate_90(void *data, Image_Entry *im)
+{
+   GETDAT(ih, iw);
+   int x, y, xx, yy, xx2, yy2;
+   unsigned int *src, *dst;
+
+   for (y = 0; y < ih; y += TILE)
+     {
+        yy2 = y + TILE;
+        if (yy2 > ih) yy2 = ih;
+        for (x = 0; x < iw; x += TILE)
+          {
+             xx2 = x + TILE;
+             if (xx2 > iw) xx2 = iw;
+             for (yy = y; yy < yy2; yy++)
+               {
+                  src = image_data2 + (yy * iw) + x;
+                  dst = image_data + (x * w) + (w - yy - 1);
+                  for (xx = x; xx < xx2; xx++)
+                    {
+                       *dst = *src;
+                       src++;
+                       dst += w;
+                    }
+               }
+          }
+     }
+   PUTDAT;
+}
+
+static void *
+_image_rotate_270(void *data, Image_Entry *im)
+{
+   GETDAT(ih, iw);
+   int x, y, xx, yy, xx2, yy2;
+   unsigned int *src, *dst;
+
+   for (y = 0; y < ih; y += TILE)
+     {
+        yy2 = y + TILE;
+        if (yy2 > ih) yy2 = ih;
+        for (x = 0; x < iw; x += TILE)
+          {
+             xx2 = x + TILE;
+             if (xx2 > iw) xx2 = iw;
+             for (yy = y; yy < yy2; yy++)
+               {
+                  src = image_data2 + (yy * iw) + x;
+                  dst = image_data + ((h - x - 1) * w) + yy;
+                  for (xx = x; xx < xx2; xx++)
+                    {
+                       *dst = *src;
+                       src++;
+                       dst -= w;
+                    }
+               }
+          }
+     }
+   PUTDAT;
+}
+
+static void *
+_image_flip_transverse(void *data, Image_Entry *im)
+{
+   GETDAT(ih, iw);
+   int x, y;
+   unsigned int *src, *dst;
+
+   src = image_data2;
+   for (y = 0; y < ih; y++)
+     {
+        dst = image_data + y;
+        for (x = 0; x < iw; x++)
+          {
+             *dst = *src;
+             src++;
+             dst += w;
+          }
+     }
+   PUTDAT;
+}
+
+static void *
+_image_flip_transpose(void *data, Image_Entry *im)
+{
+   GETDAT(ih, iw);
+   int x, y;
+   unsigned int *src, *dst;
+
+   src = image_data2 + (iw * ih) - 1;
+   for (y = 0; y < ih; y++)
+     {
+        dst = image_data + y;
+        for (x = 0; x < iw; x++)
+          {
+             *dst = *src;
+             src--;
+             dst += w;
+          }
+     }
+   PUTDAT;
+}
+
+#undef GETDAT
+#undef PUTDAT
+
+static void *
+eng_image_orient_set(void *data, void *image, Evas_Image_Orient orient)
+{
+   Image_Entry *im;
+
+   if (!image) return NULL;
+   im = image;
+   if (im->orient == orient) return im;
+
+   if ((im->orient >= EVAS_IMAGE_ORIENT_0) &&
+       (im->orient <= EVAS_IMAGE_ORIENT_270) &&
+       (orient >= EVAS_IMAGE_ORIENT_0) &&
+       (orient <= EVAS_IMAGE_ORIENT_270))
+     {
+        // we are rotating from one anglee to another, so figure out delta
+        // and apply that delta
+        Evas_Image_Orient rot_delta = (4 + orient - im->orient) % 4;
+        switch (rot_delta)
+          {
+           case EVAS_IMAGE_ORIENT_0:
+             ERR("You shouldn't get this message, wrong orient value");
+             break;
+           case EVAS_IMAGE_ORIENT_90:
+             im = _image_rotate_90(data, im);
+             im->orient = orient;
+             break;
+           case EVAS_IMAGE_ORIENT_180:
+             im = _image_rotate_180(data, im);
+             im->orient = orient;
+             break;
+           case EVAS_IMAGE_ORIENT_270:
+             im = _image_rotate_270(data, im);
+             im->orient = orient;
+             break;
+           default:
+             ERR("Wrong orient value");
+             break;
+          }
+     }
+   else if (((im->orient == EVAS_IMAGE_ORIENT_NONE) &&
+             (orient == EVAS_IMAGE_FLIP_HORIZONTAL)) ||
+            ((im->orient == EVAS_IMAGE_FLIP_HORIZONTAL) &&
+             (orient == EVAS_IMAGE_ORIENT_NONE)))
+     {
+        // flip horizontally to get the new orientation
+        im = _image_flip_horizontal(data, im);
+        im->orient = orient;
+     }
+   else if (((im->orient == EVAS_IMAGE_ORIENT_NONE) &&
+             (orient == EVAS_IMAGE_FLIP_VERTICAL)) ||
+            ((im->orient == EVAS_IMAGE_FLIP_VERTICAL) &&
+             (orient == EVAS_IMAGE_ORIENT_NONE)))
+     {
+        // flip vertically to get the new orientation
+        im = _image_flip_vertical(data, im);
+        im->orient = orient;
+     }
+   else
+     {
+        // generic solution - undo the previous orientation and then apply the
+        // new one after that
+        int i;
+
+        for (i = 0; i < 2; i++)
+          {
+             switch (im->orient)
+               {
+                case EVAS_IMAGE_ORIENT_0:
+                  break;
+                case EVAS_IMAGE_ORIENT_90:
+                  if(i == 1) im = _image_rotate_90(data, im);
+                  else im = _image_rotate_270(data, im);
+                  break;
+                case EVAS_IMAGE_ORIENT_180:
+                  im = _image_rotate_180(data, im);
+                  break;
+                case EVAS_IMAGE_ORIENT_270:
+                  if(i == 1) im = _image_rotate_270(data, im);
+                  else im = _image_rotate_90(data, im);
+                  break;
+                case EVAS_IMAGE_FLIP_HORIZONTAL:
+                  im = _image_flip_horizontal(data, im);
+                  break;
+                case EVAS_IMAGE_FLIP_VERTICAL:
+                  im = _image_flip_vertical(data, im);
+                  break;
+                case EVAS_IMAGE_FLIP_TRANSPOSE:
+                  im = _image_flip_transpose(data, im);
+                  break;
+                case EVAS_IMAGE_FLIP_TRANSVERSE:
+                  im = _image_flip_transverse(data, im);
+                  break;
+                default:
+                  ERR("Wrong orient value");
+                  break;
+               }
+             im->orient = orient;
+          }
+     }
+   return im;
+}
+
+static Evas_Image_Orient
+eng_image_orient_get(void *data EINA_UNUSED, void *image)
+{
+   Image_Entry *im;
+
+   if (!image) return EVAS_IMAGE_ORIENT_NONE;
+   im = image;
+   return im->orient;
+}
+
 static void
 eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const Eo 
*target)
 {
@@ -3158,6 +3497,8 @@ static Evas_Func func =
      eng_image_data_preload_cancel,
      eng_image_alpha_set,
      eng_image_alpha_get,
+     eng_image_orient_set,
+     eng_image_orient_get,
      eng_image_border_set,
      eng_image_border_get,
      eng_image_draw,

-- 


Reply via email to