gdip-pixbuf-loader r26 - in trunk: . src



Author: doml
Date: Thu Feb 21 22:31:12 2008
New Revision: 26
URL: http://svn.gnome.org/viewvc/gdip-pixbuf-loader?rev=26&view=rev

Log:
2008-02-21  Dom Lachowicz <domlachowicz gmail com>

	* src/*.[ch]: Infrastructure for saving GdkPixbufs to GdkPixbufSaveFunc callbacks.
	Should be trivial to write a PNG or JPEG saver now.

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 22:31:12 2008
@@ -142,10 +142,34 @@
 };
 typedef struct _PropItem PropertyItem;
 
+struct _EncoderParameter
+{
+    GUID    Guid;
+    ULONG   NumberOfValues;
+    ULONG   Type;
+    VOID*   Value;
+};
+typedef struct _EncoderParameter EncoderParameter;
+
+struct _EncoderParameters
+{
+    UINT Count;                      // Number of parameters in this structure
+    EncoderParameter Parameter[1];   // Parameter values
+};
+typedef struct _EncoderParameters EncoderParameters;
+
 #ifndef IStream_Release
 #define IStream_Release(This) (This)->lpVtbl->Release(This)
 #endif
 
+#ifndef IStream_Seek
+#define IStream_Seek(This,dlibMove,dwOrigin,plibNewPosition) (This)->lpVtbl->Seek(This,dlibMove,dwOrigin,plibNewPosition)
+#endif
+
+#ifndef IStream_Read
+#define IStream_Read(This,pv,cb,pcbRead) (This)->lpVtbl->Read(This,pv,cb,pcbRead)
+#endif
+
 typedef GpStatus (WINGDIPAPI* GdiplusStartupFunc) (gpointer, const gpointer, gpointer);
 typedef GpStatus (WINGDIPAPI* GdipCreateBitmapFromStreamFunc) (gpointer, GpBitmap**);
 typedef GpStatus (WINGDIPAPI* GdipBitmapGetPixelFunc) (GpBitmap*, gint x, gint y, ARGB*);
@@ -159,5 +183,9 @@
 typedef GpStatus (WINGDIPAPI* GdipGetPropertyItemFunc) (GpImage *image, int propId, guint propSize, PropertyItem* buffer);
 typedef GpStatus (WINGDIPAPI* GdipGetPropertyCountFunc) (GpImage *image, guint* numOfProperty);
 typedef GpStatus (WINGDIPAPI* GdipGetPropertyIdListFunc) (GpImage *image, guint numOfProperty, PROPID* list);
+typedef GpStatus (WINGDIPAPI* GdipCreateBitmapFromScan0Func) (INT width, INT height, INT stride, PixelFormat format, BYTE* scan0, 
+                                                              GpBitmap** bitmap);
+typedef GpStatus (WINGDIPAPI* GdipSaveImageToStreamFunc) (GpImage *image, IStream* stream, const CLSID* clsidEncoder, 
+                                                          const EncoderParameters* encoderParams);
 
 #endif

Modified: trunk/src/io-gdip-utils.c
==============================================================================
--- trunk/src/io-gdip-utils.c	(original)
+++ trunk/src/io-gdip-utils.c	Thu Feb 21 22:31:12 2008
@@ -1,11 +1,11 @@
 /* -*- 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
- * Copyright (C) 2008 Dom Lachowicz
  *
- * Authors: Alberto Ruiz <aruiz gnome org>
- *          Dom Lachowicz <domlachowicz gmail com>
+ * 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
@@ -25,6 +25,7 @@
 #include "io-gdip-native.h"
 #include "io-gdip-propertytags.h"
 #include <ole2.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
 
 static GdiplusStartupFunc GdiplusStartup;
 static GdipCreateBitmapFromStreamFunc GdipCreateBitmapFromStream;
@@ -39,6 +40,10 @@
 static GdipGetPropertyItemFunc GdipGetPropertyItem;
 static GdipGetPropertyCountFunc GdipGetPropertyCount;
 static GdipGetPropertyIdListFunc GdipGetPropertyIdList;
+static GdipCreateBitmapFromScan0Func GdipCreateBitmapFromScan0;
+static GdipSaveImageToStreamFunc GdipSaveImageToStream;
+
+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);
@@ -78,6 +83,8 @@
   LOOKUP (GdipGetPropertyItem);
   LOOKUP (GdipGetPropertyCount);
   LOOKUP (GdipGetPropertyIdList);
+  LOOKUP (GdipCreateBitmapFromScan0);
+  LOOKUP (GdipSaveImageToStream);
 
 #undef LOOKUP
   
@@ -99,6 +106,113 @@
   return hg;
 }
 
+gboolean
+io_gdip_save_bitmap_to_callback (GpBitmap *bitmap,
+                                 const CLSID *format,
+                                 const EncoderParameters *encoder_params,
+                                 GdkPixbufSaveFunc save_func,
+                                 gpointer user_data,
+                                 GError **error)
+{
+  HRESULT hr;  
+  IStream *streamOut = NULL;
+  gboolean success = FALSE;
+
+  hr = CreateStreamOnHGlobal (NULL, TRUE, &streamOut);
+  if (!SUCCEEDED(hr))
+    {
+      gdip_propegate_error (error, "Couldn't save", GDK_PIXBUF_ERROR_FAILED);
+      return FALSE;
+    }
+
+  if (0 != GdipSaveImageToStream((GpImage*)bitmap, streamOut, format, encoder_params))
+    {
+      gdip_propegate_error (error, "Couldn't save", GDK_PIXBUF_ERROR_FAILED);
+      IStream_Release(streamOut);
+      return FALSE;
+    }
+
+  while (1)
+    {
+      char buffer[1024];
+      ULONG nread;
+
+      hr = IStream_Read(streamOut, buffer, sizeof(buffer), &nread);
+      if (!SUCCEEDED(hr))
+          break;
+      else if (0 == nread)
+        {
+          success = TRUE; /* EOF */
+          break;
+        }
+      else if (!(*save_func)(buffer, nread, error, user_data))
+        break;
+    }
+  
+  IStream_Release(streamOut);
+
+  return success;
+}                     
+
+GpBitmap *
+io_gdip_pixbuf_to_bitmap (GdkPixbuf *pixbuf)
+{
+  GpBitmap *bitmap = NULL;
+
+  int width, height, stride, n_channels;
+  guint8 *pixels;
+
+  width = gdk_pixbuf_get_width(pixbuf);
+  height = gdk_pixbuf_get_height(pixbuf);
+  stride = gdk_pixbuf_get_rowstride(pixbuf);
+  n_channels = gdk_pixbuf_get_n_channels(pixbuf);
+  pixels = gdk_pixbuf_get_pixels(pixbuf);
+
+  if (n_channels == 3)
+    {
+      /* rgb24 */
+      GdipCreateBitmapFromScan0(width, height, stride, PixelFormat24bppRGB, pixels, &bitmap);
+    }
+  else if (n_channels == 4)
+    {
+      /* rgba. need to convert to argb */
+      guint8 *pixels_dup;
+
+      pixels_dup = g_memdup(pixels, height * stride);
+      if (pixels_dup)
+        {
+          int y;
+          for (y = 0; y < height; y++)
+            {
+              int x;
+
+              for (x = 0; x < width; x++)
+                {
+                  guint32 pixel;
+                  guchar *b = pixels_dup + (y * stride + (x * n_channels));
+                  
+                  memcpy (&pixel, b, sizeof (guint32));
+                  
+                  /* swap rgba -> argb */
+                  b[0] = (pixel & 0xff000000) >> 24;
+                  b[1] = (pixel & 0x00ff0000) >> 16;
+                  b[2] = (pixel & 0x0000ff00) >> 8;
+                  b[3] = (pixel & 0x000000ff) >> 0;                  
+                }
+            }
+          
+          GdipCreateBitmapFromScan0(width, height, stride, PixelFormat32bppARGB, pixels_dup, &bitmap);
+          g_free(pixels_dup);
+        }
+    }
+  else
+    {
+      g_warning ("Unsupported number of channels: %d\n", n_channels);
+    }
+
+  return bitmap;
+}
+
 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 22:31:12 2008
@@ -1,9 +1,11 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
 /* GdkPixbuf library - Win32 GDI+ Pixbuf Loader
  *
+ * Copyright (C) 2008 Dominic Lachowicz
  * Copyright (C) 2008 Alberto Ruiz
  *
- * Authors: Alberto Ruiz <aruiz gnome org>
+ * 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
@@ -54,4 +56,15 @@
 gboolean
 io_gdip_bitmap_get_property_as_string (GpBitmap *bitmap, guint propertyId, gchar **str);
 
+gboolean
+io_gdip_save_bitmap_to_callback (GpBitmap *bitmap,
+                                 const CLSID *format,
+                                 const EncoderParameters *encoder_params,
+                                 GdkPixbufSaveFunc save_func,
+                                 gpointer user_data,
+                                 GError **error);
+
+GpBitmap *
+io_gdip_pixbuf_to_bitmap (GdkPixbuf *pixbuf);
+
 #endif

Modified: trunk/src/io-gdip.c
==============================================================================
--- trunk/src/io-gdip.c	(original)
+++ trunk/src/io-gdip.c	Thu Feb 21 22:31:12 2008
@@ -1,9 +1,11 @@
 /* -*- 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: Alberto Ruiz <aruiz gnome org>
+ * 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
@@ -19,14 +21,13 @@
  * Boston, MA 02111-1307, USA.
  */
 
-
-#include "io-gdip-utils.h"
-#include "io-gdip-propertytags.h"
-
 #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;
@@ -43,7 +44,7 @@
 G_MODULE_EXPORT void fill_vtable (GdkPixbufModule *module);
 G_MODULE_EXPORT void fill_info (GdkPixbufFormat *info);
 
-static void
+void
 gdip_propegate_error (GError ** err,
                       const char * reason,
                       gint code)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]