[Swfdec] Branch 'interpreter' - 18 commits -
libswfdec/swfdec_image.c libswfdec/swfdec_image.h
libswfdec/swfdec_js.c libswfdec/swfdec_js_color.c
libswfdec/swfdec_js_sound.c libswfdec/swfdec_pattern.c
libswfdec/swfdec_scriptable.c libswfdec/swfdec_script.c
Benjamin Otte
company at kemper.freedesktop.org
Mon Jan 29 13:33:00 PST 2007
libswfdec/swfdec_image.c | 113 ++++++++----
libswfdec/swfdec_image.h | 5
libswfdec/swfdec_js.c | 5
libswfdec/swfdec_js_color.c | 8
libswfdec/swfdec_js_sound.c | 7
libswfdec/swfdec_pattern.c | 3
libswfdec/swfdec_script.c | 376 +++++++++++++++++++++++++++++++++++++++---
libswfdec/swfdec_scriptable.c | 2
8 files changed, 441 insertions(+), 78 deletions(-)
New commits:
diff-tree d8b4748701572b483c96bbb4a66a6f026cd1c1d7 (from 1986ae14a62fc9d28ac38f53621fadaf9b42877f)
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Jan 29 19:07:12 2007 +0100
implement InitObject action
all tests pass now
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index b1f1a63..64f0746 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1105,6 +1105,35 @@ fail:
return JS_TRUE;
}
+static JSBool
+swfdec_action_init_object (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ JSStackFrame *fp = cx->fp;
+ JSObject *object;
+ guint i, n_args;
+
+ if (!JS_ValueToECMAUint32 (cx, fp->sp[-1], &n_args))
+ return JS_FALSE;
+ if ((guint) (fp->sp - fp->spbase) < 2 * n_args + 1) {
+ SWFDEC_ERROR ("not enough stack space");
+ return JS_FALSE;
+ }
+
+ object = JS_NewObject (cx, &js_ObjectClass, NULL, NULL);
+ if (object == NULL)
+ return JS_FALSE;
+ for (i = 0; i < n_args; i++) {
+ const char *s = swfdec_js_to_string (cx, fp->sp[-3 - 2 * i]);
+ if (s == NULL)
+ return JS_FALSE;
+ if (!JS_SetProperty (cx, object, s, &fp->sp[-2 - 2 * i]))
+ return JS_FALSE;
+ }
+ fp->sp -= 2 * n_args;
+ fp->sp[-1] = OBJECT_TO_JSVAL (object);
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -1321,7 +1350,7 @@ static const SwfdecActionSpec actions[25
[0x40] = { "NewObject", NULL, -1, 1, { NULL, NULL, swfdec_action_new_object, swfdec_action_new_object, swfdec_action_new_object } },
[0x41] = { "DefineLocal2", NULL },
[0x42] = { "InitArray", NULL },
- [0x43] = { "InitObject", NULL },
+ [0x43] = { "InitObject", NULL, -1, 1, { NULL, NULL, swfdec_action_init_object, swfdec_action_init_object, swfdec_action_init_object } },
[0x44] = { "Typeof", NULL },
[0x45] = { "TargetPath", NULL },
[0x46] = { "Enumerate", NULL },
diff-tree 1986ae14a62fc9d28ac38f53621fadaf9b42877f (from 7718526823b5db8d2d81c0caaed70500cb575c6f)
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Jan 29 18:15:06 2007 +0100
implement NewObject
also fixes the constructors to work with it.
5/44 failures
diff --git a/libswfdec/swfdec_js_color.c b/libswfdec/swfdec_js_color.c
index a117118..ade8d6a 100644
--- a/libswfdec/swfdec_js_color.c
+++ b/libswfdec/swfdec_js_color.c
@@ -178,20 +178,16 @@ static JSBool
swfdec_js_color_new (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
SwfdecMovie *movie;
- JSObject *new;
movie = swfdec_scriptable_from_jsval (cx, argv[0], SWFDEC_TYPE_MOVIE);
if (movie == NULL) {
SWFDEC_INFO ("attempted to construct a color without a movie");
return JS_TRUE;
}
- new = JS_NewObject (cx, &color_class, NULL, NULL);
- if (new == NULL)
- return JS_TRUE;
- if (!JS_SetPrivate (cx, new, movie))
+ if (!JS_SetPrivate (cx, obj, movie))
return JS_TRUE;
g_object_ref (movie);
- *rval = OBJECT_TO_JSVAL (new);
+ *rval = OBJECT_TO_JSVAL (obj);
return JS_TRUE;
}
diff --git a/libswfdec/swfdec_js_sound.c b/libswfdec/swfdec_js_sound.c
index 67e11bd..b9f8d57 100644
--- a/libswfdec/swfdec_js_sound.c
+++ b/libswfdec/swfdec_js_sound.c
@@ -61,12 +61,7 @@ static JSClass sound_class = {
static JSBool
swfdec_js_sound_new (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
- JSObject *new;
-
- new = JS_NewObject (cx, &sound_class, NULL, NULL);
- if (new == NULL)
- return JS_TRUE;
- *rval = OBJECT_TO_JSVAL (new);
+ *rval = OBJECT_TO_JSVAL (obj);
return JS_TRUE;
}
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 8a0d3a6..b1f1a63 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -35,6 +35,7 @@
#include "swfdec_movie.h"
#include "swfdec_player_internal.h"
#include "swfdec_root_movie.h"
+#include "js/jsfun.h"
/*** CONSTANT POOLS ***/
@@ -1063,6 +1064,47 @@ swfdec_action_stop_sounds (JSContext *cx
return JS_TRUE;
}
+static JSBool
+swfdec_action_new_object (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ JSStackFrame *fp = cx->fp;
+ jsval constructor;
+ JSObject *object;
+ const JSClass *clasp;
+ guint n_args;
+
+ constructor = fp->sp[-1];
+ if (!swfdec_eval_jsval (cx, NULL, &constructor))
+ return JS_FALSE;
+ if (!JS_ValueToECMAUint32 (cx, fp->sp[-2], &n_args))
+ return JS_FALSE;
+ if ((guint) (fp->sp - fp->spbase) < n_args + 2) {
+ SWFDEC_ERROR ("not enough stack space");
+ return JS_FALSE;
+ }
+ fp->sp[-1] = constructor;
+
+ if (!JSVAL_IS_OBJECT (constructor))
+ goto fail;
+ object = JSVAL_TO_OBJECT (constructor);
+ if (JS_GetClass (object) != &js_FunctionClass)
+ goto fail;
+ clasp = ((JSFunction *) JS_GetPrivate (cx, object))->clasp;
+ object = JS_NewObject (cx, clasp, NULL, NULL);
+ if (object == NULL)
+ return JS_FALSE;
+ fp->sp[-2] = OBJECT_TO_JSVAL (object);
+ if (!swfdec_action_call (cx, n_args, JSINVOKE_CONSTRUCT))
+ return JS_FALSE;
+ fp->sp[-1] = OBJECT_TO_JSVAL (object);
+ return JS_TRUE;
+
+fail:
+ fp->sp -= n_args + 1;
+ fp->sp[-1] = JSVAL_VOID;
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -1276,7 +1318,7 @@ static const SwfdecActionSpec actions[25
[0x3d] = { "CallFunction", NULL },
[0x3e] = { "Return", NULL },
[0x3f] = { "Modulo", NULL },
- [0x40] = { "NewObject", NULL },
+ [0x40] = { "NewObject", NULL, -1, 1, { NULL, NULL, swfdec_action_new_object, swfdec_action_new_object, swfdec_action_new_object } },
[0x41] = { "DefineLocal2", NULL },
[0x42] = { "InitArray", NULL },
[0x43] = { "InitObject", NULL },
diff-tree 7718526823b5db8d2d81c0caaed70500cb575c6f (from 766926a5baf0ca465c0010f2cf157a41498cd841)
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Jan 29 12:35:59 2007 +0100
implement StopSounds
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 1decae7..8a0d3a6 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1054,6 +1054,15 @@ swfdec_action_end_drag (JSContext *cx, g
return JS_TRUE;
}
+static JSBool
+swfdec_action_stop_sounds (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ SwfdecPlayer *player = JS_GetContextPrivate (cx);
+
+ swfdec_player_stop_all_sounds (player);
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -1219,7 +1228,7 @@ static const SwfdecActionSpec actions[25
[0x06] = { "Play", NULL, 0, 0, { swfdec_action_play, swfdec_action_play, swfdec_action_play, swfdec_action_play, swfdec_action_play } },
[0x07] = { "Stop", NULL, 0, 0, { swfdec_action_stop, swfdec_action_stop, swfdec_action_stop, swfdec_action_stop, swfdec_action_stop } },
[0x08] = { "ToggleQuality", NULL },
- [0x09] = { "StopSounds", NULL },
+ [0x09] = { "StopSounds", NULL, 0, 0, { swfdec_action_stop_sounds, swfdec_action_stop_sounds, swfdec_action_stop_sounds, swfdec_action_stop_sounds, swfdec_action_stop_sounds } },
/* version 4 */
[0x0a] = { "Add", NULL, 2, 1, { NULL, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary } },
[0x0b] = { "Subtract", NULL, 2, 1, { NULL, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary } },
diff-tree 766926a5baf0ca465c0010f2cf157a41498cd841 (from e5233b84a86161a483eb16754dfd89f8f194b0d6)
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Jan 29 12:30:39 2007 +0100
implement StartDrag and EndDrag actions
this makes speedball.swf work again
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 537fced..1decae7 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -359,23 +359,26 @@ swfdec_action_trace (JSContext *cx, guin
* This function is similar to js_Invoke, however it uses a reversed stack
* order. sp[-1] has to be the function to call, sp[-2] will be the object the
* function is called on, sp[-3] is the first argument, followed by the rest of
- * the arguments. The function reorders the stack on success and pushes the
- * return value on top.
+ * the arguments. The function removes all of these argumends from the stack
+ * and pushes the return value on top.
*
* Returns: JS_TRUE on success, JS_FALSE on failure.
**/
static JSBool
swfdec_action_call (JSContext *cx, guint n_args, guint flags)
{
+ JSStackFrame *fp = cx->fp;
int i, j;
jsval tmp;
+ g_assert ((guint) (fp->sp - fp->spbase) >= n_args + 2);
+
j = -1;
i = - (n_args + 2);
while (i < j) {
- tmp = cx->fp->sp[j];
- cx->fp->sp[j] = cx->fp->sp[i];
- cx->fp->sp[i] = tmp;
+ tmp = fp->sp[j];
+ fp->sp[j] = fp->sp[i];
+ fp->sp[i] = tmp;
j--;
i++;
}
@@ -1006,6 +1009,51 @@ swfdec_action_set_target2 (JSContext *cx
return swfdec_action_do_set_target (cx, JSVAL_TO_OBJECT (val));
}
+static JSBool
+swfdec_action_start_drag (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ JSStackFrame *fp = cx->fp;
+ guint stack_size = fp->sp - fp->spbase;
+ guint n_args = 1;
+
+ if (stack_size < 3)
+ return JS_FALSE;
+ if (!swfdec_eval_jsval (cx, NULL, &fp->sp[-1]))
+ return JS_FALSE;
+ if (swfdec_action_to_number (cx, fp->sp[-3])) {
+ jsval tmp;
+ if (stack_size < 7)
+ return JS_FALSE;
+ n_args = 5;
+ /* yay for order */
+ tmp = fp->sp[-4];
+ fp->sp[-4] = fp->sp[-7];
+ fp->sp[-7] = tmp;
+ tmp = fp->sp[-6];
+ fp->sp[-6] = fp->sp[-5];
+ fp->sp[-5] = tmp;
+ }
+ if (!JSVAL_IS_OBJECT (fp->sp[-1])) {
+ fp->sp -= n_args + 2;
+ return JS_TRUE;
+ }
+ fp->sp[-3] = fp->sp[-2];
+ fp->sp[-2] = fp->sp[-1];
+ if (!JS_GetProperty (cx, JSVAL_TO_OBJECT (fp->sp[-2]), "startDrag", &fp->sp[-1]))
+ return JS_FALSE;
+ swfdec_action_call (cx, n_args, 0);
+ fp->sp--;
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_end_drag (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ SwfdecPlayer *player = JS_GetContextPrivate (cx);
+ swfdec_player_set_drag_movie (player, NULL, FALSE, NULL);
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -1196,8 +1244,8 @@ static const SwfdecActionSpec actions[25
[0x24] = { "CloneSprite", NULL },
[0x25] = { "RemoveSprite", NULL },
[0x26] = { "Trace", NULL, 1, 0, { NULL, swfdec_action_trace, swfdec_action_trace, swfdec_action_trace, swfdec_action_trace } },
- [0x27] = { "StartDrag", NULL },
- [0x28] = { "EndDrag", NULL },
+ [0x27] = { "StartDrag", NULL, -1, 0, { NULL, swfdec_action_start_drag, swfdec_action_start_drag, swfdec_action_start_drag, swfdec_action_start_drag } },
+ [0x28] = { "EndDrag", NULL, 0, 0, { NULL, swfdec_action_end_drag, swfdec_action_end_drag, swfdec_action_end_drag, swfdec_action_end_drag } },
[0x29] = { "StringLess", NULL },
/* version 7 */
[0x2a] = { "Throw", NULL },
diff-tree e5233b84a86161a483eb16754dfd89f8f194b0d6 (from 5a4bd5f45bc800d333c356097037c13d13152850)
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Jan 29 10:30:56 2007 +0100
various fixes to reference the correct this object
diff --git a/libswfdec/swfdec_js.c b/libswfdec/swfdec_js.c
index e501c4f..829c1ad 100644
--- a/libswfdec/swfdec_js.c
+++ b/libswfdec/swfdec_js.c
@@ -384,7 +384,7 @@ swfdec_js_eval_internal (JSContext *cx,
if (cx->fp == NULL)
goto out;
g_assert (cx->fp->scopeChain);
- cur = OBJECT_TO_JSVAL (cx->fp->scopeChain);
+ cur = OBJECT_TO_JSVAL (OBJ_THIS_OBJECT (cx, cx->fp->scopeChain));
}
finish:
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index dca72e0..537fced 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -98,7 +98,9 @@ swfdec_constant_pool_free (SwfdecConstan
static SwfdecMovie *
swfdec_action_get_target (JSContext *cx)
{
- return swfdec_scriptable_from_jsval (cx, OBJECT_TO_JSVAL (cx->fp->scopeChain), SWFDEC_TYPE_MOVIE);
+ JSObject *object = cx->fp->scopeChain;
+ object = OBJ_THIS_OBJECT (cx, object);
+ return swfdec_scriptable_from_jsval (cx, OBJECT_TO_JSVAL (object), SWFDEC_TYPE_MOVIE);
}
static JSBool
@@ -442,6 +444,8 @@ swfdec_eval_jsval (JSContext *cx, JSObje
return JS_FALSE;
*val = swfdec_js_eval (cx, obj, bytes);
} else {
+ if (obj == NULL)
+ obj = OBJ_THIS_OBJECT (cx, cx->fp->scopeChain);
*val = OBJECT_TO_JSVAL (obj);
}
return JS_TRUE;
diff-tree 5a4bd5f45bc800d333c356097037c13d13152850 (from 7f5416c27464e7f7f59444e8b2fff80eb65a43c2)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 28 22:17:14 2007 +0100
implement SetTarget and SetTarget2
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 8f86eea..dca72e0 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -949,6 +949,59 @@ swfdec_action_equals2 (JSContext *cx, gu
return JS_TRUE;
}
+static JSBool
+swfdec_action_do_set_target (JSContext *cx, JSObject *target)
+{
+ JSObject *with;
+
+ /* FIXME: this whole function stops working the moment it's used together
+ * with With */
+ if (target == cx->fp->scopeChain)
+ return JS_TRUE;
+ if (target == cx->fp->thisp) {
+ /* FIXME: will probably break once SetTarget is called inside DefineFunctions */
+ cx->fp->scopeChain = cx->fp->thisp;
+ return JS_TRUE;
+ }
+ with = js_NewObject(cx, &js_WithClass, target, cx->fp->scopeChain);
+ if (!with)
+ return JS_FALSE;
+ cx->fp->scopeChain = with;
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_set_target (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ jsval target;
+
+ if (!memchr (data, 0, len)) {
+ SWFDEC_ERROR ("SetTarget action does not specify a string");
+ return JS_FALSE;
+ }
+ /* evaluate relative to this to not get trapped by previous SetTarget calls */
+ target = swfdec_js_eval (cx, cx->fp->thisp, (const char *) data);
+ if (!JSVAL_IS_OBJECT (target)) {
+ SWFDEC_WARNING ("target is not an object");
+ return JS_TRUE;
+ }
+ return swfdec_action_do_set_target (cx, JSVAL_TO_OBJECT (target));
+}
+
+static JSBool
+swfdec_action_set_target2 (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ jsval val;
+
+ val = cx->fp->sp[-1];
+ cx->fp->sp--;
+ if (!JSVAL_IS_OBJECT (val)) {
+ SWFDEC_WARNING ("target is not an object");
+ return JS_TRUE;
+ }
+ return swfdec_action_do_set_target (cx, JSVAL_TO_OBJECT (val));
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -1132,7 +1185,7 @@ static const SwfdecActionSpec actions[25
[0x18] = { "ToInteger", NULL },
[0x1c] = { "GetVariable", NULL, 1, 1, { NULL, swfdec_action_get_variable, swfdec_action_get_variable, swfdec_action_get_variable, swfdec_action_get_variable } },
[0x1d] = { "SetVariable", NULL, 2, 0, { NULL, swfdec_action_set_variable, swfdec_action_set_variable, swfdec_action_set_variable, swfdec_action_set_variable } },
- [0x20] = { "SetTarget2", NULL },
+ [0x20] = { "SetTarget22", NULL, 1, 0, { swfdec_action_set_target2, swfdec_action_set_target2, swfdec_action_set_target2, swfdec_action_set_target2, swfdec_action_set_target2 } },
[0x21] = { "StringAdd", NULL, 2, 1, { NULL, swfdec_action_string_add, swfdec_action_string_add, swfdec_action_string_add, swfdec_action_string_add } },
[0x22] = { "GetProperty", NULL, 2, 1, { NULL, swfdec_action_get_property, swfdec_action_get_property, swfdec_action_get_property, swfdec_action_get_property } },
[0x23] = { "SetProperty", NULL, 3, 0, { NULL, swfdec_action_set_property, swfdec_action_set_property, swfdec_action_set_property, swfdec_action_set_property } },
@@ -1207,7 +1260,7 @@ static const SwfdecActionSpec actions[25
[0x88] = { "ConstantPool", swfdec_action_print_constant_pool, 0, 0, { NULL, NULL, swfdec_action_constant_pool, swfdec_action_constant_pool, swfdec_action_constant_pool } },
/* version 3 */
[0x8a] = { "WaitForFrame", swfdec_action_print_wait_for_frame, 0, 0, { swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame } },
- [0x8b] = { "SetTarget", NULL },
+ [0x8b] = { "SetTarget", NULL, 0, 0, { swfdec_action_set_target, swfdec_action_set_target, swfdec_action_set_target, swfdec_action_set_target, swfdec_action_set_target } },
[0x8c] = { "GotoLabel", NULL },
/* version 4 */
[0x8d] = { "WaitForFrame2", NULL },
diff-tree 7f5416c27464e7f7f59444e8b2fff80eb65a43c2 (from 2f1ed9bb15785a9dfde7fdef1adc92346c11ab82)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 28 22:16:50 2007 +0100
didn't catch NULL here, oops
diff --git a/libswfdec/swfdec_scriptable.c b/libswfdec/swfdec_scriptable.c
index 479bad9..d1ff8da 100644
--- a/libswfdec/swfdec_scriptable.c
+++ b/libswfdec/swfdec_scriptable.c
@@ -144,6 +144,8 @@ swfdec_scriptable_from_jsval (JSContext
if (!JSVAL_IS_OBJECT (val))
return NULL;
+ if (JSVAL_IS_NULL (val))
+ return NULL;
object = JSVAL_TO_OBJECT (val);
klass = g_type_class_peek (type);
if (klass == NULL)
diff-tree 2f1ed9bb15785a9dfde7fdef1adc92346c11ab82 (from 2c8b93b57d2d93c187ac1e0c45667884047fc48d)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 28 20:53:14 2007 +0100
implement Equals2 and fix If and Goto to jump correctly
7/44 failures (all due to NewObject)
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index b736136..8f86eea 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -776,7 +776,7 @@ swfdec_action_jump (JSContext *cx, guint
SWFDEC_ERROR ("Jump action length invalid (is %u, should be 2", len);
return JS_FALSE;
}
- cx->fp->pc += 4 + GINT16_FROM_LE (*((gint16*) data));
+ cx->fp->pc += 5 + GINT16_FROM_LE (*((gint16*) data));
return JS_TRUE;
}
@@ -792,7 +792,7 @@ swfdec_action_if (JSContext *cx, guint a
d = swfdec_action_to_number (cx, cx->fp->sp[-1]);
cx->fp->sp--;
if (d != 0)
- cx->fp->pc += 4 + GINT16_FROM_LE (*((gint16*) data));
+ cx->fp->pc += 5 + GINT16_FROM_LE (*((gint16*) data));
return JS_TRUE;
}
@@ -899,6 +899,56 @@ swfdec_action_less (JSContext *cx, guint
return JS_TRUE;
}
+static JSBool
+swfdec_action_equals2 (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ jsval rval, lval;
+ int ltag, rtag;
+ JSBool cond;
+
+ rval = cx->fp->sp[-1];
+ lval = cx->fp->sp[-2];
+ ltag = JSVAL_TAG(lval);
+ rtag = JSVAL_TAG(rval);
+ if (ltag == rtag) {
+ if (ltag == JSVAL_STRING) {
+ cond = js_CompareStrings (JSVAL_TO_STRING (lval), JSVAL_TO_STRING (rval)) == 0;
+ } else if (ltag == JSVAL_DOUBLE) {
+ cond = *JSVAL_TO_DOUBLE(lval) == *JSVAL_TO_DOUBLE(rval);
+ } else {
+ cond = lval == rval;
+ }
+ } else {
+ if (JSVAL_IS_NULL(lval) || JSVAL_IS_VOID(lval)) {
+ cond = (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval));
+ } else if (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) {
+ cond = JS_FALSE;
+ } else {
+ if (ltag == JSVAL_OBJECT) {
+ if (!OBJ_DEFAULT_VALUE (cx, JSVAL_TO_OBJECT(lval), 0, &lval))
+ return JS_FALSE;
+ ltag = JSVAL_TAG(lval);
+ } else if (rtag == JSVAL_OBJECT) {
+ if (!OBJ_DEFAULT_VALUE (cx, JSVAL_TO_OBJECT(rval), 0, &rval))
+ return JS_FALSE;
+ rtag = JSVAL_TAG(rval);
+ }
+ if (ltag == JSVAL_STRING && rtag == JSVAL_STRING) {
+ cond = js_CompareStrings (JSVAL_TO_STRING (lval), JSVAL_TO_STRING (rval)) == 0;
+ } else {
+ double d, d2;
+ if (!JS_ValueToNumber (cx, lval, &d) ||
+ !JS_ValueToNumber (cx, rval, &d2))
+ return JS_FALSE;
+ cond = d == d2;
+ }
+ }
+ }
+ cx->fp->sp--;
+ cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (cond);
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -1121,7 +1171,7 @@ static const SwfdecActionSpec actions[25
[0x46] = { "Enumerate", NULL },
[0x47] = { "Add2", NULL, 2, 1, { NULL, NULL, swfdec_action_add2_5, swfdec_action_add2_5, swfdec_action_add2_7 } },
[0x48] = { "Less2", NULL, 2, 1, { NULL, NULL, swfdec_action_new_comparison_6, swfdec_action_new_comparison_6, swfdec_action_new_comparison_7 } },
- [0x49] = { "Equals2", NULL },
+ [0x49] = { "Equals2", NULL, 2, 1, { NULL, NULL, swfdec_action_equals2, swfdec_action_equals2, swfdec_action_equals2 } },
[0x4a] = { "ToNumber", NULL },
[0x4b] = { "ToString", NULL },
[0x4c] = { "PushDuplicate", NULL, 1, 2, { NULL, NULL, swfdec_action_push_duplicate, swfdec_action_push_duplicate, swfdec_action_push_duplicate } },
diff-tree 2c8b93b57d2d93c187ac1e0c45667884047fc48d (from 0a490e81dada959efc3ed155a98b8de577ff4dd2)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 28 20:52:23 2007 +0100
another fix for swfdec_js_internal
This code is nasty, I seriously have to clean it up
diff --git a/libswfdec/swfdec_js.c b/libswfdec/swfdec_js.c
index 62cf665..e501c4f 100644
--- a/libswfdec/swfdec_js.c
+++ b/libswfdec/swfdec_js.c
@@ -376,7 +376,7 @@ swfdec_js_eval_internal (JSContext *cx,
if (!swfdec_js_eval_get_property (cx, obj, str, strlen (str), &cur))
goto out;
}
- str = NULL;
+ goto finish;
}
obj = JSVAL_TO_OBJECT (cur);
}
@@ -387,6 +387,7 @@ swfdec_js_eval_internal (JSContext *cx,
cur = OBJECT_TO_JSVAL (cx->fp->scopeChain);
}
+finish:
g_free (work);
*val = cur;
return TRUE;
diff-tree 0a490e81dada959efc3ed155a98b8de577ff4dd2 (from 25d626bfbf646328e7209d72a6ebe73e1036b5b1)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 28 19:32:59 2007 +0100
implement ActionLess
this includes a fix to swfdec_action_to_number since apparently Flash 4 pushes
numbers as strings and converts them for numerical operations.
9/44 failures in the testsuite
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index acb34fa..b736136 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -29,6 +29,7 @@
#include "js/jsinterp.h"
#include <string.h>
+#include <math.h>
#include "swfdec_decoder.h"
#include "swfdec_js.h"
#include "swfdec_movie.h"
@@ -523,6 +524,11 @@ swfdec_action_to_number (JSContext *cx,
return *JSVAL_TO_DOUBLE (val);
} else if (JSVAL_IS_BOOLEAN (val)) {
return JSVAL_TO_BOOLEAN (val);
+ } else if (JSVAL_IS_STRING (val)) {
+ double d;
+ if (!JS_ValueToNumber (cx, val, &d))
+ return 0;
+ return isnan (d) ? 0 : d;
} else {
return 0;
}
@@ -872,6 +878,27 @@ swfdec_action_random_number (JSContext *
return JS_NewNumberValue(cx, result, &cx->fp->sp[-1]);
}
+static JSBool
+swfdec_action_less (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ jsval rval, lval;
+ double l, r;
+ JSBool cond;
+
+ rval = cx->fp->sp[-1];
+ lval = cx->fp->sp[-2];
+ l = swfdec_action_to_number (cx, lval);
+ r = swfdec_action_to_number (cx, rval);
+ cond = l < r;
+ cx->fp->sp--;
+ if (((SwfdecScript *) cx->fp->swf)->version < 5) {
+ cx->fp->sp[-1] = INT_TO_JSVAL (cond ? 1 : 0);
+ } else {
+ cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (cond);
+ }
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -1044,7 +1071,7 @@ static const SwfdecActionSpec actions[25
[0x0c] = { "Multiply", NULL, 2, 1, { NULL, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary } },
[0x0d] = { "Divide", NULL, 2, 1, { NULL, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary } },
[0x0e] = { "Equals", NULL },
- [0x0f] = { "Less", NULL },
+ [0x0f] = { "Less", NULL, 2, 1, { NULL, swfdec_action_less, swfdec_action_less, swfdec_action_less, swfdec_action_less } },
[0x10] = { "And", NULL },
[0x11] = { "Or", NULL },
[0x12] = { "Not", NULL, 1, 1, { NULL, swfdec_action_not_4, swfdec_action_not_5, swfdec_action_not_5, swfdec_action_not_5 } },
diff-tree 25d626bfbf646328e7209d72a6ebe73e1036b5b1 (from ca7b42ca13e0758954f41e5f0dc673a90c07a89b)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 28 19:11:03 2007 +0100
stop printing out all actions
That part of the code should work well enough now :)
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 0a40480..acb34fa 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1227,7 +1227,7 @@ validate_action (gconstpointer bytecode,
return FALSE;
}
/* we might want to do stuff here for certain actions */
-#if 1
+#if 0
{
char *foo = swfdec_script_print_action (action, data, len);
if (foo == NULL)
diff-tree ca7b42ca13e0758954f41e5f0dc673a90c07a89b (from 635f8982ba523747ac79bc87a4d106ba61ba3b44)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 28 19:04:42 2007 +0100
ints are ints not uints in Push action
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index a98b165..0a40480 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -260,8 +260,7 @@ swfdec_action_push (JSContext *cx, guint
}
case 7: /* 32bit int */
{
- /* FIXME: spec says U32, do they mean this? */
- guint i = swfdec_bits_get_u32 (&bits);
+ int i = swfdec_bits_get_u32 (&bits);
*cx->fp->sp++ = INT_TO_JSVAL (i);
break;
}
@@ -954,7 +953,7 @@ swfdec_action_print_push (guint action,
g_string_append_printf (string, "%g", swfdec_bits_get_double (&bits));
break;
case 7: /* 32bit int */
- g_string_append_printf (string, "%u", swfdec_bits_get_u32 (&bits));
+ g_string_append_printf (string, "%d", swfdec_bits_get_u32 (&bits));
break;
case 8: /* 8bit ConstantPool address */
g_string_append_printf (string, "Pool %u", swfdec_bits_get_u8 (&bits));
diff-tree 635f8982ba523747ac79bc87a4d106ba61ba3b44 (from 56d1844f206f946a24755bdb03ccfafdb5c51571)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 28 19:00:06 2007 +0100
implement RandomNumber and PushDuplicate
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 22ada41..a98b165 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -849,6 +849,30 @@ swfdec_action_string_add (JSContext *cx,
return JS_TRUE;
}
+static JSBool
+swfdec_action_push_duplicate (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ cx->fp->sp++;
+ cx->fp->sp[-1] = cx->fp->sp[-2];
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_random_number (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ gint32 max, result;
+
+ if (!JS_ValueToECMAInt32 (cx, cx->fp->sp[-1], &max))
+ return JS_FALSE;
+
+ if (max <= 0)
+ result = 0;
+ else
+ result = g_random_int_range (0, max);
+
+ return JS_NewNumberValue(cx, result, &cx->fp->sp[-1]);
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -1047,7 +1071,7 @@ static const SwfdecActionSpec actions[25
[0x2b] = { "Cast", NULL },
[0x2c] = { "Implements", NULL },
/* version 4 */
- [0x30] = { "RandomNumber", NULL },
+ [0x30] = { "RandomNumber", NULL, 1, 1, { NULL, swfdec_action_random_number, swfdec_action_random_number, swfdec_action_random_number, swfdec_action_random_number } },
[0x31] = { "MBStringLength", NULL },
[0x32] = { "CharToAscii", NULL },
[0x33] = { "AsciiToChar", NULL },
@@ -1074,7 +1098,7 @@ static const SwfdecActionSpec actions[25
[0x49] = { "Equals2", NULL },
[0x4a] = { "ToNumber", NULL },
[0x4b] = { "ToString", NULL },
- [0x4c] = { "PushDuplicate", NULL },
+ [0x4c] = { "PushDuplicate", NULL, 1, 2, { NULL, NULL, swfdec_action_push_duplicate, swfdec_action_push_duplicate, swfdec_action_push_duplicate } },
[0x4d] = { "Swap", NULL },
[0x4e] = { "GetMember", NULL, 2, 1, { NULL, swfdec_action_get_member, swfdec_action_get_member, swfdec_action_get_member, swfdec_action_get_member } },
[0x4f] = { "SetMember", NULL, 3, 0, { NULL, swfdec_action_set_member, swfdec_action_set_member, swfdec_action_set_member, swfdec_action_set_member } },
diff-tree 56d1844f206f946a24755bdb03ccfafdb5c51571 (from ca1d6d627bbc5c221ae0ef51d5b7a1c573fe32e5)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 28 18:48:41 2007 +0100
implement naive Add2 for Flash 5 and 6
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 7848e14..22ada41 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -580,6 +580,49 @@ swfdec_action_binary (JSContext *cx, gui
return JS_NewNumberValue (cx, l, &cx->fp->sp[-1]);
}
+static JSString *
+swfdec_action_to_string_5 (JSContext *cx, jsval val)
+{
+ if (JSVAL_IS_VOID (val) || JSVAL_IS_NULL (val))
+ return cx->runtime->emptyString;
+ return js_ValueToString (cx, val);
+}
+
+static JSBool
+swfdec_action_add2_5 (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ jsval rval, lval;
+ gboolean cond;
+
+ rval = cx->fp->sp[-1];
+ lval = cx->fp->sp[-2];
+ if ((cond = JSVAL_IS_STRING (lval)) || JSVAL_IS_STRING (rval)) {
+ JSString *str, *str2;
+ if (cond) {
+ str = JSVAL_TO_STRING (lval);
+ if ((str2 = swfdec_action_to_string_5 (cx, rval)) == NULL)
+ return JS_FALSE;
+ } else {
+ str2 = JSVAL_TO_STRING (rval);
+ if ((str = swfdec_action_to_string_5 (cx, lval)) == NULL)
+ return JS_FALSE;
+ }
+ str = js_ConcatStrings (cx, str, str2);
+ if (!str)
+ return JS_FALSE;
+ cx->fp->sp--;
+ cx->fp->sp[-1] = STRING_TO_JSVAL (str);
+ } else {
+ double d, d2;
+ d = swfdec_action_to_number (cx, lval);
+ d2 = swfdec_action_to_number (cx, rval);
+ d += d2;
+ cx->fp->sp--;
+ return JS_NewNumberValue(cx, d, &cx->fp->sp[-1]);
+ }
+ return JS_TRUE;
+}
+
static JSBool
swfdec_action_add2_7 (JSContext *cx, guint action, const guint8 *data, guint len)
{
@@ -1026,7 +1069,7 @@ static const SwfdecActionSpec actions[25
[0x44] = { "Typeof", NULL },
[0x45] = { "TargetPath", NULL },
[0x46] = { "Enumerate", NULL },
- [0x47] = { "Add2", NULL, 2, 1, { NULL, NULL, NULL, NULL, swfdec_action_add2_7 } },
+ [0x47] = { "Add2", NULL, 2, 1, { NULL, NULL, swfdec_action_add2_5, swfdec_action_add2_5, swfdec_action_add2_7 } },
[0x48] = { "Less2", NULL, 2, 1, { NULL, NULL, swfdec_action_new_comparison_6, swfdec_action_new_comparison_6, swfdec_action_new_comparison_7 } },
[0x49] = { "Equals2", NULL },
[0x4a] = { "ToNumber", NULL },
diff-tree ca1d6d627bbc5c221ae0ef51d5b7a1c573fe32e5 (from 10d7419e68981104fb2e59b6d3df874170a977f1)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 28 18:11:16 2007 +0100
implement alpha handling in a smarter way
diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index 725ce74..23602c4 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -168,10 +168,18 @@ tag_func_define_bits_jpeg (SwfdecSwfDeco
return SWFDEC_STATUS_OK;
}
+static gboolean
+swfdec_image_has_alpha (SwfdecImage *image)
+{
+ return image->type == SWFDEC_IMAGE_TYPE_LOSSLESS2 ||
+ image->type == SWFDEC_IMAGE_TYPE_JPEG3;
+}
+
static void
-swfdec_image_create_surface (SwfdecImage *image, guint8 *data, gboolean has_alpha)
+swfdec_image_create_surface (SwfdecImage *image, guint8 *data)
{
static const cairo_user_data_key_t key;
+ gboolean has_alpha = swfdec_image_has_alpha (image);
g_assert (image->surface == NULL);
@@ -204,7 +212,7 @@ swfdec_image_jpeg_load (SwfdecImage *ima
jpeg_rgb_decoder_get_image (dec, &image_data,
&image->rowstride, NULL, NULL);
jpeg_rgb_decoder_free (dec);
- swfdec_image_create_surface (image, image_data, FALSE);
+ swfdec_image_create_surface (image, image_data);
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
@@ -252,7 +260,7 @@ swfdec_image_jpeg2_load (SwfdecImage *im
jpeg_rgb_decoder_get_image (dec, &image_data,
&image->rowstride, &image->width, &image->height);
jpeg_rgb_decoder_free (dec);
- swfdec_image_create_surface (image, image_data, FALSE);
+ swfdec_image_create_surface (image, image_data);
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
@@ -317,7 +325,7 @@ swfdec_image_jpeg3_load (SwfdecImage *im
merge_alpha (image, image_data, alpha_data);
g_free (alpha_data);
- swfdec_image_create_surface (image, image_data, TRUE);
+ swfdec_image_create_surface (image, image_data);
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
@@ -487,7 +495,7 @@ swfdec_image_lossless_load (SwfdecImage
#endif
}
- swfdec_image_create_surface (image, image_data, have_alpha);
+ swfdec_image_create_surface (image, image_data);
}
int
@@ -611,11 +619,7 @@ swfdec_image_get_surface_for_target (Swf
/* FIXME: we might want to create multiple surfaces here if there's multiple
* live rendering sources. Right now, this is the quick fix, that transforms
* the cache to the most recent used type */
- if (cairo_surface_get_type (current) == CAIRO_SURFACE_TYPE_IMAGE &&
- cairo_image_surface_get_format (current) == CAIRO_FORMAT_RGB24)
- content = CAIRO_CONTENT_COLOR;
- else
- content = CAIRO_CONTENT_COLOR_ALPHA;
+ content = swfdec_image_has_alpha (image) ? CAIRO_CONTENT_COLOR_ALPHA : CAIRO_CONTENT_COLOR;
similar = cairo_surface_create_similar (target,
content,
image->width, image->height);
diff-tree 10d7419e68981104fb2e59b6d3df874170a977f1 (from parents)
Merge: bf21308d97b50d9867f2c084122e5fc0cfd85f6e 2cb8680a8577ff5d018b50e7da55c233e8eaa4af
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 28 15:02:44 2007 +0100
Merge branch 'master' into interpreter
diff --cc libswfdec/swfdec_image.c
index 2810291,0cf6502..725ce74
@@@ -484,10 -512,9 +484,10 @@@
}
}
}
+#endif
}
- swfdec_image_create_surface (image, image_data);
+ swfdec_image_create_surface (image, image_data, have_alpha);
}
int
diff-tree bf21308d97b50d9867f2c084122e5fc0cfd85f6e (from e06edd91cd480f68e8612517abac3aa7a287abab)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 28 14:52:16 2007 +0100
various fixes for the previous image decoding cleanups
diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index c9df0de..2810291 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -117,7 +117,7 @@ lossless (const guint8 *zptr, int zlen,
z.avail_out = len;
ret = inflateInit (&z);
- ret = inflate (&z, Z_SYNC_FLUSH);
+ ret = inflate (&z, Z_FINISH);
if (ret != Z_STREAM_END) {
SWFDEC_WARNING ("lossless: ret == %d", ret);
}
@@ -348,9 +348,8 @@ static void
swfdec_image_lossless_load (SwfdecImage *image)
{
int format;
- int color_table_size;
+ guint color_table_size;
unsigned char *ptr;
- unsigned char *endptr;
SwfdecBits bits;
unsigned char *image_data = NULL;
int have_alpha = (image->type == SWFDEC_IMAGE_TYPE_LOSSLESS2);
@@ -377,66 +376,70 @@ swfdec_image_lossless_load (SwfdecImage
if (image->width == 0 || image->height == 0)
return;
swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
- ptr = lossless (bits.ptr, endptr - bits.ptr, image->width * image->height);
- bits.ptr = endptr;
if (format == 3) {
- unsigned char *color_table;
unsigned char *indexed_data;
- int i;
+ guint i;
+ unsigned int rowstride = (image->width + 3) & ~3;
image_data = g_malloc (4 * image->width * image->height);
image->rowstride = image->width * 4;
- color_table = g_malloc (color_table_size * 4);
-
if (have_alpha) {
+ ptr = lossless (bits.ptr, bits.end - bits.ptr,
+ color_table_size * 4 + rowstride * image->height);
for (i = 0; i < color_table_size; i++) {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- color_table[i * 4 + 0] = ptr[i * 4 + 2];
- color_table[i * 4 + 1] = ptr[i * 4 + 1];
- color_table[i * 4 + 2] = ptr[i * 4 + 0];
- color_table[i * 4 + 3] = ptr[i * 4 + 3];
+ guint8 tmp = ptr[i * 4 + 0];
+ ptr[i * 4 + 0] = ptr[i * 4 + 2];
+ ptr[i * 4 + 2] = tmp;
#else
- color_table[i * 4 + 0] = ptr[i * 4 + 3];
- color_table[i * 4 + 1] = ptr[i * 4 + 0];
- color_table[i * 4 + 2] = ptr[i * 4 + 1];
- color_table[i * 4 + 3] = ptr[i * 4 + 2];
+ 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
}
indexed_data = ptr + color_table_size * 4;
} else {
- for (i = 0; i < color_table_size; i++) {
+ ptr = lossless (bits.ptr, bits.end - bits.ptr,
+ color_table_size * 3 + rowstride * image->height);
+ 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
- color_table[i * 4 + 0] = ptr[i * 3 + 2];
- color_table[i * 4 + 1] = ptr[i * 3 + 1];
- color_table[i * 4 + 2] = ptr[i * 3 + 0];
- color_table[i * 4 + 3] = 255;
+ ptr[i * 4 + 0] = color[2];
+ ptr[i * 4 + 1] = color[1];
+ ptr[i * 4 + 2] = color[0];
+ ptr[i * 4 + 3] = 255;
#else
- color_table[i * 4 + 0] = 255;
- color_table[i * 4 + 1] = ptr[i * 3 + 0];
- color_table[i * 4 + 2] = ptr[i * 3 + 1];
- color_table[i * 4 + 3] = ptr[i * 3 + 2];
+ ptr[i * 4 + 0] = 255;
+ ptr[i * 4 + 1] = color[0];
+ ptr[i * 4 + 2] = color[1];
+ ptr[i * 4 + 3] = color[2];
#endif
}
indexed_data = ptr + color_table_size * 3;
}
swfdec_image_colormap_decode (image, image_data, indexed_data,
- color_table, color_table_size);
+ ptr, color_table_size);
- g_free (color_table);
g_free (ptr);
}
if (format == 4) {
- unsigned char *p = ptr;
int i, j;
unsigned int c;
unsigned char *idata;
if (have_alpha) {
SWFDEC_INFO("16bit images aren't allowed to have alpha, ignoring");
+ have_alpha = FALSE;
}
+ ptr = lossless (bits.ptr, bits.end - bits.ptr, 2 * image->width * image->height);
image_data = g_malloc (4 * image->width * image->height);
idata = image_data;
image->rowstride = image->width * 4;
@@ -444,7 +447,7 @@ swfdec_image_lossless_load (SwfdecImage
/* 15 bit packed */
for (j = 0; j < image->height; j++) {
for (i = 0; i < image->width; i++) {
- c = p[1] | (p[0] << 8);
+ c = ptr[1] | (ptr[0] << 8);
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
idata[0] = (c << 3) | ((c >> 2) & 0x7);
idata[1] = ((c >> 2) & 0xf8) | ((c >> 7) & 0x7);
@@ -456,32 +459,32 @@ swfdec_image_lossless_load (SwfdecImage
idata[1] = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7);
idata[0] = 0xff;
#endif
- p += 2;
+ ptr += 2;
idata += 4;
}
}
g_free (ptr);
}
if (format == 5) {
- int i, j;
- image_data = ptr;
+ image_data = lossless (bits.ptr, bits.end - bits.ptr, 4 * image->width * image->height);
image->rowstride = image->width * 4;
- if (!have_alpha) {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ {
+ int i, j;
/* image is stored in 0RGB format. We use ARGB/BGRA. */
for (j = 0; j < image->height; j++) {
for (i = 0; i < image->width; i++) {
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
ptr[0] = ptr[3];
ptr[1] = ptr[2];
ptr[2] = ptr[1];
ptr[3] = 255;
-#endif
ptr += 4;
}
}
}
+#endif
}
swfdec_image_create_surface (image, image_data);
diff-tree 2cb8680a8577ff5d018b50e7da55c233e8eaa4af (from 7005f0c65edf0177ea22cbb4514c7df1cbb099c1)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Jan 26 22:54:14 2007 +0100
implement caching in the target's surface type
This is a naive way that only caches in the last used format,
but it should be good enough for most uses
diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index 6c2dcae..0cf6502 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -185,15 +185,15 @@ tag_func_define_bits_jpeg (SwfdecSwfDeco
}
static void
-swfdec_image_create_surface (SwfdecImage *image, guint8 *data)
+swfdec_image_create_surface (SwfdecImage *image, guint8 *data, gboolean has_alpha)
{
static const cairo_user_data_key_t key;
g_assert (image->surface == NULL);
image->surface = cairo_image_surface_create_for_data (data,
- CAIRO_FORMAT_ARGB32, image->width, image->height,
- image->rowstride);
+ has_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
+ image->width, image->height, image->rowstride);
cairo_surface_set_user_data (image->surface, &key, data,
g_free);
}
@@ -220,7 +220,7 @@ swfdec_image_jpeg_load (SwfdecImage *ima
jpeg_rgb_decoder_get_image (dec, &image_data,
&image->rowstride, NULL, NULL);
jpeg_rgb_decoder_free (dec);
- swfdec_image_create_surface (image, image_data);
+ swfdec_image_create_surface (image, image_data, FALSE);
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
@@ -268,7 +268,7 @@ swfdec_image_jpeg2_load (SwfdecImage *im
jpeg_rgb_decoder_get_image (dec, &image_data,
&image->rowstride, &image->width, &image->height);
jpeg_rgb_decoder_free (dec);
- swfdec_image_create_surface (image, image_data);
+ swfdec_image_create_surface (image, image_data, FALSE);
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
@@ -339,7 +339,7 @@ swfdec_image_jpeg3_load (SwfdecImage *im
merge_alpha (image, image_data, alpha_data);
g_free (alpha_data);
- swfdec_image_create_surface (image, image_data);
+ swfdec_image_create_surface (image, image_data, TRUE);
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
@@ -464,6 +464,7 @@ swfdec_image_lossless_load (SwfdecImage
if (have_alpha) {
SWFDEC_INFO("16bit images aren't allowed to have alpha, ignoring");
+ have_alpha = FALSE;
}
image_data = g_malloc (4 * image->width * image->height);
@@ -513,7 +514,7 @@ swfdec_image_lossless_load (SwfdecImage
}
}
- swfdec_image_create_surface (image, image_data);
+ swfdec_image_create_surface (image, image_data, have_alpha);
}
int
@@ -626,3 +627,33 @@ swfdec_image_get_surface (SwfdecImage *i
return image->surface;
}
+cairo_surface_t *
+swfdec_image_get_surface_for_target (SwfdecImage *image, cairo_surface_t *target)
+{
+ cairo_surface_t *current, *similar;
+ cairo_t *copy;
+ cairo_content_t content;
+
+ current = swfdec_image_get_surface (image);
+ if (cairo_surface_get_type (current) == cairo_surface_get_type (target))
+ return current;
+
+ /* FIXME: we might want to create multiple surfaces here if there's multiple
+ * live rendering sources. Right now, this is the quick fix, that transforms
+ * the cache to the most recent used type */
+ if (cairo_surface_get_type (current) == CAIRO_SURFACE_TYPE_IMAGE &&
+ cairo_image_surface_get_format (current) == CAIRO_FORMAT_RGB24)
+ content = CAIRO_CONTENT_COLOR;
+ else
+ content = CAIRO_CONTENT_COLOR_ALPHA;
+ similar = cairo_surface_create_similar (target,
+ content,
+ image->width, image->height);
+ copy = cairo_create (similar);
+ cairo_set_source_surface (copy, current, 0, 0);
+ cairo_paint (copy);
+ cairo_destroy (copy);
+ cairo_surface_destroy (current);
+ image->surface = similar;
+ return similar;
+}
diff --git a/libswfdec/swfdec_image.h b/libswfdec/swfdec_image.h
index af230f2..bcd22f0 100644
--- a/libswfdec/swfdec_image.h
+++ b/libswfdec/swfdec_image.h
@@ -65,7 +65,10 @@ struct _SwfdecImageClass {
GType swfdec_image_get_type (void);
-cairo_surface_t * swfdec_image_get_surface (SwfdecImage * image);
+cairo_surface_t * swfdec_image_get_surface (SwfdecImage * image);
+cairo_surface_t * swfdec_image_get_surface_for_target
+ (SwfdecImage * image,
+ cairo_surface_t * target);
int swfdec_image_jpegtables (SwfdecSwfDecoder * s);
int tag_func_define_bits_jpeg (SwfdecSwfDecoder * s);
diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c
index 312118f..f8902ef 100644
--- a/libswfdec/swfdec_pattern.c
+++ b/libswfdec/swfdec_pattern.c
@@ -267,7 +267,8 @@ swfdec_image_pattern_paint (SwfdecPatter
cairo_matrix_t mat;
cairo_surface_t *surface;
- surface = swfdec_image_get_surface (image->image);
+ surface = swfdec_image_get_surface_for_target (image->image,
+ cairo_get_target (cr));
cairo_append_path (cr, (cairo_path_t *) path);
color = swfdec_color_apply_transform (0xFFFFFFFF, trans);
pattern = cairo_pattern_create_for_surface (surface);
More information about the Swfdec
mailing list