gif loader
authordoursse <doursse>
Sat, 8 Apr 2006 12:22:18 +0000 (12:22 +0000)
committerdoursse <doursse@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 8 Apr 2006 12:22:18 +0000 (12:22 +0000)
SVN revision: 21951

legacy/evas/configure.in
legacy/evas/src/modules/loaders/Makefile.am
legacy/evas/src/modules/loaders/gif/Makefile.am [new file with mode: 0644]
legacy/evas/src/modules/loaders/gif/evas_image_load_gif.c [new file with mode: 0644]

index f9c00b4..8bff470 100644 (file)
@@ -144,11 +144,9 @@ if test "x$have_fontconfig" = "xyes"; then
         [ 
             have_fontconfig="yes"
             AC_DEFINE(HAVE_FONTCONFIG, 1, [have fontconfig searching capabilities])
-            AC_MSG_RESULT(yes)
         ],
         [ 
             have_fontconfig="no"
-            AC_MSG_RESULT(no)
         ]
     )
 else 
@@ -648,6 +646,46 @@ AM_CONDITIONAL(BUILD_ENGINE_XRENDER_XCB, test "x$have_evas_xrender_xcb" = "xyes"
 ## Image loaders
 
 #######################################
+## GIF
+have_gif="no";
+AC_CHECK_HEADER(gif_lib.h,
+  [ have_gif="yes" ],
+  [ have_gif="no" ]
+)
+AC_MSG_CHECKING(whether to enable gif image loader)
+AC_ARG_ENABLE(image-loader-gif, 
+  [  --enable-image-loader-gif       enable GIF image loader], [
+      if test x"$enableval" = x"yes" ; then
+        AC_MSG_RESULT(yes)
+       have_gif="yes"
+      else
+        AC_MSG_RESULT(no)
+       have_gif="no"
+      fi
+  ], [
+      AC_MSG_RESULT($have_gif)
+  ]
+)
+if test "x$have_gif" = "xyes"; then
+  AC_CHECK_HEADER(gif_lib.h,
+    [ AC_CHECK_LIB(gif, DGifOpenFileName,
+       [ gif_libs="-lgif"
+         have_gif="yes" ],
+       [ AC_CHECK_LIB(ungif, DGifOpenFileName,
+          [ gif_libs="-lungif"
+            have_gif="yes" ],
+          [ have_gif="no" ]) ]) ],
+    [ have_gif="no" ]
+  )
+fi
+if test "x$have_gif" = "xyes"; then
+  AC_DEFINE(BUILD_LOADER_GIF, 1, [GIF Image Loader Support])
+  gif_cflags=""
+fi
+
+AM_CONDITIONAL(BUILD_LOADER_GIF, test x$have_gif = xyes)
+
+#######################################
 ## PNG
 have_png="no";
 AC_CHECK_HEADER(png.h,
@@ -1652,6 +1690,8 @@ AC_SUBST(qt_cflags)
 AC_SUBST(qt_libs)
 AC_SUBST(qt_moc)
 
+AC_SUBST(gif_cflags)
+AC_SUBST(gif_libs)
 AC_SUBST(png_cflags)
 AC_SUBST(png_libs)
 AC_SUBST(jpeg_cflags)
@@ -1723,6 +1763,7 @@ src/modules/engines/xrender_xcb/Makefile
 src/modules/loaders/Makefile
 src/modules/loaders/edb/Makefile
 src/modules/loaders/eet/Makefile
+src/modules/loaders/gif/Makefile
 src/modules/loaders/jpeg/Makefile
 src/modules/loaders/png/Makefile
 src/modules/savers/Makefile
@@ -1773,6 +1814,7 @@ echo "  XRender Xcb.............: $have_evas_xrender_xcb"
 # FIXME: xrender engine to be written
 echo
 echo "Image Loaders:"
+echo "  GIF.....................: $have_gif"
 echo "  PNG.....................: $have_png"
 echo "  JPEG....................: $have_jpeg"
 echo "  EET.....................: $have_eet"
index 50fe0a0..b57ba38 100644 (file)
@@ -8,6 +8,10 @@ if BUILD_LOADER_EET
 eet_subdir = eet
 endif
 
+if BUILD_LOADER_GIF
+gif_subdir = gif
+endif
+
 if BUILD_LOADER_JPEG
 jpeg_subdir = jpeg
 endif
@@ -16,4 +20,4 @@ if BUILD_LOADER_PNG
 png_subdir = png
 endif
 
-SUBDIRS = $(edb_subdir) $(eet_subdir) $(jpeg_subdir) $(png_subdir)
+SUBDIRS = $(edb_subdir) $(eet_subdir) $(gif_subdir) $(jpeg_subdir) $(png_subdir)
diff --git a/legacy/evas/src/modules/loaders/gif/Makefile.am b/legacy/evas/src/modules/loaders/gif/Makefile.am
new file mode 100644 (file)
index 0000000..d521974
--- /dev/null
@@ -0,0 +1,24 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS     = 1.4 foreign
+
+# A list of all the files in the current directory which can be regenerated
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES              = -I. \
+                        -I$(top_srcdir)/src/lib \
+                        -I$(top_srcdir)/src/lib/include \
+                        @FREETYPE_CFLAGS@ @gif_cflags@
+
+pkgdir                 = $(libdir)/evas/modules/loaders/gif/$(MODULE_ARCH)
+
+pkg_LTLIBRARIES        = module.la
+
+module_la_SOURCES      = evas_image_load_gif.c
+
+module_la_LIBADD       = @gif_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LDFLAGS      = -module -avoid-version -L$(top_builddir)/src/lib -L$(top_builddir)/src/lib/.libs
+
+module_la_DEPENDENCIES = $(top_builddir)/config.h
+
+EXTRA_DIST             = evas_image_load_gif.c
diff --git a/legacy/evas/src/modules/loaders/gif/evas_image_load_gif.c b/legacy/evas/src/modules/loaders/gif/evas_image_load_gif.c
new file mode 100644 (file)
index 0000000..b624e68
--- /dev/null
@@ -0,0 +1,317 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <gif_lib.h>
+
+#include "evas_common.h"
+#include "evas_private.h"
+
+
+int evas_image_load_file_head_gif(RGBA_Image *im, const char *file, const char *key);
+int evas_image_load_file_data_gif(RGBA_Image *im, const char *file, const char *key);
+
+Evas_Image_Load_Func evas_image_load_gif_func =
+{
+  evas_image_load_file_head_gif,
+  evas_image_load_file_data_gif
+};
+
+
+int
+evas_image_load_file_head_gif(RGBA_Image *im, const char *file, const char *key)
+{
+   int                 fd;
+   GifFileType        *gif;
+   GifRecordType       rec;
+   int                 done;
+   int                 w;
+   int                 h;
+   int                 alpha;
+
+   done = 0;
+   w = 0;
+   h = 0;
+   alpha = -1;
+
+   if (!file) return 0;
+
+#ifndef __EMX__
+   fd = open(file, O_RDONLY);
+#else
+   fd = open(file, O_RDONLY | O_BINARY);
+#endif
+   if (fd < 0)
+      return 0;
+
+   gif = DGifOpenFileHandle(fd);
+   if (!gif)
+     {
+        close(fd);
+        return 0;
+     }
+
+   do
+     {
+        if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
+          {
+             /* PrintGifError(); */
+             rec = TERMINATE_RECORD_TYPE;
+          }
+        if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done))
+          {
+             if (DGifGetImageDesc(gif) == GIF_ERROR)
+               {
+                  /* PrintGifError(); */
+                  rec = TERMINATE_RECORD_TYPE;
+               }
+             w = gif->Image.Width;
+             h = gif->Image.Height;
+             done = 1;
+          }
+        else if (rec == EXTENSION_RECORD_TYPE)
+          {
+             int                 ext_code;
+             GifByteType        *ext;
+
+             ext = NULL;
+             DGifGetExtension(gif, &ext_code, &ext);
+             while (ext)
+               {
+                  if ((ext_code == 0xf9) && (ext[1] & 1) && (alpha < 0))
+                    {
+                       alpha = (int)ext[4];
+                    }
+                  ext = NULL;
+                  DGifGetExtensionNext(gif, &ext);
+               }
+          }
+   } while (rec != TERMINATE_RECORD_TYPE);
+
+   if (alpha >= 0) im->flags |= RGBA_IMAGE_HAS_ALPHA;
+   if (!im->image)
+     im->image = evas_common_image_surface_new(im);
+   if (!im->image)
+     {
+        DGifCloseFile(gif);
+       return 0;
+     }
+   im->image->w = w;
+   im->image->h = h;
+
+   DGifCloseFile(gif);
+   return 1;
+}
+
+int
+evas_image_load_file_data_gif(RGBA_Image *im, const char *file, const char *key)
+{
+   int                 intoffset[] = { 0, 4, 2, 1 };
+   int                 intjump[] = { 8, 8, 4, 2 };
+   double              per;
+   double              per_inc;
+   int                 fd;
+   GifFileType        *gif;
+   GifRecordType       rec;
+   GifRowType         *rows;
+   ColorMapObject     *cmap;
+   DATA32             *ptr;
+   int                 done;
+   int                 last_y;
+   int                 last_per;
+   int                 w;
+   int                 h;
+   int                 alpha;
+   int                 i;
+   int                 j;
+   int                 bg;
+   int                 r;
+   int                 g;
+   int                 b;
+
+   rows = NULL;
+   per = 0.0;
+   done = 0;
+   last_y = 0;
+   last_per = 0;
+   w = 0;
+   h = 0;
+   alpha = -1;
+
+   if (!file) return 0;
+
+#ifndef __EMX__
+   fd = open(file, O_RDONLY);
+#else
+   fd = open(file, O_RDONLY | O_BINARY);
+#endif
+   if (fd < 0)
+      return 0;
+
+   gif = DGifOpenFileHandle(fd);
+   if (!gif)
+     {
+        close(fd);
+        return 0;
+     }
+   do
+     {
+        if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
+          {
+             /* PrintGifError(); */
+             rec = TERMINATE_RECORD_TYPE;
+          }
+        if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done))
+          {
+             if (DGifGetImageDesc(gif) == GIF_ERROR)
+               {
+                  /* PrintGifError(); */
+                  rec = TERMINATE_RECORD_TYPE;
+               }
+             w = gif->Image.Width;
+             h = gif->Image.Height;
+             rows = malloc(h * sizeof(GifRowType *));
+             if (!rows)
+               {
+                  DGifCloseFile(gif);
+                  return 0;
+               }
+             for (i = 0; i < h; i++)
+               {
+                  rows[i] = NULL;
+               }
+             for (i = 0; i < h; i++)
+               {
+                  rows[i] = malloc(w * sizeof(GifPixelType));
+                  if (!rows[i])
+                    {
+                       DGifCloseFile(gif);
+                       for (i = 0; i < h; i++)
+                         {
+                            if (rows[i])
+                              {
+                                 free(rows[i]);
+                              }
+                         }
+                       free(rows);
+                       return 0;
+                    }
+               }
+             if (gif->Image.Interlace)
+               {
+                  for (i = 0; i < 4; i++)
+                    {
+                       for (j = intoffset[i]; j < h; j += intjump[i])
+                         {
+                            DGifGetLine(gif, rows[j], w);
+                         }
+                    }
+               }
+             else
+               {
+                  for (i = 0; i < h; i++)
+                    {
+                       DGifGetLine(gif, rows[i], w);
+                    }
+               }
+             done = 1;
+          }
+        else if (rec == EXTENSION_RECORD_TYPE)
+          {
+             int                 ext_code;
+             GifByteType        *ext;
+
+             ext = NULL;
+             DGifGetExtension(gif, &ext_code, &ext);
+             while (ext)
+               {
+                  if ((ext_code == 0xf9) && (ext[1] & 1) && (alpha < 0))
+                    {
+                       alpha = (int)ext[4];
+                    }
+                  ext = NULL;
+                  DGifGetExtensionNext(gif, &ext);
+               }
+          }
+   } while (rec != TERMINATE_RECORD_TYPE);
+
+   if (alpha >= 0) im->flags |= RGBA_IMAGE_HAS_ALPHA;
+   if (!im->image)
+     im->image = evas_common_image_surface_new(im);
+   if (!im->image)
+     {
+        DGifCloseFile(gif);
+       return 0;
+     }
+   im->image->w = w;
+   im->image->h = h;
+
+   evas_common_image_surface_alloc(im->image);
+   if (!im->image->data)
+     {
+       evas_common_image_surface_free(im->image);
+        DGifCloseFile(gif);
+        for (i = 0; i < h; i++)
+          {
+            free(rows[i]);
+          }
+        free(rows);
+       return 0;
+     }
+
+   bg = gif->SBackGroundColor;
+   cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
+
+   ptr = im->image->data;
+   per_inc = 100.0 / (((double)w) * h);
+
+   for (i = 0; i < h; i++)
+     {
+       for (j = 0; j < w; j++)
+         {
+           if (rows[i][j] == alpha)
+             {
+               r = cmap->Colors[bg].Red;
+               g = cmap->Colors[bg].Green;
+               b = cmap->Colors[bg].Blue;
+               *ptr++ = 0x00ffffff & ((r << 16) | (g << 8) | b);
+             }
+           else
+             {
+               r = cmap->Colors[rows[i][j]].Red;
+               g = cmap->Colors[rows[i][j]].Green;
+               b = cmap->Colors[rows[i][j]].Blue;
+               *ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
+             }
+           per += per_inc;
+         }
+     }
+   DGifCloseFile(gif);
+   for (i = 0; i < h; i++)
+     {
+        free(rows[i]);
+     }
+   free(rows);
+
+   return 1;
+}
+
+int module_open(Evas_Module *em)
+{
+   if (!em) return 0;
+   em->functions = (void *)(&evas_image_load_gif_func);
+   return 1;
+}
+
+void module_close(void)
+{
+   
+}
+
+Evas_Module_Api evas_modapi =
+{
+   EVAS_MODULE_API_VERSION,
+     EVAS_MODULE_TYPE_IMAGE_LOADER,
+     "gif",
+     "none"
+};