[Swfdec-commits] Branch '0.6' - 3 commits - swfdec-gtk/swfdec_playback_alsa.c swfdec/swfdec_image.c test/image

Benjamin Otte company at kemper.freedesktop.org
Thu Apr 10 13:57:54 PDT 2008


 swfdec-gtk/swfdec_playback_alsa.c           |   49 ++++++++++--
 swfdec/swfdec_image.c                       |  111 +++++++---------------------
 test/image/Makefile.am                      |   12 +++
 test/image/definebits-palette-5.swf         |binary
 test/image/definebits-palette-5.swf.org.png |binary
 test/image/definebits-palette-5.swf.png     |binary
 test/image/definebits-palette-6.swf         |binary
 test/image/definebits-palette-6.swf.org.png |binary
 test/image/definebits-palette-6.swf.png     |binary
 test/image/definebits-palette-7.swf         |binary
 test/image/definebits-palette-7.swf.png     |binary
 test/image/definebits-palette-8.swf         |binary
 test/image/definebits-palette-8.swf.png     |binary
 test/image/definebits-palette-base64.c      |   94 +++++++++++++++++++++++
 test/image/definebits-palette.xml           |   93 +++++++++++++++++++++++
 15 files changed, 269 insertions(+), 90 deletions(-)

New commits:
commit 0d78b94f47a5535731eb076a5a02137cd28d6fa2
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 10 22:46:09 2008 +0200

    add testcase for latest fix

diff --git a/test/image/Makefile.am b/test/image/Makefile.am
index 8349615..f33ab90 100644
--- a/test/image/Makefile.am
+++ b/test/image/Makefile.am
@@ -46,6 +46,18 @@ EXTRA_DIST = \
 	color-transform-add80-alpha.swf.png \
 	default.stas \
 	default.sts \
+	definebits-palette-5.swf \
+	definebits-palette-5.swf.org.png \
+	definebits-palette-5.swf.png \
+	definebits-palette-6.swf \
+	definebits-palette-6.swf.org.png \
+	definebits-palette-6.swf.png \
+	definebits-palette-7.swf \
+	definebits-palette-7.swf.png \
+	definebits-palette-8.swf \
+	definebits-palette-8.swf.png \
+	definebits-palette-base64.c \
+	definebits-palette.xml \
 	duplicate-depth.c \
 	duplicate-depth-5.swf \
 	duplicate-depth-5.swf.png \
diff --git a/test/image/definebits-palette-5.swf b/test/image/definebits-palette-5.swf
new file mode 100644
index 0000000..829d8e0
Binary files /dev/null and b/test/image/definebits-palette-5.swf differ
diff --git a/test/image/definebits-palette-5.swf.org.png b/test/image/definebits-palette-5.swf.org.png
new file mode 100644
index 0000000..ac7db19
Binary files /dev/null and b/test/image/definebits-palette-5.swf.org.png differ
diff --git a/test/image/definebits-palette-5.swf.png b/test/image/definebits-palette-5.swf.png
new file mode 100644
index 0000000..c1dba49
Binary files /dev/null and b/test/image/definebits-palette-5.swf.png differ
diff --git a/test/image/definebits-palette-6.swf b/test/image/definebits-palette-6.swf
new file mode 100644
index 0000000..c25cbdc
Binary files /dev/null and b/test/image/definebits-palette-6.swf differ
diff --git a/test/image/definebits-palette-6.swf.org.png b/test/image/definebits-palette-6.swf.org.png
new file mode 100644
index 0000000..1dc05e2
Binary files /dev/null and b/test/image/definebits-palette-6.swf.org.png differ
diff --git a/test/image/definebits-palette-6.swf.png b/test/image/definebits-palette-6.swf.png
new file mode 100644
index 0000000..c1dba49
Binary files /dev/null and b/test/image/definebits-palette-6.swf.png differ
diff --git a/test/image/definebits-palette-7.swf b/test/image/definebits-palette-7.swf
new file mode 100644
index 0000000..4fa202d
Binary files /dev/null and b/test/image/definebits-palette-7.swf differ
diff --git a/test/image/definebits-palette-7.swf.png b/test/image/definebits-palette-7.swf.png
new file mode 100644
index 0000000..c1dba49
Binary files /dev/null and b/test/image/definebits-palette-7.swf.png differ
diff --git a/test/image/definebits-palette-8.swf b/test/image/definebits-palette-8.swf
new file mode 100644
index 0000000..e7ec025
Binary files /dev/null and b/test/image/definebits-palette-8.swf differ
diff --git a/test/image/definebits-palette-8.swf.png b/test/image/definebits-palette-8.swf.png
new file mode 100644
index 0000000..a6d104f
Binary files /dev/null and b/test/image/definebits-palette-8.swf.png differ
diff --git a/test/image/definebits-palette-base64.c b/test/image/definebits-palette-base64.c
new file mode 100644
index 0000000..c2d6072
--- /dev/null
+++ b/test/image/definebits-palette-base64.c
@@ -0,0 +1,94 @@
+/* gcc `pkg-config --libs --cflags libming glib-2.0 -lz` movie21.c -o movie21 && ./movie21
+ */
+
+#include <string.h>
+#include <zlib.h>
+#include <glib.h>
+
+static const guint32 palette[5] = { 0xFF0000FF, 0xCF00CF00, 0x9F9F0000, 0x6F006F6F, 0x3F3F003F };
+
+static const guint8 indexes[9 * 11] = {
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 1, 1, 1, 1, 1, 1, 1, 0, 
+  0, 1, 2, 2, 2, 2, 2, 1, 0, 
+  0, 1, 2, 3, 3, 3, 2, 1, 0, 
+  0, 1, 2, 3, 4, 3, 2, 1, 0, 
+  0, 1, 2, 3, 4, 3, 2, 1, 0, 
+  0, 1, 2, 3, 4, 3, 2, 1, 0, 
+  0, 1, 2, 3, 3, 3, 2, 1, 0, 
+  0, 1, 2, 2, 2, 2, 2, 1, 0, 
+  0, 1, 1, 1, 1, 1, 1, 1, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 
+};
+
+#define SWFDEC_COLOR_COMBINE(r,g,b,a)	(((a)<<24) | ((r)<<16) | ((g)<<8) | (b))
+#define SWFDEC_COLOR_A(x)		(((x)>>24)&0xff)
+#define SWFDEC_COLOR_R(x)		(((x)>>16)&0xff)
+#define SWFDEC_COLOR_G(x)		(((x)>>8)&0xff)
+#define SWFDEC_COLOR_B(x)		((x)&0xff)
+
+gsize
+create_palletized (guint8 *data, gboolean alpha)
+{
+  guint i;
+  guint8 *start = data;
+
+  if (!alpha)
+    *data++ = G_N_ELEMENTS (palette) - 1;
+  for (i = 0; i < G_N_ELEMENTS (palette); i++) {
+    *data++ = SWFDEC_COLOR_R (palette[i]);
+    *data++ = SWFDEC_COLOR_G (palette[i]);
+    *data++ = SWFDEC_COLOR_B (palette[i]);
+    if (alpha)
+      *data++ = SWFDEC_COLOR_A (palette[i]);
+  }
+  for (i = 0; i < 11; i++) {
+    memcpy (data, &indexes[9 * i], 9);
+    data += 12;
+  }
+  return data - start;
+}
+
+static void
+run (int format, gboolean alpha)
+{
+  guint8 data[2000] = { 0, };
+  guint8 compressed[2000] = { 0, };
+  gsize len; 
+  gulong clen;
+  int ret;
+  char *s;
+
+  switch (format) {
+    case 3:
+      len = create_palletized (data, alpha);
+      g_print ("%u\n", len);
+      break;
+    default:
+      g_assert_not_reached ();
+      return;
+  }
+  
+  if (alpha) {
+    clen = sizeof (compressed);
+    ret = compress2 (compressed, &clen, data, len, 9);
+  } else {
+    clen = sizeof (compressed) - 1;
+    ret = compress2 (compressed + 1, &clen, data + 1, len - 1, 9);
+    compressed[0] = data[0];
+  }
+  g_assert (ret == Z_OK);
+
+  s = g_base64_encode (compressed, clen + 1);
+  g_print ("%s\n\n", s);
+  g_free (s);
+}
+
+int
+main (int argc, char **argv)
+{
+  run (3, FALSE);
+  run (3, TRUE);
+
+  return 0;
+}
diff --git a/test/image/definebits-palette.xml b/test/image/definebits-palette.xml
new file mode 100644
index 0000000..736760e
--- /dev/null
+++ b/test/image/definebits-palette.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<swf version="7" compressed="1">
+  <Header framerate="31" frames="27">
+    <size>
+      <Rectangle left="0" right="4000" top="0" bottom="3000"/>
+    </size>
+    <tags>
+
+      <DefineBitsLossless objectID="1" format="3" width="9" height="11">
+        <data>
+	  <data>BHjaY2D4D4YMDP//Q2gIcNq3nYERAhjkvgHZTCDACJZjZGJmZgayZcDizCwgNt8VBBuqBsxewsIBVw8Rh5gjvmY/3HxksPDbdgDX3xLS</data>
+        </data>
+      </DefineBitsLossless>
+      <DefineShape objectID="2">
+        <bounds>
+          <Rectangle left="0" right="180" top="0" bottom="220"/>
+        </bounds>
+        <styles>
+          <StyleList>
+            <fillStyles>
+              <ClippedBitmap objectID="1">
+                <matrix>
+                  <Transform scaleX="20.00000000000000" scaleY="20.00000000000000" transX="0" transY="0"/>
+                </matrix>
+              </ClippedBitmap>
+            </fillStyles>
+            <lineStyles/>
+          </StyleList>
+        </styles>
+        <shapes>
+          <Shape>
+            <edges>
+              <ShapeSetup fillStyle1="1"/>
+              <LineTo x="180" y="0"/>
+              <LineTo x="0" y="220"/>
+              <LineTo x="-180" y="0"/>
+              <LineTo x="0" y="-220"/>
+              <ShapeSetup/>
+            </edges>
+          </Shape>
+        </shapes>
+      </DefineShape>
+      <PlaceObject2 replace="0" depth="1" objectID="2">
+	<transform>
+	  <Transform transX="500" transY="500"/>
+	</transform>
+      </PlaceObject2>
+
+      <DefineBitsLossless2 objectID="3" format="3" width="9" height="11" n_colormap="4">
+        <data>
+	  <data>eNpjYPj/n+E8w/n5DAzzGfLz8+0Z7O0ZkAEjBEDYTCAAYzMzMyPYLESwkdQjmYNkPhIAAP04B1kA</data>
+	</data>
+      </DefineBitsLossless2>
+      <DefineShape objectID="4">
+        <bounds>
+          <Rectangle left="0" right="180" top="0" bottom="220"/>
+        </bounds>
+        <styles>
+          <StyleList>
+            <fillStyles>
+              <ClippedBitmap objectID="3">
+                <matrix>
+                  <Transform scaleX="20.00000000000000" scaleY="20.00000000000000" transX="0" transY="0"/>
+                </matrix>
+              </ClippedBitmap>
+            </fillStyles>
+            <lineStyles/>
+          </StyleList>
+        </styles>
+        <shapes>
+          <Shape>
+            <edges>
+              <ShapeSetup fillStyle1="1"/>
+              <LineTo x="180" y="0"/>
+              <LineTo x="0" y="220"/>
+              <LineTo x="-180" y="0"/>
+              <LineTo x="0" y="-220"/>
+              <ShapeSetup/>
+            </edges>
+          </Shape>
+        </shapes>
+      </DefineShape>
+      <PlaceObject2 replace="0" depth="2" objectID="4">
+	<transform>
+	  <Transform transX="1000" transY="500"/>
+	</transform>
+      </PlaceObject2>
+
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>
commit a126ae9d57e0729ac758b76b4dba415a04a9221f
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 10 22:41:32 2008 +0200

    fix memory overwrite error that could lead to segfaults
    
    https://bugzilla.redhat.com/show_bug.cgi?id=441614

diff --git a/swfdec/swfdec_image.c b/swfdec/swfdec_image.c
index b4bff6c..fc54511 100644
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@ -37,9 +37,6 @@ static const cairo_user_data_key_t key;
 
 static void merge_alpha (SwfdecImage * image, unsigned char *image_data,
     unsigned char *alpha);
-static void swfdec_image_colormap_decode (SwfdecImage * image,
-    unsigned char *dest,
-    unsigned char *src, unsigned char *colormap, int colormap_len);
 
 G_DEFINE_TYPE (SwfdecImage, swfdec_image, SWFDEC_TYPE_CACHED)
 
@@ -321,7 +318,6 @@ static void
 swfdec_image_lossless_load (SwfdecImage *image)
 {
   int format;
-  guint color_table_size;
   unsigned char *ptr;
   SwfdecBits bits;
   guint8 *data;
@@ -335,16 +331,10 @@ swfdec_image_lossless_load (SwfdecImage *image)
   SWFDEC_LOG ("  width = %d", image->width);
   image->height = swfdec_bits_get_u16 (&bits);
   SWFDEC_LOG ("  height = %d", image->height);
-  if (format == 3) {
-    color_table_size = swfdec_bits_get_u8 (&bits) + 1;
-  } else {
-    color_table_size = 0;
-  }
 
   SWFDEC_LOG ("format = %d", format);
   SWFDEC_LOG ("width = %d", image->width);
   SWFDEC_LOG ("height = %d", image->height);
-  SWFDEC_LOG ("color_table_size = %d", color_table_size);
 
   if (image->width == 0 || image->height == 0)
     return;
@@ -352,63 +342,55 @@ swfdec_image_lossless_load (SwfdecImage *image)
 
   if (format == 3) {
     SwfdecBuffer *buffer;
-    unsigned char *indexed_data;
-    guint i;
+    guchar *indexed_data;
+    guint32 palette[256], *pixels;
+    guint i, j;
+    guint palette_size;
     guint rowstride = (image->width + 3) & ~3;
 
+    palette_size = swfdec_bits_get_u8 (&bits) + 1;
+    SWFDEC_LOG ("palette_size = %d", palette_size);
+
     data = g_malloc (4 * image->width * image->height);
 
     if (have_alpha) {
-      buffer = swfdec_bits_decompress (&bits, -1, color_table_size * 4 + rowstride * image->height);
+      buffer = swfdec_bits_decompress (&bits, -1, palette_size * 4 + rowstride * image->height);
       if (buffer == NULL) {
 	SWFDEC_ERROR ("failed to decompress data");
 	memset (data, 0, 4 * image->width * image->height);
 	goto out;
       }
       ptr = buffer->data;
-      for (i = 0; i < color_table_size; i++) {
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-	guint8 tmp = ptr[i * 4 + 0];
-        ptr[i * 4 + 0] = ptr[i * 4 + 2];
-        ptr[i * 4 + 2] = tmp;
-#else
-        guint8 tmp = ptr[i * 4 + 3];
-        ptr[i * 4 + 3] = ptr[i * 4 + 2];
-        ptr[i * 4 + 2] = ptr[i * 4 + 1];
-        ptr[i * 4 + 1] = ptr[i * 4 + 0];
-        ptr[i * 4 + 0] = tmp;
-#endif
+      for (i = 0; i < palette_size; i++) {
+	palette[i] = SWFDEC_COLOR_COMBINE (ptr[i * 4 + 0], ptr[i * 4 + 1],
+	    ptr[i * 4 + 2], ptr[i * 4 + 3]);
       }
-      indexed_data = ptr + color_table_size * 4;
+      indexed_data = ptr + palette_size * 4;
     } else {
-      buffer = swfdec_bits_decompress (&bits, -1, color_table_size * 3 + rowstride * image->height);
+      buffer = swfdec_bits_decompress (&bits, -1, palette_size * 3 + rowstride * image->height);
       if (buffer == NULL) {
 	SWFDEC_ERROR ("failed to decompress data");
 	memset (data, 0, 4 * image->width * image->height);
 	goto out;
       }
       ptr = buffer->data;
-      for (i = color_table_size - 1; i < color_table_size; i--) {
-	guint8 color[3];
-	color[0] = ptr[i * 3 + 0];
-	color[1] = ptr[i * 3 + 1];
-	color[2] = ptr[i * 3 + 2];
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-        ptr[i * 4 + 0] = color[2];
-        ptr[i * 4 + 1] = color[1];
-	ptr[i * 4 + 2] = color[0];
-        ptr[i * 4 + 3] = 255;
-#else
-        ptr[i * 4 + 0] = 255;
-        ptr[i * 4 + 1] = color[0];
-        ptr[i * 4 + 2] = color[1];
-        ptr[i * 4 + 3] = color[2];
-#endif
+      for (i = 0; i < palette_size; i++) {
+	palette[i] = SWFDEC_COLOR_COMBINE (ptr[i * 3 + 0],
+	    ptr[i * 3 + 1], ptr[i * 3 + 2], 0xFF);
+      }
+      indexed_data = ptr + palette_size * 3;
+    }
+    if (palette_size < 256)
+      memset (palette + palette_size, 0, (256 - palette_size) * 4);
+
+    pixels = (guint32 *) data;
+    for (j = 0; j < (guint) image->height; j++) {
+      for (i = 0; i < (guint) image->width; i++) {
+	*pixels = palette[indexed_data[i]];
+	pixels++;
       }
-      indexed_data = ptr + color_table_size * 3;
+      indexed_data += rowstride;
     }
-    swfdec_image_colormap_decode (image, data, indexed_data,
-	ptr, color_table_size);
 
     swfdec_buffer_unref (buffer);
   } else if (format == 4) {
@@ -525,43 +507,6 @@ tag_func_define_bits_lossless_2 (SwfdecSwfDecoder * s, guint tag)
   return SWFDEC_STATUS_OK;
 }
 
-static void
-swfdec_image_colormap_decode (SwfdecImage * image,
-    unsigned char *dest,
-    unsigned char *src, unsigned char *colormap, int colormap_len)
-{
-  int c;
-  int i;
-  int j;
-  int rowstride;
-
-  rowstride = (image->width + 3) & ~0x3;
-  SWFDEC_DEBUG ("rowstride %d", rowstride);
-
-  for (j = 0; j < image->height; j++) {
-    for (i = 0; i < image->width; i++) {
-      c = src[i];
-      if (colormap_len < 256 && c == 255) {
-        dest[0] = 0;
-        dest[1] = 0;
-        dest[2] = 0;
-        dest[3] = 0;
-      } else if (c >= colormap_len) {
-        SWFDEC_ERROR ("colormap index out of range (%d>=%d) (%d,%d)",
-            c, colormap_len, i, j);
-        dest[0] = 0;
-        dest[1] = 0;
-        dest[2] = 0;
-        dest[3] = 0;
-      } else {
-	memmove (dest, &colormap[c*4], 4);
-      }
-      dest += 4;
-    }
-    src += rowstride;
-  }
-}
-
 static cairo_status_t
 swfdec_image_png_read (void *bitsp, unsigned char *data, unsigned int length)
 {
commit 3c743afcb529963d4f8da2bdd826c62aa915c0e1
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 10 17:47:32 2008 +0200

    add snd_pcm_write support to make PA work via ALSA

diff --git a/swfdec-gtk/swfdec_playback_alsa.c b/swfdec-gtk/swfdec_playback_alsa.c
index bddd189..9d1a8f7 100644
--- a/swfdec-gtk/swfdec_playback_alsa.c
+++ b/swfdec-gtk/swfdec_playback_alsa.c
@@ -47,14 +47,16 @@ struct _SwfdecPlayback {
   GMainContext *	context;	/* context we work in */
 };
 
-typedef struct {
+typedef struct _Stream Stream;
+struct _Stream {
   SwfdecPlayback *     	sound;		/* reference to sound object */
   SwfdecAudio *		audio;		/* the audio we play back */
   snd_pcm_t *		pcm;		/* the pcm we play back to */
   GSource **		sources;	/* sources for writing data */
   guint			n_sources;	/* number of sources */
   guint			offset;		/* offset into sound */
-} Stream;
+  gboolean		(* write)	(Stream *);
+};
 
 #define ALSA_TRY(func,msg) G_STMT_START{ \
   int err = func; \
@@ -90,7 +92,7 @@ write_player (Stream *stream, const snd_pcm_channel_area_t *dst,
 }
 
 static gboolean
-try_write (Stream *stream)
+try_write_mmap (Stream *stream)
 {
   snd_pcm_sframes_t avail_result;
   snd_pcm_uframes_t offset, avail;
@@ -117,6 +119,31 @@ try_write (Stream *stream)
   return TRUE;
 }
 
+static gboolean
+try_write_so_pa_gets_it (Stream *stream)
+{
+#define STEP 1024
+  snd_pcm_sframes_t avail, step;
+  avail = snd_pcm_avail_update (stream->pcm);
+  ALSA_ERROR (avail, "snd_pcm_avail_update failed", FALSE);
+
+  while (avail > 0) {
+    gint16 data[2 * STEP] = { 0, };
+
+    step = MIN (avail, STEP);
+    swfdec_audio_render (stream->audio, data, stream->offset, step);
+    step = snd_pcm_writei (stream->pcm, data, step);
+    ALSA_ERROR (step, "snd_pcm_writei failed", FALSE);
+    avail -= step;
+    stream->offset += step;
+  }
+
+  return TRUE;
+#undef STEP
+}
+
+#define try_write(stream) ((stream)->write (stream))
+
 static void
 swfdec_playback_stream_remove_handlers (Stream *stream)
 {
@@ -141,10 +168,10 @@ handle_stream (GIOChannel *source, GIOCondition cond, gpointer data)
   state = snd_pcm_state (stream->pcm);
   if (state != SND_PCM_STATE_RUNNING) {
     swfdec_playback_stream_start (stream);
+    return TRUE;
   } else {
-    try_write (stream);
+    return try_write (stream);
   }
-  return TRUE;
 }
 
 static void
@@ -185,7 +212,9 @@ swfdec_playback_stream_start (Stream *stream)
       stream->offset = 0;
       //g_print ("offset: %u (delay: %ld)\n", sound->offset, delay);
       if (try_write (stream)) {
-	ALSA_ERROR (snd_pcm_start (stream->pcm), "error starting",);
+	if (stream->write == try_write_mmap) {
+	  ALSA_ERROR (snd_pcm_start (stream->pcm), "error starting",);
+	}
 	swfdec_playback_stream_install_handlers (stream);
       }
       break;
@@ -208,6 +237,7 @@ swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio)
   snd_pcm_hw_params_t *hw_params;
   guint rate;
   snd_pcm_uframes_t uframes;
+  gboolean (* try_write) (Stream *);
 
   /* "default" uses dmix, and dmix ticks way slow, so this thingy here stutters */
   ALSA_ERROR (snd_pcm_open (&ret, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK),
@@ -218,7 +248,11 @@ swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio)
     g_printerr ("No sound format available\n");
     return;
   }
-  if (snd_pcm_hw_params_set_access (ret, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) {
+  if (snd_pcm_hw_params_set_access (ret, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED) >= 0) {
+    try_write = try_write_mmap;
+  } else if (snd_pcm_hw_params_set_access (ret, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED) >= 0) {
+    try_write = try_write_so_pa_gets_it;
+  } else {
     g_printerr ("Failed setting access\n");
     goto fail;
   }
@@ -252,6 +286,7 @@ swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio)
   }
 #endif
   stream = g_new0 (Stream, 1);
+  stream->write = try_write;
   stream->sound = sound;
   stream->audio = g_object_ref (audio);
   stream->pcm = ret;


More information about the Swfdec-commits mailing list