package com.intellij.flex.uiDesigner.abc;
import gnu.trove.TIntArrayList;
import org.jetbrains.annotations.TestOnly;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class EntireMovieTranscoder extends MovieTranscoder {
// Sprite ID and FrameCount
private static final int SPRITE_TAG_LENGTH_EXCEPT_CONTROL_TAGS = 4;
// we hope, this id is not used in transcoded swf
private static final int DOCUMENT_SPRITE_ID = 65532;
private short frameCount;
private int swfHeaderEnd;
@SuppressWarnings("UnusedDeclaration")
@TestOnly
public void transcode(File in, File out) throws IOException {
//noinspection IOResourceOpenedButNotSafelyClosed
transcode(new FileInputStream(in), in.length(), out, false);
}
@Override
protected void readFrameSizeFrameRateAndFrameCount(byte b) throws IOException {
decodeRect();
buffer.position(buffer.position() + 2);
frameCount = buffer.getShort();
swfHeaderEnd = buffer.position();
}
@Override
protected void transcode(boolean writeBounds) throws IOException {
if (writeBounds) {
writeMovieBounds();
}
TIntArrayList ignoredBytesPositions = null;
// write movie as 1-frame, frameCount = 1
buffer.putShort(swfHeaderEnd - 2, (short)1);
int initialStartPosition = swfHeaderEnd;
int fileAttributesFullLength;
int tagStart;
int fileLength = buffer.capacity();
analyze:
while ((tagStart = buffer.position()) < buffer.limit()) {
final int tagCodeAndLength = buffer.getShort();
final int type = tagCodeAndLength >> 6;
int length = tagCodeAndLength & 0x3F;
if (length == 63) {
length = buffer.getInt();
}
switch (type) {
case TagTypes.End:
break analyze;
case TagTypes.FileAttributes:
fileAttributesFullLength = length + (buffer.position() - tagStart);
initialStartPosition = tagStart + fileAttributesFullLength;
break;
case TagTypes.Metadata:
case TagTypes.DebugID:
case TagTypes.EnableDebugger:
case TagTypes.EnableDebugger2:
case TagTypes.ScriptLimits:
case TagTypes.ProductInfo:
case TagTypes.ExportAssets:
case TagTypes.SymbolClass:
if (ignoredBytesPositions == null) {
ignoredBytesPositions = new TIntArrayList();
}
ignoredBytesPositions.add(tagStart);
final int fullLength = length + (buffer.position() - tagStart);
ignoredBytesPositions.add(tagStart + fullLength);
fileLength -= fullLength;
break;
}
buffer.position(buffer.position() + length);
}
final int spriteTagLength = (fileLength - initialStartPosition) + SPRITE_TAG_LENGTH_EXCEPT_CONTROL_TAGS;
final byte[] symbolOwnClassAbc = getSymbolOwnClassAbc(frameCount);
fileLength += PARTIAL_HEADER_LENGTH + symbolOwnClassAbc.length + recordHeaderLength(spriteTagLength) +
SPRITE_TAG_LENGTH_EXCEPT_CONTROL_TAGS + SwfUtil.getWrapFooterLength() + SYMBOL_CLASS_TAG_FULL_LENGTH;
writePartialHeader(out, fileLength);
out.write(data, 0, initialStartPosition);
buffer.position(0);
encodeTagHeader(TagTypes.DefineSprite, spriteTagLength);
buffer.putShort((short)DOCUMENT_SPRITE_ID);
buffer.putShort(frameCount);
out.write(data, 0, buffer.position());
if (ignoredBytesPositions == null) {
out.write(data, initialStartPosition, data.length - initialStartPosition);
}
else {
writeSparseBytes(ignoredBytesPositions, initialStartPosition, data.length);
}
out.write(symbolOwnClassAbc);
writeSymbolClass(DOCUMENT_SPRITE_ID);
SwfUtil.footer(out);
}
}