[evas] add image load module(BMP, WBMP)
authorSangjin Lee <lsj119@samsung.com>
Tue, 18 May 2010 10:15:11 +0000 (19:15 +0900)
committerSangjin Lee <lsj119@samsung.com>
Tue, 18 May 2010 10:15:11 +0000 (19:15 +0900)
16 files changed:
configure.ac [changed mode: 0644->0755]
evas.spec.in [changed mode: 0644->0755]
m4/evas_check_loader.m4 [changed mode: 0644->0755]
src/lib/engines/common/evas_image_load.c [changed mode: 0644->0755]
src/lib/file/evas_module.c [changed mode: 0644->0755]
src/lib/include/evas_wink.h [new file with mode: 0755]
src/modules/loaders/Makefile.am [changed mode: 0644->0755]
src/modules/loaders/bmp/.cvsignore [new file with mode: 0755]
src/modules/loaders/bmp/Makefile.am [new file with mode: 0755]
src/modules/loaders/bmp/evas_image_load_bmp.c [new file with mode: 0755]
src/modules/loaders/gif/evas_image_load_gif.c [changed mode: 0644->0755]
src/modules/loaders/jpeg/evas_image_load_jpeg.c [changed mode: 0644->0755]
src/modules/loaders/png/evas_image_load_png.c [changed mode: 0644->0755]
src/modules/loaders/wbmp/.cvsignore [new file with mode: 0755]
src/modules/loaders/wbmp/Makefile.am [new file with mode: 0755]
src/modules/loaders/wbmp/evas_image_load_wbmp.c [new file with mode: 0755]

old mode 100644 (file)
new mode 100755 (executable)
index e865dd8..346cb74
@@ -94,6 +94,8 @@ want_evas_image_loader_png="yes"
 want_evas_image_loader_svg="yes"
 want_evas_image_loader_tiff="yes"
 want_evas_image_loader_xpm="yes"
+want_evas_image_loader_bmp="yes"
+want_evas_image_loader_wbmp="yes"
 
 want_evas_font_loader_eet="yes"
 
@@ -205,6 +207,18 @@ PKG_CHECK_MODULES([FREETYPE], [freetype2 >= 9.3.0])
 
 requirement_evas="freetype2 eina-0 ${requirement_evas}"
 
+#WinkCodec
+AC_ARG_ENABLE([winkcodec],
+               AS_HELP_STRING([--enable-winkcodec],
+                       [enable/disable wink codec (default: no)]),
+               [WINK=$enableval], [WINK=no])
+
+#if test "x${WINK}" = "xyes" ; then
+#      PKG_CHECK_MODULES([LIBWINK],[wink])
+#      AC_DEFINE(USE_WINK_CODEC, 1, [use wink codec])
+#      requirement_evas="wink ${requirement_evas}"
+#fi
+
 ## optional dependencies
 
 # FontConfig
@@ -669,6 +683,10 @@ EVAS_CHECK_IMAGE_LOADER([Tiff], [${want_evas_image_loader_tiff}])
 
 EVAS_CHECK_IMAGE_LOADER([XPM], [${want_evas_image_loader_xpm}])
 
+EVAS_CHECK_IMAGE_LOADER([BMP], [${want_evas_image_loader_bmp}])
+
+EVAS_CHECK_IMAGE_LOADER([WBMP], [${want_evas_image_loader_wbmp}])
+
 
 #####################################################################
 ## Cpu based optimizations
@@ -1351,6 +1369,8 @@ src/modules/loaders/jpeg/Makefile
 src/modules/loaders/png/Makefile
 src/modules/loaders/tiff/Makefile
 src/modules/loaders/xpm/Makefile
+src/modules/loaders/bmp/Makefile
+src/modules/loaders/wbmp/Makefile
 src/modules/loaders/svg/Makefile
 src/modules/loaders/pmaps/Makefile
 src/modules/savers/Makefile
@@ -1428,6 +1448,8 @@ echo "  PNG.....................: $have_evas_image_loader_png"
 echo "  SVG.....................: $have_evas_image_loader_svg"
 echo "  TIFF....................: $have_evas_image_loader_tiff"
 echo "  XPM.....................: $have_evas_image_loader_xpm"
+echo "  BMP.....................: $have_evas_image_loader_bmp"
+echo "  WBMP....................: $have_evas_image_loader_wbmp"
 # FIXME: need to add modular image loader system
 # FIXME: add more image loader modules
 echo
old mode 100644 (file)
new mode 100755 (executable)
index 65fd1b9..d51dcb8
@@ -216,6 +216,24 @@ BuildRequires: edb-devel
 EDB Image saver module for Evas
 %endif
 
+%if %{with module_loader_bmp}
+%package module_loader_bmp
+Summary: BMP Image loader module for Evas
+Group: System Environment/Libraries
+##BuildRequires: (none, X?)
+%description module_loader_bmp
+BMP Image loader module for Evas
+%endif
+
+%if %{with module_loader_wbmp}
+%package module_loader_wbmp
+Summary: WBMP Image loader module for Evas
+Group: System Environment/Libraries
+##BuildRequires: (none, X?)
+%description module_loader_wbmp
+WBMP Image loader module for Evas
+%endif
+
 %if %{with module_loader_xpm}
 %package module_loader_xpm
 Summary: XPM Image loader module for Evas
old mode 100644 (file)
new mode 100755 (executable)
index 7b95465..f6b59e4
@@ -307,6 +307,48 @@ fi
 
 ])
 
+
+dnl use: EVAS_CHECK_LOADER_DEP_BMP(loader, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+
+AC_DEFUN([EVAS_CHECK_LOADER_DEP_BMP],
+[
+
+have_dep="yes"
+evas_image_loader_[]$1[]_cflags=""
+evas_image_loader_[]$1[]_libs=""
+
+AC_SUBST([evas_image_loader_$1_cflags])
+AC_SUBST([evas_image_loader_$1_libs])
+
+if test "x${have_dep}" = "xyes" ; then
+  m4_default([$3], [:])
+else
+  m4_default([$4], [:])
+fi
+
+])
+
+
+dnl use: EVAS_CHECK_LOADER_DEP_WBMP(loader, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+
+AC_DEFUN([EVAS_CHECK_LOADER_DEP_WBMP],
+[
+
+have_dep="yes"
+evas_image_loader_[]$1[]_cflags=""
+evas_image_loader_[]$1[]_libs=""
+
+AC_SUBST([evas_image_loader_$1_cflags])
+AC_SUBST([evas_image_loader_$1_libs])
+
+if test "x${have_dep}" = "xyes" ; then
+  m4_default([$3], [:])
+else
+  m4_default([$4], [:])
+fi
+
+])
+
 dnl use: EVAS_CHECK_IMAGE_LOADER(loader, want_loader, macro)
 
 
old mode 100644 (file)
new mode 100755 (executable)
index 410d713..cecaacc
@@ -21,6 +21,8 @@ static struct ext_loader_s    const loaders[] = {
    { "eap", "eet" },
    { "edb", "edb" },
    { "xpm", "xpm" },
+   { "bmp", "bmp" },
+   { "wbmp", "wbmp" },
    { "tiff", "tiff" },
    { "tif", "tiff" },
    { "svg", "svg" },
@@ -33,7 +35,7 @@ static struct ext_loader_s    const loaders[] = {
 };
 
 static const char *loaders_name[] = {
-  "png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "pmaps", "edb"
+  "png", "jpeg", "eet", "xpm", "bmp", "wbmp", "tiff", "gif", "svg", "pmaps", "edb"
 };
 
 struct evas_image_foreach_loader_data
old mode 100644 (file)
new mode 100755 (executable)
index e00f4e7..2176fdc
@@ -113,6 +113,8 @@ EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_sdl);
 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_x11);
 EVAS_EINA_STATIC_MODULE_DEFINE(engine, xrender_x11);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, xpm);
+EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, bmp);
+EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, wbmp);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tiff);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, svg);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, png);
@@ -194,6 +196,12 @@ static const struct {
 #ifdef EVAS_STATIC_BUILD_XPM
   EVAS_EINA_STATIC_MODULE_USE(image_loader, xpm),
 #endif
+#ifdef EVAS_STATIC_BUILD_BMP
+  EVAS_EINA_STATIC_MODULE_USE(image_loader, bmp),
+#endif
+#ifdef EVAS_STATIC_BUILD_WBMP
+  EVAS_EINA_STATIC_MODULE_USE(image_loader, wbmp),
+#endif
 #ifdef EVAS_STATIC_BUILD_TIFF
   EVAS_EINA_STATIC_MODULE_USE(image_loader, tiff),
 #endif
diff --git a/src/lib/include/evas_wink.h b/src/lib/include/evas_wink.h
new file mode 100755 (executable)
index 0000000..692fafa
--- /dev/null
@@ -0,0 +1,128 @@
+#ifndef EVAS_WINK_H
+#define EVAS_WINK_H
+
+#ifndef EVAS_WINK_MODULE_NAME
+#error "EVAS_WINK_MODULE_NAME (bmp/wbmp/png/jpeg/gif) should be defined before include evas_wink.h"
+#endif
+
+#ifdef USE_WINK_CODEC
+
+#define _LOAD_FILE_HEAD_WINK(module) evas_image_load_file_head_##module##_wink
+#define _LOAD_FILE_DATA_WINK(module) evas_image_load_file_data_##module##_wink
+#define LOAD_FILE_HEAD_WINK(module) _LOAD_FILE_HEAD_WINK(module)
+#define LOAD_FILE_DATA_WINK(module) _LOAD_FILE_DATA_WINK(module)
+
+#define _WINK_DEC_FROM_FILE(module) wink_dec_##module##_from_file
+#define WINK_DEC_FROM_FILE(module) _WINK_DEC_FROM_FILE(module)
+
+#define WK_IMG_TYPE(module) _WK_IMG_TYPE(module)
+#define _WK_IMG_TYPE(module) _WK_IMG_TYPE_##module
+
+#define _WK_IMG_TYPE_bmp   WK_IMG_TYPE_BMP
+#define _WK_IMG_TYPE_wbmp  WK_IMG_TYPE_WBMP
+#define _WK_IMG_TYPE_png   WK_IMG_TYPE_PNG
+#define _WK_IMG_TYPE_jpeg  WK_IMG_TYPE_JPEG
+#define _WK_IMG_TYPE_gif   WK_IMG_TYPE_GIF
+
+#include "wink_codec_api.h"
+
+static Eina_Bool LOAD_FILE_HEAD_WINK(EVAS_WINK_MODULE_NAME)(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error) EINA_ARG_NONNULL(1, 2, 4);
+static Eina_Bool LOAD_FILE_DATA_WINK(EVAS_WINK_MODULE_NAME)(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error) EINA_ARG_NONNULL(1, 2, 4);
+
+static Eina_Bool
+LOAD_FILE_HEAD_WINK(EVAS_WINK_MODULE_NAME)(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+   WINKImageType type;
+   WINKImageInfo image_info;
+
+   type = wink_parse_from_file((WKUCHAR *) file, &image_info);
+
+   if (type != WK_IMG_TYPE(EVAS_WINK_MODULE_NAME))
+   {
+       *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+       return EINA_FALSE;
+   }
+
+   ie->w = image_info.width;
+   ie->h = image_info.height;
+
+   *error = EVAS_LOAD_ERROR_NONE;
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+LOAD_FILE_DATA_WINK(EVAS_WINK_MODULE_NAME)(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+   WINKRawInfo * rawinfo;
+   WINKDecOption option = 0;
+
+   WINKResult result;
+
+   DATA32 * pixels;
+
+   rawinfo = wink_create_raw_info(ie->w, ie->h, WK_RAW_BGRA8888);
+   if (rawinfo == NULL)
+   {
+      *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+       return EINA_FALSE;
+   }
+
+   result = WINK_DEC_FROM_FILE(EVAS_WINK_MODULE_NAME)((WKUCHAR *) file, rawinfo, option);
+
+   if (result != WK_RESULT_SUCC)
+   {
+#ifdef WINK_SUPPORT_GET_LAST_ERROR
+      WINKError errno = wink_get_last_error();
+      switch(errno)
+      {
+      case WINK_ERR_NO_ERROR:
+            *error = EVAS_LOAD_ERROR_NONE;
+            break;
+      case WINK_ERR_INVALID_INPUTADDRESS:
+            *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+            break;
+      case WINK_ERR_CODEC_PARSE_FAIL:
+      case WINK_ERR_CODEC_DEC_FAIL:
+      case WINK_ERR_CODEC_ENC_FAIL:
+            *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+            break;
+      case WINK_ERR_UNSUPPORTED_COLORSPACE:
+      case WINK_ERR_UNSUPPORTED_TYPE:
+            *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+            break;
+      case WINK_ERR_INVALID_INPUTSIZE:
+      case WINK_ERR_INVALID_IMAGESIZE:
+      case WINK_ERR_OUTOF_MEMORY:
+      case WINK_ERR_NOT_ENOUGH_DISKSPACE:
+            *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+            break;
+      default:
+            *error = EVAS_LOAD_ERROR_GENERIC;
+      }
+#else
+      *error = EVAS_LOAD_ERROR_GENERIC;
+#endif
+      wink_destroy_raw_info(rawinfo);
+      return EINA_FALSE;
+   }
+   *error = EVAS_LOAD_ERROR_NONE;
+
+   evas_cache_image_surface_alloc(ie, ie->w, ie->h);
+   pixels = evas_cache_image_pixels(ie);
+   if (!pixels)
+   {
+      *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+      wink_destroy_raw_info(rawinfo);
+      return EINA_FALSE;
+   }
+
+   memcpy(pixels, rawinfo->raw_stream, ie->w * ie->h * 4);
+
+   wink_destroy_raw_info(rawinfo);
+   return EINA_TRUE;
+}
+#endif /* USE_WINK_CODEC */
+
+#endif /* EVAS_WINK_H */
+
old mode 100644 (file)
new mode 100755 (executable)
index 569887c..67bd86f
@@ -56,3 +56,15 @@ SUBDIRS += xpm
 endif
 endif
 
+if BUILD_LOADER_BMP
+if !EVAS_STATIC_BUILD_BMP
+SUBDIRS += bmp
+endif
+endif
+
+if BUILD_LOADER_WBMP
+if !EVAS_STATIC_BUILD_WBMP
+SUBDIRS += wbmp
+endif
+endif
+
diff --git a/src/modules/loaders/bmp/.cvsignore b/src/modules/loaders/bmp/.cvsignore
new file mode 100755 (executable)
index 0000000..a51c966
--- /dev/null
@@ -0,0 +1,6 @@
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+*.la
\ No newline at end of file
diff --git a/src/modules/loaders/bmp/Makefile.am b/src/modules/loaders/bmp/Makefile.am
new file mode 100755 (executable)
index 0000000..fa36193
--- /dev/null
@@ -0,0 +1,34 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+@FREETYPE_CFLAGS@ \
+@evas_image_loader_bmp_cflags@ \
+@EINA_CFLAGS@
+
+AM_CFLAGS = @WIN32_CFLAGS@
+
+if BUILD_LOADER_BMP
+if !EVAS_STATIC_BUILD_BMP
+
+pkgdir = $(libdir)/evas/modules/loaders/bmp/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_bmp.c
+
+module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_bmp_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+else
+
+noinst_LTLIBRARIES = libevas_loader_bmp.la
+
+libevas_loader_bmp_la_SOURCES = evas_image_load_bmp.c
+libevas_loader_bmp_la_LIBADD = @evas_image_loader_bmp_libs@
+
+endif
+endif
diff --git a/src/modules/loaders/bmp/evas_image_load_bmp.c b/src/modules/loaders/bmp/evas_image_load_bmp.c
new file mode 100755 (executable)
index 0000000..b30e98e
--- /dev/null
@@ -0,0 +1,711 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include "evas_common.h"
+#include "evas_private.h"
+
+#define EVAS_WINK_MODULE_NAME bmp
+#include "evas_wink.h"
+
+static Eina_Bool evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
+static Eina_Bool evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
+
+static Evas_Image_Load_Func evas_image_load_bmp_func =
+{
+  EINA_TRUE,
+  evas_image_load_file_head_bmp,
+  evas_image_load_file_data_bmp
+};
+
+
+typedef struct tagRGBQUAD {
+       unsigned char       rgbBlue;
+       unsigned char       rgbGreen;
+       unsigned char       rgbRed;
+       unsigned char       rgbReserved;
+} RGBQUAD;
+
+#define BI_RGB       0
+#define BI_RLE8      1
+#define BI_RLE4      2
+#define BI_BITFIELDS 3
+
+/* 21.3.3006 - Use enumeration for RLE encoding. This makes it more readable */
+enum {
+       RLE_NEXT = 0, /* Next line */
+       RLE_END = 1,  /* End of RLE encoding */
+       RLE_MOVE = 2  /* Move by X and Y (Offset is stored in two next bytes) */
+};
+
+# define IMAGE_DIMENSIONS_OK(w, h) \
+   ( ((w) > 0) && ((h) > 0) && \
+     ((unsigned long long)(w) * (unsigned long long)(w) <= (1ULL << 29) - 1) )
+
+static int
+ReadleShort(FILE * file, unsigned short *ret)
+{
+       unsigned char       b[2];
+
+       if (fread(b, sizeof(unsigned char), 2, file) != 2)
+               return 0;
+
+       *ret = (b[1] << 8) | b[0];   
+       return 1;
+}
+
+static int
+ReadleLong(FILE * file, unsigned long *ret)
+{
+       unsigned char       b[4];
+
+       if (fread(b, sizeof(unsigned char), 4, file) != 4)
+               return 0;
+
+       *ret = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
+       return 1;
+}
+
+static Eina_Bool
+evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+#ifdef USE_WINK_CODEC
+   return evas_image_load_file_head_bmp_wink(ie, file, key, error);
+#endif
+
+   FILE               *f;
+   char                type[2];
+   unsigned long       size, offset, headSize;
+   unsigned short      tmpShort;
+   unsigned long       w, h;
+   f = fopen(file, "rb");
+   if (!f)
+     {
+      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+      return EINA_FALSE;
+     }
+
+   /* header */
+   {
+      struct stat         statbuf;
+
+      if (stat(file, &statbuf) == -1)
+        {
+           *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+           fclose(f);
+           return EINA_FALSE;
+        }
+      size = statbuf.st_size;
+
+      if (fread(type, 1, 2, f) != 2)
+        {
+           *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+           fclose(f);
+           return EINA_FALSE;
+        }
+      if (strncmp(type, "BM", 2))
+        {
+           *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+           fclose(f);
+           return EINA_FALSE;
+        }
+
+      fseek(f, 8, SEEK_CUR);
+      ReadleLong(f, &offset);
+      ReadleLong(f, &headSize);
+      if (offset >= size)
+        {
+           *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+           fclose(f);
+           return EINA_FALSE;
+        }
+      if (headSize == 12)
+        {
+           ReadleShort(f, &tmpShort);
+           w = tmpShort;
+           ReadleShort(f, &tmpShort);
+           h = tmpShort;
+        }
+      else if (headSize == 40)
+        {
+           ReadleLong(f, &w);
+           ReadleLong(f, &h);
+       }
+   }
+
+   ie->w = w;
+   ie->h = (h > 0 ? h : -h);
+
+   *error = EVAS_LOAD_ERROR_NONE;
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+#ifdef USE_WINK_CODEC
+   return evas_image_load_file_data_bmp_wink(ie, file, key, error);
+#endif
+
+   FILE               *f;
+   char                type[2];
+   unsigned long       size, offset, headSize, comp, imgsize, j, k, l;
+   unsigned short      tmpShort, planes, bitcount, ncols, skip;
+   unsigned char       byte = 0, g, b, r;
+   long       i, w, h;
+   unsigned short      x, y;
+   DATA32             *dst_data;
+   DATA32             *ptr, *data_end;
+   unsigned char      *buffer_ptr, *buffer, *buffer_end;
+   RGBQUAD             rgbQuads[256];
+   unsigned long       rmask = 0xff, gmask = 0xff, bmask = 0xff;
+   unsigned long       rshift = 0, gshift = 0, bshift = 0;
+   unsigned long       rleftshift = 0, gleftshift = 0, bleftshift = 0;
+
+   /*
+    * 21.3.2006:
+    * Added these two variables for RLE.
+    */
+   unsigned char       byte1, byte2;
+
+   f = fopen(file, "rb");
+   if (!f)
+     {
+      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+      return EINA_FALSE;
+     }
+
+   /* header */
+   {
+      struct stat         statbuf;
+
+      if (stat(file, &statbuf) == -1)
+        {
+           *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+           fclose(f);
+           return EINA_FALSE;
+        }
+      size = statbuf.st_size;
+
+      if (fread(type, 1, 2, f) != 2)
+        {
+           *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+           fclose(f);
+           return EINA_FALSE;
+        }
+      if (strncmp(type, "BM", 2))
+        {
+           *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+           fclose(f);
+           return EINA_FALSE;
+        }
+
+      fseek(f, 8, SEEK_CUR);
+      ReadleLong(f, &offset);
+      ReadleLong(f, &headSize);
+      if (offset >= size)
+        {
+           *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+           fclose(f);
+           return EINA_FALSE;
+        }
+      if (headSize == 12)
+        {
+           ReadleShort(f, &tmpShort);
+           w = tmpShort;
+           ReadleShort(f, &tmpShort);
+           h = tmpShort;
+           ReadleShort(f, &planes);
+           ReadleShort(f, &bitcount);
+           imgsize = size - offset;
+           comp = BI_RGB;
+        }
+      else if (headSize == 40)
+        {
+           ReadleLong(f, &w);
+           ReadleLong(f, &h);
+           ReadleShort(f, &planes);
+           ReadleShort(f, &bitcount);
+           ReadleLong(f, &comp);
+           ReadleLong(f, &imgsize);
+           imgsize = size - offset;
+           fseek(f, 16, SEEK_CUR);
+        }
+      else
+        {
+           *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+           fclose(f);
+           return EINA_FALSE;
+        }
+
+      h = h > 0 ? h : -h;
+
+      if (!IMAGE_DIMENSIONS_OK(w, h))
+        {
+           *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+           fclose(f);
+           return EINA_FALSE;
+        }
+
+      if (bitcount < 16)
+        {
+           ncols = (offset - headSize - 14);
+           if (headSize == 12)
+             {
+                ncols /= 3;
+                if (ncols > 256) ncols = 256;
+                for (i = 0; i < ncols; i++)
+                   fread(&rgbQuads[i], 3, 1, f);
+             }
+           else
+             {
+                ncols /= 4;
+                if (ncols > 256) ncols = 256;
+                fread(rgbQuads, 4, ncols, f);
+             }
+        }
+      else if (bitcount == 16 || bitcount == 32)
+        {
+           if (comp == BI_BITFIELDS)
+             {
+                int                 bit;
+
+                ReadleLong(f, &rmask);
+                ReadleLong(f, &gmask);
+                ReadleLong(f, &bmask);
+                for (bit = bitcount - 1; bit >= 0; bit--)
+                  {
+                     if (bmask & (1 << bit)) bshift = bit;
+                     if (gmask & (1 << bit)) gshift = bit;
+                     if (rmask & (1 << bit)) rshift = bit;
+                  }
+                while(((((0xffffL & bmask) >> bshift) << bleftshift) & 0x80) == 0)
+                  {
+                     bleftshift++;
+                  }
+                while(((((0xffffL & gmask) >> gshift) << gleftshift) & 0x80) == 0)
+                  {
+                     gleftshift++;
+                  }
+                while(((((0xffffL & rmask) >> rshift) << rleftshift) & 0x80) == 0)
+                  {
+                     rleftshift++;
+                  }
+              }
+           else if (bitcount == 16)
+             {
+                rmask = 0x7C00;
+                gmask = 0x03E0;
+                bmask = 0x001F;
+                rshift = 10;
+                gshift = 5;
+                bshift = 0;
+                rleftshift = gleftshift = bleftshift = 3;
+             }
+           else if (bitcount == 32)
+             {
+                rmask = 0x00FF0000;
+                gmask = 0x0000FF00;
+                bmask = 0x000000FF;
+                rshift = 16;
+                gshift = 8;
+                bshift = 0;
+             }
+        }
+
+      ie->w = w;
+      ie->h = h;
+   }
+
+   if (1)
+     {
+        fseek(f, offset, SEEK_SET);
+        buffer = malloc(imgsize);
+        if (!buffer)
+          {
+             *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+             fclose(f);
+             return EINA_FALSE;
+          }
+
+        evas_cache_image_surface_alloc(ie, ie->w, ie->h);
+        dst_data = evas_cache_image_pixels(ie);
+
+        fread(buffer, imgsize, 1, f);
+        fclose(f);
+        buffer_ptr = buffer;
+        buffer_end = buffer + imgsize;
+
+        data_end = dst_data + w * h;
+        ptr = dst_data + ((h - 1) * w);
+
+        if (bitcount == 1)
+          {
+             if (comp == BI_RGB)
+               {
+                  skip = ((((w + 31) / 32) * 32) - w) / 8;
+                  for (y = 0; y < h; y++)
+                    {
+                       for (x = 0; x < w && buffer_ptr < buffer_end; x++)
+                         {
+                            if ((x & 7) == 0)
+                               byte = *(buffer_ptr++);
+                            k = (byte >> 7) & 1;
+                            *ptr++ = 0xff000000 |
+                                (rgbQuads[k].rgbRed << 16) |
+                                (rgbQuads[k].rgbGreen << 8) |
+                                rgbQuads[k].rgbBlue;
+                            byte <<= 1;
+                         }
+                       buffer_ptr += skip;
+                       ptr -= w * 2;
+                   }
+               }
+          }
+
+        /*
+         * 21.3.2006
+         * Bug fixes and optimization:
+         * 
+         * RLE encoding is dangerous and can be used by attackers by creating special files.
+         * We has 'buffer_ptr' and 'buffer_end' variables and buffer_end points to first 
+         * unaccessible byte in buffer.
+         * - If we use 'byte = *(buffer_ptr++) in main loop we must check if 
+         *   'buffer_ptr != buffer_end', because special or incomplete bmp file can generate
+         *   segfault (I was writing it, because in RLE we need to read depending count of
+                *   bytes that depends on requester operation).
+         *   SOLUTION: Don't read one byte, read two bytes and check.
+         * - If RLE teels us than single color length will be larger than allowed, we can
+         *   stop, because bitmap is corrupted or crawled.
+         *   SOLUTION: Check for length ('l' variable in RLE) and break loop if it's invalid
+         *   IMPROVEMENTS: We can stop checking if 'x' is out of rangle, because it never be.
+         * - In RLE4 use one bigger loop that fills two pixels. This is faster and cleaner.
+         *   If one pixel remains (the tail), do it on end of the loop.
+         * - If we will check x and y (new line and skipping), we can't go outsize imlib
+         *   image buffer.
+         */
+
+        if (bitcount == 4)
+          {
+             if (comp == BI_RLE4)
+               {
+                  /*
+                   * 21.3.2006: This is better than using 'if buffer_ptr + 1 < buffer_end'
+                   */
+                  unsigned char *buffer_end_minus_1 = buffer_end - 1;
+                  x = 0;
+                  y = 0;
+
+                  for (i = 0; i < imgsize && buffer_ptr < buffer_end_minus_1; i++)
+                    {
+                       byte1 = buffer_ptr[0];
+                       byte2 = buffer_ptr[1];
+                       buffer_ptr += 2;
+                       if (byte1)
+                         {
+                            DATA32 t1, t2;
+
+                            l = byte1;
+                            /* Check for invalid length */
+                            if (l + x > w) goto _bail;
+
+                            t1 = 0xff000000 | (rgbQuads[byte2 >>  4].rgbRed   << 16) |
+                                              (rgbQuads[byte2 >>  4].rgbGreen <<  8) |
+                                              (rgbQuads[byte2 >>  4].rgbBlue       ) ;
+                            t2 = 0xff000000 | (rgbQuads[byte2 & 0xF].rgbRed   << 16) |
+                                              (rgbQuads[byte2 & 0xF].rgbGreen <<  8) |
+                                              (rgbQuads[byte2 & 0xF].rgbBlue       ) ;
+                            for (j = l/2; j; j--) {
+                               ptr[0] = t1;
+                               ptr[1] = t2;
+                               ptr += 2;
+                            }
+                            /* tail */
+                            if (l & 1) *ptr++ = t1;
+                            x += l;
+                         }
+                       else
+                         {
+                            switch (byte2)
+                              {
+                                case RLE_NEXT:
+                                   x = 0;
+                                   if (++y >= h) goto _bail;
+                                   ptr = dst_data + (h - y - 1) * w;
+                                   break;
+                                case RLE_END:
+                                   goto _bail;
+                                case RLE_MOVE:
+                                   /* Need to read two bytes */
+                                   if (buffer_ptr >= buffer_end_minus_1) goto _bail; 
+                                   x += buffer_ptr[0];
+                                   y += buffer_ptr[1];
+                                   buffer_ptr += 2;
+                                   /* Check for correct coordinates */
+                                   if (x >= w) goto _bail;
+                                   if (y >= h) goto _bail;
+                                   ptr = dst_data + (h - y - 1) * w + x;
+                                   break;
+                                default:
+                                   l = byte2;
+                                   /* Check for invalid length and valid buffer size */
+                                   if (l + x > w) goto _bail;
+                                   if (buffer_ptr + (l >> 1) + (l & 1) > buffer_end) goto _bail;
+
+                                   for (j = l/2; j; j--) {
+                                     byte = *buffer_ptr++;
+                                     ptr[0] = 0xff000000 | (rgbQuads[byte >>  4].rgbRed   << 16) |
+                                                           (rgbQuads[byte >>  4].rgbGreen <<  8) |
+                                                           (rgbQuads[byte >>  4].rgbBlue       ) ;
+                                     ptr[1] = 0xff000000 | (rgbQuads[byte & 0xF].rgbRed   << 16) |
+                                                           (rgbQuads[byte & 0xF].rgbGreen <<  8) |
+                                                           (rgbQuads[byte & 0xF].rgbBlue       ) ;
+                                     ptr += 2;
+                                   }
+                                   if (l & 1) {
+                                     byte = *buffer_ptr++;
+                                     *ptr++ = 0xff000000 | (rgbQuads[byte >>  4].rgbRed   << 16) |
+                                                           (rgbQuads[byte >>  4].rgbGreen <<  8) |
+                                                           (rgbQuads[byte >>  4].rgbBlue       ) ;
+                                   }
+                                   x += l;
+
+                                   if ((l & 3) == 1)
+                                      buffer_ptr += 2;
+                                   else if ((l & 3) == 2)
+                                      buffer_ptr++;
+                                   break;
+                              }
+                         }
+                    }
+               }
+             else if (comp == BI_RGB)
+               {
+                  skip = ((((w + 7) / 8) * 8) - w) / 2;
+                  for (y = 0; y < h; y++)
+                    {
+                       for (x = 0; x < w && buffer_ptr < buffer_end; x++)
+                         {
+                            if ((x & 1) == 0)
+                               byte = *(buffer_ptr++);
+                            k = (byte & 0xF0) >> 4;
+                            *ptr++ = 0xff000000 |
+                                (rgbQuads[k].rgbRed << 16) |
+                                (rgbQuads[k].rgbGreen << 8) |
+                                rgbQuads[k].rgbBlue;
+                            byte <<= 4;
+                         }
+                       buffer_ptr += skip;
+                       ptr -= w * 2;
+                   }
+               }
+          }
+        if (bitcount == 8)
+          {
+             if (comp == BI_RLE8)
+               {
+                  /*
+                   * 21.3.2006: This is better than using 'if buffer_ptr + 1 < buffer_end'
+                   */
+                  unsigned char *buffer_end_minus_1 = buffer_end - 1;
+                  x = 0;
+                  y = 0;
+                  for (i = 0; i < imgsize && buffer_ptr < buffer_end_minus_1; i++)
+                    {
+                       byte1 = buffer_ptr[0];
+                       byte2 = buffer_ptr[1];
+                       buffer_ptr += 2;
+                       if (byte1)
+                         {
+                            DATA32 pix = 0xff000000 | (rgbQuads[byte2].rgbRed   << 16) |
+                                                      (rgbQuads[byte2].rgbGreen <<  8) |
+                                                      (rgbQuads[byte2].rgbBlue       ) ;
+                            l = byte1;
+                            if (x + l > w) goto _bail;
+                            for (j = l; j; j--) *ptr++ = pix;
+                            x += l;
+                         }
+                       else
+                         {
+                            switch (byte2)
+                              {
+                                case RLE_NEXT:
+                                   x = 0;
+                                   if (++y >= h) goto _bail;
+                                   ptr = dst_data + ((h - y - 1) * w) + x;
+                                   break;
+                                case RLE_END:
+                                   goto _bail;
+                                case RLE_MOVE:
+                                   /* Need to read two bytes */
+                                   if (buffer_ptr >= buffer_end_minus_1) goto _bail; 
+                                   x += buffer_ptr[0];
+                                   y += buffer_ptr[1];
+                                   buffer_ptr += 2;
+                                   /* Check for correct coordinates */
+                                   if (x >= w) goto _bail;
+                                   if (y >= h) goto _bail;
+                                   ptr = dst_data + ((h - y - 1) * w) + x;
+                                   break;
+                                default:
+                                   l = byte2;
+                                   if (x + l > w) goto _bail;
+                                   if (buffer_ptr + l > buffer_end) goto _bail;
+                                   for (j = 0; j < l; j++)
+                                     {
+                                        byte = *(buffer_ptr++);
+
+                                        *ptr++ = 0xff000000 |
+                                            (rgbQuads[byte].rgbRed << 16) |
+                                            (rgbQuads[byte].rgbGreen << 8) |
+                                            rgbQuads[byte].rgbBlue;
+                                     }
+                                   x += l;
+                                   if (l & 1)
+                                      buffer_ptr++;
+                                   break;
+                              }
+                         }
+                    }
+              }
+             else if (comp == BI_RGB)
+               {
+                  skip = (((w + 3) / 4) * 4) - w;
+                  for (y = 0; y < h; y++)
+                    {
+                       for (x = 0; x < w && buffer_ptr < buffer_end; x++)
+                         {
+                            byte = *(buffer_ptr++);
+                            *ptr++ = 0xff000000 |
+                                (rgbQuads[byte].rgbRed << 16) |
+                                (rgbQuads[byte].rgbGreen << 8) |
+                                rgbQuads[byte].rgbBlue;
+                         }
+                       ptr -= w * 2;
+                       buffer_ptr += skip;
+                   }
+               }
+
+          }
+        else if (bitcount == 16)
+          {
+             /* 21.3.2006 - Need to check for buffer_ptr + 1 < buffer_end */
+             unsigned char *buffer_end_minus_1 = buffer_end - 1;
+             skip = (((w * 16 + 31) / 32) * 4) - (w * 2);
+             for (y = 0; y < h; y++)
+               {
+                  for (x = 0; x < w && buffer_ptr < buffer_end_minus_1; x++)
+                    {
+                       /*
+                        * THIS WAS OLD CODE 
+                        *
+                        * r = ((unsigned short)(*buffer_ptr) & rmask) >> rshift;
+                        * g = ((unsigned short)(*buffer_ptr) & gmask) >> gshift;
+                        * b = ((unsigned short)(*(buffer_ptr++)) & bmask) >>
+                        *   bshift;
+                        * *ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
+                        */
+                       unsigned short pix = *(unsigned short *)buffer_ptr;
+                       *ptr++ = 0xff000000 | ((((pix & rmask) >> rshift) << rleftshift) << 16) |
+                                             ((((pix & gmask) >> gshift) << gleftshift) <<  8) |
+                                             ((((pix & bmask) >> bshift) << bleftshift)      ) ;
+                       buffer_ptr += 2;
+                    }
+                  ptr -= w * 2;
+                  buffer_ptr += skip;
+              }
+          }
+        else if (bitcount == 24)
+          {
+             /* 21.3.2006 - Fix: need to check for buffer_ptr + 2 < buffer_end */
+             unsigned char *buffer_end_minus_2 = buffer_end - 2;
+             skip = (4 - ((w * 3) % 4)) & 3;
+             for (y = 0; y < h; y++)
+               {
+                  for (x = 0; x < w && buffer_ptr < buffer_end_minus_2; x++)
+                    {
+                       b = *(buffer_ptr++);
+                       g = *(buffer_ptr++);
+                       r = *(buffer_ptr++);
+                       *ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
+                    }
+                  ptr -= w * 2;
+                  buffer_ptr += skip;
+              }
+          }
+        else if (bitcount == 32)
+          {
+             /* 21.3.2006 - Need to check buffer_ptr + 3 < buffer_end */
+             unsigned char *buffer_end_minus_3 = buffer_end_minus_3;
+             skip = (((w * 32 + 31) / 32) * 4) - (w * 4);
+             for (y = 0; y < h; y++)
+               {
+                  for (x = 0; x < w && buffer_ptr < buffer_end_minus_3; x++)
+                    {
+                       /*
+                        * THIS WAS OLD CODE: I don't understand it and it's invalid.
+                        *
+                        * r = ((unsigned long)(*buffer_ptr) & rmask) >> rshift;
+                        * g = ((unsigned long)(*buffer_ptr) & gmask) >> gshift;
+                        * b = ((unsigned long)(*buffer_ptr) & bmask) >> bshift;
+                        * *ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
+                        * r = *(buffer_ptr++);
+                        * r = *(buffer_ptr++);
+                        */
+
+                       /* TODO: What about alpha channel...Is used? */
+                       DATA32 pix = *(unsigned int *)buffer_ptr;
+                       *ptr++ = 0xff000000 | (((pix & rmask) >> rshift) << 16) |
+                                             (((pix & gmask) >> gshift) <<  8) |
+                                             (((pix & bmask) >> bshift)      ) ; 
+                       buffer_ptr += 4;
+                    }
+                  ptr -= w * 2;
+                  buffer_ptr += skip;
+              }
+          }
+_bail:
+        free(buffer);
+     }
+
+   return EINA_TRUE;
+}
+
+static int
+module_open(Evas_Module *em)
+{
+   if (!em) return 0;
+   em->functions = (void *)(&evas_image_load_bmp_func);
+   return 1;
+}
+
+static void
+module_close(Evas_Module *em)
+{
+}
+
+static Evas_Module_Api evas_modapi =
+{
+  EVAS_MODULE_API_VERSION,
+  "bmp",
+  "none",
+  {
+    module_open,
+    module_close
+  }
+};
+
+EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, bmp);
+
+#ifndef EVAS_STATIC_BUILD_BMP
+EVAS_EINA_MODULE_DEFINE(image_loader, bmp);
+#endif
old mode 100644 (file)
new mode 100755 (executable)
index 1bf75b9..86bbe38
@@ -7,6 +7,9 @@
 
 #include <gif_lib.h>
 
+#define EVAS_WINK_MODULE_NAME gif
+#include "evas_wink.h"
+
 static Eina_Bool evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
 static Eina_Bool evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
 
@@ -20,6 +23,11 @@ static Evas_Image_Load_Func evas_image_load_gif_func =
 static Eina_Bool
 evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
 {
+#ifdef USE_WINK_CODEC
+   if (evas_image_load_file_head_gif_wink(ie, file, key, error) == EINA_TRUE)
+      return EINA_TRUE;
+#endif
+
    int                 fd;
    GifFileType        *gif;
    GifRecordType       rec;
@@ -111,6 +119,11 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
 static Eina_Bool
 evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
 {
+#ifdef USE_WINK_CODEC
+   if (evas_image_load_file_data_gif_wink(ie, file, key, error) == EINA_TRUE)
+      return EINA_TRUE;
+#endif
+
    int                 intoffset[] = { 0, 4, 2, 1 };
    int                 intjump[] = { 8, 8, 4, 2 };
    double              per;
old mode 100644 (file)
new mode 100755 (executable)
index 59fb79c..a5a5729
@@ -13,6 +13,8 @@
 #include "evas_common.h"
 #include "evas_private.h"
 
+#define EVAS_WINK_MODULE_NAME jpeg
+#include "evas_wink.h"
 
 typedef struct _JPEG_error_mgr *emptr;
 struct _JPEG_error_mgr
@@ -720,6 +722,11 @@ evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f, int *err
 static Eina_Bool
 evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *key, int *error)
 {
+#ifdef USE_WINK_CODEC
+   if (evas_image_load_file_head_jpeg_wink(ie, file, key, error) == EINA_TRUE)
+          return EINA_TRUE;
+#endif
+
    int val;
    FILE *f;
 
@@ -738,6 +745,11 @@ evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *ke
 static Eina_Bool
 evas_image_load_file_data_jpeg(Image_Entry *ie, const char *file, const char *key, int *error)
 {
+#ifdef USE_WINK_CODEC
+   if (evas_image_load_file_data_jpeg_wink(ie, file, key, error) == EINA_TRUE)
+          return EINA_TRUE;
+#endif
+
    int val;
    FILE *f;
 
old mode 100644 (file)
new mode 100755 (executable)
index 989fcfe..97d0d7a
@@ -28,6 +28,8 @@
 #include "evas_common.h"
 #include "evas_private.h"
 
+#define EVAS_WINK_MODULE_NAME png
+#include "evas_wink.h"
 
 #define PNG_BYTES_TO_CHECK 4
 
@@ -45,6 +47,11 @@ static Evas_Image_Load_Func evas_image_load_png_func =
 static Eina_Bool
 evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
 {
+#ifdef USE_WINK_CODEC
+   if (evas_image_load_file_head_png_wink(ie, file, key, error) == EINA_TRUE)
+      return EINA_TRUE;
+#endif
+
    png_uint_32 w32, h32;
    FILE *f;
    png_structp png_ptr = NULL;
@@ -130,6 +137,11 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key
 static Eina_Bool
 evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
 {
+#ifdef USE_WINK_CODEC
+   if (evas_image_load_file_data_png_wink(ie, file, key, error) == EINA_TRUE)
+      return EINA_TRUE;
+#endif
+
    unsigned char *surface;
    png_uint_32 w32, h32;
    int w, h;
diff --git a/src/modules/loaders/wbmp/.cvsignore b/src/modules/loaders/wbmp/.cvsignore
new file mode 100755 (executable)
index 0000000..a51c966
--- /dev/null
@@ -0,0 +1,6 @@
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+*.la
\ No newline at end of file
diff --git a/src/modules/loaders/wbmp/Makefile.am b/src/modules/loaders/wbmp/Makefile.am
new file mode 100755 (executable)
index 0000000..41a8d12
--- /dev/null
@@ -0,0 +1,34 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+@FREETYPE_CFLAGS@ \
+@evas_image_loader_wbmp_cflags@ \
+@EINA_CFLAGS@
+
+AM_CFLAGS = @WIN32_CFLAGS@
+
+if BUILD_LOADER_WBMP
+if !EVAS_STATIC_BUILD_WBMP
+
+pkgdir = $(libdir)/evas/modules/loaders/wbmp/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_wbmp.c
+
+module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_wbmp_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+else
+
+noinst_LTLIBRARIES = libevas_loader_wbmp.la
+
+libevas_loader_wbmp_la_SOURCES = evas_image_load_wbmp.c
+libevas_loader_wbmp_la_LIBADD = @evas_image_loader_wbmp_libs@
+
+endif
+endif
diff --git a/src/modules/loaders/wbmp/evas_image_load_wbmp.c b/src/modules/loaders/wbmp/evas_image_load_wbmp.c
new file mode 100755 (executable)
index 0000000..313fe36
--- /dev/null
@@ -0,0 +1,219 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include "evas_common.h"
+#include "evas_private.h"
+
+#define EVAS_WINK_MODULE_NAME wbmp
+#include "evas_wink.h"
+
+static Eina_Bool evas_image_load_file_head_wbmp(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
+static Eina_Bool evas_image_load_file_data_wbmp(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
+
+static Evas_Image_Load_Func evas_image_load_wbmp_func =
+{
+  EINA_TRUE,
+  evas_image_load_file_head_wbmp,
+  evas_image_load_file_data_wbmp
+};
+
+
+static int read_mb(unsigned int * data, FILE * f) {
+   int ac = 0;
+   int ct = 0;
+   unsigned char buf;
+
+   while (1) {
+      if ((ct++) == 6)
+         return -1;
+
+      if ((fread(&buf, 1, 1, f)) < 1)
+         return -1;
+
+      ac = (ac << 7) | (buf & 0x7f);
+      if ((buf & 0x80) == 0)
+         break;
+   }
+   *data = ac;
+   return 0;
+}
+
+static Eina_Bool
+evas_image_load_file_head_wbmp(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+#ifdef USE_WINK_CODEC
+   return evas_image_load_file_head_wbmp_wink(ie, file, key, error);
+#endif
+
+   FILE          * f;
+   unsigned int       type;
+   unsigned char      fixed_header;
+   unsigned int       width, height;
+
+   struct stat    statbuf;
+
+   *error = EVAS_LOAD_ERROR_GENERIC;
+
+   f = fopen(file, "rb");
+   if (!f)
+   {
+      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+      return EINA_FALSE;
+   }
+
+   if (stat(file, &statbuf) == -1)
+       goto bail0;
+   if (read_mb(&type, f) < 0)
+      goto bail0;
+
+   if (type != 0)
+   {
+       *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+       goto bail0;
+   }
+   if (fread(&fixed_header, 1, 1, f) != 1)
+      goto bail0;
+   if (read_mb(&width, f) < 0)
+      goto bail0;
+   if (read_mb(&height, f) < 0)
+      goto bail0;
+
+   fclose(f);
+
+   ie->w = width;
+   ie->h = height;
+
+   *error = EVAS_LOAD_ERROR_NONE;
+
+   return EINA_TRUE;
+
+bail0:
+   fclose(f);
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_wbmp(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+#ifdef USE_WINK_CODEC
+   return evas_image_load_file_data_wbmp_wink(ie, file, key, error);
+#endif
+
+   FILE          * f;
+   unsigned int       width, height;
+   unsigned int       dummy;
+   unsigned char      * line = NULL;
+   unsigned int       line_length;
+   int           cur = 0;
+   int           i, j;
+   DATA32        * dst_data;
+
+   *error = EVAS_LOAD_ERROR_GENERIC;
+   
+   f = fopen(file, "rb");
+   if (!f)
+   {
+      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+      return EINA_FALSE;
+   }
+
+   if (read_mb(&dummy, f) < 0)
+      goto bail0;
+   if (fread(&dummy, 1, 1, f) != 1)
+      goto bail0;
+   if (read_mb(&dummy, f) < 0)
+      goto bail0;
+   if (read_mb(&dummy, f) < 0)
+      goto bail0;
+
+   width = ie->w;
+   height = ie->h;
+
+   evas_cache_image_surface_alloc(ie, ie->w, ie->h);
+   dst_data = evas_cache_image_pixels(ie);
+   if (!dst_data)
+   {
+      *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+      goto bail0;
+   }
+   
+   line_length = (width + 7) >> 3;
+   line = (unsigned char *) malloc(line_length);
+
+   for(i=0;i<height;i++)
+   {
+      if (fread(line, 1, line_length, f) != line_length)
+         goto bail0;
+
+      for(j=0;j<width;j++)
+      {
+         int idx = j >> 3;
+         int offset = 1 << (0x07 - (j & 0x07));
+         if (line[idx] & offset)
+            dst_data[cur] = 0xFFFFFFFF;
+         else
+            dst_data[cur] = 0xFF000000;
+         cur++;
+      }
+   }
+
+   if (line)
+      free(line);
+
+   fclose(f);
+
+   *error = EVAS_LOAD_ERROR_NONE;
+
+   return EINA_TRUE;
+
+bail0:
+   fclose(f);
+
+   if (line)
+      free(line);
+
+   return EINA_FALSE;
+}
+
+static int
+module_open(Evas_Module *em)
+{
+   if (!em) return 0;
+   em->functions = (void *)(&evas_image_load_wbmp_func);
+   return 1;
+}
+
+static void
+module_close(Evas_Module *em)
+{
+}
+
+static Evas_Module_Api evas_modapi =
+{
+  EVAS_MODULE_API_VERSION,
+  "wbmp",
+  "none",
+  {
+    module_open,
+    module_close
+  }
+};
+
+EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, wbmp);
+
+#ifndef EVAS_STATIC_BUILD_WBMP
+EVAS_EINA_MODULE_DEFINE(image_loader, wbmp);
+#endif