swfmill 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.swfmill +0 -134
- data/README.rdoc +28 -8
- data/Rakefile +6 -5
- data/VERSION +1 -1
- data/ext/.gitignore +1 -0
- data/ext/buffer.h +95 -0
- data/ext/deflate.h +125 -0
- data/ext/extconf.rb +77 -43
- data/ext/inflate.h +82 -0
- data/ext/swfmill/.gitignore +3 -16
- data/ext/swfmill/AUTHORS +2 -1
- data/ext/swfmill/Makefile.in +2 -1
- data/ext/swfmill/NEWS +5 -0
- data/ext/swfmill/autogen.sh +7 -1
- data/ext/swfmill/configure +361 -275
- data/ext/swfmill/configure.ac +28 -20
- data/ext/swfmill/src/Makefile.am +93 -20
- data/ext/swfmill/src/Makefile.in +454 -170
- data/ext/swfmill/src/SWF.h +3 -0
- data/ext/swfmill/src/SWFFile.cpp +1 -1
- data/ext/swfmill/src/SWFShapeMaker.cpp +4 -3
- data/ext/swfmill/src/codegen/basics.xsl +2 -1
- data/ext/swfmill/src/codegen/header.xsl +3 -0
- data/ext/swfmill/src/codegen/parsexml.xsl +53 -2
- data/ext/swfmill/src/codegen/writexml.xsl +54 -1
- data/ext/swfmill/src/swfmill.cpp +52 -35
- data/ext/swfmill/src/swft/swft_import_jpeg.cpp +62 -16
- data/ext/swfmill/src/xslt/simple-elements.xslt +1 -0
- data/ext/swfmill/test/Makefile.in +2 -1
- data/ext/swfmill/test/xml/Makefile.in +2 -1
- data/ext/swfmill_ext.cc +12 -366
- data/ext/swfmill_ext_to_swf.cc +260 -0
- data/ext/swfmill_ext_to_swf.h +6 -0
- data/ext/swfmill_ext_to_xml.cc +262 -0
- data/ext/swfmill_ext_to_xml.h +6 -0
- data/ext/test/Makefile +16 -0
- data/ext/test/buffer_test.cc +84 -0
- data/ext/test/deflate_test.cc +61 -0
- data/ext/test/inflate_test.cc +84 -0
- data/ext/test/test.dat +0 -0
- data/lib/swfmill.rb +14 -23
- data/spec/swfmill_spec.rb +0 -123
- metadata +28 -17
- data/ext/swfmill/src/codegen/Makefile.am +0 -15
- data/ext/swfmill/src/codegen/Makefile.in +0 -346
- data/ext/swfmill/src/swft/Makefile.am +0 -55
- data/ext/swfmill/src/swft/Makefile.in +0 -717
- data/ext/swfmill/src/xslt/Makefile.am +0 -51
- data/ext/swfmill/src/xslt/Makefile.in +0 -536
- data/ext/swfmill/src/xslt/README +0 -19
- data/ext/swfmill/src/xslt/simple.cpp +0 -1686
@@ -39,6 +39,7 @@
|
|
39
39
|
<xsl:variable name="frames">
|
40
40
|
<xsl:choose>
|
41
41
|
<xsl:when test="@frames"><xsl:value-of select="@frames"/></xsl:when>
|
42
|
+
<xsl:when test="frame"><xsl:value-of select="count(frame)"/></xsl:when>
|
42
43
|
<xsl:otherwise>1</xsl:otherwise>
|
43
44
|
</xsl:choose>
|
44
45
|
</xsl:variable>
|
@@ -80,12 +80,13 @@ ECHO_N = @ECHO_N@
|
|
80
80
|
ECHO_T = @ECHO_T@
|
81
81
|
EGREP = @EGREP@
|
82
82
|
EXEEXT = @EXEEXT@
|
83
|
+
EXSLT_CFLAGS = @EXSLT_CFLAGS@
|
84
|
+
EXSLT_LIBS = @EXSLT_LIBS@
|
83
85
|
F77 = @F77@
|
84
86
|
FFLAGS = @FFLAGS@
|
85
87
|
FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
|
86
88
|
FREETYPE_LIBS = @FREETYPE_LIBS@
|
87
89
|
GREP = @GREP@
|
88
|
-
HAVE_PKGCONFIG = @HAVE_PKGCONFIG@
|
89
90
|
INSTALL = @INSTALL@
|
90
91
|
INSTALL_DATA = @INSTALL_DATA@
|
91
92
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
@@ -68,12 +68,13 @@ ECHO_N = @ECHO_N@
|
|
68
68
|
ECHO_T = @ECHO_T@
|
69
69
|
EGREP = @EGREP@
|
70
70
|
EXEEXT = @EXEEXT@
|
71
|
+
EXSLT_CFLAGS = @EXSLT_CFLAGS@
|
72
|
+
EXSLT_LIBS = @EXSLT_LIBS@
|
71
73
|
F77 = @F77@
|
72
74
|
FFLAGS = @FFLAGS@
|
73
75
|
FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
|
74
76
|
FREETYPE_LIBS = @FREETYPE_LIBS@
|
75
77
|
GREP = @GREP@
|
76
|
-
HAVE_PKGCONFIG = @HAVE_PKGCONFIG@
|
77
78
|
INSTALL = @INSTALL@
|
78
79
|
INSTALL_DATA = @INSTALL_DATA@
|
79
80
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
data/ext/swfmill_ext.cc
CHANGED
@@ -1,375 +1,21 @@
|
|
1
|
-
#include <zlib.h>
|
2
1
|
#include "ruby.h"
|
3
|
-
#include "
|
4
|
-
#include "
|
5
|
-
#include "SWFWriter.h"
|
2
|
+
#include "swfmill_ext_to_xml.h"
|
3
|
+
#include "swfmill_ext_to_swf.h"
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
VALUE rb_mSwfmill;
|
6
|
+
VALUE rb_eSwfmill_Error;
|
7
|
+
VALUE rb_eSwfmill_EOFError;
|
10
8
|
|
11
|
-
|
12
|
-
call-seq:
|
13
|
-
Swfmill.to_xmlstr(str [, params]) -> String
|
14
|
-
|
15
|
-
+params+
|
16
|
-
{
|
17
|
-
:version => Fixnum,
|
18
|
-
:compressed => Boolean,
|
19
|
-
}
|
20
|
-
*/
|
21
|
-
VALUE swfmill_ext_to_xmlstr(int argc, VALUE *argv, VALUE self)
|
22
|
-
{
|
23
|
-
VALUE arg_str, arg_param;
|
24
|
-
int arg_num = rb_scan_args(argc, argv, "11", &arg_str, &arg_param);
|
25
|
-
|
26
|
-
unsigned char version = 7;
|
27
|
-
bool compressed = false;
|
28
|
-
|
29
|
-
Check_Type(arg_str, T_STRING);
|
30
|
-
if(arg_num == 2)
|
31
|
-
{
|
32
|
-
Check_Type(arg_param, T_HASH);
|
33
|
-
|
34
|
-
VALUE ver = rb_hash_aref(arg_param, ID2SYM(rb_intern("version")));
|
35
|
-
if(!NIL_P(ver))
|
36
|
-
{
|
37
|
-
version = (unsigned char)NUM2INT(ver);
|
38
|
-
}
|
39
|
-
|
40
|
-
VALUE cmp = rb_hash_aref(arg_param, ID2SYM(rb_intern("compressed")));
|
41
|
-
if(!NIL_P(cmp))
|
42
|
-
{
|
43
|
-
compressed = cmp == Qtrue;
|
44
|
-
}
|
45
|
-
}
|
46
|
-
|
47
|
-
unsigned char* data = (unsigned char*)StringValuePtr(arg_str);
|
48
|
-
size_t size = RSTRING_LEN(arg_str);
|
49
|
-
|
50
|
-
SWF::Header header;
|
51
|
-
{
|
52
|
-
SWF::Context context;
|
53
|
-
SWF::Reader reader(data, size);
|
54
|
-
header.parse(&reader, size, &context);
|
55
|
-
switch(reader.getError())
|
56
|
-
{
|
57
|
-
case SWFR_ERROR:
|
58
|
-
rb_raise(rb_eSwfmill_Error, "unknown error while reading SWF");
|
59
|
-
break;
|
60
|
-
case SWFR_EOF:
|
61
|
-
rb_raise(rb_eSwfmill_EOFError, "reached EOF while reading SWF");
|
62
|
-
break;
|
63
|
-
}
|
64
|
-
}
|
65
|
-
|
66
|
-
VALUE xml = Qnil;
|
67
|
-
{
|
68
|
-
SWF::Context context;
|
69
|
-
xmlDocPtr doc = xmlNewDoc((const xmlChar*)"1.0");
|
70
|
-
xmlNodePtr root = doc->xmlRootNode = xmlNewDocNode(doc, NULL, (const xmlChar *)"swf", NULL);
|
71
|
-
char tmp[4];
|
72
|
-
|
73
|
-
snprintf(tmp, sizeof(tmp), "%i", version);
|
74
|
-
xmlSetProp(root, (const xmlChar*)"version", (const xmlChar*)tmp);
|
75
|
-
|
76
|
-
snprintf(tmp, sizeof(tmp), "%i", compressed?1:0);
|
77
|
-
xmlSetProp(root, (const xmlChar*)"compressed", (const xmlChar*)tmp);
|
78
|
-
|
79
|
-
context.swfVersion = version;
|
80
|
-
header.writeXML(root, &context);
|
81
|
-
|
82
|
-
char* xml_data = NULL;
|
83
|
-
int xml_size;
|
84
|
-
xmlDocDumpFormatMemory(doc, (xmlChar **)&xml_data, &xml_size, 1);
|
85
|
-
|
86
|
-
if(xml_size > 0)
|
87
|
-
{
|
88
|
-
xml = rb_str_new(xml_data, xml_size);
|
89
|
-
}
|
90
|
-
|
91
|
-
if(xml_data != NULL)
|
92
|
-
{
|
93
|
-
xmlFree(xml_data);
|
94
|
-
}
|
95
|
-
|
96
|
-
xmlFreeDoc(doc);
|
97
|
-
}
|
98
|
-
|
99
|
-
return xml;
|
100
|
-
}
|
101
|
-
|
102
|
-
/*
|
103
|
-
call-seq:
|
104
|
-
Swfmill.to_swf(str [, params]) -> Array
|
105
|
-
|
106
|
-
+params+
|
107
|
-
{
|
108
|
-
:compress => Boolean,
|
109
|
-
:level => Symbol,
|
110
|
-
}
|
111
|
-
|
112
|
-
:compress
|
113
|
-
true
|
114
|
-
false
|
115
|
-
nil
|
9
|
+
extern "C" {
|
116
10
|
|
117
|
-
|
118
|
-
:best
|
119
|
-
:speed
|
120
|
-
:none
|
121
|
-
*/
|
122
|
-
VALUE swfmill_ext_to_swf(int argc, VALUE *argv, VALUE self)
|
11
|
+
void Init_swfmill_ext(void)
|
123
12
|
{
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
unsigned char version = 7;
|
128
|
-
bool compressed = false;
|
129
|
-
int compress = 0;
|
130
|
-
int compress_level = Z_BEST_COMPRESSION;
|
131
|
-
|
132
|
-
Check_Type(arg_str, T_STRING);
|
133
|
-
if(arg_num == 2)
|
134
|
-
{
|
135
|
-
Check_Type(arg_param, T_HASH);
|
136
|
-
|
137
|
-
VALUE lvl = rb_hash_aref(arg_param, ID2SYM(rb_intern("level")));
|
138
|
-
if(!NIL_P(lvl))
|
139
|
-
{
|
140
|
-
if(lvl == ID2SYM(rb_intern("speed")))
|
141
|
-
{
|
142
|
-
compress_level = Z_BEST_SPEED;
|
143
|
-
}
|
144
|
-
if(lvl == ID2SYM(rb_intern("none")))
|
145
|
-
{
|
146
|
-
compress_level = Z_NO_COMPRESSION;
|
147
|
-
}
|
148
|
-
}
|
149
|
-
|
150
|
-
VALUE cmp = rb_hash_aref(arg_param, ID2SYM(rb_intern("compressed")));
|
151
|
-
if(!NIL_P(cmp))
|
152
|
-
{
|
153
|
-
compress = cmp == Qtrue ? 1 : 2;
|
154
|
-
}
|
155
|
-
}
|
13
|
+
rb_mSwfmill = rb_define_module("Swfmill");
|
14
|
+
rb_eSwfmill_Error = rb_define_class_under(rb_mSwfmill, "Error", rb_eStandardError);
|
15
|
+
rb_eSwfmill_EOFError = rb_define_class_under(rb_mSwfmill, "EOFError", rb_eStandardError);
|
156
16
|
|
157
|
-
|
158
|
-
|
159
|
-
xmlDocPtr doc = xmlParseMemory(data, size);
|
160
|
-
|
161
|
-
if(doc == NULL)
|
162
|
-
{
|
163
|
-
rb_raise(rb_eSwfmill_Error, "XML parser error");
|
164
|
-
}
|
165
|
-
|
166
|
-
xmlNodePtr root = doc->xmlRootNode;
|
167
|
-
if(strcmp((const char*)root->name, "swf") != 0)
|
168
|
-
{
|
169
|
-
xmlFreeDoc(doc);
|
170
|
-
rb_raise(rb_eSwfmill_Error, "doesn't seem to be a swfml file");
|
171
|
-
}
|
172
|
-
|
173
|
-
xmlNodePtr headerNode = root->children;
|
174
|
-
while((headerNode != NULL) &&
|
175
|
-
(headerNode->name == NULL || strcmp((const char*)headerNode->name, "Header") != 0))
|
176
|
-
{
|
177
|
-
headerNode = headerNode->next;
|
178
|
-
}
|
179
|
-
if(headerNode == NULL)
|
180
|
-
{
|
181
|
-
xmlFreeDoc(doc);
|
182
|
-
rb_raise(rb_eSwfmill_Error, "swfml file is empty");
|
183
|
-
}
|
184
|
-
|
185
|
-
{
|
186
|
-
xmlChar *tmp;
|
187
|
-
tmp = xmlGetProp(root, (const xmlChar*)"version");
|
188
|
-
if(tmp != NULL)
|
189
|
-
{
|
190
|
-
int i;
|
191
|
-
sscanf((char*)tmp, "%i", &i);
|
192
|
-
version = i;
|
193
|
-
xmlFree(tmp);
|
194
|
-
}
|
195
|
-
|
196
|
-
tmp = xmlGetProp(root, (const xmlChar*)"compressed");
|
197
|
-
if(tmp != NULL)
|
198
|
-
{
|
199
|
-
int i;
|
200
|
-
sscanf((char*)tmp, "%i", &i);
|
201
|
-
compressed = i > 0;
|
202
|
-
xmlFree(tmp);
|
203
|
-
}
|
204
|
-
}
|
205
|
-
if(compress > 0)
|
206
|
-
{
|
207
|
-
compressed = compress == 1;
|
208
|
-
}
|
209
|
-
|
210
|
-
SWF::Header header;
|
211
|
-
size_t swf_size;
|
212
|
-
{
|
213
|
-
SWF::Context context;
|
214
|
-
context.swfVersion = version;
|
215
|
-
header.parseXML(headerNode, &context);
|
216
|
-
swf_size = header.getSize(&context, 0) / 8;
|
217
|
-
}
|
218
|
-
|
219
|
-
char swf_head[8+1];
|
220
|
-
{
|
221
|
-
swf_size += 8;
|
222
|
-
snprintf(swf_head, 8, "%s%c%c%c%c%c",
|
223
|
-
compressed ? "CWS" : "FWS",
|
224
|
-
version,
|
225
|
-
((swf_size>> 0) & 0xFF),
|
226
|
-
((swf_size>> 8) & 0xFF),
|
227
|
-
((swf_size>>16) & 0xFF),
|
228
|
-
((swf_size>>24) & 0xFF));
|
229
|
-
swf_size -= 8;
|
230
|
-
}
|
231
|
-
|
232
|
-
unsigned char* swf_buff = (unsigned char*)ruby_xmalloc(swf_size);
|
233
|
-
{
|
234
|
-
SWF::Context context;
|
235
|
-
SWF::Writer writer(swf_buff, swf_size);
|
236
|
-
context.swfVersion = version;
|
237
|
-
header.write(&writer, &context);
|
238
|
-
switch(writer.getError())
|
239
|
-
{
|
240
|
-
case SWFW_ERROR:
|
241
|
-
ruby_xfree(swf_buff);
|
242
|
-
xmlFreeDoc(doc);
|
243
|
-
rb_raise(rb_eSwfmill_Error, "unknown write error");
|
244
|
-
break;
|
245
|
-
case SWFW_FULL:
|
246
|
-
ruby_xfree(swf_buff);
|
247
|
-
xmlFreeDoc(doc);
|
248
|
-
rb_raise(rb_eSwfmill_Error, "write buffer full");
|
249
|
-
break;
|
250
|
-
}
|
251
|
-
}
|
252
|
-
|
253
|
-
if(compressed)
|
254
|
-
{
|
255
|
-
unsigned char temp[BUFSIZ];
|
256
|
-
z_stream stream={Z_NULL};
|
257
|
-
int status, count;
|
258
|
-
|
259
|
-
unsigned char* out_buff = (unsigned char*)ruby_xmalloc(swf_size);
|
260
|
-
int out_offset = 0, out_size = swf_size;
|
261
|
-
|
262
|
-
stream.next_in = swf_buff;
|
263
|
-
stream.avail_in = swf_size;
|
264
|
-
stream.next_out = temp;
|
265
|
-
stream.avail_out = BUFSIZ;
|
266
|
-
|
267
|
-
status = deflateInit(&stream, compress_level);
|
268
|
-
if(status != Z_OK)
|
269
|
-
{
|
270
|
-
ruby_xfree(swf_buff);
|
271
|
-
xmlFreeDoc(doc);
|
272
|
-
rb_raise(rb_eSwfmill_Error, "Error compressing SWF: %s", stream.msg);
|
273
|
-
}
|
274
|
-
|
275
|
-
for(;;)
|
276
|
-
{
|
277
|
-
if(stream.avail_in == 0)
|
278
|
-
{
|
279
|
-
break;
|
280
|
-
}
|
281
|
-
|
282
|
-
status = deflate(&stream, Z_NO_FLUSH);
|
283
|
-
if(status != Z_OK)
|
284
|
-
{
|
285
|
-
ruby_xfree(swf_buff);
|
286
|
-
xmlFreeDoc(doc);
|
287
|
-
rb_raise(rb_eSwfmill_Error, "Error compressing SWF: %s", stream.msg);
|
288
|
-
}
|
289
|
-
|
290
|
-
count = BUFSIZ - stream.avail_out;
|
291
|
-
if(count > 0)
|
292
|
-
{
|
293
|
-
if(out_offset + count >= out_size)
|
294
|
-
{
|
295
|
-
int tmp_size = out_size + out_size / 2;
|
296
|
-
unsigned char* tmp_buff = (unsigned char*)ruby_xmalloc(tmp_size);
|
297
|
-
memcpy(tmp_buff, out_buff, out_size);
|
298
|
-
ruby_xfree(out_buff);
|
299
|
-
out_buff = tmp_buff;
|
300
|
-
out_size = tmp_size;
|
301
|
-
}
|
302
|
-
memcpy(out_buff + out_offset, temp, count);
|
303
|
-
out_offset += count;
|
304
|
-
}
|
305
|
-
|
306
|
-
stream.next_out = temp;
|
307
|
-
stream.avail_out = BUFSIZ;
|
308
|
-
}
|
309
|
-
|
310
|
-
do
|
311
|
-
{
|
312
|
-
status = deflate(&stream, Z_FINISH);
|
313
|
-
|
314
|
-
count = BUFSIZ - stream.avail_out;
|
315
|
-
if(count > 0)
|
316
|
-
{
|
317
|
-
if(out_offset + count >= out_size)
|
318
|
-
{
|
319
|
-
int tmp_size = out_size + out_size / 2;
|
320
|
-
unsigned char* tmp_buff = (unsigned char*)ruby_xmalloc(tmp_size);
|
321
|
-
memcpy(tmp_buff, out_buff, out_size);
|
322
|
-
ruby_xfree(out_buff);
|
323
|
-
out_buff = tmp_buff;
|
324
|
-
out_size = tmp_size;
|
325
|
-
}
|
326
|
-
memcpy(out_buff + out_offset, temp, count);
|
327
|
-
out_offset += count;
|
328
|
-
}
|
329
|
-
|
330
|
-
stream.next_out = temp;
|
331
|
-
stream.avail_out = BUFSIZ;
|
332
|
-
} while(status == Z_OK);
|
333
|
-
|
334
|
-
if(status != Z_STREAM_END)
|
335
|
-
{
|
336
|
-
ruby_xfree(swf_buff);
|
337
|
-
xmlFreeDoc(doc);
|
338
|
-
rb_raise(rb_eSwfmill_Error, "Error compressing SWF: %s", stream.msg);
|
339
|
-
}
|
340
|
-
|
341
|
-
status = deflateEnd(&stream);
|
342
|
-
if(status != Z_OK)
|
343
|
-
{
|
344
|
-
ruby_xfree(swf_buff);
|
345
|
-
xmlFreeDoc(doc);
|
346
|
-
rb_raise(rb_eSwfmill_Error, "Error compressing SWF: %s", stream.msg);
|
347
|
-
}
|
348
|
-
|
349
|
-
ruby_xfree(swf_buff);
|
350
|
-
swf_size = out_offset;
|
351
|
-
swf_buff = (unsigned char*)ruby_xmalloc(swf_size);
|
352
|
-
memcpy(swf_buff, out_buff, swf_size);
|
353
|
-
ruby_xfree(out_buff);
|
354
|
-
}
|
355
|
-
|
356
|
-
VALUE swf;
|
357
|
-
swf = rb_str_new(swf_head, 8);
|
358
|
-
rb_str_cat(swf, (const char*)swf_buff, swf_size);
|
359
|
-
|
360
|
-
ruby_xfree(swf_buff);
|
361
|
-
xmlFreeDoc(doc);
|
362
|
-
return swf;
|
17
|
+
rb_define_singleton_method(rb_mSwfmill, "to_xml", (VALUE (*)(...))swfmill_ext_to_xml, 2);
|
18
|
+
rb_define_singleton_method(rb_mSwfmill, "to_swf", (VALUE (*)(...))swfmill_ext_to_swf, 2);
|
363
19
|
}
|
364
20
|
|
365
|
-
extern "C" {
|
366
|
-
void Init_swfmill_ext(void)
|
367
|
-
{
|
368
|
-
rb_mSwfmill = rb_define_module("Swfmill");
|
369
|
-
rb_define_singleton_method(rb_mSwfmill, "to_xmlstr", (VALUE(*)(...))swfmill_ext_to_xmlstr, -1);
|
370
|
-
rb_define_singleton_method(rb_mSwfmill, "to_swf", (VALUE(*)(...))swfmill_ext_to_swf, -1);
|
371
|
-
|
372
|
-
rb_eSwfmill_Error = rb_define_class_under(rb_mSwfmill, "Error", rb_eStandardError);
|
373
|
-
rb_eSwfmill_EOFError = rb_define_class_under(rb_mSwfmill, "EOFError", rb_eStandardError);
|
374
|
-
}
|
375
21
|
}
|
@@ -0,0 +1,260 @@
|
|
1
|
+
#include <zlib.h>
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "SWF.h"
|
4
|
+
#include "SWFWriter.h"
|
5
|
+
#include "deflate.h"
|
6
|
+
|
7
|
+
extern VALUE rb_eSwfmill_Error;
|
8
|
+
extern VALUE rb_eSwfmill_EOFError;
|
9
|
+
|
10
|
+
#define SIGNATURE_SIZE 8
|
11
|
+
typedef struct {
|
12
|
+
VALUE string;
|
13
|
+
VALUE encoding;
|
14
|
+
bool compressed;
|
15
|
+
SWF::Header *header;
|
16
|
+
SWF::Context *context;
|
17
|
+
size_t datasize;
|
18
|
+
unsigned char *databuff;
|
19
|
+
int compress_level;
|
20
|
+
xmlDocPtr document;
|
21
|
+
xmlNodePtr root_node;
|
22
|
+
xmlNodePtr header_node;
|
23
|
+
} swfmill_to_swf;
|
24
|
+
|
25
|
+
static void
|
26
|
+
sts_mark(swfmill_to_swf * const sts)
|
27
|
+
{
|
28
|
+
if(sts != NULL)
|
29
|
+
{
|
30
|
+
rb_gc_mark(sts->string);
|
31
|
+
rb_gc_mark(sts->encoding);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
static void
|
36
|
+
sts_free(swfmill_to_swf * const sts)
|
37
|
+
{
|
38
|
+
if(sts != NULL)
|
39
|
+
{
|
40
|
+
if(sts->document != NULL)
|
41
|
+
{
|
42
|
+
xmlFreeDoc(sts->document);
|
43
|
+
sts->document = NULL;
|
44
|
+
}
|
45
|
+
|
46
|
+
ruby_xfree(sts->databuff);
|
47
|
+
sts->databuff = NULL;
|
48
|
+
|
49
|
+
delete sts->header;
|
50
|
+
sts->header = NULL;
|
51
|
+
|
52
|
+
delete sts->context;
|
53
|
+
sts->context = NULL;
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
static bool
|
58
|
+
sts_parse_document(swfmill_to_swf * const sts)
|
59
|
+
{
|
60
|
+
sts->document = xmlParseMemory(RSTRING_PTR(sts->string), RSTRING_LEN(sts->string));
|
61
|
+
if(sts->document == NULL)
|
62
|
+
{
|
63
|
+
rb_raise(rb_eSwfmill_Error, "XML parser error");
|
64
|
+
return false;
|
65
|
+
}
|
66
|
+
|
67
|
+
sts->root_node = sts->document->xmlRootNode;
|
68
|
+
if(strcmp((const char*)sts->root_node->name, "swf") != 0)
|
69
|
+
{
|
70
|
+
rb_raise(rb_eSwfmill_Error, "doesn't seem to be a swfml file");
|
71
|
+
return false;
|
72
|
+
}
|
73
|
+
|
74
|
+
return true;
|
75
|
+
}
|
76
|
+
|
77
|
+
static bool
|
78
|
+
sts_search_header_node(swfmill_to_swf * const sts)
|
79
|
+
{
|
80
|
+
xmlNodePtr headerNode = sts->root_node->children;
|
81
|
+
|
82
|
+
while((headerNode != NULL) &&
|
83
|
+
(headerNode->name == NULL || strcmp((const char*)headerNode->name, "Header") != 0))
|
84
|
+
{
|
85
|
+
headerNode = headerNode->next;
|
86
|
+
}
|
87
|
+
|
88
|
+
if(headerNode == NULL)
|
89
|
+
{
|
90
|
+
rb_raise(rb_eSwfmill_Error, "swfml file is empty");
|
91
|
+
return false;
|
92
|
+
}
|
93
|
+
|
94
|
+
sts->header_node = headerNode;
|
95
|
+
|
96
|
+
return true;
|
97
|
+
}
|
98
|
+
|
99
|
+
static void
|
100
|
+
sts_get_version(swfmill_to_swf * const sts)
|
101
|
+
{
|
102
|
+
xmlChar *tmp = xmlGetProp(sts->root_node, (const xmlChar*)"version");
|
103
|
+
|
104
|
+
sts->context = new SWF::Context;
|
105
|
+
sts->context->debugTrace = false;
|
106
|
+
sts->context->quiet = true;
|
107
|
+
|
108
|
+
if(tmp != NULL)
|
109
|
+
{
|
110
|
+
sscanf((char*)tmp, "%i", &sts->context->swfVersion);
|
111
|
+
xmlFree(tmp);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
static void
|
116
|
+
sts_get_compressed(swfmill_to_swf * const sts)
|
117
|
+
{
|
118
|
+
xmlChar *tmp = xmlGetProp(sts->root_node, (const xmlChar*)"compressed");
|
119
|
+
int compress;
|
120
|
+
|
121
|
+
sts->compressed = false;
|
122
|
+
if(tmp != NULL)
|
123
|
+
{
|
124
|
+
sscanf((char*)tmp, "%i", &compress);
|
125
|
+
sts->compressed = compress > 0;
|
126
|
+
xmlFree(tmp);
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
static void
|
131
|
+
sts_parse_xml(swfmill_to_swf * const sts)
|
132
|
+
{
|
133
|
+
sts->context->convertEncoding = true;
|
134
|
+
sts->context->swf_encoding = StringValueCStr(sts->encoding);
|
135
|
+
|
136
|
+
sts->header = new SWF::Header;
|
137
|
+
sts->header->parseXML(sts->header_node, sts->context);
|
138
|
+
|
139
|
+
sts->datasize = sts->header->getSize(sts->context, 0) / 8;
|
140
|
+
sts->databuff = (unsigned char*)ruby_xmalloc(sts->datasize + SIGNATURE_SIZE);
|
141
|
+
}
|
142
|
+
|
143
|
+
static bool
|
144
|
+
sts_compress(swfmill_to_swf * const sts)
|
145
|
+
{
|
146
|
+
if(!sts->compressed)
|
147
|
+
{
|
148
|
+
return true;
|
149
|
+
}
|
150
|
+
|
151
|
+
Deflate deflate(sts->databuff + SIGNATURE_SIZE, sts->datasize, sts->compress_level);
|
152
|
+
|
153
|
+
if(!deflate.compress())
|
154
|
+
{
|
155
|
+
rb_raise(rb_eSwfmill_Error, "compressing SWF: %s", deflate.error());
|
156
|
+
return false;
|
157
|
+
}
|
158
|
+
|
159
|
+
ruby_xfree(sts->databuff);
|
160
|
+
sts->databuff = NULL;
|
161
|
+
|
162
|
+
sts->datasize = deflate.size();
|
163
|
+
sts->databuff = (unsigned char*)ruby_xmalloc(sts->datasize + SIGNATURE_SIZE);
|
164
|
+
memcpy(sts->databuff + SIGNATURE_SIZE, deflate.data(), sts->datasize);
|
165
|
+
|
166
|
+
return true;
|
167
|
+
}
|
168
|
+
|
169
|
+
static bool
|
170
|
+
sts_write(swfmill_to_swf * const sts)
|
171
|
+
{
|
172
|
+
SWF::Writer writer(sts->databuff + SIGNATURE_SIZE, sts->datasize);
|
173
|
+
size_t datasize;
|
174
|
+
|
175
|
+
sts->header->write(&writer, sts->context);
|
176
|
+
switch(writer.getError())
|
177
|
+
{
|
178
|
+
case SWFW_ERROR:
|
179
|
+
rb_raise(rb_eSwfmill_Error, "unknown write error");
|
180
|
+
return false;
|
181
|
+
case SWFW_FULL:
|
182
|
+
rb_raise(rb_eSwfmill_Error, "write buffer full");
|
183
|
+
return false;
|
184
|
+
}
|
185
|
+
|
186
|
+
if(!sts_compress(sts))
|
187
|
+
{
|
188
|
+
return false;
|
189
|
+
}
|
190
|
+
|
191
|
+
sts->databuff[0] = (unsigned char)(sts->compressed ? 'C' : 'F');
|
192
|
+
sts->databuff[1] = (unsigned char)'W';
|
193
|
+
sts->databuff[2] = (unsigned char)'S';
|
194
|
+
sts->databuff[3] = (unsigned char)sts->context->swfVersion;
|
195
|
+
|
196
|
+
datasize = sts->datasize;
|
197
|
+
sts->databuff[4] = (unsigned char)((datasize >> 0) & 0xFF);
|
198
|
+
sts->databuff[5] = (unsigned char)((datasize >> 8) & 0xFF);
|
199
|
+
sts->databuff[6] = (unsigned char)((datasize >> 16) & 0xFF);
|
200
|
+
sts->databuff[7] = (unsigned char)((datasize >> 24) & 0xFF);
|
201
|
+
|
202
|
+
return true;
|
203
|
+
}
|
204
|
+
|
205
|
+
static bool
|
206
|
+
sts_parse(swfmill_to_swf * const sts)
|
207
|
+
{
|
208
|
+
if(!sts_parse_document(sts))
|
209
|
+
{
|
210
|
+
return false;
|
211
|
+
}
|
212
|
+
if(!sts_search_header_node(sts))
|
213
|
+
{
|
214
|
+
return false;
|
215
|
+
}
|
216
|
+
sts_get_version(sts);
|
217
|
+
sts_get_compressed(sts);
|
218
|
+
sts_parse_xml(sts);
|
219
|
+
if(!sts_write(sts))
|
220
|
+
{
|
221
|
+
return false;
|
222
|
+
}
|
223
|
+
return true;
|
224
|
+
}
|
225
|
+
|
226
|
+
static VALUE
|
227
|
+
sts_to_string(swfmill_to_swf * const sts)
|
228
|
+
{
|
229
|
+
VALUE str = rb_str_new((const char*)sts->databuff, sts->datasize + SIGNATURE_SIZE);
|
230
|
+
|
231
|
+
ruby_xfree(sts->databuff);
|
232
|
+
sts->databuff = NULL;
|
233
|
+
|
234
|
+
return str;
|
235
|
+
}
|
236
|
+
|
237
|
+
/*
|
238
|
+
call-seq:
|
239
|
+
Swfmill.to_swf(str, encoding) -> String
|
240
|
+
*/
|
241
|
+
VALUE swfmill_ext_to_swf(VALUE self, VALUE string, VALUE encoding)
|
242
|
+
{
|
243
|
+
swfmill_to_swf *sts;
|
244
|
+
|
245
|
+
Check_Type(string, T_STRING);
|
246
|
+
Check_Type(encoding, T_STRING);
|
247
|
+
|
248
|
+
Data_Make_Struct(rb_cData, swfmill_to_swf, sts_mark, sts_free, sts);
|
249
|
+
|
250
|
+
sts->string = string;
|
251
|
+
sts->encoding = encoding;
|
252
|
+
sts->compress_level = Z_BEST_COMPRESSION;
|
253
|
+
|
254
|
+
if(sts_parse(sts))
|
255
|
+
{
|
256
|
+
return sts_to_string(sts);
|
257
|
+
}
|
258
|
+
|
259
|
+
return Qnil;
|
260
|
+
}
|