Hi,

I have a patch to Evas_Object_Image that's here for a long time.
We even release our evas with this patch, but I never found the time
to finish it (needs conversion to from YUV colorspaces).
The main idea of the patch is to enable images with colorspace != 8888
to be saved to a file. It adds a method evas_object_image_data_convert
that can be really useful in other cases.

If you want I can commit it, tell me what you think

BR

Ps.: The patch is generated against a really old evas, but I believe
it still applies :)

-- 
Andre Moreira Magalhaes (andrunko)
--------------------------------------------------------
Jabber: [EMAIL PROTECTED]
MSN: [EMAIL PROTECTED]
Skype: andrunko
Blog: http://andrunko.blogspot.com
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);
 
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to