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();
}
}