]> Pileus Git - ~andy/gtk/commitdiff
Add stream i/o functions for gdk-pixbuf
authorMatthias Clasen <matthiasc@src.gnome.org>
Wed, 16 Jan 2008 02:24:47 +0000 (02:24 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Wed, 16 Jan 2008 02:24:47 +0000 (02:24 +0000)
svn path=/trunk/; revision=19373

docs/reference/ChangeLog
docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt
docs/reference/gdk-pixbuf/gdk-pixbuf.sgml
docs/reference/gtk/gtk-docs.sgml
gdk-pixbuf/ChangeLog
gdk-pixbuf/gdk-pixbuf-core.h
gdk-pixbuf/gdk-pixbuf-io.c
gdk-pixbuf/gdk-pixbuf.symbols

index 79e8fed59820bf196ee3fb6b87584564f09fdf0f..f84a3e6d812381858b883fecbadf12774c0a0beb 100644 (file)
@@ -1,3 +1,10 @@
+2008-01-14  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtk-docs.sgml:
+       * gdk-pixbuf/gdk-pixbuf.sgml: Add indices for 2.16 
+
+       * gdk-pixbuf/gdk-pixbuf-sections.txt: Add stream i/o functions.
+
 2008-01-10  Sven Neumann  <sven@gimp.org>
 
        * gtk/tmpl/gtkeditable.sgml: corrected documentation for
@@ -8,6 +15,20 @@
        * gtk/tmpl/gtkcalendar.sgml: Move documentation for
        GtkCalendarDisplayOptions to gtk/gtkcalendar.c.
 
+2007-12-27  Mathias Hasselmann  <mathias@openismus.com>
+
+       * gtk/tmpl/gtkcalendar.sgml: Move documentation for
+       GtkCalendarDisplayOptions to gtk/gtkcalendar.c.
+
+2007-12-27  Mathias Hasselmann  <mathias@openismus.com>
+
+       * docs/reference/gtk/gtk-sections.txt: Add new GtkCalendar symbols.
+
+2007-12-27  Mathias Hasselmann  <mathias@openismus.com>
+
+       * gtk/tmpl/gtkcalendar.sgml: Move documentation for
+       GtkCalendarDisplayOptions to gtk/gtkcalendar.c.
+
 2007-12-27  Mathias Hasselmann  <mathias@openismus.com>
 
        * reference/gtk/gtk-sections.txt: Add new GtkCalendar symbols.
index f441f65d09740547f07868ff8850508e03a6e26a..be208fdeb36dd10bacbfa40091d66921695d7e69 100644 (file)
@@ -65,6 +65,8 @@ gdk_pixbuf_new_from_file
 gdk_pixbuf_new_from_file_at_size
 gdk_pixbuf_new_from_file_at_scale
 gdk_pixbuf_get_file_info
+gdk_pixbuf_new_from_stream
+gdk_pixbuf_new_from_stream_at_scale
 </SECTION>
 
 <SECTION>
@@ -76,6 +78,7 @@ gdk_pixbuf_save_to_callback
 gdk_pixbuf_save_to_callbackv
 gdk_pixbuf_save_to_buffer
 gdk_pixbuf_save_to_bufferv
+gdk_pixbuf_save_to_stream
 </SECTION>
 
 <SECTION>
index 55bfbdec7819e32358afcdd35eb6845e739c0c18..c962fd305d4869e8e27a87131d0e079cb34695e9 100644 (file)
   <index role="2.8">
     <title>Index of new symbols in 2.8</title>
   </index>  
+  <index role="2.16">
+    <title>Index of new symbols in 2.16</title>
+  </index>  
 
   &Porting-From-Imlib;
 
index 3eb8843c6fb6c976a4e4225e4f5494d10c013961..9aa3874bde77dc5aabebf0f828d76f396e89b77f 100644 (file)
@@ -686,4 +686,7 @@ that is, GUI components such as #GtkButton or #GtkTextView.
   <index role="2.12">
     <title>Index of new symbols in 2.12</title>
   </index>  
+  <index role="2.16">
+    <title>Index of new symbols in 2.16</title>
+  </index>  
 </book>
index 560eeff38c1c5c2fa8d6dc174fbe4b0dc041e579..620a8bf8452bbc38eea441ab6901c0369f33deb2 100644 (file)
@@ -1,3 +1,11 @@
+2008-01-15  Matthias Clasen  <mclasne@redhat.com>
+
+       * gdk-pixbuf.symbols:
+       * gdk-pixbuf-core.h:
+       * gdk-pixbuf-io.c (gdk_pixbuf_new_from_stream):
+       (gdk_pixbuf_new_from_stream_at_scale):
+       (gdk_pixbuf_save_to_stream): New stream i/o functions.
+
 2008-01-14  Michael Natterer  <mitch@imendio.com>
 
        * gdk-pixbuf-loader.c (gdk_pixbuf_loader_prepare): cast the return
index 4ae589526bc74d66538c09320672c1471ba4f87a..04f89b0008a17c964e47c82ce927fa6c7af1b705 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <glib.h>
 #include <glib-object.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
@@ -214,6 +215,24 @@ gboolean gdk_pixbuf_save_to_bufferv     (GdkPixbuf  *pixbuf,
                                         char      **option_values,
                                         GError    **error);
 
+GdkPixbuf *gdk_pixbuf_new_from_stream   (GInputStream   *stream,
+                                        GCancellable   *cancellable,
+                                         GError        **error);
+
+GdkPixbuf *gdk_pixbuf_new_from_stream_at_scale   (GInputStream   *stream,
+                                                  gint            width,
+                                                  gint            height,
+                                                  gboolean        preserve_aspect_ratio,
+                                                 GCancellable   *cancellable,
+                                                  GError        **error);
+
+gboolean   gdk_pixbuf_save_to_stream    (GdkPixbuf      *pixbuf,
+                                         GOutputStream  *stream,
+                                         const char     *type,
+                                        GCancellable   *cancellable,
+                                         GError        **error,
+                                         ...);
+
 /* Adding an alpha channel */
 GdkPixbuf *gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf, gboolean substitute_color,
                                 guchar r, guchar g, guchar b);
index 1dbbd26cf9101290543c029f8ab5a6d6341c8be4..61b7991db75182268b4bb0871c7efd8ec531bf74 100644 (file)
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <glib.h>
 #include <errno.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 
+#include <glib.h>
+#include <gio/gio.h>
+
 #include "gdk-pixbuf-private.h"
 #include "gdk-pixbuf-io.h"
+#include "gdk-pixbuf-loader.h"
 #include "gdk-pixbuf-alias.h"
 
 #include <glib/gstdio.h>
@@ -45,6 +48,9 @@
 #undef STRICT
 #endif
 
+#define SNIFF_BUFFER_SIZE 4096
+#define LOAD_BUFFER_SIZE 65536
+
 static gint 
 format_check (GdkPixbufModule *module, guchar *buffer, int size)
 {
@@ -755,7 +761,7 @@ _gdk_pixbuf_generic_image_load (GdkPixbufModule *module,
                                FILE *f,
                                GError **error)
 {
-       guchar buffer[4096];
+       guchar buffer[LOAD_BUFFER_SIZE];
        size_t length;
        GdkPixbuf *pixbuf = NULL;
        GdkPixbufAnimation *animation = NULL;
@@ -829,7 +835,7 @@ gdk_pixbuf_new_from_file (const char *filename,
        GdkPixbuf *pixbuf;
        int size;
        FILE *f;
-       guchar buffer[1024];
+       guchar buffer[SNIFF_BUFFER_SIZE];
        GdkPixbufModule *image_module;
        gchar *display_name;
 
@@ -934,49 +940,6 @@ gdk_pixbuf_new_from_file (const char *filename,
 }
 #endif
 
-static void
-size_prepared_cb (GdkPixbufLoader *loader, 
-                 int              width,
-                 int              height,
-                 gpointer         data)
-{
-       struct {
-               gint width;
-               gint height;
-               gboolean preserve_aspect_ratio;
-       } *info = data;
-
-       g_return_if_fail (width > 0 && height > 0);
-
-       if (info->preserve_aspect_ratio && 
-           (info->width > 0 || info->height > 0)) {
-               if (info->width < 0)
-               {
-                       width = width * (double)info->height/(double)height;
-                       height = info->height;
-               }
-               else if (info->height < 0)
-               {
-                       height = height * (double)info->width/(double)width;
-                       width = info->width;
-               }
-               else if ((double)height * (double)info->width >
-                        (double)width * (double)info->height) {
-                       width = 0.5 + (double)width * (double)info->height / (double)height;
-                       height = info->height;
-               } else {
-                       height = 0.5 + (double)height * (double)info->width / (double)width;
-                       width = info->width;
-               }
-       } else {
-               if (info->width > 0)
-                       width = info->width;
-               if (info->height > 0)
-                       height = info->height;
-       }
-       
-       gdk_pixbuf_loader_set_size (loader, width, height);
-}
 
 /**
  * gdk_pixbuf_new_from_file_at_size:
@@ -1037,6 +1000,52 @@ gdk_pixbuf_new_from_file_at_size (const char *filename,
 }
 #endif
 
+typedef        struct {
+       gint width;
+       gint height;
+       gboolean preserve_aspect_ratio;
+} AtScaleData; 
+
+static void
+at_scale_size_prepared_cb (GdkPixbufLoader *loader, 
+                          int              width,
+                          int              height,
+                          gpointer         data)
+{
+       AtScaleData *info = data;
+
+       g_return_if_fail (width > 0 && height > 0);
+
+       if (info->preserve_aspect_ratio && 
+           (info->width > 0 || info->height > 0)) {
+               if (info->width < 0)
+               {
+                       width = width * (double)info->height/(double)height;
+                       height = info->height;
+               }
+               else if (info->height < 0)
+               {
+                       height = height * (double)info->width/(double)width;
+                       width = info->width;
+               }
+               else if ((double)height * (double)info->width >
+                        (double)width * (double)info->height) {
+                       width = 0.5 + (double)width * (double)info->height / (double)height;
+                       height = info->height;
+               } else {
+                       height = 0.5 + (double)height * (double)info->width / (double)width;
+                       width = info->width;
+               }
+       } else {
+               if (info->width > 0)
+                       width = info->width;
+               if (info->height > 0)
+                       height = info->height;
+       }
+       
+       gdk_pixbuf_loader_set_size (loader, width, height);
+}
+
 /**
  * gdk_pixbuf_new_from_file_at_scale:
  * @filename: Name of file to load, in the GLib file name encoding
@@ -1075,15 +1084,10 @@ gdk_pixbuf_new_from_file_at_scale (const char *filename,
 
        GdkPixbufLoader *loader;
        GdkPixbuf       *pixbuf;
-
-       guchar buffer [4096];
+       guchar buffer[LOAD_BUFFER_SIZE];
        int length;
        FILE *f;
-       struct {
-               gint width;
-               gint height;
-               gboolean preserve_aspect_ratio;
-       } info;
+       AtScaleData info;
        GdkPixbufAnimation *animation;
        GdkPixbufAnimationIter *iter;
        gboolean has_frame;
@@ -1112,7 +1116,8 @@ gdk_pixbuf_new_from_file_at_scale (const char *filename,
        info.height = height;
         info.preserve_aspect_ratio = preserve_aspect_ratio;
 
-       g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), &info);
+       g_signal_connect (loader, "size-prepared", 
+                         G_CALLBACK (at_scale_size_prepared_cb), &info);
 
        has_frame = FALSE;
        while (!has_frame && !feof (f) && !ferror (f)) {
@@ -1193,6 +1198,157 @@ gdk_pixbuf_new_from_file_at_scale (const char *filename,
 #endif
 
 
+static GdkPixbuf *
+load_from_stream (GdkPixbufLoader  *loader,
+                 GInputStream     *stream,
+                 GCancellable     *cancellable,
+                 GError          **error)
+{
+       GdkPixbuf *pixbuf;
+       gssize n_read;
+       guchar buffer[LOAD_BUFFER_SIZE];
+       gboolean res;
+
+       res = TRUE;
+       while (1) { 
+               n_read = g_input_stream_read (stream, 
+                                             buffer, 
+                                             sizeof (buffer), 
+                                             cancellable, 
+                                             error);
+               if (n_read < 0) {
+                       res = FALSE;
+                       error = NULL; /* Ignore further errors */
+                       break;
+               }
+
+               if (n_read == 0)
+                       break;
+
+               if (!gdk_pixbuf_loader_write (loader, 
+                                             buffer, 
+                                             n_read, 
+                                             error)) {
+                       res = FALSE;
+                       error = NULL;
+                       break;
+               }
+       }
+
+       if (!gdk_pixbuf_loader_close (loader, error)) {
+               res = FALSE;
+               error = NULL;
+       }
+
+       pixbuf = NULL;
+       if (res) {
+               pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+               if (pixbuf)
+                       g_object_ref (pixbuf);
+       }
+
+       return pixbuf;
+}
+
+
+/**
+ * gdk_pixbuf_new_from_stream_at_scale:
+ * @stream:  a #GInputStream to load the pixbuf from
+ * @width: The width the image should have or -1 to not constrain the width
+ * @height: The height the image should have or -1 to not constrain the height
+ * @preserve_aspect_ratio: %TRUE to preserve the image's aspect ratio
+ * @cancellable: optional #GCancellable object, %NULL to ignore
+ * @error: Return location for an error
+ *
+ * Creates a new pixbuf by loading an image from an input stream.  
+ *
+ * The file format is detected automatically. If %NULL is returned, then 
+ * @error will be set. The @cancellable can be used to abort the operation
+ * from another thread. If the operation was cancelled, the error 
+ * %GIO_ERROR_CANCELLED will be returned. Other possible errors are in 
+ * the #GDK_PIXBUF_ERROR and %G_IO_ERROR domains. 
+ *
+ * The image will be scaled to fit in the requested size, optionally 
+ * preserving the image's aspect ratio. When preserving the aspect ratio, 
+ * a @width of -1 will cause the image to be scaled to the exact given 
+ * height, and a @height of -1 will cause the image to be scaled to the 
+ * exact given width. When not preserving aspect ratio, a @width or 
+ * @height of -1 means to not scale the image at all in that dimension.
+ *
+ * The stream is not closed.
+ *
+ * Return value: A newly-created pixbuf, or %NULL if any of several error 
+ * conditions occurred: the file could not be opened, the image format is 
+ * not supported, there was not enough memory to allocate the image buffer, 
+ * the stream contained invalid data, or the operation was cancelled.
+ *
+ * Since: 2.16
+ */
+GdkPixbuf *
+gdk_pixbuf_new_from_stream_at_scale (GInputStream  *stream,
+                                    gint           width,
+                                    gint           height,
+                                    gboolean       preserve_aspect_ratio,
+                                    GCancellable  *cancellable,
+                                    GError       **error)
+{
+       GdkPixbufLoader *loader;
+       GdkPixbuf *pixbuf;
+       AtScaleData info;
+
+       loader = gdk_pixbuf_loader_new ();
+
+       info.width = width;
+       info.height = height;
+        info.preserve_aspect_ratio = preserve_aspect_ratio;
+
+       g_signal_connect (loader, "size-prepared", 
+                         G_CALLBACK (at_scale_size_prepared_cb), &info);
+
+       pixbuf = load_from_stream (loader, stream, cancellable, error);
+       g_object_unref (loader);
+
+       return pixbuf;
+}
+
+/**
+ * gdk_pixbuf_new_from_stream:
+ * @stream:  a #GInputStream to load the pixbuf from
+ * @cancellable: optional #GCancellable object, %NULL to ignore
+ * @error: Return location for an error
+ *
+ * Creates a new pixbuf by loading an image from an input stream.  
+ *
+ * The file format is detected automatically. If %NULL is returned, then 
+ * @error will be set. The @cancellable can be used to abort the operation
+ * from another thread. If the operation was cancelled, the error 
+ * %GIO_ERROR_CANCELLED will be returned. Other possible errors are in 
+ * the #GDK_PIXBUF_ERROR and %G_IO_ERROR domains. 
+ *
+ * The stream is not closed.
+ *
+ * Return value: A newly-created pixbuf, or %NULL if any of several error 
+ * conditions occurred: the file could not be opened, the image format is 
+ * not supported, there was not enough memory to allocate the image buffer, 
+ * the stream contained invalid data, or the operation was cancelled.
+ *
+ * Since: 2.16
+ **/
+GdkPixbuf *
+gdk_pixbuf_new_from_stream (GInputStream  *stream,
+                           GCancellable  *cancellable,
+                           GError       **error)
+{
+       GdkPixbuf *pixbuf;
+       GdkPixbufLoader *loader;
+
+       loader = gdk_pixbuf_loader_new ();
+       pixbuf = load_from_stream (loader, stream, cancellable, error);
+       g_object_unref (loader);
+
+       return pixbuf;
+}
+
 static void
 info_cb (GdkPixbufLoader *loader, 
         int              width,
@@ -1234,7 +1390,7 @@ gdk_pixbuf_get_file_info (const gchar  *filename,
                          gint         *height)
 {
        GdkPixbufLoader *loader;
-       guchar buffer [4096];
+       guchar buffer[SNIFF_BUFFER_SIZE];
        int length;
        FILE *f;
        struct {
@@ -1579,18 +1735,18 @@ gdk_pixbuf_real_save_to_callback (GdkPixbuf         *pixbuf,
  * installed. The list of all writable formats can be determined in the 
  * following way:
  *
- * <informalexample><programlisting>
+ * |[
  * void add_if_writable (GdkPixbufFormat *data, GSList **list)
  * {
  *   if (gdk_pixbuf_format_is_writable (data))
  *     *list = g_slist_prepend (*list, data);
  * }
- * <!-- -->
- * GSList *formats = gdk_pixbuf_get_formats (<!-- -->);
+ * 
+ * GSList *formats = gdk_pixbuf_get_formats ();
  * GSList *writable_formats = NULL;
- * g_slist_foreach (formats, add_if_writable, &amp;writable_formats);
+ * g_slist_foreach (formats, add_if_writable, &writable_formats);
  * g_slist_free (formats);
- * </programlisting></informalexample>
+ * ]|
  *
  * If @error is set, %FALSE will be returned. Possible errors include 
  * those in the #GDK_PIXBUF_ERROR domain and those in the #G_FILE_ERROR domain.
@@ -1999,7 +2155,8 @@ save_to_buffer_callback (const gchar *data,
  * @error: return location for error, or %NULL
  *
  * Saves pixbuf to a new buffer in format @type, which is currently "jpeg",
- * "tiff", "png", "ico" or "bmp".  See gdk_pixbuf_save_to_buffer() for more details.
+ * "tiff", "png", "ico" or "bmp".  See gdk_pixbuf_save_to_buffer() 
+ * for more details.
  *
  * Return value: whether an error was set
  *
@@ -2044,6 +2201,87 @@ gdk_pixbuf_save_to_bufferv     (GdkPixbuf  *pixbuf,
        return TRUE;
 }
 
+typedef struct {
+       GOutputStream *stream;
+       GCancellable  *cancellable;
+} SaveToStreamData;
+
+static gboolean
+save_to_stream (const gchar  *buffer,
+               gsize         count,
+               GCancellable *cancellable,
+               GError      **error,
+               gpointer      data)
+{
+       SaveToStreamData *sdata = (SaveToStreamData *)data;
+
+       g_output_stream_write (sdata->stream, 
+                              buffer, count, 
+                              sdata->cancellable, 
+                              error);
+}
+
+/** 
+ * gdk_pixbuf_save_to_stream:
+ * @pixbuf: a #GdkPixbuf
+ * @stream: a #GOutputStream to save the pixbuf to
+ * @type: name of file format
+ * @cancellable: optional #GCancellable object, %NULL to ignore
+ * @error: return location for error, or %NULL
+ * @Varargs: list of key-value save options
+ *
+ * Saves @pixbuf to an output stream.
+ *
+ * Supported file formats are currently "jpeg", "tiff", "png", "ico" or 
+ * "bmp". See gdk_pixbuf_save_to_buffer() for more details.
+ *
+ * The @cancellable can be used to abort the operation from another 
+ * thread. If the operation was cancelled, the error %GIO_ERROR_CANCELLED 
+ * will be returned. Other possible errors are in the #GDK_PIXBUF_ERROR 
+ * and %G_IO_ERROR domains. 
+ *
+ * The stream is not closed.
+ *
+ * Returns: %TRUE if the pixbuf was saved successfully, %FALSE if an
+ *     error was set.
+ *
+ * Since: 2.16
+ */
+gboolean
+gdk_pixbuf_save_to_stream (GdkPixbuf      *pixbuf,
+                          GOutputStream  *stream,
+                          const char     *type,
+                          GCancellable   *cancellable,
+                          GError        **error,
+                          ...)
+{
+       gboolean res;
+       gchar **keys = NULL;
+       gchar **values = NULL;
+       va_list args;
+       SaveToStreamData data;
+
+       va_start (args, error);
+       collect_save_options (args, &keys, &values);
+       va_end (args);
+
+       data.stream = stream;
+       data.cancellable = cancellable;
+
+       if (!gdk_pixbuf_save_to_callbackv (pixbuf, save_to_stream, 
+                                          &data, type, 
+                                          keys, values, 
+                                          error)) {
+               error = NULL; /* Ignore further errors */
+               res = FALSE;
+       }
+
+       g_strfreev (keys);
+       g_strfreev (values);
+
+       return res;
+}
+
 /**
  * gdk_pixbuf_format_get_name:
  * @format: a #GdkPixbufFormat
index fa9e906d7dca5343db1a40c9e7e908f6dd9fc18c..37b6a9b8bdb2f8608bb9effc7ed2e05f8c0a5228 100644 (file)
@@ -56,6 +56,8 @@ gdk_pixbuf_new_from_file_at_scale PRIVATE
 gdk_pixbuf_new_from_file_at_scale_utf8
 #endif
 gdk_pixbuf_new_from_xpm_data
+gdk_pixbuf_new_from_stream
+gdk_pixbuf_new_from_stream_at_scale
 gdk_pixbuf_save PRIVATE G_GNUC_NULL_TERMINATED
 #ifdef G_OS_WIN32
 gdk_pixbuf_save_utf8
@@ -68,6 +70,7 @@ gdk_pixbuf_savev PRIVATE
 #ifdef G_OS_WIN32
 gdk_pixbuf_savev_utf8
 #endif
+gdk_pixbuf_save_to_stream
 #endif
 #endif