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"
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
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
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
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
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
])
+
+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)
{ "eap", "eet" },
{ "edb", "edb" },
{ "xpm", "xpm" },
+ { "bmp", "bmp" },
+ { "wbmp", "wbmp" },
{ "tiff", "tiff" },
{ "tif", "tiff" },
{ "svg", "svg" },
};
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
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);
#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
--- /dev/null
+#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 */
+
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
+
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+*.la
\ No newline at end of file
--- /dev/null
+
+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
--- /dev/null
+#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
#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);
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;
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;
#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
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;
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;
#include "evas_common.h"
#include "evas_private.h"
+#define EVAS_WINK_MODULE_NAME png
+#include "evas_wink.h"
#define PNG_BYTES_TO_CHECK 4
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;
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;
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+*.la
\ No newline at end of file
--- /dev/null
+
+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
--- /dev/null
+#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