]> Pileus Git - ~andy/gtk/blobdiff - gdk-pixbuf/gdk-pixdata.c
Apply a cleanup patch by Kjartan Maraas (#341812)
[~andy/gtk] / gdk-pixbuf / gdk-pixdata.c
index 4a5735f764dd48fce2dd9b676754c6ab44eb2140..024bac9d5f02084230e5f7a86a3756d730a59863 100644 (file)
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
-#include "gdk-pixdata.h"
+#include <config.h>
 
 #include "gdk-pixbuf-private.h"
-#include "gdk-pixbuf-i18n.h"
+#include "gdk-pixdata.h"
+#include "gdk-pixbuf-alias.h"
 #include <string.h>
 
 #define APPEND g_string_append_printf
@@ -198,7 +199,7 @@ gdk_pixdata_deserialize (GdkPixdata   *pixdata,
 
   /* deserialize header */
   stream = get_uint32 (stream, &pixdata->magic);
-  stream = get_uint32 (stream, &pixdata->length);
+  stream = get_uint32 (stream, (guint32 *)&pixdata->length);
   if (pixdata->magic != GDK_PIXBUF_MAGIC_NUMBER || pixdata->length < GDK_PIXDATA_HEADER_LENGTH)
     return_header_corrupt (error);
   stream = get_uint32 (stream, &pixdata->pixdata_type);
@@ -289,6 +290,13 @@ rl_encode_rgbx (guint8 *bp,        /* dest buffer */
   return bp;
 }
 
+/* Used as the destroy notification function for gdk_pixbuf_new() */
+static void
+free_buffer (guchar *pixels, gpointer data)
+{
+       g_free (pixels);
+}
+
 /**
  * gdk_pixdata_from_pixbuf:
  * @pixdata: a #GdkPixdata to fill.
@@ -327,16 +335,36 @@ gdk_pixdata_from_pixbuf (GdkPixdata      *pixdata,
     {
       guint pad, n_bytes = rowstride * height;
       guint8 *img_buffer_end, *data;
+      GdkPixbuf *buf = NULL;
 
+      if (n_bytes % bpp != 0) 
+       {
+         rowstride = pixbuf->width * bpp;
+         n_bytes = rowstride * height;
+         data = g_malloc (n_bytes);
+         buf = gdk_pixbuf_new_from_data (data,
+                                         GDK_COLORSPACE_RGB,
+                                         pixbuf->has_alpha, 8,
+                                         pixbuf->width,
+                                         pixbuf->height,
+                                         rowstride,
+                                         free_buffer, NULL);
+         gdk_pixbuf_copy_area (pixbuf, 0, 0, pixbuf->width, pixbuf->height,
+                               buf, 0, 0);
+       }
+      else
+       buf = (GdkPixbuf *)pixbuf;
       pad = rowstride;
       pad = MAX (pad, 130 + n_bytes / 127);
       data = g_new (guint8, pad + n_bytes);
       free_me = data;
       img_buffer = data;
       img_buffer_end = rl_encode_rgbx (img_buffer,
-                                      pixbuf->pixels, pixbuf->pixels + n_bytes,
+                                      buf->pixels, buf->pixels + n_bytes,
                                       bpp);
       length = img_buffer_end - img_buffer;
+      if (buf != pixbuf)
+       g_object_unref (buf);
     }
   else
     {
@@ -400,7 +428,9 @@ gdk_pixbuf_from_pixdata (const GdkPixdata *pixdata,
        {
          g_set_error (error, GDK_PIXBUF_ERROR,
                       GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
-                      _("failed to allocate image buffer of %u bytes"),
+                      ngettext("failed to allocate image buffer of %u byte",
+                               "failed to allocate image buffer of %u bytes",
+                               pixdata->rowstride * pixdata->height),
                       pixdata->rowstride * pixdata->height);
          return NULL;
        }
@@ -579,7 +609,7 @@ save_rle_decoder (GString     *gstring,
  * into programs. 
  *
  * GTK+ ships with a program called <command>gdk-pixbuf-csource</command> 
- * which offers a cmdline interface to this functions.
+ * which offers a command line interface to this function.
  *
  * Returns: a newly-allocated string containing the C source form
  *   of @pixdata.
@@ -636,7 +666,7 @@ gdk_pixdata_to_csource (GdkPixdata        *pixdata,
   cdata.dump_rle_decoder = (dump_type & GDK_PIXDATA_DUMP_RLE_DECODER) > 0;
   cdata.static_prefix = (dump_type & GDK_PIXDATA_DUMP_STATIC) ? "static " : "";
   cdata.const_prefix = (dump_type & GDK_PIXDATA_DUMP_CONST) ? "const " : "";
-  gstring = g_string_new ("");
+  gstring = g_string_new (NULL);
   cdata.gstring = gstring;
 
   if (!cdata.dump_macros && cdata.dump_gtypes)
@@ -707,7 +737,7 @@ gdk_pixdata_to_csource (GdkPixdata        *pixdata,
              cdata.static_prefix, cdata.const_prefix, name);
       APPEND (gstring, "  0x%x, /* Pixbuf magic: 'GdkP' */\n",
              GDK_PIXBUF_MAGIC_NUMBER);
-      APPEND (gstring, "  %u + %lu, /* header length + pixel_data length */\n",
+      APPEND (gstring, "  %d + %lu, /* header length + pixel_data length */\n",
              GDK_PIXDATA_HEADER_LENGTH,
              rle_encoded ? (glong)(img_buffer_end - img_buffer) : (glong)rowstride * height);
       APPEND (gstring, "  0x%x, /* pixdata_type */\n",
@@ -728,16 +758,28 @@ gdk_pixdata_to_csource (GdkPixdata        *pixdata,
       img_buffer = stream;
       img_buffer_end = stream + stream_length;
 
+      APPEND (gstring, "#ifdef __SUNPRO_C\n");
+      APPEND (gstring, "#pragma align 4 (%s)\n", name);   
+      APPEND (gstring, "#endif\n");
+
+      APPEND (gstring, "#ifdef __GNUC__\n");
+      APPEND (gstring, "%s%s%s %s[] __attribute__ ((__aligned__ (4))) = \n",
+             cdata.static_prefix, cdata.const_prefix,
+             cdata.dump_gtypes ? "guint8" : "unsigned char",
+             name);
+      APPEND (gstring, "#else\n");
       APPEND (gstring, "%s%s%s %s[] = \n",
              cdata.static_prefix, cdata.const_prefix,
              cdata.dump_gtypes ? "guint8" : "unsigned char",
              name);
+      APPEND (gstring, "#endif\n");
+
       APPEND (gstring, "{ \"\"\n  /* Pixbuf magic (0x%x) */\n  \"",
              GDK_PIXBUF_MAGIC_NUMBER);
       cdata.pos = 3;
       save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++);
       save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++);
-      APPEND (gstring, "\"\n  /* length: header (%u) + pixel_data (%u) */\n  \"",
+      APPEND (gstring, "\"\n  /* length: header (%d) + pixel_data (%u) */\n  \"",
              GDK_PIXDATA_HEADER_LENGTH,
              rle_encoded ? pix_length : rowstride * height);
       cdata.pos = 3;
@@ -820,7 +862,8 @@ gdk_pixdata_to_csource (GdkPixdata        *pixdata,
 
 /**
  * gdk_pixbuf_new_from_inline:
- * @data_length: Length in bytes of the @data argument
+ * @data_length: Length in bytes of the @data argument or -1 to 
+ *    disable length checks
  * @data: Byte data containing a serialized #GdkPixdata structure
  * @copy_pixels: Whether to copy the pixel data, or use direct pointers
  *               @data for the resulting pixbuf
@@ -848,13 +891,18 @@ gdk_pixdata_to_csource (GdkPixdata        *pixdata,
  * generally a bad idea.)
  *
  * If you create a pixbuf from const inline data compiled into your
- * program, it's probably safe to ignore errors, since things will
- * always succeed.  For non-const inline data, you could get out of
- * memory. For untrusted inline data located at runtime, you could
- * have corrupt inline data in addition.
+ * program, it's probably safe to ignore errors and disable length checks, 
+ * since things will always succeed:
+ * <informalexample><programlisting>
+ * pixbuf = gdk_pixbuf_new_from_inline (-1, myimage_inline, FALSE, NULL);
+ * </programlisting></informalexample>
+ *
+ * For non-const inline data, you could get out of memory. For untrusted 
+ * inline data located at runtime, you could have corrupt inline data in 
+ * addition.
  *
  * Return value: A newly-created #GdkPixbuf structure with a reference,
- *   count of 1, or %NULL if error is set.
+ *   count of 1, or %NULL if an error occurred.
  **/
 GdkPixbuf*
 gdk_pixbuf_new_from_inline (gint          data_length,
@@ -873,3 +921,6 @@ gdk_pixbuf_new_from_inline (gint          data_length,
 
   return gdk_pixbuf_from_pixdata (&pixdata, copy_pixels, error);
 }
+
+#define __GDK_PIXDATA_C__
+#include "gdk-pixbuf-aliasdef.c"