summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkabeer khan <kabeer.khan@samsung.com>2015-02-11 17:30:49 +0100
committerCedric BAIL <cedric@osg.samsung.com>2015-02-11 17:30:54 +0100
commit46b9b23144ba6a95d619b1aa21ec326ea92303b6 (patch)
tree1fb951df8d0f01d8477352f42438c003326be1fe
parent566eefd7d0e4ac70dca3f12b6ce99ae12bec7102 (diff)
downloadefl-46b9b23144ba6a95d619b1aa21ec326ea92303b6.tar.gz
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.khan@samsung.com> Reviewers: raster, stephenmhouston, cedric Subscribers: stephenmhouston, cedric Differential Revision: https://phab.enlightenment.org/D1950 Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
-rw-r--r--src/examples/evas/.gitignore1
-rw-r--r--src/examples/evas/Makefile.am6
-rw-r--r--src/examples/evas/Makefile.examples1
-rw-r--r--src/examples/evas/evas-images4.c180
-rw-r--r--src/lib/evas/Evas_Common.h18
-rw-r--r--src/lib/evas/canvas/evas_image.eo28
-rw-r--r--src/lib/evas/canvas/evas_object_image.c64
-rw-r--r--src/lib/evas/include/evas_common_private.h1
-rw-r--r--src/lib/evas/include/evas_private.h2
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c341
10 files changed, 641 insertions, 1 deletions
diff --git a/src/examples/evas/.gitignore b/src/examples/evas/.gitignore
index 7c29ff584b..579d96b971 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 fd8e552e00..b5846f3e24 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 be10cd57cd..313be1b3b0 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 0000000000..391664ef94
--- /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 e1ab7d6c42..27d8dfa199 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 23e563de6c..df97e32525 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 9ec344a15d..cf4309778c 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 56dc039c53..0160af565b 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 3cd94aa6f8..c07cfa31df 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 a3b15b4dcc..58cbb23a60 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,