[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