gdip-pixbuf-loader r31 - in trunk: . src
- From: doml svn gnome org
- To: svn-commits-list gnome org
- Subject: gdip-pixbuf-loader r31 - in trunk: . src
- Date: Fri, 22 Feb 2008 21:40:21 +0000 (GMT)
Author: doml
Date: Fri Feb 22 21:40:21 2008
New Revision: 31
URL: http://svn.gnome.org/viewvc/gdip-pixbuf-loader?rev=31&view=rev
Log:
2008-02-22 Dom Lachowicz <domlachowicz gmail com>
* src/*.[ch]: Separate out formats that are writable into their own plugins. The GDI+ loader
can now save as BMP, GIF, JPEG, PNG, or TIFF. Also, some tweaks so that the format plugins
can be statically compiled into GTK+ if we choose to do so.
Added:
trunk/src/io-gdip-bmp.c
trunk/src/io-gdip-gif.c
trunk/src/io-gdip-jpeg.c
trunk/src/io-gdip-png.c
trunk/src/io-gdip-tiff.c
trunk/src/test-save.c
Modified:
trunk/ChangeLog
trunk/src/Makefile.test
trunk/src/io-gdip-native.h
trunk/src/io-gdip-utils.c
trunk/src/io-gdip-utils.h
trunk/src/io-gdip.c
Modified: trunk/src/Makefile.test
==============================================================================
--- trunk/src/Makefile.test (original)
+++ trunk/src/Makefile.test Fri Feb 22 21:40:21 2008
@@ -1,7 +1,40 @@
-CC=/usr/bin/i586-mingw32msvc-gcc
-ARGS=`pkg-config --cflags gtk+-2.0`
+CC=gcc.exe
-all: test.exe
+PREFIX=/c/Program\ Files/Common\ Files/GTK/2.0
-test.exe:
- $(CC) test.c io-gdip-utils.c $(ARGS) -lole32 -o test.exe
+CFLAGS=-I$(PREFIX)/include/glib-2.0/ -I$(PREFIX)/include/gtk-2.0 -I$(PREFIX)/include/pango-1.0 -I$(PREFIX)/lib/glib-2.0/include/
+
+LDFLAGS=-L$(PREFIX)/lib/
+
+all: libpixbufloader-gdip-bmp.dll libpixbufloader-gdip-gif.dll libpixbufloader-gdip-jpeg.dll libpixbufloader-gdip-png.dll libpixbufloader-gdip-tiff.dll libpixbufloader-gdip.dll
+
+clean:
+ rm -f *.dll *.o *.exe *~
+
+test-save.exe: test-save.c
+ $(CC) -Wall -O0 -g $(CFLAGS) $(LDFLAGS) test-save.c -o test-save.exe -lole32 -lglib-2.0 -lgobject-2.0 -lgdk_pixbuf-2.0
+ cp test-save.exe $(PREFIX)/bin
+
+libpixbufloader-gdip.dll: io-gdip-native.h io-gdip-utils.c io-gdip-utils.h io-gdip.c
+ $(CC) -Wall -O0 -g -shared io-gdip-utils.c io-gdip.c $(CFLAGS) $(LDFLAGS) -lole32 -lglib-2.0 -lgobject-2.0 -lgdk_pixbuf-2.0 -o $@
+ cp $@ $(PREFIX)/lib/gtk-2.0/2.10.0/loaders
+
+libpixbufloader-gdip-bmp.dll: io-gdip-native.h io-gdip-utils.c io-gdip-utils.h io-gdip-bmp.c
+ $(CC) -Wall -O0 -g -shared io-gdip-utils.c io-gdip-bmp.c $(CFLAGS) $(LDFLAGS) -lole32 -lglib-2.0 -lgobject-2.0 -lgdk_pixbuf-2.0 -o $@
+ cp $@ $(PREFIX)/lib/gtk-2.0/2.10.0/loaders
+
+libpixbufloader-gdip-gif.dll: io-gdip-native.h io-gdip-utils.c io-gdip-utils.h io-gdip-gif.c
+ $(CC) -Wall -O0 -g -shared io-gdip-utils.c io-gdip-gif.c $(CFLAGS) $(LDFLAGS) -lole32 -lglib-2.0 -lgobject-2.0 -lgdk_pixbuf-2.0 -o $@
+ cp $@ $(PREFIX)/lib/gtk-2.0/2.10.0/loaders
+
+libpixbufloader-gdip-jpeg.dll: io-gdip-native.h io-gdip-utils.c io-gdip-utils.h io-gdip-jpeg.c
+ $(CC) -Wall -O0 -g -shared io-gdip-utils.c io-gdip-jpeg.c $(CFLAGS) $(LDFLAGS) -lole32 -lglib-2.0 -lgobject-2.0 -lgdk_pixbuf-2.0 -o $@
+ cp $@ $(PREFIX)/lib/gtk-2.0/2.10.0/loaders
+
+libpixbufloader-gdip-png.dll: io-gdip-native.h io-gdip-utils.c io-gdip-utils.h io-gdip-png.c
+ $(CC) -Wall -O0 -g -shared io-gdip-utils.c io-gdip-png.c $(CFLAGS) $(LDFLAGS) -lole32 -lglib-2.0 -lgobject-2.0 -lgdk_pixbuf-2.0 -o $@
+ cp $@ $(PREFIX)/lib/gtk-2.0/2.10.0/loaders
+
+libpixbufloader-gdip-tiff.dll: io-gdip-native.h io-gdip-utils.c io-gdip-utils.h io-gdip-tiff.c
+ $(CC) -Wall -O0 -g -shared io-gdip-utils.c io-gdip-tiff.c $(CFLAGS) $(LDFLAGS) -lole32 -lglib-2.0 -lgobject-2.0 -lgdk_pixbuf-2.0 -o $@
+ cp $@ $(PREFIX)/lib/gtk-2.0/2.10.0/loaders
\ No newline at end of file
Added: trunk/src/io-gdip-bmp.c
==============================================================================
--- (empty file)
+++ trunk/src/io-gdip-bmp.c Fri Feb 22 21:40:21 2008
@@ -0,0 +1,89 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* GdkPixbuf library - Win32 GDI+ Pixbuf Loader
+ *
+ * Copyright (C) 2008 Dominic Lachowicz
+ * Copyright (C) 2008 Alberto Ruiz
+ *
+ * Authors: Dominic Lachowicz <domlachowicz gmail com>
+ * Alberto Ruiz <aruiz gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "io-gdip-utils.h"
+
+static gboolean
+gdk_pixbuf__gdip_image_save_BMP_to_callback (GdkPixbufSaveFunc save_func,
+ gpointer user_data,
+ GdkPixbuf *pixbuf,
+ gchar **keys,
+ gchar **values,
+ GError **error)
+{
+ EncoderParameters *encoder_params = NULL;
+ gboolean status;
+
+ status = io_gdip_save_pixbuf (pixbuf, L"image/bmp", encoder_params, save_func, user_data, error);
+
+ g_free (encoder_params);
+
+ return status;
+}
+
+static gboolean
+gdk_pixbuf__gdip_image_save_BMP (FILE *f,
+ GdkPixbuf *pixbuf,
+ gchar **keys,
+ gchar **values,
+ GError **error)
+{
+ return gdk_pixbuf__gdip_image_save_BMP_to_callback(gdip_save_to_file_callback, f, pixbuf, keys, values, error);
+}
+
+void
+MODULE_ENTRY(bmp, fill_vtable) (GdkPixbufModule *module)
+{
+ gdip_fill_vtable(module);
+
+ module->save_to_callback = gdk_pixbuf__gdip_image_save_BMP_to_callback;
+ module->save = gdk_pixbuf__gdip_image_save_BMP; /* for gtk < 2.14, you need to implement both. otherwise gdk-pixbuf-queryloaders fails */
+}
+
+void
+MODULE_ENTRY(bmp, fill_info) (GdkPixbufFormat *info)
+{
+ static GdkPixbufModulePattern signature[] = {
+ { "BM", NULL, 100 }, /* BMP */
+ { NULL, NULL, 0 }
+ };
+
+ static gchar *mime_types[] = {
+ "image/bmp",
+ "image/x-bmp",
+ "image/x-MS-bmp",
+ NULL
+ };
+
+ static gchar *extensions[] = {
+ "bmp",
+ NULL
+ };
+
+ info->name = "bmp";
+ info->signature = signature;
+ info->description = "Win32 GDI+ BMP loader.";
+ info->mime_types = mime_types;
+ info->extensions = extensions;
+ info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
+}
Added: trunk/src/io-gdip-gif.c
==============================================================================
--- (empty file)
+++ trunk/src/io-gdip-gif.c Fri Feb 22 21:40:21 2008
@@ -0,0 +1,88 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* GdkPixbuf library - Win32 GDI+ Pixbuf Loader
+ *
+ * Copyright (C) 2008 Dominic Lachowicz
+ * Copyright (C) 2008 Alberto Ruiz
+ *
+ * Authors: Dominic Lachowicz <domlachowicz gmail com>
+ * Alberto Ruiz <aruiz gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "io-gdip-utils.h"
+
+static gboolean
+gdk_pixbuf__gdip_image_save_GIF_to_callback (GdkPixbufSaveFunc save_func,
+ gpointer user_data,
+ GdkPixbuf *pixbuf,
+ gchar **keys,
+ gchar **values,
+ GError **error)
+{
+ /* TODO: support exif data and the like */
+ EncoderParameters *encoder_params = NULL;
+ gboolean status;
+
+ status = io_gdip_save_pixbuf (pixbuf, L"image/gif", encoder_params, save_func, user_data, error);
+
+ g_free (encoder_params);
+
+ return status;
+}
+
+static gboolean
+gdk_pixbuf__gdip_image_save_GIF (FILE *f,
+ GdkPixbuf *pixbuf,
+ gchar **keys,
+ gchar **values,
+ GError **error)
+{
+ return gdk_pixbuf__gdip_image_save_GIF_to_callback(gdip_save_to_file_callback, f, pixbuf, keys, values, error);
+}
+
+void
+MODULE_ENTRY(gif, fill_vtable) (GdkPixbufModule *module)
+{
+ gdip_fill_vtable(module);
+
+ module->save_to_callback = gdk_pixbuf__gdip_image_save_GIF_to_callback;
+ module->save = gdk_pixbuf__gdip_image_save_GIF; /* for gtk < 2.14, you need to implement both. otherwise gdk-pixbuf-queryloaders fails */
+}
+
+void
+MODULE_ENTRY(gif, fill_info) (GdkPixbufFormat *info)
+{
+ static GdkPixbufModulePattern signature[] = {
+ { "GIF8", NULL, 100 }, /* GIF */
+ { NULL, NULL, 0 }
+ };
+
+ static gchar *mime_types[] = {
+ "image/gif",
+ NULL
+ };
+
+ static gchar *extensions[] = {
+ "gif",
+ NULL
+ };
+
+ info->name = "gif";
+ info->signature = signature;
+ info->description = "Win32 GDI+ GIF loader.";
+ info->mime_types = mime_types;
+ info->extensions = extensions;
+ info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
+}
Added: trunk/src/io-gdip-jpeg.c
==============================================================================
--- (empty file)
+++ trunk/src/io-gdip-jpeg.c Fri Feb 22 21:40:21 2008
@@ -0,0 +1,89 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* GdkPixbuf library - Win32 GDI+ Pixbuf Loader
+ *
+ * Copyright (C) 2008 Dominic Lachowicz
+ * Copyright (C) 2008 Alberto Ruiz
+ *
+ * Authors: Dominic Lachowicz <domlachowicz gmail com>
+ * Alberto Ruiz <aruiz gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "io-gdip-utils.h"
+
+static gboolean
+gdk_pixbuf__gdip_image_save_JPEG_to_callback (GdkPixbufSaveFunc save_func,
+ gpointer user_data,
+ GdkPixbuf *pixbuf,
+ gchar **keys,
+ gchar **values,
+ GError **error)
+{
+ EncoderParameters *encoder_params = NULL;
+ gboolean status;
+
+ status = io_gdip_save_pixbuf (pixbuf, L"image/jpeg", encoder_params, save_func, user_data, error);
+
+ g_free (encoder_params);
+
+ return status;
+}
+
+static gboolean
+gdk_pixbuf__gdip_image_save_JPEG (FILE *f,
+ GdkPixbuf *pixbuf,
+ gchar **keys,
+ gchar **values,
+ GError **error)
+{
+ return gdk_pixbuf__gdip_image_save_JPEG_to_callback(gdip_save_to_file_callback, f, pixbuf, keys, values, error);
+}
+
+void
+MODULE_ENTRY(jpeg, fill_vtable) (GdkPixbufModule *module)
+{
+ gdip_fill_vtable(module);
+
+ module->save_to_callback = gdk_pixbuf__gdip_image_save_JPEG_to_callback;
+ module->save = gdk_pixbuf__gdip_image_save_JPEG; /* for gtk < 2.14, you need to implement both. otherwise gdk-pixbuf-queryloaders fails */
+}
+
+void
+MODULE_ENTRY(jpeg, fill_info) (GdkPixbufFormat *info)
+{
+ static GdkPixbufModulePattern signature[] = {
+ { "\xff\xd8", NULL, 100 }, /* JPEG */
+ { NULL, NULL, 0 }
+ };
+
+ static gchar *mime_types[] = {
+ "image/jpeg",
+ NULL
+ };
+
+ static gchar *extensions[] = {
+ "jpeg",
+ "jpe",
+ "jpg",
+ NULL
+ };
+
+ info->name = "jpeg";
+ info->signature = signature;
+ info->description = "Win32 GDI+ JPEG loader.";
+ info->mime_types = mime_types;
+ info->extensions = extensions;
+ info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
+}
Modified: trunk/src/io-gdip-native.h
==============================================================================
--- trunk/src/io-gdip-native.h (original)
+++ trunk/src/io-gdip-native.h Fri Feb 22 21:40:21 2008
@@ -26,7 +26,6 @@
#include <windef.h>
#include <glib.h>
-
/* //////////// Native API ///////////// */
#define WINGDIPAPI __stdcall
@@ -153,8 +152,8 @@
struct _EncoderParameters
{
- UINT Count; // Number of parameters in this structure
- EncoderParameter Parameter[1]; // Parameter values
+ UINT Count; /* Number of parameters in this structure */
+ EncoderParameter Parameter[1]; /* Parameter values */
};
typedef struct _EncoderParameters EncoderParameters;
Added: trunk/src/io-gdip-png.c
==============================================================================
--- (empty file)
+++ trunk/src/io-gdip-png.c Fri Feb 22 21:40:21 2008
@@ -0,0 +1,88 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* GdkPixbuf library - Win32 GDI+ Pixbuf Loader
+ *
+ * Copyright (C) 2008 Dominic Lachowicz
+ * Copyright (C) 2008 Alberto Ruiz
+ *
+ * Authors: Dominic Lachowicz <domlachowicz gmail com>
+ * Alberto Ruiz <aruiz gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "io-gdip-utils.h"
+
+static gboolean
+gdk_pixbuf__gdip_image_save_PNG_to_callback (GdkPixbufSaveFunc save_func,
+ gpointer user_data,
+ GdkPixbuf *pixbuf,
+ gchar **keys,
+ gchar **values,
+ GError **error)
+{
+ /* TODO: support exif data and the like */
+ EncoderParameters *encoder_params = NULL;
+ gboolean status;
+
+ status = io_gdip_save_pixbuf (pixbuf, L"image/png", encoder_params, save_func, user_data, error);
+
+ g_free (encoder_params);
+
+ return status;
+}
+
+static gboolean
+gdk_pixbuf__gdip_image_save_PNG (FILE *f,
+ GdkPixbuf *pixbuf,
+ gchar **keys,
+ gchar **values,
+ GError **error)
+{
+ return gdk_pixbuf__gdip_image_save_PNG_to_callback(gdip_save_to_file_callback, f, pixbuf, keys, values, error);
+}
+
+void
+MODULE_ENTRY(png, fill_vtable) (GdkPixbufModule *module)
+{
+ gdip_fill_vtable(module);
+
+ module->save_to_callback = gdk_pixbuf__gdip_image_save_PNG_to_callback;
+ module->save = gdk_pixbuf__gdip_image_save_PNG; /* for gtk < 2.14, you need to implement both. otherwise gdk-pixbuf-queryloaders fails */
+}
+
+void
+MODULE_ENTRY(png, fill_info) (GdkPixbufFormat *info)
+{
+ static GdkPixbufModulePattern signature[] = {
+ { "\x89PNG\r\n\x1a\x0a", NULL, 100 }, /* PNG */
+ { NULL, NULL, 0 }
+ };
+
+ static gchar *mime_types[] = {
+ "image/png",
+ NULL
+ };
+
+ static gchar *extensions[] = {
+ "png",
+ NULL
+ };
+
+ info->name = "png";
+ info->signature = signature;
+ info->description = "Win32 GDI+ PNG loader.";
+ info->mime_types = mime_types;
+ info->extensions = extensions;
+ info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
+}
Added: trunk/src/io-gdip-tiff.c
==============================================================================
--- (empty file)
+++ trunk/src/io-gdip-tiff.c Fri Feb 22 21:40:21 2008
@@ -0,0 +1,90 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* GdkPixbuf library - Win32 GDI+ Pixbuf Loader
+ *
+ * Copyright (C) 2008 Dominic Lachowicz
+ * Copyright (C) 2008 Alberto Ruiz
+ *
+ * Authors: Dominic Lachowicz <domlachowicz gmail com>
+ * Alberto Ruiz <aruiz gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "io-gdip-utils.h"
+
+static gboolean
+gdk_pixbuf__gdip_image_save_TIFF_to_callback (GdkPixbufSaveFunc save_func,
+ gpointer user_data,
+ GdkPixbuf *pixbuf,
+ gchar **keys,
+ gchar **values,
+ GError **error)
+{
+ /* TODO: support exif data and the like */
+ EncoderParameters *encoder_params = NULL;
+ gboolean status;
+
+ status = io_gdip_save_pixbuf (pixbuf, L"image/tiff", encoder_params, save_func, user_data, error);
+
+ g_free (encoder_params);
+
+ return status;
+}
+
+static gboolean
+gdk_pixbuf__gdip_image_save_TIFF (FILE *f,
+ GdkPixbuf *pixbuf,
+ gchar **keys,
+ gchar **values,
+ GError **error)
+{
+ return gdk_pixbuf__gdip_image_save_TIFF_to_callback(gdip_save_to_file_callback, f, pixbuf, keys, values, error);
+}
+
+void
+MODULE_ENTRY(tiff, fill_vtable) (GdkPixbufModule *module)
+{
+ gdip_fill_vtable(module);
+
+ module->save_to_callback = gdk_pixbuf__gdip_image_save_TIFF_to_callback;
+ module->save = gdk_pixbuf__gdip_image_save_TIFF; /* for gtk < 2.14, you need to implement both. otherwise gdk-pixbuf-queryloaders fails */
+}
+
+void
+MODULE_ENTRY(tiff, fill_info) (GdkPixbufFormat *info)
+{
+ static GdkPixbufModulePattern signature[] = {
+ { "MM \x2a", " z ", 100 }, /* TIFF */
+ { "II\x2a ", " z", 100 }, /* TIFF */
+ { NULL, NULL, 0 }
+ };
+
+ static gchar *mime_types[] = {
+ "image/tiff",
+ NULL
+ };
+
+ static gchar *extensions[] = {
+ "tiff",
+ "tif",
+ NULL
+ };
+
+ info->name = "tiff";
+ info->signature = signature;
+ info->description = "Win32 GDI+ TIFF loader.";
+ info->mime_types = mime_types;
+ info->extensions = extensions;
+ info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
+}
Modified: trunk/src/io-gdip-utils.c
==============================================================================
--- trunk/src/io-gdip-utils.c (original)
+++ trunk/src/io-gdip-utils.c Fri Feb 22 21:40:21 2008
@@ -21,13 +21,12 @@
* Boston, MA 02111-1307, USA.
*/
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
#define INITGUID
-#include "io-gdip-native.h"
+#include <ole2.h>
+
#include "io-gdip-utils.h"
+#include "io-gdip-native.h"
#include "io-gdip-propertytags.h"
-#include <ole2.h>
static GdiplusStartupFunc GdiplusStartup;
static GdipCreateBitmapFromStreamFunc GdipCreateBitmapFromStream;
@@ -50,8 +49,6 @@
static GetImageEncodersFunc GetImageEncoders;
static GetImageEncodersSizeFunc GetImageEncodersSize;
-extern void gdip_propegate_error (GError ** err, const char * reason, gint code);
-
DEFINE_GUID(FrameDimensionTime, 0x6aedbd6d,0x3fb5,0x418a,0x83,0xa6,0x7f,0x45,0x22,0x9d,0xc8,0x72);
DEFINE_GUID(FrameDimensionPage, 0x7462dc86,0x6180,0x4c7e,0x8e,0x3f,0xee,0x73,0x33,0xa7,0xa4,0x83);
@@ -583,3 +580,284 @@
return success;
}
+
+/*************************************************************************/
+/*************************************************************************/
+
+struct _GdipContext{
+ GdkPixbufModuleUpdatedFunc updated_func;
+ GdkPixbufModulePreparedFunc prepared_func;
+ GdkPixbufModuleSizeFunc size_func;
+
+ gboolean first_write;
+
+ gpointer user_data;
+
+ GByteArray* buffer;
+};
+typedef struct _GdipContext GdipContext;
+
+static void
+destroy_gdipcontext (GdipContext *context)
+{
+ if (context != NULL)
+ {
+ g_byte_array_free (context->buffer, TRUE);
+ g_free (context);
+ }
+}
+
+static void
+emit_updated (GdipContext *context, GdkPixbuf *pixbuf)
+{
+ if (context->updated_func != NULL)
+ (* context->updated_func) (pixbuf,
+ 0, 0,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf),
+ context->user_data);
+}
+
+static void
+emit_prepared (GdipContext *context, GdkPixbuf *pixbuf, GdkPixbufAnimation *anim)
+{
+ if (context->prepared_func != NULL)
+ (* context->prepared_func) (pixbuf, anim, context->user_data);
+}
+
+static gpointer
+gdk_pixbuf__gdip_image_begin_load (GdkPixbufModuleSizeFunc size_func,
+ GdkPixbufModulePreparedFunc prepared_func,
+ GdkPixbufModuleUpdatedFunc updated_func,
+ gpointer user_data,
+ GError **error)
+{
+ GdipContext *context = g_new(GdipContext, 1);
+
+ if (!context)
+ {
+ gdip_propegate_error (error, "Couldn't create context", GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY);
+ return NULL;
+ }
+
+ if (error)
+ *error = NULL;
+
+ context->first_write = TRUE;
+ context->size_func = size_func;
+
+ context->prepared_func = prepared_func;
+ context->updated_func = updated_func;
+ context->user_data = user_data;
+
+ context->buffer = g_byte_array_new();
+
+ return context;
+}
+
+static gboolean
+gdk_pixbuf__gdip_image_load_increment (gpointer data,
+ const guchar *buf, guint size,
+ GError **error)
+{
+ GdipContext *context = (GdipContext *)data;
+ GByteArray *image_buffer = context->buffer;
+
+ if (error)
+ *error = NULL;
+
+ g_byte_array_append(image_buffer, (guint8*)buf, size);
+
+ return TRUE;
+}
+
+static GdkPixbuf*
+gdi_bitmap_to_pixbuf (GpBitmap *bitmap)
+{
+ GdkPixbuf *pixbuf = NULL;
+ guchar *cursor = NULL;
+ gint rowstride;
+ gboolean has_alpha = FALSE;
+ gint n_channels = 0;
+ gchar *option;
+
+ guint width = 0, height = 0, x, y;
+
+ io_gdip_bitmap_get_size (bitmap, &width, &height);
+ io_gdip_bitmap_get_has_alpha (bitmap, &has_alpha);
+
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha, 8, width, height);
+
+ if (!pixbuf)
+ {
+ return NULL;
+ }
+
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ cursor = gdk_pixbuf_get_pixels (pixbuf);
+ n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ ARGB pixel;
+ guchar *b = cursor + (y * rowstride + (x * n_channels));
+
+ pixel = io_gdip_bitmap_get_pixel (bitmap, x, y);
+
+ b[0] = (pixel & 0xff0000) >> 16;
+ b[1] = (pixel & 0x00ff00) >> 8;
+ b[2] = (pixel & 0x0000ff) >> 0;
+
+ if (has_alpha)
+ {
+ b[3] = (pixel & 0xff000000) >> 24;
+ }
+ }
+ }
+
+ io_gdip_bitmap_get_property_as_string(bitmap, PropertyTagImageWidth, &option);
+ g_free(option);
+
+ if (io_gdip_bitmap_get_property_as_string(bitmap, PropertyTagOrientation, &option))
+ {
+ gdk_pixbuf_set_option (pixbuf, "orientation", option);
+ g_free(option);
+ }
+
+ if (io_gdip_bitmap_get_property_as_string(bitmap, PropertyTagArtist, &option))
+ {
+ gdk_pixbuf_set_option (pixbuf, "Author", option);
+ g_free(option);
+ }
+
+ if (io_gdip_bitmap_get_property_as_string(bitmap, PropertyTagImageTitle, &option))
+ {
+ gdk_pixbuf_set_option (pixbuf, "Title", option);
+ g_free(option);
+ }
+
+ return pixbuf;
+}
+
+static gboolean
+gdk_pixbuf__gdip_image_stop_load (gpointer data, GError **error)
+{
+ GdipContext *context = (GdipContext *)data;
+ GpBitmap *bitmap = NULL;
+
+ GByteArray *image_buffer = context->buffer;
+ guint8 *tmp_buffer = NULL;
+ guint buffer_len = 0;
+ guint n_frames = 1, i;
+
+ GdkPixbufAnimation *anim = NULL;
+
+ if (error)
+ *error = NULL;
+
+ buffer_len = image_buffer->len;
+ tmp_buffer = image_buffer->data;
+
+ bitmap = io_gdip_buffer_to_bitmap ((gchar*)image_buffer->data, image_buffer->len);
+
+ if (!bitmap)
+ {
+ destroy_gdipcontext (context);
+ gdip_propegate_error (error, "Couldn't load bitmap", GDK_PIXBUF_ERROR_CORRUPT_IMAGE);
+ return FALSE;
+ }
+
+ io_gdip_bitmap_get_n_frames (bitmap, &n_frames, TRUE);
+
+ for (i = 0; i < n_frames; i++)
+ {
+ GdkPixbuf *pixbuf = NULL;
+
+ io_gdip_bitmap_select_frame (bitmap, i, TRUE);
+
+ if (n_frames > 1 && i == 0)
+ {
+ guint delay; /* in hundredths per second */
+ guint width = 0, height = 0;
+ gfloat rate = 1;
+
+ io_gdip_bitmap_get_frame_delay (bitmap, &delay);
+ rate = 1.0f / ((gfloat)delay / 100);
+
+ io_gdip_bitmap_get_size (bitmap, &width, &height);
+ /* anim = GDK_PIXBUF_ANIMATION(gdk_pixbuf_simple_anim_new (width, height, rate)); */
+ }
+
+ pixbuf = gdi_bitmap_to_pixbuf (bitmap);
+
+ if (!pixbuf)
+ {
+ destroy_gdipcontext (context);
+ gdip_propegate_error (error, "Couldn't create pixbuf", GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY);
+ return FALSE;
+ }
+
+ if (anim != NULL)
+ {
+ gdk_pixbuf_simple_anim_add_frame (GDK_PIXBUF_SIMPLE_ANIM(anim), pixbuf);
+ }
+
+ if (i == 0)
+ {
+ emit_prepared (context, pixbuf, anim);
+ }
+
+ emit_updated (context, pixbuf);
+ }
+
+ destroy_gdipcontext (context);
+
+ return TRUE;
+}
+
+gboolean
+gdip_save_to_file_callback (const gchar *buf,
+ gsize count,
+ GError **error,
+ gpointer data)
+{
+ FILE *filehandle = data;
+ gsize n;
+
+ n = fwrite (buf, 1, count, filehandle);
+ if (n != count) {
+ gint save_errno = errno;
+ g_set_error (error,
+ G_FILE_ERROR,
+ g_file_error_from_errno (save_errno),
+ "Error writing to image file: %s",
+ g_strerror (save_errno));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* meant to be shared across various GDI+ plugins, since we'll need multiple plugins to support saving to multiple formats */
+void
+gdip_fill_vtable (GdkPixbufModule *module)
+{
+ io_gdip_init ();
+
+ module->begin_load = gdk_pixbuf__gdip_image_begin_load;
+ module->stop_load = gdk_pixbuf__gdip_image_stop_load;
+ module->load_increment = gdk_pixbuf__gdip_image_load_increment;
+}
+
+void
+gdip_propegate_error (GError ** err,
+ const char * reason,
+ gint code)
+{
+ if (err)
+ {
+ *err = NULL;
+ g_set_error (err, GDK_PIXBUF_ERROR, code, reason);
+ }
+}
Modified: trunk/src/io-gdip-utils.h
==============================================================================
--- trunk/src/io-gdip-utils.h (original)
+++ trunk/src/io-gdip-utils.h Fri Feb 22 21:40:21 2008
@@ -24,8 +24,32 @@
#ifndef _HAVE_IO_GDIP_UTILS_H
#define _HAVE_IO_GDIP_UTILS_H
+#define GDK_PIXBUF_ENABLE_BACKEND
+#include <gdk-pixbuf/gdk-pixbuf-io.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
#include "io-gdip-native.h"
+#ifndef INCLUDE_gdi
+#define MODULE_ENTRY(type,function) function
+#else
+#define MODULE_ENTRY(type,function) _gdk_pixbuf__ ## type ## _ ## function
+#endif
+
+gboolean
+gdip_save_to_file_callback (const gchar *buf,
+ gsize count,
+ GError **error,
+ gpointer data);
+
+void
+gdip_fill_vtable (GdkPixbufModule *module);
+
+void
+gdip_propegate_error (GError ** err,
+ const char * reason,
+ gint code);
+
gboolean
io_gdip_init (void);
Modified: trunk/src/io-gdip.c
==============================================================================
--- trunk/src/io-gdip.c (original)
+++ trunk/src/io-gdip.c Fri Feb 22 21:40:21 2008
@@ -21,358 +21,20 @@
* Boston, MA 02111-1307, USA.
*/
-#define GDK_PIXBUF_ENABLE_BACKEND
-#include <gdk-pixbuf/gdk-pixbuf-io.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
#include "io-gdip-utils.h"
-#include "io-gdip-propertytags.h"
-
-struct _GdipContext{
- GdkPixbufModuleUpdatedFunc updated_func;
- GdkPixbufModulePreparedFunc prepared_func;
- GdkPixbufModuleSizeFunc size_func;
-
- gboolean first_write;
-
- gpointer user_data;
-
- GByteArray* buffer;
-};
-typedef struct _GdipContext GdipContext;
-
-G_MODULE_EXPORT void fill_vtable (GdkPixbufModule *module);
-G_MODULE_EXPORT void fill_info (GdkPixbufFormat *info);
-
-void
-gdip_propegate_error (GError ** err,
- const char * reason,
- gint code)
-{
- if (err)
- {
- *err = NULL;
- g_set_error (err, GDK_PIXBUF_ERROR, code, reason);
- }
-}
-
-static void
-destroy_gdipcontext (GdipContext *context)
-{
- if (context != NULL)
- {
- g_byte_array_free (context->buffer, TRUE);
- g_free (context);
- }
-}
-
-static void
-emit_updated (GdipContext *context, GdkPixbuf *pixbuf)
-{
- if (context->updated_func != NULL)
- (* context->updated_func) (pixbuf,
- 0, 0,
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf),
- context->user_data);
-}
-
-static void
-emit_prepared (GdipContext *context, GdkPixbuf *pixbuf, GdkPixbufAnimation *anim)
-{
- if (context->prepared_func != NULL)
- (* context->prepared_func) (pixbuf, anim, context->user_data);
-}
-
-static gpointer
-gdk_pixbuf__gdip_image_begin_load (GdkPixbufModuleSizeFunc size_func,
- GdkPixbufModulePreparedFunc prepared_func,
- GdkPixbufModuleUpdatedFunc updated_func,
- gpointer user_data,
- GError **error)
-{
- GdipContext *context = g_new(GdipContext, 1);
-
- if (!context)
- {
- gdip_propegate_error (error, "Couldn't create context", GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY);
- return NULL;
- }
-
- if (error)
- *error = NULL;
-
- context->first_write = TRUE;
- context->size_func = size_func;
-
- context->prepared_func = prepared_func;
- context->updated_func = updated_func;
- context->user_data = user_data;
-
- context->buffer = g_byte_array_new();
-
- return context;
-}
-
-static gboolean
-gdk_pixbuf__gdip_image_load_increment (gpointer data,
- const guchar *buf, guint size,
- GError **error)
-{
- GdipContext *context = (GdipContext *)data;
- GByteArray *image_buffer = context->buffer;
-
- if (error)
- *error = NULL;
-
- g_byte_array_append(image_buffer, (guint8*)buf, size);
-
- return TRUE;
-}
-
-static GdkPixbuf*
-gdi_bitmap_to_pixbuf (GpBitmap *bitmap)
-{
- GdkPixbuf *pixbuf = NULL;
- guchar *cursor = NULL;
- gint rowstride;
- gboolean has_alpha = FALSE;
- gint n_channels = 0;
- gchar *option;
-
- guint width = 0, height = 0, x, y;
-
- io_gdip_bitmap_get_size (bitmap, &width, &height);
- io_gdip_bitmap_get_has_alpha (bitmap, &has_alpha);
-
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha, 8, width, height);
-
- if (!pixbuf)
- {
- return NULL;
- }
-
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
- cursor = gdk_pixbuf_get_pixels (pixbuf);
- n_channels = gdk_pixbuf_get_n_channels (pixbuf);
-
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- ARGB pixel;
- guchar *b = cursor + (y * rowstride + (x * n_channels));
-
- pixel = io_gdip_bitmap_get_pixel (bitmap, x, y);
-
- b[0] = (pixel & 0xff0000) >> 16;
- b[1] = (pixel & 0x00ff00) >> 8;
- b[2] = (pixel & 0x0000ff) >> 0;
-
- if (has_alpha)
- {
- b[3] = (pixel & 0xff000000) >> 24;
- }
- }
- }
-
- io_gdip_bitmap_get_property_as_string(bitmap, PropertyTagImageWidth, &option);
- g_free(option);
-
- if (io_gdip_bitmap_get_property_as_string(bitmap, PropertyTagOrientation, &option))
- {
- gdk_pixbuf_set_option (pixbuf, "orientation", option);
- g_free(option);
- }
-
- if (io_gdip_bitmap_get_property_as_string(bitmap, PropertyTagArtist, &option))
- {
- gdk_pixbuf_set_option (pixbuf, "Author", option);
- g_free(option);
- }
-
- if (io_gdip_bitmap_get_property_as_string(bitmap, PropertyTagImageTitle, &option))
- {
- gdk_pixbuf_set_option (pixbuf, "Title", option);
- g_free(option);
- }
-
- return pixbuf;
-}
-
-static gboolean
-gdk_pixbuf__gdip_image_stop_load (gpointer data, GError **error)
-{
- GdipContext *context = (GdipContext *)data;
- GpBitmap *bitmap = NULL;
-
- GByteArray *image_buffer = context->buffer;
- guint8 *tmp_buffer = NULL;
- guint buffer_len = 0;
- guint n_frames = 1, i;
-
- GdkPixbufAnimation *anim = NULL;
-
- if (error)
- *error = NULL;
-
- buffer_len = image_buffer->len;
- tmp_buffer = image_buffer->data;
-
- bitmap = io_gdip_buffer_to_bitmap ((gchar*)image_buffer->data, image_buffer->len);
-
- if (!bitmap)
- {
- destroy_gdipcontext (context);
- gdip_propegate_error (error, "Couldn't load bitmap", GDK_PIXBUF_ERROR_CORRUPT_IMAGE);
- return FALSE;
- }
-
- io_gdip_bitmap_get_n_frames (bitmap, &n_frames, TRUE);
-
- for (i = 0; i < n_frames; i++)
- {
- GdkPixbuf *pixbuf = NULL;
-
- io_gdip_bitmap_select_frame (bitmap, i, TRUE);
-
- if (n_frames > 1 && i == 0)
- {
- guint delay; /* in hundredths per second */
- guint width = 0, height = 0;
- gfloat rate = 1;
-
- io_gdip_bitmap_get_frame_delay (bitmap, &delay);
- rate = 1.0f / ((gfloat)delay / 100);
-
- io_gdip_bitmap_get_size (bitmap, &width, &height);
- // anim = GDK_PIXBUF_ANIMATION(gdk_pixbuf_simple_anim_new (width, height, rate));
- }
-
- pixbuf = gdi_bitmap_to_pixbuf (bitmap);
-
- if (!pixbuf)
- {
- destroy_gdipcontext (context);
- gdip_propegate_error (error, "Couldn't create pixbuf", GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY);
- return FALSE;
- }
-
- if (anim != NULL)
- {
- gdk_pixbuf_simple_anim_add_frame (GDK_PIXBUF_SIMPLE_ANIM(anim), pixbuf);
- }
-
- if (i == 0)
- {
- emit_prepared (context, pixbuf, anim);
- }
-
- emit_updated (context, pixbuf);
- }
-
- destroy_gdipcontext (context);
-
- return TRUE;
-}
-
-gboolean
-gdip_save_to_file_callback (const gchar *buf,
- gsize count,
- GError **error,
- gpointer data)
-{
- FILE *filehandle = data;
- gsize n;
-
- n = fwrite (buf, 1, count, filehandle);
- if (n != count) {
- gint save_errno = errno;
- g_set_error (error,
- G_FILE_ERROR,
- g_file_error_from_errno (save_errno),
- "Error writing to image file: %s",
- g_strerror (save_errno));
- return FALSE;
- }
- return TRUE;
-}
-
-/*
- The MIME types of the encoders built into Microsoft Windows GDI+ are as follows:
-
- * image/bmp
- * image/jpeg
- * image/gif
- * image/tiff
- * image/png
-*/
-
-#ifdef GDIP_TEST_SAVING
-static gboolean
-gdk_pixbuf__gdip_image_save_PNG_to_callback (GdkPixbufSaveFunc save_func,
- gpointer user_data,
- GdkPixbuf *pixbuf,
- gchar **keys,
- gchar **values,
- GError **error)
-{
- /* TODO: support exif data and the like */
- EncoderParameters *encoder_params = NULL;
- gboolean status;
-
- status = io_gdip_save_pixbuf (pixbuf, L"image/png", encoder_params, save_func, user_data, error);
-
- g_free (encoder_params);
-
- return status;
-}
-
-static gboolean
-gdk_pixbuf__gdip_image_save_PNG (FILE *f,
- GdkPixbuf *pixbuf,
- gchar **keys,
- gchar **values,
- GError **error)
-{
- return gdk_pixbuf__gdip_image_save_PNG_to_callback(gdip_save_to_file_callback, f, pixbuf, keys, values, error);
-}
-#endif
-
-/* meant to be shared across various GDI+ plugins, since we'll need multiple plugins to support saving to multiple formats */
-void
-gdip_fill_vtable (GdkPixbufModule *module)
-{
- io_gdip_init ();
-
- module->begin_load = gdk_pixbuf__gdip_image_begin_load;
- module->stop_load = gdk_pixbuf__gdip_image_stop_load;
- module->load_increment = gdk_pixbuf__gdip_image_load_increment;
-}
void
-fill_vtable (GdkPixbufModule *module)
+MODULE_ENTRY(gdi, fill_vtable) (GdkPixbufModule *module)
{
gdip_fill_vtable(module);
-
-#ifdef GDIP_TEST_SAVING
- module->save_to_callback = gdk_pixbuf__gdip_image_save_PNG_to_callback;
- module->save = gdk_pixbuf__gdip_image_save_PNG; /* for gtk < 2.14, you need to implement both. otherwise gdk-pixbuf-queryloaders fails */
-#endif
}
void
-fill_info (GdkPixbufFormat *info)
+MODULE_ENTRY(gdi, fill_info) (GdkPixbufFormat *info)
{
static GdkPixbufModulePattern signature[] = {
- { "\xff\xd8", NULL, 100 }, /* JPEG */
- { "BM", NULL, 100 }, /* BMP */
- { "GIF8", NULL, 100 }, /* GIF */
{ " \x1 ", "zz znz", 100 }, /* ICO */
{ " \x2 ", "zz znz", 100 }, /* ICO */
- { "\x89PNG\r\n\x1a\x0a", NULL, 100 }, /* PNG */
- { "MM \x2a", " z ", 100 }, /* TIFF */
- { "II\x2a ", " z", 100 }, /* TIFF */
{ "\xd7\xcd\xc6\x9a", NULL, 100 }, /* WMF */
{ "\x01\x00\x09\x00", NULL, 100 }, /* WMF */
{ "\x01\x00\x00\x00", NULL, 100 }, /* EMF */
@@ -380,15 +42,8 @@
};
static gchar *mime_types[] = {
- "image/jpeg",
- "image/bmp",
- "image/x-bmp",
- "image/x-MS-bmp",
- "image/gif",
"image/x-icon",
"image/x-ico",
- "image/png",
- "image/tiff",
"image/x-wmf",
"application/emf",
"application/x-emf",
@@ -399,36 +54,18 @@
};
static gchar *extensions[] = {
- "jpeg",
- "jpe",
- "jpg",
- "bmp",
- "gif",
"ico",
"cur",
- "png",
- "tiff",
- "tif",
"wmf",
"apm",
"emf",
NULL
};
-#ifdef GDIP_TEST_SAVING
- info->name = "png";
-#else
- info->name = "Win32 GDI+";
-#endif
-
+ info->name = "gdi";
info->signature = signature;
- info->description = "Win32 GDI+ JPEG, Tiff and PNG loader.";
+ info->description = "Win32 GDI+ image loader.";
info->mime_types = mime_types;
info->extensions = extensions;
-
-#ifdef GDIP_TEST_SAVING
- info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
-#else
- info->flags = 0;
-#endif
+ info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
}
Added: trunk/src/test-save.c
==============================================================================
--- (empty file)
+++ trunk/src/test-save.c Fri Feb 22 21:40:21 2008
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+int main(int argc, char **argv)
+{
+ GdkPixbuf *pixbuf;
+ GError *error = NULL;
+
+ if (argc != 3)
+ {
+ g_print("Usage: test-save.exe in.png out.png\n");
+ exit(1);
+ }
+
+ g_type_init();
+
+ pixbuf = gdk_pixbuf_new_from_file (argv[1], &error);
+ if (!pixbuf)
+ {
+ g_print("Error loading: %s\n", error->message);
+ g_error_free(error);
+ exit(1);
+ }
+
+ if (!gdk_pixbuf_save(pixbuf, argv[2], "png", &error, NULL))
+ {
+ g_print("Error saving: %s\n", error->message);
+ g_error_free(error);
+ exit(1);
+ }
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]