[byzanz] Make the gifenc API only accept cairo-style xRGB surfaces



commit 1fc2bbf8deb20cee4366e85ba3170af18d47dea3
Author: Benjamin Otte <otte gnome org>
Date:   Sun Aug 16 00:10:02 2009 +0200

    Make the gifenc API only accept cairo-style xRGB surfaces

 gifenc/gifenc.c      |   65 ++++++++++++++++---------------------------------
 gifenc/gifenc.h      |    9 +------
 gifenc/quantize.c    |   57 ++++++-------------------------------------
 src/byzanzrecorder.c |    5 +--
 4 files changed, 32 insertions(+), 104 deletions(-)
---
diff --git a/gifenc/gifenc.c b/gifenc/gifenc.c
index d223fd1..d633da0 100644
--- a/gifenc/gifenc.c
+++ b/gifenc/gifenc.c
@@ -44,6 +44,12 @@ log2n (guint number)
   return ret;
 }
 
+#define RED(x) ((guint8) ((x) >> 16))
+#define GREEN(x) ((guint8) ((x) >> 8))
+#define BLUE(x) ((guint8) (x))
+
+#define COLOR(r, g, b) (((r) << 16) | ((g) << 8) | (b))
+
 /*** WRITE ROUTINES ***/
 
 static void
@@ -125,20 +131,15 @@ static void
 gifenc_write_color_table (Gifenc *enc, GifencPalette *palette)
 {
   guint i, table_size;
-  guint8 buf[3];
 
   if (!palette)
     return;
   i = gifenc_palette_get_num_colors (palette);
   table_size = 1 << log2n (i - 1);
   for (i = 0; i < palette->num_colors; i++) {
-    GIFENC_WRITE_TRIPLET (buf, palette->colors[i]);
-    if (palette->byte_order == G_LITTLE_ENDIAN) {
-      guint8 tmp = buf[2];
-      buf[2] = buf[0];
-      buf[0] = tmp;
-    }
-    gifenc_write (enc, buf, 3);
+    gifenc_write_byte (enc, RED (palette->colors[i]));
+    gifenc_write_byte (enc, GREEN (palette->colors[i]));
+    gifenc_write_byte (enc, BLUE (palette->colors[i]));
   }
   if (palette->alpha) {
     gifenc_write (enc, (guint8 *) "\272\219\001", 3);
@@ -438,30 +439,6 @@ gifenc_set_looping (Gifenc *enc)
   gifenc_write_loop (enc);
 }
 
-/*** test code ***/
-
-//#include "testimage.h"
-
-guint8 *
-gifenc_dither_pixbuf (GdkPixbuf *pixbuf, const GifencPalette *palette)
-{
-  guint8 *ret;
-  guint width, height;
-  
-  g_return_val_if_fail (!gdk_pixbuf_get_has_alpha (pixbuf), NULL);
-  g_return_val_if_fail (palette->byte_order == G_BIG_ENDIAN, NULL);
-
-  width = gdk_pixbuf_get_width (pixbuf);
-  height = gdk_pixbuf_get_height (pixbuf);
-  ret = g_new (guint8, width * height);
-
-  gifenc_dither_rgb (ret, width, palette, gdk_pixbuf_get_pixels (pixbuf),
-      width, height,
-      gdk_pixbuf_get_has_alpha (pixbuf) ? 4 : 3,
-      gdk_pixbuf_get_rowstride (pixbuf));
-  return ret;
-}
-
 /* Floyd-Steinman factors */
 #define FACTOR0 (23)
 #define FACTOR1 (79)
@@ -471,7 +448,7 @@ gifenc_dither_pixbuf (GdkPixbuf *pixbuf, const GifencPalette *palette)
 void
 gifenc_dither_rgb (guint8* target, guint target_rowstride, 
     const GifencPalette *palette, const guint8 *data, guint width, guint height, 
-    guint bpp, guint rowstride)
+    guint rowstride)
 {
   guint x, y, i, c;
   gint *this_error, *next_error;
@@ -485,7 +462,7 @@ gifenc_dither_rgb (guint8* target, guint target_rowstride,
   next_error = g_new (gint, (width + 2) * 3);
   i = 0;
   for (y = 0; y < height; y++) {
-    const guchar *row = data;
+    const guint32 *row = (const guint32 *) data;
     gint *cur_error = this_error + 3;
     gint *cur_next_error = next_error;
     err[0] = err[1] = err[2] = 0;
@@ -495,22 +472,22 @@ gifenc_dither_rgb (guint8* target, guint target_rowstride,
       //    (err[0] + cur_error[0]) >> 8, (err[1] + cur_error[1]) >> 8,
       //    (err[2] + cur_error[2]) >> 8);
       for (c = 0; c < 3; c++) {
-	err[c] = ((err[c] + cur_error[c]) >> 8) + (gint) row[c];
+	err[c] = ((err[c] + cur_error[c]) >> 8) + (guint8) (*row >> 8 * c);
 	this[c] = err[c] = CLAMP (err[c], 0, 0xFF);
       }
+      pixel = COLOR (err[2], err[1], err[0]);
       //g_print ("  %2X%2X%2X =>", this[0], this[1], this[2]);
-      GIFENC_READ_TRIPLET (pixel, this);
       target[x] = palette->lookup (palette->data, pixel, &pixel);
-      GIFENC_WRITE_TRIPLET (this, pixel);
       //g_print (" %2X%2X%2X (%u) %p\n", this[0], this[1], this[2], (guint) target[x], target + x);
       for (c = 0; c < 3; c++) {
+	this[c] = *row >> 8 * c;
 	err[c] -= this[c];
 	cur_next_error[c] += FACTOR0 * err[c];
 	cur_next_error[c + 3] += FACTOR1 * err[c];
 	cur_next_error[c + 6] = FACTOR2 * err[c];
 	err[c] *= FACTOR_FRONT;
       }
-      row += bpp;
+      row++;
       cur_error += 3;
       cur_next_error += 3;
     }
@@ -528,7 +505,7 @@ gboolean
 gifenc_dither_rgb_with_full_image (guint8 *target, guint target_rowstride, 
     guint8 *full, guint full_rowstride,
     const GifencPalette *palette, const guint8 *data, guint width, guint height, 
-    guint bpp, guint rowstride, GdkRectangle *rect_out)
+    guint rowstride, GdkRectangle *rect_out)
 {
   int x, y, i, c;
   gint *this_error, *next_error;
@@ -545,7 +522,7 @@ gifenc_dither_rgb_with_full_image (guint8 *target, guint target_rowstride,
   next_error = g_new (gint, (width + 2) * 3);
   i = 0;
   for (y = 0; y < (int) height; y++) {
-    const guchar *row = data;
+    const guint32 *row = (const guint32 *) data;
     gint *cur_error = this_error + 3;
     gint *cur_next_error = next_error;
     err[0] = err[1] = err[2] = 0;
@@ -555,11 +532,11 @@ gifenc_dither_rgb_with_full_image (guint8 *target, guint target_rowstride,
       //    (err[0] + cur_error[0]) >> 8, (err[1] + cur_error[1]) >> 8,
       //    (err[2] + cur_error[2]) >> 8);
       for (c = 0; c < 3; c++) {
-	err[c] = ((err[c] + cur_error[c]) >> 8) + (gint) row[c];
+	err[c] = ((err[c] + cur_error[c]) >> 8) + (guint8) (*row >> 8 * c);
 	this[c] = err[c] = CLAMP (err[c], 0, 0xFF);
       }
       //g_print ("  %2X%2X%2X =>", this[0], this[1], this[2]);
-      GIFENC_READ_TRIPLET (pixel, this);
+      pixel = COLOR (this[2], this[1], this[0]);
       target[x] = palette->lookup (palette->data, pixel, &pixel);
       if (target[x] == full[x]) {
 	target[x] = alpha;
@@ -570,16 +547,16 @@ gifenc_dither_rgb_with_full_image (guint8 *target, guint target_rowstride,
 	area.height = MAX (y, area.height);
 	full[x] = target[x];
       }
-      GIFENC_WRITE_TRIPLET (this, pixel);
       //g_print (" %2X%2X%2X (%u) %p\n", this[0], this[1], this[2], (guint) target[x], target + x);
       for (c = 0; c < 3; c++) {
+	this[0] = *row >> 8 * c;
 	err[c] -= this[c];
 	cur_next_error[c] += FACTOR0 * err[c];
 	cur_next_error[c + 3] += FACTOR1 * err[c];
 	cur_next_error[c + 6] = FACTOR2 * err[c];
 	err[c] *= FACTOR_FRONT;
       }
-      row += bpp;
+      row++;
       cur_error += 3;
       cur_next_error += 3;
     }
diff --git a/gifenc/gifenc.h b/gifenc/gifenc.h
index a608b53..4d43352 100644
--- a/gifenc/gifenc.h
+++ b/gifenc/gifenc.h
@@ -72,15 +72,12 @@ void		gifenc_add_image	(Gifenc *	enc,
 					 guint		rowstride);
 gboolean	gifenc_close		(Gifenc *	enc);
 
-guint8 *	gifenc_dither_pixbuf	(GdkPixbuf *	pixbuf,
-					 const GifencPalette *	palette);
 void		gifenc_dither_rgb	(guint8 *	target,
 					 guint		target_rowstride,
 					 const GifencPalette *	palette,
 					 const guint8 *	data,
 					 guint		width,
 					 guint		height,
-					 guint		bpp,
 					 guint		rowstride);
 gboolean	gifenc_dither_rgb_with_full_image
 					(guint8 *	target,
@@ -91,21 +88,17 @@ gboolean	gifenc_dither_rgb_with_full_image
 					 const guint8 *	data,
 					 guint		width,
 					 guint		height,
-					 guint		bpp,
 					 guint		rowstride,
 					 GdkRectangle *	rect_out);
 
 /* from quantize.c */
 void		gifenc_palette_free	(GifencPalette *palette);
-GifencPalette *	gifenc_palette_get_simple (guint	byte_order,
-					 gboolean	alpha);
+GifencPalette *	gifenc_palette_get_simple (gboolean	alpha);
 GifencPalette *	gifenc_quantize_image	(const guint8 *	data,
 					 guint		width, 
 					 guint		height,
-					 guint		bpp, 
 					 guint		rowstride, 
 					 gboolean	alpha,
-					 gint		byte_order,
 					 guint		max_colors);
 guint		gifenc_palette_get_alpha_index
 					(const GifencPalette *palette);
diff --git a/gifenc/quantize.c b/gifenc/quantize.c
index e77abb1..f078db5 100644
--- a/gifenc/quantize.c
+++ b/gifenc/quantize.c
@@ -79,13 +79,11 @@ gifenc_palette_simple_lookup (gpointer data, guint32 color, guint32 *resulting_c
 }
 
 GifencPalette *
-gifenc_palette_get_simple (guint byte_order, gboolean alpha)
+gifenc_palette_get_simple (gboolean alpha)
 {
   GifencPalette *palette;
   guint r, g, b, i = 0;
 
-  g_return_val_if_fail (byte_order == G_LITTLE_ENDIAN || byte_order == G_BIG_ENDIAN, NULL);
-  
   palette = g_new (GifencPalette, 1);
 
   palette->alpha = alpha;
@@ -98,7 +96,6 @@ gifenc_palette_get_simple (guint byte_order, gboolean alpha)
       }
     }
   }
-  palette->byte_order = byte_order;
   palette->data = GINT_TO_POINTER (alpha ? 1 : 0);
   palette->lookup = gifenc_palette_simple_lookup;
   palette->free = NULL;
@@ -212,6 +209,8 @@ gifenc_octree_add_color (OctreeInfo *info, guint32 color, guint count)
   guint i;
   GifencOctree *tree = info->tree;
 
+  color &= 0xFFFFFF;
+
   for (;;) {
     tree->count += count;
     if (tree->level == 8 || OCTREE_IS_LEAF (tree)) {
@@ -351,14 +350,13 @@ gifenc_octree_lookup (gpointer data, guint32 color, guint32 *looked_up_color)
 }
 
 GifencPalette *
-gifenc_quantize_image (const guint8 *data, guint width, guint height, guint bpp, 
-    guint rowstride, gboolean alpha, gint byte_order, guint max_colors)
+gifenc_quantize_image (const guint8 *data, guint width, guint height,
+    guint rowstride, gboolean alpha, guint max_colors)
 {
   guint x, y;
-  const guint8 *row;
+  const guint32 *row;
   OctreeInfo info = { NULL, NULL, 0 };
   GifencPalette *palette;
-  guint32 color;
   
   g_return_val_if_fail (width * height <= (G_MAXUINT >> 8), NULL);
 
@@ -380,11 +378,9 @@ gifenc_quantize_image (const guint8 *data, guint width, guint height, guint bpp,
   }
   
   for (y = 0; y < height; y++) {
-    row = data;
+    row = (const guint32 *) data;
     for (x = 0; x < width; x++) {
-      GIFENC_READ_TRIPLET (color, row);
-      gifenc_octree_add_color (&info, color, 1);
-      row += bpp;
+      gifenc_octree_add_color (&info, row[x] & 0xFFFFFF, 1);
     }
     //if (info.num_leaves > MAX_LEAVES)
     //  gifenc_octree_reduce_colors (&info, STOP_LEAVES);
@@ -401,7 +397,6 @@ gifenc_quantize_image (const guint8 *data, guint width, guint height, guint bpp,
   palette->alpha = alpha;
   palette->colors = g_new (guint, info.num_leaves);
   palette->num_colors = info.num_leaves;
-  palette->byte_order = byte_order;
   palette->data = info.tree;
   palette->lookup = gifenc_octree_lookup;
   palette->free = gifenc_octree_free;
@@ -412,39 +407,3 @@ gifenc_quantize_image (const guint8 *data, guint width, guint height, guint bpp,
   return (GifencPalette *) palette;
 }
 
-#ifdef TEST_QUANTIZE
-
-int
-main (int argc, char **argv)
-{
-  GError *error = NULL;
-  GdkPixbuf *pixbuf;
-  guint8 *image;
-  GifencPalette *palette;
-  Gifenc *enc;
-  
-  gtk_init (&argc, &argv);
-
-  pixbuf = gdk_pixbuf_new_from_file (argc > 1 ? argv[1] : "/root/rachael.jpg", &error);
-  if (error)
-    g_printerr ("error: %s\n", error->message);
-  palette = gifenc_quantize_image (gdk_pixbuf_get_pixels (pixbuf), 
-      gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), 
-      gdk_pixbuf_get_has_alpha (pixbuf) ? 4 : 3,
-      gdk_pixbuf_get_rowstride (pixbuf), gdk_pixbuf_get_has_alpha (pixbuf), 
-      G_BIG_ENDIAN, 255);
-  
-  image = gifenc_dither_pixbuf (pixbuf, palette);
-  enc = gifenc_open (gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), "test.gif");
-  gifenc_set_palette (enc, palette);
-  gifenc_add_image (enc, 0, 0, gdk_pixbuf_get_width (pixbuf), 
-      gdk_pixbuf_get_height (pixbuf), 0, image, gdk_pixbuf_get_width (pixbuf));
-  g_free (image);
-  g_object_unref (pixbuf);
-  gifenc_close (enc);
-
-  return 0;
-}
-
-#endif
-
diff --git a/src/byzanzrecorder.c b/src/byzanzrecorder.c
index 885a95d..5a977a3 100644
--- a/src/byzanzrecorder.c
+++ b/src/byzanzrecorder.c
@@ -257,7 +257,7 @@ byzanz_recorder_dither_region (ByzanzRecorder *rec, GdkRegion *region,
     if (gifenc_dither_rgb_with_full_image (
 	rec->data + rec->area.width * rects[i].y + rects[i].x, rec->area.width, 
 	rec->data_full + rec->area.width * rects[i].y + rects[i].x, rec->area.width, 
-	rec->gifenc->palette, mem, rects[i].width, rects[i].height, 4, bpl, &area)) {
+	rec->gifenc->palette, mem, rects[i].width, rects[i].height, bpl, &area)) {
       area.x += rects[i].x;
       area.y += rects[i].y;
       gdk_region_union_with_rect (rev, &area);
@@ -459,8 +459,7 @@ byzanz_recorder_quantize (ByzanzRecorder *rec, cairo_surface_t *image)
   GifencPalette *palette;
 
   palette = gifenc_quantize_image (cairo_image_surface_get_data (image),
-      rec->area.width, rec->area.height, 4, cairo_image_surface_get_stride (image), TRUE,
-      G_BYTE_ORDER, 255);
+      rec->area.width, rec->area.height, cairo_image_surface_get_stride (image), TRUE, 255);
   
   gifenc_set_palette (rec->gifenc, palette);
   if (rec->loop)



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