--- /dev/null
+diff --git a/src/lib/Evas.h b/src/lib/Evas.h
+index 18864ce..a56fd92 100644
+--- a/src/lib/Evas.h
++++ b/src/lib/Evas.h
+@@ -478,6 +478,7 @@ extern "C" {
+ EAPI void evas_object_image_size_get (Evas_Object *obj, int *w, int *h);
+ EAPI int evas_object_image_stride_get (Evas_Object *obj);
+ EAPI int evas_object_image_load_error_get (Evas_Object *obj);
++ EAPI void *evas_object_image_data_convert (Evas_Object *obj, Evas_Colorspace to_cspace);
+ EAPI void evas_object_image_data_set (Evas_Object *obj, void *data);
+ EAPI void *evas_object_image_data_get (Evas_Object *obj, Evas_Bool for_writing);
+ EAPI void evas_object_image_data_copy_set (Evas_Object *obj, void *data);
+diff --git a/src/lib/canvas/evas_object_image.c b/src/lib/canvas/evas_object_image.c
+index 6a8df55..92b0651 100644
+--- a/src/lib/canvas/evas_object_image.c
++++ b/src/lib/canvas/evas_object_image.c
+@@ -69,6 +69,8 @@ static int evas_object_image_is_opaque(Evas_Object *obj);
+ static int evas_object_image_was_opaque(Evas_Object *obj);
+ static int evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+
++static void *evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace);
++
+ static const Evas_Object_Func object_func =
+ {
+ /* methods (compulsory) */
+@@ -708,6 +710,46 @@ evas_object_image_load_error_get(Evas_Object *obj)
+ */
+
+ /**
++ * Converts the raw image data of the given image object to the
++ * specified colorspace.
++ *
++ * Note that this function does not modify the raw image data.
++ * If the requested colorspace is the same as the image colorspace
++ * nothing is done and NULL is returned. You should use
++ * evas_object_image_colorspace_get() to check the current image
++ * colorspace.
++ *
++ * See @ref evas_object_image_colorspace_get.
++ *
++ * @param obj The given image object.
++ * @param to_cspace The colorspace to which the image raw data will be converted.
++ * @return data A newly allocated data in the format specified by to_cspace.
++ * @ingroup Evas_Object_Image_Data
++ */
++EAPI void *
++evas_object_image_data_convert(Evas_Object *obj, Evas_Colorspace to_cspace)
++{
++ Evas_Object_Image *o;
++ DATA32 *data;
++
++ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
++ return NULL;
++ MAGIC_CHECK_END();
++ o = (Evas_Object_Image *)(obj->object_data);
++ MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
++ return NULL;
++ MAGIC_CHECK_END();
++ if (!o->engine_data) return NULL;
++ if (!o->cur.cspace == to_cspace) return NULL;
++ data = NULL;
++ o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
++ o->engine_data,
++ 0,
++ &data);
++ return evas_object_image_data_convert_internal(o, data, to_cspace);
++}
++
++/**
+ * Sets the raw image data of the given image object.
+ *
+ * Note that the raw data must be of the same size and colorspace
+@@ -1126,11 +1168,22 @@ evas_object_image_save(Evas_Object *obj, const char *file, const char *key, cons
+ {
+ if (o->cur.has_alpha) im->flags |= RGBA_IMAGE_HAS_ALPHA;
+
+- im->image->data = data;
+- im->image->w = o->cur.image.w;
+- im->image->h = o->cur.image.h;
+- im->image->no_free = 1;
+- ok = evas_common_save_image_to_file(im, file, key, quality, compress);
++ if (o->cur.cspace == EVAS_COLORSPACE_ARGB8888)
++ im->image->data = data;
++ else
++ im->image->data = evas_object_image_data_convert_internal(o,
++ data,
++ EVAS_COLORSPACE_ARGB8888);
++ if (im->image->data)
++ {
++ im->image->w = o->cur.image.w;
++ im->image->h = o->cur.image.h;
++ im->image->no_free = 1;
++ ok = evas_common_save_image_to_file(im, file, key, quality, compress);
++
++ if (o->cur.cspace != EVAS_COLORSPACE_ARGB8888)
++ free(im->image->data);
++ }
+
+ evas_cache_image_drop(im);
+ }
+@@ -2376,3 +2429,36 @@ evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+
+ return (a != 0);
+ }
++
++static void *
++evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace)
++{
++ void *out = NULL;
++
++ if (!data)
++ return NULL;
++
++ switch (o->cur.cspace)
++ {
++ case EVAS_COLORSPACE_ARGB8888:
++ out = evas_common_convert_argb8888_to(data,
++ o->cur.image.w,
++ o->cur.image.h,
++ o->cur.image.stride,
++ o->cur.has_alpha,
++ to_cspace);
++ break;
++ case EVAS_COLORSPACE_RGB565_A5P:
++ out = evas_common_convert_rgb565_a5p_to(data,
++ o->cur.image.w,
++ o->cur.image.h,
++ o->cur.image.stride,
++ o->cur.has_alpha,
++ to_cspace);
++ break;
++ default:
++ break;
++ }
++
++ return out;
++}
+diff --git a/src/lib/engines/common/Makefile.am b/src/lib/engines/common/Makefile.am
+index c15675b..3d5fd7c 100644
+--- a/src/lib/engines/common/Makefile.am
++++ b/src/lib/engines/common/Makefile.am
+@@ -21,6 +21,7 @@ evas_op_mul_main_.c \
+ evas_blend_main.c \
+ evas_blit_main.c \
+ evas_convert_color.c \
++evas_convert_colorspace.c \
+ evas_convert_gry_1.c \
+ evas_convert_gry_4.c \
+ evas_convert_gry_8.c \
+diff --git a/src/lib/engines/common/evas_convert_colorspace.c b/src/lib/engines/common/evas_convert_colorspace.c
+new file mode 100644
+index 0000000..287bd2e
+--- /dev/null
++++ b/src/lib/engines/common/evas_convert_colorspace.c
+@@ -0,0 +1,69 @@
++#include "evas_common.h"
++
++#define CONVERT_RGB_565_TO_RGB_888(s) \
++ (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
++ ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
++ ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
++
++#define CONVERT_A5P_TO_A8(s) \
++ ((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7))
++
++static inline void *
++evas_common_convert_argb8888_to_rgb565_a5p(void *data, int w, int h, int stride, Evas_Bool has_alpha)
++{
++}
++
++static inline void *
++evas_common_convert_rgb565_a5p_to_argb8888(void *data, int w, int h, int stride, Evas_Bool has_alpha)
++{
++ DATA16 *src, *end;
++ DATA32 *ret, *dst;
++ int r, g, b;
++
++ src = data;
++ end = src + (stride * h);
++ ret = malloc(w * h * sizeof(DATA32));
++
++ dst = ret;
++ if (has_alpha)
++ {
++ DATA8 *alpha;
++
++ alpha = end;
++ for (; src < end; src++, alpha++, dst++)
++ *dst = (CONVERT_A5P_TO_A8(*alpha) << 24) |
++ CONVERT_RGB_565_TO_RGB_888(*src);
++ }
++ else
++ {
++ for (; src < end; src++, dst++)
++ *dst = CONVERT_RGB_565_TO_RGB_888(*src);
++ }
++ return ret;
++}
++
++EAPI void *
++evas_common_convert_argb8888_to(void *data, int w, int h, int stride, Evas_Bool has_alpha, Evas_Colorspace cspace)
++{
++ switch (cspace)
++ {
++ case EVAS_COLORSPACE_RGB565_A5P:
++ return evas_common_convert_argb8888_to_rgb565_a5p(data, w, h, stride, has_alpha);
++ default:
++ break;
++ }
++ return NULL;
++}
++
++EAPI void *
++evas_common_convert_rgb565_a5p_to(void *data, int w, int h, int stride, Evas_Bool has_alpha, Evas_Colorspace cspace)
++{
++ switch (cspace)
++ {
++ case EVAS_COLORSPACE_ARGB8888:
++ return evas_common_convert_rgb565_a5p_to_argb8888(data, w, h, stride, has_alpha);
++ default:
++ break;
++ }
++ return NULL;
++}
+diff --git a/src/lib/include/evas_common.h b/src/lib/include/evas_common.h
+index a61ed6d..4c724b1 100644
+--- a/src/lib/include/evas_common.h
++++ b/src/lib/include/evas_common.h
+@@ -998,6 +998,9 @@ EAPI void evas_common_convert_color_rgb_to_hsv (int r, int g
+ EAPI void evas_common_convert_color_hsv_to_rgb_int (int h, int s, int v, int *r, int *g, int *b);
+ EAPI void evas_common_convert_color_rgb_to_hsv_int (int r, int g, int b, int *h, int *s, int *v);
+
++EAPI void *evas_common_convert_argb8888_to (void *data, int w, int h, int stride, Evas_Bool has_alpha, Evas_Colorspace cspace);
++EAPI void *evas_common_convert_rgb565_a5p_to (void *data, int w, int h, int stride, Evas_Bool has_alpha, Evas_Colorspace cspace);
++
+ /****/
+ EAPI void evas_common_scale_init (void);
+