swfmill 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.swfmill +0 -134
  2. data/README.rdoc +28 -8
  3. data/Rakefile +6 -5
  4. data/VERSION +1 -1
  5. data/ext/.gitignore +1 -0
  6. data/ext/buffer.h +95 -0
  7. data/ext/deflate.h +125 -0
  8. data/ext/extconf.rb +77 -43
  9. data/ext/inflate.h +82 -0
  10. data/ext/swfmill/.gitignore +3 -16
  11. data/ext/swfmill/AUTHORS +2 -1
  12. data/ext/swfmill/Makefile.in +2 -1
  13. data/ext/swfmill/NEWS +5 -0
  14. data/ext/swfmill/autogen.sh +7 -1
  15. data/ext/swfmill/configure +361 -275
  16. data/ext/swfmill/configure.ac +28 -20
  17. data/ext/swfmill/src/Makefile.am +93 -20
  18. data/ext/swfmill/src/Makefile.in +454 -170
  19. data/ext/swfmill/src/SWF.h +3 -0
  20. data/ext/swfmill/src/SWFFile.cpp +1 -1
  21. data/ext/swfmill/src/SWFShapeMaker.cpp +4 -3
  22. data/ext/swfmill/src/codegen/basics.xsl +2 -1
  23. data/ext/swfmill/src/codegen/header.xsl +3 -0
  24. data/ext/swfmill/src/codegen/parsexml.xsl +53 -2
  25. data/ext/swfmill/src/codegen/writexml.xsl +54 -1
  26. data/ext/swfmill/src/swfmill.cpp +52 -35
  27. data/ext/swfmill/src/swft/swft_import_jpeg.cpp +62 -16
  28. data/ext/swfmill/src/xslt/simple-elements.xslt +1 -0
  29. data/ext/swfmill/test/Makefile.in +2 -1
  30. data/ext/swfmill/test/xml/Makefile.in +2 -1
  31. data/ext/swfmill_ext.cc +12 -366
  32. data/ext/swfmill_ext_to_swf.cc +260 -0
  33. data/ext/swfmill_ext_to_swf.h +6 -0
  34. data/ext/swfmill_ext_to_xml.cc +262 -0
  35. data/ext/swfmill_ext_to_xml.h +6 -0
  36. data/ext/test/Makefile +16 -0
  37. data/ext/test/buffer_test.cc +84 -0
  38. data/ext/test/deflate_test.cc +61 -0
  39. data/ext/test/inflate_test.cc +84 -0
  40. data/ext/test/test.dat +0 -0
  41. data/lib/swfmill.rb +14 -23
  42. data/spec/swfmill_spec.rb +0 -123
  43. metadata +28 -17
  44. data/ext/swfmill/src/codegen/Makefile.am +0 -15
  45. data/ext/swfmill/src/codegen/Makefile.in +0 -346
  46. data/ext/swfmill/src/swft/Makefile.am +0 -55
  47. data/ext/swfmill/src/swft/Makefile.in +0 -717
  48. data/ext/swfmill/src/xslt/Makefile.am +0 -51
  49. data/ext/swfmill/src/xslt/Makefile.in +0 -536
  50. data/ext/swfmill/src/xslt/README +0 -19
  51. data/ext/swfmill/src/xslt/simple.cpp +0 -1686
@@ -28,6 +28,9 @@ struct Context {
28
28
  char tagVersion;
29
29
  bool alpha;
30
30
  bool many_shapes;
31
+
32
+ bool convertEncoding;
33
+ const char *swf_encoding;
31
34
 
32
35
  int fillBits;
33
36
  int lineBits;
@@ -209,7 +209,7 @@ int File::saveXML( FILE *fp, Context *ctx ) {
209
209
  xmlDocPtr doc = getXML( ctx );
210
210
  if( !doc ) goto fail;
211
211
 
212
- xmlDocDumpFormatMemory( doc, (xmlChar**)&data, &size, 1 );
212
+ xmlDocDumpFormatMemoryEnc( doc, (xmlChar**)&data, &size, "UTF-8", 1 );
213
213
 
214
214
  if( size ) fwrite( data, size, 1, fp );
215
215
 
@@ -15,9 +15,10 @@ ShapeMaker::ShapeMaker( List<ShapeItem>* e, double fx, double fy, double ofsx, d
15
15
  factory = fy;
16
16
  offsetx = ofsx;
17
17
  offsety = ofsy;
18
- diffx = diffy = 0;
19
- lastx = lasty = 0;
20
- smoothx = smoothy = 0;
18
+ diffx = diffy = 0.0;
19
+ lastx = lasty = 0.0;
20
+ smoothx = smoothy = 0.0;
21
+ minx = miny = maxx = maxy = 0.0;
21
22
  have_first = false;
22
23
 
23
24
  fillStyle0 = lineStyle = fillStyle1 = -1;
@@ -57,7 +57,7 @@ namespace <xsl:value-of select="/format/@format"/> {
57
57
 
58
58
  // ------------ context structure
59
59
 
60
- Context::Context() {
60
+ Context::Context() : swf_encoding(0) {
61
61
  swfVersion = 0;
62
62
  transientPropsToXML = false;
63
63
  debugTrace = false;
@@ -65,6 +65,7 @@ Context::Context() {
65
65
  isLast = false;
66
66
  tagVersion = 0;
67
67
  quiet = false;
68
+ convertEncoding = false;
68
69
  <xsl:apply-templates select="//*[@context]" mode="ctor"/>
69
70
  }
70
71
 
@@ -31,6 +31,9 @@ struct Context {
31
31
  char tagVersion;
32
32
  bool alpha;
33
33
  bool many_shapes;
34
+
35
+ bool convertEncoding;
36
+ const char *swf_encoding;
34
37
 
35
38
  <xsl:for-each select="contextvariable">
36
39
  <xsl:variable name="tmp">
@@ -8,11 +8,62 @@
8
8
  #include &lt;cctype&gt;
9
9
  #include &lt;cstdlib&gt;
10
10
  #include "base64.h"
11
+ #include &lt;errno.h&gt;
12
+ #include &lt;iconv.h&gt;
11
13
 
12
14
  using namespace std;
13
15
 
14
16
  namespace <xsl:value-of select="/format/@format"/> {
15
17
 
18
+ char *fromXmlChar(const Context *ctx, const xmlChar *from_str) {
19
+ if (ctx-&gt;convertEncoding) {
20
+ size_t len = strlen((const char *)from_str);
21
+ iconv_t cd = iconv_open(ctx-&gt;swf_encoding, "UTF-8");
22
+ if (cd &lt; 0) {
23
+ fprintf(stderr, "iconv_open failed.\n");
24
+ char *buf = new char[1];
25
+ buf[0] = '\0';
26
+ return buf;
27
+ }
28
+ size_t buf_size = (len + 1) * 2;
29
+ for (;;) {
30
+ char * const dst = new char[buf_size];
31
+ size_t inbytesleft = len;
32
+ size_t outbytesleft = buf_size - 1; // reserve 1 byte for '\0'
33
+ char *pin = (char*)from_str;
34
+ char *pout = dst;
35
+ bool expandbuf = false;
36
+
37
+ while (inbytesleft &gt; 0) {
38
+ size_t r = iconv(cd, &amp;pin, &amp;inbytesleft, &amp;pout, &amp;outbytesleft);
39
+ if (r == (size_t)-1) {
40
+ if (errno == E2BIG) {
41
+ expandbuf = true;
42
+ } else {
43
+ // bad input charctor
44
+ fprintf(stderr, "iconv failed: %s\n", from_str);
45
+ }
46
+ break;
47
+ }
48
+ }
49
+ if (expandbuf) {
50
+ iconv(cd, 0, 0, 0, 0);
51
+ delete[] dst;
52
+ buf_size *= 2;
53
+ continue;
54
+ }
55
+ *pout = '\0';
56
+ iconv_close(cd);
57
+ return dst;
58
+ }
59
+ } else {
60
+ size_t len = strlen((const char *)from_str) + 1;
61
+ char *buf = new char[len];
62
+ strcpy(buf, (const char *)from_str);
63
+ return buf;
64
+ }
65
+ }
66
+
16
67
  char *strdupx(const char *src) {
17
68
  char *t = new char[strlen(src)+1];
18
69
  strcpy(t, src);
@@ -174,8 +225,8 @@ void <xsl:value-of select="@name"/>::parseXML( xmlNodePtr node, Context *ctx ) {
174
225
  <xsl:template match="string" mode="parsexml">
175
226
  tmp = xmlGetProp( node, (const xmlChar *)"<xsl:value-of select="@name"/>" );
176
227
  if( tmp ) {
177
- <xsl:value-of select="@name"/> = strdupx((const char *)tmp);
178
- xmlFree(tmp);
228
+ <xsl:value-of select="@name"/> = fromXmlChar(ctx, (const xmlChar*)tmp);
229
+ xmlFree(tmp);
179
230
  } else {
180
231
  fprintf(stderr,"WARNING: no <xsl:value-of select="@name"/> property in %s element\n", (const char *)node->name );
181
232
  <xsl:value-of select="@name"/> = strdupx("[undefined]");
@@ -6,9 +6,61 @@
6
6
  #include "<xsl:value-of select="/format/@format"/>.h"
7
7
  #include "base64.h"
8
8
  #include &lt;cstring&gt;
9
+ #include &lt;errno.h&gt;
10
+ #include &lt;iconv.h&gt;
9
11
 
10
12
  namespace <xsl:value-of select="/format/@format"/> {
11
13
 
14
+ xmlChar *toXmlChar(const Context *ctx, const char *from_str) {
15
+ if (ctx-&gt;convertEncoding) {
16
+ size_t len = strlen(from_str);
17
+ iconv_t cd = iconv_open("UTF-8", ctx-&gt;swf_encoding);
18
+ if (cd &lt; 0) {
19
+ fprintf(stderr, "iconv_open failed.\n");
20
+ return xmlCharStrdup("");
21
+ }
22
+
23
+ size_t buf_size = (len + 1) * 2;
24
+ char *dst;
25
+ for (;;) {
26
+ dst = new char[buf_size];
27
+ size_t inbytesleft = len;
28
+ size_t outbytesleft = buf_size - 1;
29
+ char *pin = (char*)from_str;
30
+ char *pout = dst;
31
+ bool expandbuf = false;
32
+
33
+ while (inbytesleft &gt; 0) {
34
+ size_t r = iconv(cd, &amp;pin, &amp;inbytesleft, &amp;pout, &amp;outbytesleft);
35
+ if (r == (size_t)-1) {
36
+ if (errno == E2BIG) {
37
+ // buf_size shorten
38
+ expandbuf = true;
39
+ } else {
40
+ //bad input charctor
41
+ fprintf(stderr, "iconv failed: %s\n", from_str);
42
+ }
43
+ break;
44
+ }
45
+ }
46
+ if (expandbuf) {
47
+ delete[] dst;
48
+ iconv(cd, 0, 0, 0, 0);
49
+ buf_size *= 2;
50
+ continue;
51
+ }
52
+ *pout = '\0';
53
+ break;
54
+ }
55
+ iconv_close(cd);
56
+ xmlChar *ret = xmlCharStrdup(dst);
57
+ delete[] dst;
58
+ return ret;
59
+ } else {
60
+ return xmlCharStrdup(from_str);
61
+ }
62
+ }
63
+
12
64
  #define TMP_STRLEN 0xFF
13
65
 
14
66
  <xsl:for-each select="type|tag|action|filter|style|stackitem|namespaceconstant|multinameconstant|trait|opcode">
@@ -72,7 +124,8 @@ void <xsl:value-of select="@name"/>::writeXML( xmlNodePtr xml, Context *ctx ) {
72
124
 
73
125
  <xsl:template match="string" mode="writexml">
74
126
  if( <xsl:value-of select="@name"/> ) {
75
- xmlSetProp( node, (const xmlChar *)"<xsl:value-of select="@name"/>", (const xmlChar *)<xsl:value-of select="@name"/> );
127
+ xmlChar *xmlstr = toXmlChar(ctx, <xsl:value-of select="@name"/>);
128
+ xmlSetProp(node, (const xmlChar *)"<xsl:value-of select="@name"/>", xmlstr);
76
129
  }
77
130
  </xsl:template>
78
131
 
@@ -17,6 +17,7 @@ bool quiet = false;
17
17
  bool verbose = false;
18
18
  bool dump = false;
19
19
  bool nonet = false;
20
+ const char *swf_encoding = "UTF-8";
20
21
  const char *internal_stylesheet = NULL;
21
22
 
22
23
  void usage() {
@@ -43,23 +44,21 @@ void usage() {
43
44
  " <out> is a single SWF file, or (by default) 'stdout'\n"
44
45
  " (for details, see README)\n"
45
46
  "\n"
46
- " xslt <xsl> <in> [<out>"
47
- //" [<param>*]"
48
- "]\n"
47
+ " xslt <xsl> <in> [<out>]\n"
49
48
  " transform <in> to <out> as described by <xsl>.\n"
50
49
  " <xsl> is the XSLT stylesheet,\n"
51
50
  " and can use the swft: extension.\n"
52
51
  " <in> must be some XML (depends on <xsl>)\n"
53
52
  " <out> is either SWF (when it ends in .swf)\n"
54
53
  " or XML, by default on 'stdout'\n"
55
- // " <param>* is a whitespace-separated list of name=value\n"
56
- // " assignments for xsl parameters\n"
57
54
  "\n"
58
55
  "<option>s are:\n"
59
56
  " -h print this help and quit\n"
60
57
  " -v verbose output\n"
61
58
  " -V extra-verbose debugging output\n"
62
59
  " -d dump SWF data when loaded (for debugging)\n"
60
+ " -e specify text encoding in SWF (for SWF 5 and earlier only;\n"
61
+ " default: UTF-8).\n"
63
62
  " -n deactivate libxml network access\n"
64
63
  "\n"
65
64
  "Please report bugs at http://bugs.launchpad.net/swfmill/+filebug\n\n"
@@ -71,7 +70,6 @@ xsltStylesheetPtr xsltParseStylesheetMemory( const char *buffer, int size ) {
71
70
  xmlDocPtr doc = xmlParseMemory( buffer, size );
72
71
  if( !doc ) return NULL;
73
72
  xsltStylesheetPtr ret = xsltParseStylesheetDoc( doc );
74
- // xmlFreeDoc( doc );
75
73
  return ret;
76
74
  }
77
75
 
@@ -83,7 +81,7 @@ int swfmill_swf2xml( int argc, char *argv[] ) {
83
81
 
84
82
  File input;
85
83
  unsigned int filesize, size, xmlsize;
86
- struct stat filestat;
84
+ struct stat filestat;
87
85
  char sig;
88
86
  Context ctx;
89
87
 
@@ -95,7 +93,7 @@ int swfmill_swf2xml( int argc, char *argv[] ) {
95
93
  infile = argv[0];
96
94
  if( argc>1 ) outfile = argv[1];
97
95
 
98
- // open files
96
+ // open files
99
97
  std_in = !strncmp( infile, "stdin", 5 );
100
98
  std_out = !strncmp( outfile, "stdout", 6 );
101
99
  in_fp = std_in ? stdin : fopen( infile, "rb" );
@@ -106,33 +104,37 @@ int swfmill_swf2xml( int argc, char *argv[] ) {
106
104
 
107
105
  if( !quiet ) fprintf(stderr,"Reading from %s\n", infile );
108
106
 
109
- // stat filesize
110
- filesize = (unsigned int)-1;
111
-
112
- if( !std_in ) {
113
- stat( infile, &filestat );
114
- filesize = filestat.st_size;
115
- // fprintf(stderr,"Filesize: %u\n",filesize);
116
- }
117
-
118
- // setup context
107
+ // stat filesize
108
+ filesize = (unsigned int)-1;
109
+ if( !std_in ) {
110
+ stat( infile, &filestat );
111
+ filesize = filestat.st_size;
112
+ }
113
+
114
+ // setup context
119
115
  ctx.debugTrace = verbose;
120
116
  ctx.quiet = quiet;
121
117
 
122
- // treat input as SWF, produce XML
123
- if( (size = input.load( in_fp, &ctx, filesize )) != 0 ) {
124
- if( dump ) input.dump();
125
- out_fp = std_out ? stdout : fopen( outfile, "wb" );
126
- if( !out_fp ) {
127
- fprintf(stderr,"ERROR: could not open file %s for writing\n", outfile );
128
- goto fail;
129
- }
130
- if( !quiet ) fprintf(stderr,"Writing XML to %s\n", outfile );
131
- if( (xmlsize = input.saveXML( out_fp, &ctx )) != 0 ) {
132
- if( !quiet ) fprintf(stderr,"XML saved to %s (%i bytes).\n", outfile, xmlsize );
133
- success = true;
134
- }
118
+ // setup encoding conversion.
119
+ if (strcmp(swf_encoding, "UTF-8")) {
120
+ ctx.convertEncoding = true;
121
+ ctx.swf_encoding = swf_encoding;
122
+ }
123
+
124
+ // treat input as SWF, produce XML
125
+ if( (size = input.load( in_fp, &ctx, filesize )) != 0 ) {
126
+ if( dump ) input.dump();
127
+ out_fp = std_out ? stdout : fopen( outfile, "wb" );
128
+ if( !out_fp ) {
129
+ fprintf(stderr,"ERROR: could not open file %s for writing\n", outfile );
130
+ goto fail;
131
+ }
132
+ if( !quiet ) fprintf(stderr,"Writing XML to %s\n", outfile );
133
+ if( (xmlsize = input.saveXML( out_fp, &ctx )) != 0 ) {
134
+ if( !quiet ) fprintf(stderr,"XML saved to %s (%i bytes).\n", outfile, xmlsize );
135
+ success = true;
135
136
  }
137
+ }
136
138
  fail:
137
139
  if( in_fp && !std_in ) fclose(in_fp);
138
140
  if( out_fp && !std_out ) fclose(out_fp);
@@ -162,7 +164,7 @@ int swfmill_xml2swf( int argc, char *argv[] ) {
162
164
  infile = argv[0];
163
165
  if( argc>1 ) outfile = argv[1];
164
166
 
165
- // open files
167
+ // open files
166
168
  std_in = !strncmp( infile, "stdin", 5 );
167
169
  std_out = !strncmp( outfile, "stdout", 6 );
168
170
  in_fp = std_in ? stdin : fopen( infile, "rb" );
@@ -173,10 +175,16 @@ int swfmill_xml2swf( int argc, char *argv[] ) {
173
175
 
174
176
  if( !quiet ) fprintf(stderr,"Reading from %s\n", infile );
175
177
 
176
- // setup context
178
+ // setup context
177
179
  ctx.debugTrace = verbose;
178
180
  ctx.quiet = quiet;
179
-
181
+
182
+ // setup encoding conversion.
183
+ if (strcmp(swf_encoding, "UTF-8")) {
184
+ ctx.convertEncoding = true;
185
+ ctx.swf_encoding = swf_encoding;
186
+ }
187
+
180
188
  {
181
189
  filename = std_in ? "-" : infile ;
182
190
  doc = xmlParseFile( filename );
@@ -212,7 +220,7 @@ int swfmill_xml2swf( int argc, char *argv[] ) {
212
220
  }
213
221
 
214
222
  // treat input as XML, produce SWF
215
- input.setXML( doc->xmlRootNode, NULL );
223
+ input.setXML( doc->xmlRootNode, &ctx );
216
224
  if( dump ) input.dump();
217
225
  out_fp = std_out ? stdout : fopen( outfile, "wb" );
218
226
  if( !out_fp ) {
@@ -438,6 +446,15 @@ int main( int argc, char *argv[] ) {
438
446
  usage();
439
447
  goto fail;
440
448
  break;
449
+ case 'e':
450
+ ++swallow;
451
+ if (i+swallow < argc) {
452
+ swf_encoding = argv[i+swallow];
453
+ } else {
454
+ usage();
455
+ goto fail;
456
+ }
457
+ break;
441
458
  default:
442
459
  fprintf(stderr,"ERROR: unknown option %c\n",argv[i][j]);
443
460
  usage();
@@ -23,6 +23,62 @@ int getJpegWord( FILE *fp ) {
23
23
  return r;
24
24
  }
25
25
 
26
+ bool getJpegDimensions (FILE *infile, int &image_width, int &image_height) {
27
+ image_width = image_height = 0;
28
+
29
+ if (fgetc(infile) != 0xff || fgetc(infile) != 0xd8) {
30
+ return false;
31
+ }
32
+
33
+ while (!feof(infile)) {
34
+ if (fgetc(infile) != 0xff) {
35
+ return false;
36
+ }
37
+
38
+ int marker;
39
+ do {
40
+ marker = fgetc(infile);
41
+ } while (marker == 0xff);
42
+
43
+ switch (marker) {
44
+ case 0xc0:
45
+ case 0xc1:
46
+ case 0xc2:
47
+ case 0xc3:
48
+ case 0xc5:
49
+ case 0xc6:
50
+ case 0xc7:
51
+ case 0xc9:
52
+ case 0xca:
53
+ case 0xcb:
54
+ case 0xcd:
55
+ case 0xce:
56
+ case 0xcf:
57
+ getJpegWord(infile);
58
+ fgetc(infile);
59
+ image_height = getJpegWord(infile);
60
+ image_width = getJpegWord(infile);
61
+ fgetc(infile);
62
+ return true;
63
+
64
+ case 0xda:
65
+ case 0xd9:
66
+ return false;
67
+
68
+ default:
69
+ int length = getJpegWord(infile);
70
+ if (length < 2) {
71
+ return false;
72
+ } else {
73
+ fseek(infile, length-2, SEEK_CUR);
74
+ }
75
+ break;
76
+ }
77
+ }
78
+
79
+ return false;
80
+ }
81
+
26
82
  void swft_import_jpeg( xmlXPathParserContextPtr ctx, int nargs ) {
27
83
  xsltTransformContextPtr tctx;
28
84
  unsigned char *filename;
@@ -51,7 +107,6 @@ void swft_import_jpeg( xmlXPathParserContextPtr ctx, int nargs ) {
51
107
  bool quiet = true;
52
108
  xmlXPathObjectPtr quietObj = xsltVariableLookup( tctx, (const xmlChar*)"quiet", NULL );
53
109
  if( quietObj && quietObj->stringval ) { quiet = !strcmp("true",(const char*)quietObj->stringval ); };
54
-
55
110
 
56
111
  FILE *fp = fopen( (const char *)filename, "rb" );
57
112
  if( !fp ) {
@@ -67,28 +122,19 @@ void swft_import_jpeg( xmlXPathParserContextPtr ctx, int nargs ) {
67
122
 
68
123
  swft_addFileName( node, (const char *)filename );
69
124
 
70
- // figure width/height
71
- int width=-1, height=-1;
72
- while( !feof( fp ) ) { // could do a && width==-1 here, but that captures preview imgs...
73
- if( fgetc(fp) == 0xff ) {
74
- if( fgetc(fp) == 0xc0 ) {
75
- // StartOfFrame
76
- // skip length and precision (UGLY, eh?)
77
- fgetc(fp); fgetc(fp); fgetc(fp);
78
-
79
- // read height, width
80
- height = getJpegWord( fp );
81
- width = getJpegWord( fp );
82
- }
83
- }
125
+ unsigned char *data = NULL;
126
+ int width, height;
127
+ if (!getJpegDimensions(fp, width, height)) {
128
+ fprintf(stderr, "WARNING: could not extract dimensions for jpeg %s\n", filename);
129
+ goto fail;
84
130
  }
131
+
85
132
  snprintf(tmp,TMP_STRLEN,"%i", width);
86
133
  xmlSetProp( node, (const xmlChar *)"width", (const xmlChar *)&tmp );
87
134
  snprintf(tmp,TMP_STRLEN,"%i", height);
88
135
  xmlSetProp( node, (const xmlChar *)"height", (const xmlChar *)&tmp );
89
136
 
90
137
  // add data
91
- unsigned char *data = NULL;
92
138
  int size, ofs;
93
139
  struct stat filestat;
94
140
  if( stat( (const char *)filename, &filestat ) ) goto fail;