[byzanz] Make the gifenc API only accept cairo-style xRGB surfaces
- From: Benjamin Otte <otte src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [byzanz] Make the gifenc API only accept cairo-style xRGB surfaces
- Date: Sat, 15 Aug 2009 22:12:31 +0000 (UTC)
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]