[gtk+] broadway: Encode urls directly into message buffer



commit 17aea1241762eb5504c22dc2d764d586bf84bf7b
Author: Alexander Larsson <alexl redhat com>
Date:   Mon Oct 1 12:44:38 2012 +0200

    broadway: Encode urls directly into message buffer
    
    No need for a temporary buffer

 gdk/broadway/broadway.c |  108 ++++++++++++++++++++++------------------------
 1 files changed, 52 insertions(+), 56 deletions(-)
---
diff --git a/gdk/broadway/broadway.c b/gdk/broadway/broadway.c
index b17d90b..c02cf99 100644
--- a/gdk/broadway/broadway.c
+++ b/gdk/broadway/broadway.c
@@ -58,7 +58,7 @@ base64_uint32 (guint32 v, char *c)
  ***********************************************************/
 
 struct PngTarget {
-  GString *url;
+  GString *buf;
   int state;
   int save;
 };
@@ -71,71 +71,71 @@ write_png_url (void		  *closure,
   struct PngTarget *target = closure;
   gsize res, old_len;
 
-  old_len = target->url->len;
-  g_string_set_size (target->url,
+  old_len = target->buf->len;
+  g_string_set_size (target->buf,
 		     old_len + (data_len / 3 + 1) * 4 + 4);
 
   res = g_base64_encode_step (data, data_len, FALSE,
-			      target->url->str + old_len,
+			      target->buf->str + old_len,
 			      &target->state, &target->save);
 
-  g_string_set_size (target->url,  old_len + res);
+  g_string_set_size (target->buf,  old_len + res);
 
   return CAIRO_STATUS_SUCCESS;
 }
 
-static char *
-to_png_rgb (int w, int h, int byte_stride, guint32 *data)
+static void
+to_png_url_rgb (GString *buf, int w, int h, int byte_stride, guint32 *data)
 {
   cairo_surface_t *surface;
   struct PngTarget target;
   gsize res, old_len;
 
-  target.url = g_string_new ("data:image/png;base64,");
+  target.buf = buf;
   target.state = 0;
   target.save = 0;
 
+  g_string_append (buf, "data:image/png;base64,");
+
   surface = cairo_image_surface_create_for_data ((guchar *)data,
 						 CAIRO_FORMAT_RGB24, w, h, byte_stride);
 
   cairo_surface_write_to_png_stream (surface, write_png_url, &target);
 
-  old_len = target.url->len;
+  old_len = buf->len;
 
-  g_string_set_size (target.url, old_len + 4);
+  g_string_set_size (buf, old_len + 4);
   res = g_base64_encode_close (FALSE,
-			       target.url->str + old_len,
+			       buf->str + old_len,
 			       &target.state, &target.save);
-  g_string_set_size (target.url, old_len + res);
-
-  return g_string_free (target.url, FALSE);
+  g_string_set_size (buf, old_len + res);
 }
 
-static char *
-to_png_rgba (int w, int h, int byte_stride, guint32 *data)
+static void
+to_png_url_rgba (GString *buf, int w, int h, int byte_stride, guint32 *data)
 {
   cairo_surface_t *surface;
   struct PngTarget target;
   gsize res, old_len;
 
-  target.url = g_string_new ("data:image/png;base64,");
+  target.buf = buf;
   target.state = 0;
   target.save = 0;
 
+  g_string_append (buf, "data:image/png;base64,");
+
   surface = cairo_image_surface_create_for_data ((guchar *)data,
 						 CAIRO_FORMAT_ARGB32, w, h, byte_stride);
 
   cairo_surface_write_to_png_stream (surface, write_png_url, &target);
 
-  old_len = target.url->len;
+  old_len = buf->len;
 
-  g_string_set_size (target.url, old_len + 4);
+  g_string_set_size (buf, old_len + 4);
   res = g_base64_encode_close (FALSE,
-			       target.url->str + old_len,
+			       buf->str + old_len,
 			       &target.state, &target.save);
-  g_string_set_size (target.url, old_len + res);
-
-  return g_string_free (target.url, FALSE);
+  g_string_set_size (buf, old_len + res);
 }
 
 #if 0
@@ -503,32 +503,30 @@ void
 broadway_output_put_rgb (BroadwayOutput *output,  int id, int x, int y,
 			 int w, int h, int byte_stride, void *data)
 {
-  gsize buf_size;
-  gsize url_len;
-  char *url, *buf;
+  char buf[HEADER_LEN + 15];
+  gsize image_start, len;
   int p;
 
-  url = to_png_rgb (w, h, byte_stride, (guint32*)data);
-  url_len = strlen (url);
-
-  buf_size = HEADER_LEN + 15 + url_len;
-  buf = g_malloc (buf_size);
-
   p = write_header (output, buf, 'i');
 
   append_uint16 (id, buf, &p);
   append_uint16 (x, buf, &p);
   append_uint16 (y, buf, &p);
 
-  append_uint32 (url_len, buf, &p);
+  append_uint32 (0, buf, &p);
+
+  g_assert (p == sizeof (buf));
+
+  broadway_output_sendmsg (output, buf, sizeof (buf));
 
-  g_assert (p == HEADER_LEN + 15);
-  strncpy (buf + p, url, url_len);
+  image_start = output->buf->len;
 
-  broadway_output_sendmsg (output, buf, buf_size);
+  to_png_url_rgb (output->buf, w, h, byte_stride, (guint32*)data);
 
-  g_free (buf);
-  free (url);
+  len = output->buf->len - image_start;
+  p = image_start - 6;
+  append_uint32 (len, output->buf->str, &p);
+  g_assert (p == image_start);
 }
 
 typedef struct  {
@@ -758,40 +756,38 @@ void
 broadway_output_put_rgba (BroadwayOutput *output,  int id, int x, int y,
 			  int w, int h, int byte_stride, void *data)
 {
+  char buf[HEADER_LEN + 15];
   BroadwayBox *rects;
   int p, i, n_rects;
+  gsize image_start, len;
 
   rects = rgba_find_rects (data, w, h, byte_stride, &n_rects);
 
   for (i = 0; i < n_rects; i++)
     {
-      gsize url_len, buf_size;
-      char *buf, *url;
       guint8 *subdata;
 
-      subdata = (guint8 *)data + rects[i].x1 * 4 + rects[i].y1 * byte_stride;
-      url = to_png_rgba (rects[i].x2 - rects[i].x1,
-			 rects[i].y2 - rects[i].y1,
-			 byte_stride, (guint32*)subdata);
-
-      url_len = strlen (url);
-      buf_size = HEADER_LEN + 15 + url_len;
-      buf = g_malloc (buf_size);
-
-
       p = write_header (output, buf, 'i');
       append_uint16 (id, buf, &p);
       append_uint16 (x + rects[i].x1, buf, &p);
       append_uint16 (y + rects[i].y1, buf, &p);
 
-      append_uint32 (url_len, buf, &p);
-      g_assert (p == HEADER_LEN + 15);
-      strncpy (buf + p, url, url_len);
+      append_uint32 (0, buf, &p);
+      g_assert (p == sizeof (buf));
 
-      broadway_output_sendmsg (output, buf, buf_size);
+      broadway_output_sendmsg (output, buf, sizeof (buf));
 
-      free (url);
-      g_free (buf);
+      image_start = output->buf->len;
+
+      subdata = (guint8 *)data + rects[i].x1 * 4 + rects[i].y1 * byte_stride;
+      to_png_url_rgba (output->buf, rects[i].x2 - rects[i].x1,
+		       rects[i].y2 - rects[i].y1,
+		       byte_stride, (guint32*)subdata);
+
+      len = output->buf->len - image_start;
+      p = image_start - 6;
+      append_uint32 (len, output->buf->str, &p);
+      g_assert (p == image_start);
     }
 
   free (rects);



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