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



Author: doml
Date: Tue Feb 19 22:54:59 2008
New Revision: 24
URL: http://svn.gnome.org/viewvc/gdip-pixbuf-loader?rev=24&view=rev

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

	* src/*.[ch]: ARGB isn't pre-multiplied; first stab @ metadata

Modified:
   trunk/ChangeLog
   trunk/src/io-gdip-native.h
   trunk/src/io-gdip-propertytags.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	Tue Feb 19 22:54:59 2008
@@ -133,15 +133,31 @@
 };
 typedef struct _GdiplusStartupInput GdiplusStartupInput;
 
-typedef GpStatus (CALLBACK* GdiplusStartupFunc) (gpointer, const gpointer, gpointer);
-
-typedef GpStatus (CALLBACK* GdipCreateBitmapFromStreamFunc) (gpointer, GpBitmap**);
+struct _PropItem
+{
+  ULONG id;
+  ULONG length;
+  WORD type;
+  VOID *value;
+};
+typedef struct _PropItem PropertyItem;
 
-typedef GpStatus (CALLBACK* GdipBitmapGetPixelFunc) (GpBitmap*, gint x, gint y, ARGB*);
+#ifndef IStream_Release
+#define IStream_Release(This) (This)->lpVtbl->Release(This)
+#endif
 
-typedef GpStatus (CALLBACK* GdipGetImageWidthFunc) (GpImage*, guint*);
-typedef GpStatus (CALLBACK* GdipGetImageHeightFunc) (GpImage*, guint*);
-typedef GpStatus (CALLBACK* GdipDisposeImageFunc) (GpImage*);
-typedef GpStatus (CALLBACK* GdipGetImageFlagsFunc) (GpImage *, guint*);
+typedef GpStatus (WINGDIPAPI* GdiplusStartupFunc) (gpointer, const gpointer, gpointer);
+typedef GpStatus (WINGDIPAPI* GdipCreateBitmapFromStreamFunc) (gpointer, GpBitmap**);
+typedef GpStatus (WINGDIPAPI* GdipBitmapGetPixelFunc) (GpBitmap*, gint x, gint y, ARGB*);
+typedef GpStatus (WINGDIPAPI* GdipGetImageWidthFunc) (GpImage*, guint*);
+typedef GpStatus (WINGDIPAPI* GdipGetImageHeightFunc) (GpImage*, guint*);
+typedef GpStatus (WINGDIPAPI* GdipDisposeImageFunc) (GpImage*);
+typedef GpStatus (WINGDIPAPI* GdipGetImageFlagsFunc) (GpImage *, guint*);
+typedef GpStatus (WINGDIPAPI* GdipImageGetFrameCountFunc) (GpImage *image, const GUID* dimensionID, UINT* count);
+typedef GpStatus (WINGDIPAPI* GdipImageSelectActiveFrameFunc) (GpImage *image, const GUID* dimensionID, UINT frameIndex);
+typedef GpStatus (WINGDIPAPI* GdipGetPropertyItemSizeFunc) (GpImage *image, int propId, guint* size);
+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);
 
 #endif

Modified: trunk/src/io-gdip-propertytags.h
==============================================================================
--- trunk/src/io-gdip-propertytags.h	(original)
+++ trunk/src/io-gdip-propertytags.h	Tue Feb 19 22:54:59 2008
@@ -9,6 +9,7 @@
 #define PropertyTagTypeUndefined   7
 #define PropertyTagTypeSLONG       9
 #define PropertyTagTypeSRational  10
+
 #define PropertyTagExifIFD             0x8769
 #define PropertyTagGpsIFD              0x8825
 #define PropertyTagNewSubfileType      0x00FE

Modified: trunk/src/io-gdip-utils.c
==============================================================================
--- trunk/src/io-gdip-utils.c	(original)
+++ trunk/src/io-gdip-utils.c	Tue Feb 19 22:54:59 2008
@@ -131,23 +131,8 @@
 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);
 
-struct _PropItem
-{
-  ULONG id;
-  ULONG length;
-  WORD type;
-  VOID *value;
-};
-typedef struct _PropItem PropertyItem;
-
-#define GDIPCONST const
-typedef GpStatus (WINGDIPAPI* GdipImageGetFrameCountFunc) (GpImage *image, GDIPCONST GUID* dimensionID, UINT* count);
-typedef GpStatus (WINGDIPAPI* GdipImageSelectActiveFrameFunc) (GpImage *image, GDIPCONST GUID* dimensionID, UINT frameIndex);
-typedef GpStatus (WINGDIPAPI* GdipGetPropertyItemSizeFunc) (GpImage *image, int propId, guint* size);
-typedef GpStatus (WINGDIPAPI* GdipGetPropertyItemFunc) (GpImage *image, int propId, guint propSize, PropertyItem* buffer);
-
 GpStatus WINGDIPAPI
-GdipImageGetFrameCount (GpImage* image, GDIPCONST GUID* dimensionID, guint* count)
+GdipImageGetFrameCount (GpImage* image, const GUID* dimensionID, guint* count)
 {
   static GdipImageGetFrameCountFunc proc = NULL;
 
@@ -161,7 +146,7 @@
 }
 
 GpStatus WINGDIPAPI
-GdipImageSelectActiveFrame (GpImage* image, GDIPCONST GUID* dimensionID, guint frameIndex)
+GdipImageSelectActiveFrame (GpImage* image, const GUID* dimensionID, guint frameIndex)
 {
   static GdipImageSelectActiveFrameFunc proc = NULL;
 
@@ -202,6 +187,34 @@
   return (*proc) (image, propId, propSize, buffer);
 }
 
+GpStatus WINGDIPAPI
+GdipGetPropertyCount (GpImage *image, guint* numOfProperty)
+{
+  static GdipGetPropertyCountFunc proc = NULL;
+
+  if (gdipluslib && !proc)
+    proc = (GdipGetPropertyCountFunc) GetProcAddress(gdipluslib, "GdipGetPropertyCount");
+
+  if (!proc)
+    return GenericError;
+
+  return (*proc) (image, numOfProperty);
+}
+
+GpStatus WINGDIPAPI
+GdipGetPropertyIdList (GpImage *image, guint numOfProperty, PROPID* list)
+{
+  static GdipGetPropertyIdListFunc proc = NULL;
+
+  if (gdipluslib && !proc)
+    proc = (GdipGetPropertyIdListFunc) GetProcAddress(gdipluslib, "GdipGetPropertyIdList");
+
+  if (!proc)
+    return GenericError;
+
+  return (*proc) (image, numOfProperty, list);
+}
+
 /*
  * END OF WRAPPER FUCNTIONS
  */
@@ -240,10 +253,6 @@
   return hg;
 }
 
-#ifndef IStream_Release
-#define IStream_Release(This) (This)->lpVtbl->Release(This)
-#endif
-
 GpBitmap *
 io_gdip_buffer_to_bitmap (const gchar * buffer, size_t size)
 {
@@ -393,3 +402,94 @@
 
   return success;
 }
+
+gboolean
+io_gdip_bitmap_get_property_as_string (GpBitmap *bitmap, guint propertyId, gchar **str)
+{
+  guint item_size;
+  gboolean success = FALSE;
+
+  if (bitmap == NULL || str == NULL)
+    return FALSE;
+
+  *str = 0;
+
+  if (0 == GdipGetPropertyItemSize ((GpImage*)bitmap, propertyId, &item_size))
+    {
+      PropertyItem *item;
+      
+      item = (PropertyItem *)g_try_malloc(item_size);
+      if (0 == GdipGetPropertyItem ((GpImage*)bitmap, propertyId, item_size, item))
+        {
+          GString *gstr;
+          int i;
+
+          gstr = g_string_new(NULL);
+
+          success = TRUE;
+          switch (item->type)
+            {
+            case PropertyTagTypeByte:
+              for (i = 0; i < item->length / sizeof(guint8); i++)
+                {
+                  guint8 *bytes = (guint8*)item->value;
+
+                  if (gstr->len != 0)
+                    g_string_append_c(gstr, ',');
+                  g_string_append_printf(gstr, "%u", (guint32)bytes[i]);
+                }
+              break;
+
+            case PropertyTagTypeASCII:
+              g_string_append_len(gstr, (const char *)item->value, item->length);
+              break;
+
+            case PropertyTagTypeShort:
+              for (i = 0; i < item->length / sizeof(guint16); i++)
+                {
+                  guint16 *shorts = (guint16*)item->value;
+
+                  if (gstr->len != 0)
+                    g_string_append_c(gstr, ',');
+                  g_string_append_printf(gstr, "%u", (guint32)shorts[i]);
+                }
+              break;
+
+            case PropertyTagTypeLong:
+              for (i = 0; i < item->length / sizeof(guint32); i++)
+                {
+                  guint32 *longs = (guint32*)item->value;
+
+                  if (gstr->len != 0)
+                    g_string_append_c(gstr, ',');
+                  g_string_append_printf(gstr, "%u", longs[i]);
+                }
+              break;
+
+            case PropertyTagTypeSLONG:
+              for (i = 0; i < item->length / sizeof(guint32); i++)
+                {
+                  gint32 *longs = (gint32*)item->value;
+
+                  if (gstr->len != 0)
+                    g_string_append_c(gstr, ',');
+                  g_string_append_printf(gstr, "%d", longs[i]);
+                }
+              break;
+
+            default:
+              success = FALSE;
+              break;
+            }
+
+          if (gstr->len > 0)
+            *str = g_string_free(gstr, FALSE);
+          else
+            g_string_free(gstr, TRUE);
+        }
+
+      g_free(item);
+    }
+
+  return success;
+}

Modified: trunk/src/io-gdip-utils.h
==============================================================================
--- trunk/src/io-gdip-utils.h	(original)
+++ trunk/src/io-gdip-utils.h	Tue Feb 19 22:54:59 2008
@@ -51,4 +51,7 @@
 gboolean
 io_gdip_bitmap_get_n_loops (GpBitmap *bitmap, guint *loops);
 
+gboolean
+io_gdip_bitmap_get_property_as_string (GpBitmap *bitmap, guint propertyId, gchar **str);
+
 #endif

Modified: trunk/src/io-gdip.c
==============================================================================
--- trunk/src/io-gdip.c	(original)
+++ trunk/src/io-gdip.c	Tue Feb 19 22:54:59 2008
@@ -21,6 +21,7 @@
 
 
 #include "io-gdip-utils.h"
+#include "io-gdip-propertytags.h"
 
 #define GDK_PIXBUF_ENABLE_BACKEND
 #include <gdk-pixbuf/gdk-pixbuf-io.h>
@@ -136,6 +137,7 @@
   gint rowstride;
   gboolean has_alpha = FALSE;
   gint n_channels = 0;
+  gchar *option;
 
   guint width = 0, height = 0, x, y;
 
@@ -158,31 +160,42 @@
       for (x = 0; x < width; x++)
         {
           ARGB pixel;
-          guint8 alpha;
           guchar *b = cursor + (y * rowstride + (x * n_channels));
 
           pixel = io_gdip_bitmap_get_pixel (bitmap, x, y);
 
-          /* un-premultiply alpha */
-          alpha = (pixel & 0xff000000) >> 24;
-          if (alpha == 0)
-            {
-              b[0] = b[1] = b[2];
-            }
-          else
-            {
-              b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
-              b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
-              b[2] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
-            }
+          b[0] = (pixel & 0xff0000) >> 16;
+          b[1] = (pixel & 0x00ff00) >> 8;
+          b[2] = (pixel & 0x0000ff) >> 0;
 
           if (has_alpha)
             {
-              b[3] = 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;
 }
 



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