1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
package pt.tumba.parser.swf;
import com.anotherbigidea.flash.SWFConstants;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Reads a SWF input stream and drives the SWFConsumer interface.
*
*@author unknown
*@created 15 de Setembro de 2002
*/
public class SWFReader {
protected SWFTags consumer;
protected InStream in;
protected InputStream inputstream;
protected boolean zipCompressed = false; // flag swf zip compressed
public int size;
/**
* Constructor for the SWFReader object
*
*@param consumer Description of the Parameter
*@param inputstream Description of the Parameter
*/
public SWFReader(SWFTags consumer, InputStream inputstream) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
int aux;
this.size = 0;
try {
while ((aux = inputstream.read()) != -1) {
size++;
out.write((char) aux);
}
} catch (Exception e) {aux=-1;}
this.consumer = consumer;
this.inputstream = new ByteArrayInputStream(out.toByteArray());
this.in = new InStream(this.inputstream);
}
/**
* Constructor for the SWFReader object
*
*@param consumer Description of the Parameter
*@param instream Description of the Parameter
*/
public SWFReader(SWFTags consumer, InStream instream) {
// ByteArrayOutputStream out = new ByteArrayOutputStream();
/*
* int aux;
* this.size = 0;
* while ( (aux=inputstream.read())!=-1 ) {
* size++;
* out.write((char)aux);
* }
*/
this.consumer = consumer;
this.in = instream;
this.size = (int) (this.in.bytesRead);
}
/**
* Drive the consumer by reading a SWF File - including the header and all
* tags. Reading first the file signature (3 byte) and throws IOException if
* no match or file version not supported
*
*@exception IOException Description of the Exception
*/
public void readFile() throws IOException {
readHeader();
readTags();
}
/**
* Drive the consumer by reading SWF tags only
*
*@exception IOException Description of the Exception
*/
public void readTags() throws IOException {
while (readOneTag() != SWFConstants.TAG_END) {
;
}
}
/**
* Drive the consumer by reading one tag
*
*@return the tag type
*@exception IOException Description of the Exception
*/
public int readOneTag() throws IOException {
int header = in.readUI16();
int type = header >> 6;
//only want the top 10 bits
int length = header & 0x3F;
//only want the bottom 6 bits
boolean longTag = (length == 0x3F);
if (longTag) {
length = (int) in.readUI32();
}
byte[] contents = in.read(length);
consumer.tag(type, longTag, contents);
return type;
}
/**
* Read the SWF file header - including the signature.
*/
public void readHeader() throws IOException {
//--Verify File Signature
// magic bytes according to specification http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/swf/pdf/swf-file-format-spec.pdf
// 0x46, 0x57, 0x53 (“FWS”) signature indicates an uncompressed SWF file
// 0x43, 0x57, 0x53 (“CWS”) indicates that the entire file after the first 8 bytes was compressed by using the ZLIB
// 0x5a, 0x57, 0x53 (“ZWS”) indicates that the entire file after the first 8 bytes was compressed by using the LZMA
int magic = in.readUI8();
switch (magic) { // F=uncompressed, C= ZIP-compressed Z=LZMA-compressed
case 'C':
zipCompressed = true;
break;
case 'F':
break;
case 'Z':
throw new IOException("LZMA compressed SWF file not supported"); // lzma compressed not supported yet
default:
throw new IOException("Invalid SWF File Signature");
}
magic = in.readUI8(); // always 'W'
if (magic != 'W') {
throw new IOException("Invalid SWF File Signature");
}
magic = in.readUI8(); // always 'S'
if (magic != 'S') {
throw new IOException("Invalid SWF File Signature");
}
int version = in.readUI8();
long length = in.readUI32();
//may be compressed from this point onwards
if (zipCompressed) {
in.readCompressed();
}
Rect frameSize = new Rect(in);
int frameRate = in.readUI16() >> 8;
int frameCount = in.readUI16();
consumer.header(version, length,
frameSize.getMaxX(), frameSize.getMaxY(),
frameRate, frameCount);
}
/**
* The main program for the SWFReader class
*
*@param args The command line arguments
*@exception IOException Description of the Exception
*/
public static void main(String[] args) throws IOException {
SWFWriter writer = new SWFWriter(System.out);
SWFReader reader = new SWFReader(writer, System.in);
reader.readFile();
System.out.flush();
}
}
|