gdip-pixbuf-loader r27 - in trunk: . src
- From: doml svn gnome org
- To: svn-commits-list gnome org
- Subject: gdip-pixbuf-loader r27 - in trunk: . src
- Date: Thu, 21 Feb 2008 23:45:44 +0000 (GMT)
Author: doml
Date: Thu Feb 21 23:45:44 2008
New Revision: 27
URL: http://svn.gnome.org/viewvc/gdip-pixbuf-loader?rev=27&view=rev
Log:
2008-02-21 Dom Lachowicz <domlachowicz gmail com>
* src/*.[ch]: If you #define GDIP_TEST_SAVING, you should be able to save
a pixbuf to a PNG via GDI+. WARNING: UNTESTED CODE
Modified:
trunk/ChangeLog
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/io-gdip-native.h
==============================================================================
--- trunk/src/io-gdip-native.h (original)
+++ trunk/src/io-gdip-native.h Thu Feb 21 23:45:44 2008
@@ -158,6 +158,24 @@
};
typedef struct _EncoderParameters EncoderParameters;
+struct _ImageCodecInfo
+{
+ CLSID Clsid;
+ GUID FormatID;
+ const WCHAR* CodecName;
+ const WCHAR* DllName;
+ const WCHAR* FormatDescription;
+ const WCHAR* FilenameExtension;
+ const WCHAR* MimeType;
+ DWORD Flags;
+ DWORD Version;
+ DWORD SigCount;
+ DWORD SigSize;
+ const BYTE* SigPattern;
+ const BYTE* SigMask;
+};
+typedef struct _ImageCodecInfo ImageCodecInfo;
+
#ifndef IStream_Release
#define IStream_Release(This) (This)->lpVtbl->Release(This)
#endif
@@ -188,4 +206,7 @@
typedef GpStatus (WINGDIPAPI* GdipSaveImageToStreamFunc) (GpImage *image, IStream* stream, const CLSID* clsidEncoder,
const EncoderParameters* encoderParams);
+typedef GpStatus (WINGDIAPI *GetImageEncodersFunc) (UINT numEncoders, UINT size, ImageCodecInfo *encoders);
+typedef GpStatus (WINGDIAPI *GetImageEncodersSizeFunc) (UINT *numEncoders, UINT *size);
+
#endif
Modified: trunk/src/io-gdip-utils.c
==============================================================================
--- trunk/src/io-gdip-utils.c (original)
+++ trunk/src/io-gdip-utils.c Thu Feb 21 23:45:44 2008
@@ -21,11 +21,13 @@
* Boston, MA 02111-1307, USA.
*/
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
#define INITGUID
#include "io-gdip-native.h"
+#include "io-gdip-utils.h"
#include "io-gdip-propertytags.h"
#include <ole2.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
static GdiplusStartupFunc GdiplusStartup;
static GdipCreateBitmapFromStreamFunc GdipCreateBitmapFromStream;
@@ -43,6 +45,10 @@
static GdipCreateBitmapFromScan0Func GdipCreateBitmapFromScan0;
static GdipSaveImageToStreamFunc GdipSaveImageToStream;
+/* apparently these don't exist until GDI+ 1.1 or later */
+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);
@@ -66,9 +72,18 @@
return FALSE;
#define LOOKUP(func) \
- func = (func##Func) GetProcAddress(gdipluslib, #func); \
- if (!func) \
- return FALSE
+ do { \
+ func = (func##Func) GetProcAddress(gdipluslib, #func); \
+ if (!func) {\
+ g_warning("Couldn't load function: %s\n", #func); \
+ return FALSE; \
+ } \
+ } while (0)
+
+#define TRY_LOOKUP(func) \
+ do { \
+ func = (func##Func) GetProcAddress(gdipluslib, #func); \
+ } while (0)
LOOKUP (GdiplusStartup);
LOOKUP (GdipCreateBitmapFromStream);
@@ -85,12 +100,70 @@
LOOKUP (GdipGetPropertyIdList);
LOOKUP (GdipCreateBitmapFromScan0);
LOOKUP (GdipSaveImageToStream);
+ TRY_LOOKUP (GetImageEncoders);
+ TRY_LOOKUP (GetImageEncodersSize);
#undef LOOKUP
return (GdiplusStartup (&gdiplusToken, &input, NULL) == 0 ? TRUE : FALSE);
}
+static int
+GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
+{
+ if (GetImageEncodersSize && GetImageEncoders)
+ {
+ UINT num = 0;
+ UINT size = 0;
+ UINT j;
+
+ ImageCodecInfo* pImageCodecInfo = NULL;
+
+ GetImageEncodersSize(&num, &size);
+ if(size == 0)
+ return -1;
+
+ pImageCodecInfo = (ImageCodecInfo*)(g_try_malloc(size));
+ if(pImageCodecInfo == NULL)
+ return -1;
+
+ GetImageEncoders(num, size, pImageCodecInfo);
+
+ for (j = 0; j < num; ++j)
+ {
+ if(wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
+ {
+ *pClsid = pImageCodecInfo[j].Clsid;
+ g_free(pImageCodecInfo);
+ return j;
+ }
+ }
+
+ g_free(pImageCodecInfo);
+ return -1;
+ }
+ else
+ {
+ static CLSID gdip_png_guid = { 0x557cf406, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } };
+
+ if (wcscmp(format, L"image/png") == 0)
+ {
+ *pClsid = gdip_png_guid;
+ return 0;
+ }
+
+ /*
+ todo:
+ image/bmp
+ image/jpeg
+ image/gif
+ image/tiff
+ */
+
+ return -1;
+ }
+}
+
static HGLOBAL
io_gdip_buffer_to_hglobal (const gchar * buffer, size_t size)
{
@@ -213,6 +286,39 @@
return bitmap;
}
+gboolean
+io_gdip_save_pixbuf (GdkPixbuf *pixbuf,
+ const WCHAR *format,
+ const EncoderParameters *encoder_params,
+ GdkPixbufSaveFunc save_func,
+ gpointer user_data,
+ GError **error)
+{
+ GpBitmap *image;
+ CLSID clsid;
+ gboolean success;
+
+ if (-1 != GetEncoderClsid(format, &clsid))
+ {
+ gdip_propegate_error (error, "Unsupported format", GDK_PIXBUF_ERROR_FAILED);
+ return FALSE;
+ }
+
+ image = io_gdip_pixbuf_to_bitmap(pixbuf);
+
+ if (image == NULL)
+ {
+ gdip_propegate_error (error, "Couldn't save", GDK_PIXBUF_ERROR_FAILED);
+ return FALSE;
+ }
+
+ success = io_gdip_save_bitmap_to_callback(image, &clsid, encoder_params, save_func, user_data, error);
+
+ io_gdip_dispose_bitmap(image);
+
+ return success;
+}
+
GpBitmap *
io_gdip_buffer_to_bitmap (const gchar * buffer, size_t size)
{
Modified: trunk/src/io-gdip-utils.h
==============================================================================
--- trunk/src/io-gdip-utils.h (original)
+++ trunk/src/io-gdip-utils.h Thu Feb 21 23:45:44 2008
@@ -67,4 +67,12 @@
GpBitmap *
io_gdip_pixbuf_to_bitmap (GdkPixbuf *pixbuf);
+gboolean
+io_gdip_save_pixbuf (GdkPixbuf *pixbuf,
+ const WCHAR *format,
+ const EncoderParameters *encoder_params,
+ GdkPixbufSaveFunc save_func,
+ gpointer user_data,
+ GError **error);
+
#endif
Modified: trunk/src/io-gdip.c
==============================================================================
--- trunk/src/io-gdip.c (original)
+++ trunk/src/io-gdip.c Thu Feb 21 23:45:44 2008
@@ -276,6 +276,37 @@
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;
+}
+#endif
+
void
fill_vtable (GdkPixbufModule *module)
{
@@ -284,6 +315,10 @@
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;
+
+#ifdef GDIP_TEST_SAVING
+ module->save_to_callback = gdk_pixbuf__gdip_image_save_PNG_to_callback;
+#endif
}
void
@@ -346,4 +381,8 @@
info->mime_types = mime_types;
info->extensions = extensions;
info->flags = 0;
+
+#ifdef GDIP_TEST_SAVING
+ info->flags |= GDK_PIXBUF_FORMAT_WRITABLE;
+#endif
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]