swfmill 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|