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.
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;