📄 fsmovie.java
字号:
{
if (listener != null)
listener.logEvent(new FSMovieEvent(FSMovieEvent.Encode, FSMovieEvent.Error, 0, 0, "FileNotFoundError"));
}
catch (IOException e)
{
if (listener != null)
listener.logEvent(new FSMovieEvent(FSMovieEvent.Encode, FSMovieEvent.Error, 0, 0, "FileWriteError"));
}
}
/**
* Returns the encoded representation of the array of objects that this Movie contains.
* If an error occurs while encoding the file then an exception is thrown.
*
* @return the array of bytes representing the encoded objects.
* @throws FSCoderException - if an error occurs while encoding the file.
* @throws IOException - if an I/O error occurs while encoding the file.
*/
public byte[] encode() throws IOException
{
FSCoder coder = new FSCoder(FSCoder.LITTLE_ENDIAN, new byte[0]);
coder.context[FSCoder.Action] = FSMovieEvent.Encode;
coder.context[FSCoder.Version] = version;
int fileLength = length(coder);
coder.setData(FSCoder.LITTLE_ENDIAN, new byte[fileLength]);
coder.writeString(signature, "UTF8");
coder.writeWord(version, 1);
coder.writeWord(fileLength, 4);
frameSize.encode(coder);
coder.writeFixedWord(frameRate, 1, 1);
coder.writeWord(numberOfFrames(), 2);
for (Iterator i = objects.iterator(); i.hasNext();)
{
FSMovieObject object = (FSMovieObject)i.next();
int len = object.getLength();
int start = coder.getPointer() + ((object.getExtendLength() || len >= 63) ? 48 : 16);
int next = start + (len << 3);
object.encode(coder);
coder.setPointer(next);
if (coder.context[FSCoder.CodingError] == 1)
{
throw new FSCoderException(
coder.context[FSCoder.TypeInError],
coder.context[FSCoder.StartOfError],
coder.context[FSCoder.ExpectedLength],
coder.context[FSCoder.Delta],
(coder.context[FSCoder.Delta] > 0) ? "ObjectOverflow" : "ObjectUnderflow");
}
}
coder.writeWord(0, 2);
byte[] data = null;
try
{
if (signature.equals("CWS"))
data = zip(coder.getData(), fileLength);
else
data = coder.getData();
}
catch (DataFormatException e)
{
throw new IOException("Error compressing Flash file.");
}
return data;
}
/**
* Returns the encoded representation of the array of objects that this Movie contains.
* If an error occurs while encoding the file then a message is sent to the
* movie listner.
*
* @return the array of bytes representing the encoded objects.
* @param listener an FSMovieListener object where errors messages are
* sent.
*
* @deprecated use the encode() method which throws an exception if an
* error is detected.
*/
public byte[] encode(FSMovieListener listener)
{
FSCoder coder = new FSCoder(FSCoder.LITTLE_ENDIAN, new byte[0]);
coder.context[FSCoder.Action] = FSMovieEvent.Encode;
coder.context[FSCoder.Version] = version;
int fileLength = length(coder);
coder.setData(FSCoder.LITTLE_ENDIAN, new byte[fileLength]);
coder.setListener(listener);
coder.beginObject("FSMovie");
coder.writeString(signature, "UTF8");
coder.writeWord(version, 1);
coder.writeWord(fileLength, 4);
frameSize.encode(coder);
coder.writeFixedWord(frameRate, 8, 8);
coder.writeWord(numberOfFrames(), 2);
coder.beginObject("ArrayList");
for (Iterator i = objects.iterator(); i.hasNext();)
{
FSMovieObject object = (FSMovieObject)i.next();
int len = object.getLength();
int start = coder.getPointer() + ((object.getExtendLength() || len >= 63) ? 48 : 16);
int next = start + (len << 3);
object.encode(coder);
coder.setPointer(next);
int delta = (coder.getPointer() - next) >> 3;
if (delta < 0)
coder.logError("ObjectOverflow", next, -delta);
else if (delta > 0)
coder.logError("ObjectUnderflow", next, delta);
}
coder.endObject("ArrayList");
coder.writeWord(0, 2);
coder.endObject("FSMovie");
byte[] data = null;
try
{
if (signature.equals("CWS"))
data = zip(coder.getData(), fileLength);
else
data = coder.getData();
}
catch (DataFormatException e)
{
coder.logError("DataFormatError", 0, 0);
}
return data;
}
/** Creates a deep copy of the entire movie.
@return a copy of the movie.
*/
public Object clone()
{
FSMovie anObject = null;
try {
anObject = (FSMovie)super.clone();
anObject.frameSize = (frameSize != null) ? (FSBounds)frameSize.clone() : null;
anObject.objects = new ArrayList();
for (Iterator i = objects.iterator(); i.hasNext();)
anObject.objects.add(((FSMovieObject)i.next()).clone());
}
catch (CloneNotSupportedException e)
{
throw new InternalError("Cannot clone movie.");
}
return anObject;
}
/** Returns true if anObject is equal to this one. The comparison is performed on all the objects contained in the movie. Objects are considered equal if they would generate identical binary data when they are encoded to a Flash file.
@return true if this object would be identical to anObject when encoded.
*/
public boolean equals(Object anObject)
{
boolean result = false;
if (super.equals(anObject))
{
FSMovie typedObject = (FSMovie)anObject;
result = version == typedObject.version;
if (frameSize != null)
result = result && frameSize.equals(typedObject.frameSize);
else
result = result && frameSize == typedObject.frameSize;
result = result && frameRate == typedObject.frameRate;
result = result && objects.equals(((FSMovie)anObject).getObjects());
}
return result;
}
/**
* AppendDescription is used to present a string description of the object including
* all nested objects up to a specified depth. This method provide a more controlled
* way of creating a string representation of an object since large objects such as
* font or shape definitions can contain dozens of nested objects.
*
* The representation of the object is appended to the StringBuffer, showing the
* name of the class and values of the attributes it contains. If the object contains
* any attributes that are objects then the object graph will be traversed up to the
* specified depth. If objects are nested at a level less than specified depth then
* the full string representation of the object is displayed. For objects at the
* specified depth only the name of the class is displayed. Any objects below this
* depth are not displayed.
*
* @param buffer a StringBuffer to which the description of each object is appended.
* @param depth the maximum level of nesting up to which objects will be displayed.
*/
public void appendDescription(StringBuffer buffer, int depth)
{
buffer.append("FSMovie");
buffer.append(" : { ");
Transform.append(buffer, "signature", signature);
Transform.append(buffer, "version", version);
Transform.append(buffer, "frameSize", frameSize, depth);
Transform.append(buffer, "frameRate", frameRate);
Transform.append(buffer, "objects", objects, depth);
buffer.append("}");
}
private int length(FSCoder coder)
{
int len = 14; // Includes End
len += frameSize.length(coder);
for (Iterator i = objects.iterator(); i.hasNext();)
{
FSMovieObject object = (FSMovieObject)i.next();
int objectLength = object.length(coder);
len += (object.getExtendLength() || objectLength >= 63) ? objectLength+6 : objectLength+2;
}
return len;
}
private int numberOfFrames()
{
int numberOfFrames = 0;
for (Iterator i = objects.iterator(); i.hasNext();)
{
if (((FSMovieObject)i.next()).getType() == FSMovieObject.ShowFrame)
numberOfFrames += 1;
}
return numberOfFrames;
}
private void isFlash(byte[] bytes) throws DataFormatException
{
if (bytes == null || bytes.length < 8)
throw new DataFormatException("Flash data is null or empty.");
boolean isFlash = (bytes[0] == 0x43 || bytes[0] == 0x46) && bytes[1] == 0x57 && bytes[2] == 0x53;
// if (isFlash && bytes[3] > Transform.VERSION)
// throw new DataFormatException("Cannot decode files later than version " + Transform.VERSION + ".");
if (isFlash == false)
throw new DataFormatException("Data does not start with a valid Flash signature.");
}
private byte[] zip(byte[] bytes, int len) throws DataFormatException
{
byte[] compressedData = null;
Deflater deflater = new Deflater();
byte[] data = new byte[len];
deflater.setInput(bytes, 8, len-8);
deflater.finish();
int bytesCompressed = deflater.deflate(data);
compressedData = new byte[8+bytesCompressed];
int i = 0;
int j = 0;
for (i=0; i<8; i++)
compressedData[i] = bytes[i];
for (j=0; j<bytesCompressed; i++, j++)
compressedData[i] = data[j];
return compressedData;
}
private byte[] unzip(byte[] bytes) throws DataFormatException
{
int movieLength = 0;
for (int i=0; i<4; i++)
movieLength += (bytes[i+4] & 0x000000FF) << (i*8);
byte[] data = new byte[movieLength];
// copy the uncompressed signature, version and length
for (int i=0; i<8; i++)
data[i] = bytes[i];
Inflater inflater = new Inflater();
inflater.setInput(bytes, 8, bytes.length-8);
inflater.inflate(data, 8, movieLength-8);
return data;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -