tag refactoring

This commit is contained in:
honfika@gmail.com
2015-05-15 00:12:35 +02:00
parent 3de39c93bb
commit abec5214bb
72 changed files with 4747 additions and 4957 deletions

View File

@@ -2650,7 +2650,7 @@ public class SWFInputStream implements AutoCloseable {
for (int i = 0; i < lineStyleCount; i++) {
ret.lineStyles[i] = readLINESTYLE(shapeNum, "lineStyle");
}
} else if (shapeNum == 4) {
} else {
ret.lineStyles = new LINESTYLE2[lineStyleCount];
for (int i = 0; i < lineStyleCount; i++) {
ret.lineStyles[i] = readLINESTYLE2(shapeNum, "lineStyle");

View File

@@ -1314,7 +1314,7 @@ public class SWFOutputStream extends OutputStream {
for (int i = 0; i < lineStyleCount; i++) {
writeLINESTYLE(value.lineStyles[i], shapeNum);
}
} else if (shapeNum == 4) {
} else {
lineStyleCount = value.lineStyles.length;
if (lineStyleCount >= 0xff) {
writeUI8(0xff);

View File

@@ -243,7 +243,7 @@ public class SwfXmlImporter {
Map<String, Class> tags = new HashMap<>();
Map<Integer, TagInfo> knownTags = Tag.getKnownClasses();
for (Integer key : knownTags.keySet()) {
Class cls = knownTags.get(key).cls;
Class cls = knownTags.get(key).getCls();
if (!ReflectionTools.canInstantiate(cls)) {
System.err.println("Can't instantiate: " + cls.getName());
}

View File

@@ -34,6 +34,10 @@ import java.io.OutputStream;
*/
public class CSMTextSettingsTag extends Tag implements CharacterIdTag {
public static final int ID = 74;
public static final String NAME = "CSMTextSettings";
@SWFType(BasicType.UI16)
public int textID;
@@ -57,34 +61,6 @@ public class CSMTextSettingsTag extends Tag implements CharacterIdTag {
@SWFType(BasicType.UI8)
public int reserved2;
public static final int ID = 74;
public static final String NAME = "CSMTextSettings";
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(textID);
sos.writeUB(2, useFlashType);
sos.writeUB(3, gridFit);
sos.writeUB(3, reserved);
sos.writeFLOAT(thickness); //F32 = FLOAT
sos.writeFLOAT(sharpness); //F32 = FLOAT
sos.writeUI8(reserved2);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -117,6 +93,30 @@ public class CSMTextSettingsTag extends Tag implements CharacterIdTag {
reserved2 = sis.readUI8("reserved2"); //reserved
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(textID);
sos.writeUB(2, useFlashType);
sos.writeUB(3, gridFit);
sos.writeUB(3, reserved);
sos.writeFLOAT(thickness); //F32 = FLOAT
sos.writeFLOAT(sharpness); //F32 = FLOAT
sos.writeUI8(reserved2);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getCharacterId() {
return textID;

View File

@@ -32,30 +32,12 @@ import java.io.OutputStream;
*/
public class DebugIDTag extends Tag {
@SWFType(value = BasicType.UI8, count = 16)
public byte[] debugId;
public static final int ID = 63;
public static final String NAME = "DebugID";
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.write(debugId);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@SWFType(value = BasicType.UI8, count = 16)
public byte[] debugId;
/**
* Constructor
@@ -83,4 +65,22 @@ public class DebugIDTag extends Tag {
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
debugId = sis.readBytesEx(16, "debugId");
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.write(debugId);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
}

View File

@@ -40,6 +40,10 @@ import java.util.Arrays;
*/
public class DefineBinaryDataTag extends CharacterTag {
public static final int ID = 87;
public static final String NAME = "DefineBinaryData";
@SWFType(BasicType.UI16)
public int tag;
@@ -49,10 +53,6 @@ public class DefineBinaryDataTag extends CharacterTag {
@SWFType(BasicType.UI32)
public long reserved;
public static final int ID = 87;
public static final String NAME = "DefineBinaryData";
@Internal
public SWF innerSwf;

View File

@@ -41,16 +41,16 @@ import java.util.logging.Logger;
*/
public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
public static final int ID = 21;
public static final String NAME = "DefineBitsJPEG2";
@SWFType(BasicType.UI16)
public int characterID;
@SWFType(BasicType.UI8)
public ByteArrayRange imageData;
public static final int ID = 21;
public static final String NAME = "DefineBitsJPEG2";
@Override
public int getCharacterId() {
return characterID;

View File

@@ -42,6 +42,10 @@ import java.util.logging.Logger;
*/
public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
public static final int ID = 35;
public static final String NAME = "DefineBitsJPEG3";
@SWFType(BasicType.UI16)
public int characterID;
@@ -51,10 +55,6 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
@SWFType(BasicType.UI8)
public byte[] bitmapAlphaData;
public static final int ID = 35;
public static final String NAME = "DefineBitsJPEG3";
@Override
public int getCharacterId() {
return characterID;

View File

@@ -42,6 +42,10 @@ import java.util.logging.Logger;
*/
public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
public static final int ID = 90;
public static final String NAME = "DefineBitsJPEG4";
@SWFType(BasicType.UI16)
public int characterID;
@@ -54,10 +58,6 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
@SWFType(BasicType.UI8)
public ByteArrayRange bitmapAlphaData;
public static final int ID = 90;
public static final String NAME = "DefineBitsJPEG4";
@Override
public int getCharacterId() {
return characterID;

View File

@@ -48,6 +48,10 @@ import java.util.zip.InflaterInputStream;
*/
public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
public static final int ID = 36;
public static final String NAME = "DefineBitsLossless2";
@SWFType(BasicType.UI16)
public int characterID;
@@ -79,10 +83,6 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
@Internal
private boolean decompressed = false;
public static final int ID = 36;
public static final String NAME = "DefineBitsLossless2";
@Override
public int getCharacterId() {
return characterID;

View File

@@ -48,6 +48,10 @@ import java.util.zip.InflaterInputStream;
*/
public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
public static final int ID = 20;
public static final String NAME = "DefineBitsLossless";
@SWFType(BasicType.UI16)
public int characterID;
@@ -81,10 +85,6 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
@Internal
private boolean decompressed = false;
public static final int ID = 20;
public static final String NAME = "DefineBitsLossless";
private byte[] createEmptyImage() {
try {
BITMAPDATA bitmapData = new BITMAPDATA();

View File

@@ -39,16 +39,16 @@ import java.util.logging.Logger;
*/
public class DefineBitsTag extends ImageTag implements TagChangedListener {
public static final int ID = 6;
public static final String NAME = "DefineBits";
@SWFType(BasicType.UI16)
public int characterID;
@SWFType(BasicType.UI8)
public ByteArrayRange jpegData;
public static final int ID = 6;
public static final String NAME = "DefineBits";
@Override
public void setImage(byte[] data) {
throw new UnsupportedOperationException("Set image is not supported for DefineBits");

View File

@@ -53,6 +53,10 @@ import java.util.Set;
*/
public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
public static final int ID = 34;
public static final String NAME = "DefineButton2";
/**
* ID for this character
*/
@@ -78,10 +82,6 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
*/
public List<BUTTONCONDACTION> actions = new ArrayList<>();
public static final int ID = 34;
public static final String NAME = "DefineButton2";
private Timeline timeline;
private boolean isSingleFrameInitialized;

View File

@@ -34,15 +34,15 @@ import java.io.OutputStream;
*/
public class DefineButtonCxformTag extends Tag implements CharacterIdTag {
public static final int ID = 23;
public static final String NAME = "DefineButtonCxform";
@SWFType(BasicType.UI16)
public int buttonId;
public CXFORM buttonColorTransform;
public static final int ID = 23;
public static final String NAME = "DefineButtonCxform";
/**
* Gets data bytes
*

View File

@@ -34,6 +34,10 @@ import java.io.OutputStream;
*/
public class DefineButtonSoundTag extends Tag implements CharacterIdTag {
public static final int ID = 17;
public static final String NAME = "DefineButtonSound";
@SWFType(BasicType.UI16)
public int buttonId;
@@ -57,10 +61,6 @@ public class DefineButtonSoundTag extends Tag implements CharacterIdTag {
public SOUNDINFO buttonSoundInfo3;
public static final int ID = 17;
public static final String NAME = "DefineButtonSound";
@Override
public int getCharacterId() {
return buttonId;

View File

@@ -61,6 +61,10 @@ import java.util.logging.Logger;
*/
public class DefineButtonTag extends ButtonTag implements ASMSource {
public static final int ID = 7;
public static final String NAME = "DefineButton";
/**
* ID for this character
*/
@@ -79,10 +83,6 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
@HideInRawEdit
public ByteArrayRange actionBytes;
public static final int ID = 7;
public static final String NAME = "DefineButton";
@Override
public int getCharacterId() {
return buttonId;

View File

@@ -83,6 +83,10 @@ import org.xml.sax.helpers.DefaultHandler;
*/
public class DefineEditTextTag extends TextTag {
public static final int ID = 37;
public static final String NAME = "DefineEditText";
@SWFType(BasicType.UI16)
public int characterID;
@@ -163,10 +167,6 @@ public class DefineEditTextTag extends TextTag {
@Conditional("hasText")
public String initialText;
public static final int ID = 37;
public static final String NAME = "DefineEditText";
@Override
public RECT getBounds() {
return bounds;

View File

@@ -43,6 +43,10 @@ import java.util.List;
*/
public class DefineFont2Tag extends FontTag {
public static final int ID = 48;
public static final String NAME = "DefineFont2";
@SWFType(BasicType.UI16)
public int fontId;
@@ -93,10 +97,6 @@ public class DefineFont2Tag extends FontTag {
@Conditional("fontFlagsHasLayout")
public List<KERNINGRECORD> fontKerningTable;
public static final int ID = 48;
public static final String NAME = "DefineFont2";
@Override
public boolean isSmall() {
return fontFlagsSmallText;

View File

@@ -47,6 +47,10 @@ import java.util.List;
*/
public class DefineFont3Tag extends FontTag {
public static final int ID = 75;
public static final String NAME = "DefineFont3";
@SWFType(BasicType.UI16)
public int fontId;
@@ -97,10 +101,6 @@ public class DefineFont3Tag extends FontTag {
@Conditional("fontFlagsHasLayout")
public List<KERNINGRECORD> fontKerningTable;
public static final int ID = 75;
public static final String NAME = "DefineFont3";
@Override
public boolean isSmall() {
return fontFlagsSmallText;

View File

@@ -34,6 +34,10 @@ import java.io.OutputStream;
*/
public class DefineFont4Tag extends CharacterTag {
public static final int ID = 91;
public static final String NAME = "DefineFont4";
@SWFType(BasicType.UI16)
public int fontID;
@@ -51,10 +55,6 @@ public class DefineFont4Tag extends CharacterTag {
public byte[] fontData;
public static final int ID = 91;
public static final String NAME = "DefineFont4";
@Override
public int getCharacterId() {
return fontID;

View File

@@ -38,6 +38,10 @@ import java.util.List;
*/
public class DefineFontAlignZonesTag extends Tag implements CharacterIdTag {
public static final int ID = 73;
public static final String NAME = "DefineFontAlignZones";
@SWFType(BasicType.UI16)
public int fontID;
@@ -51,10 +55,6 @@ public class DefineFontAlignZonesTag extends Tag implements CharacterIdTag {
@SWFArray(value = "zone", countField = "glyphCount")
public List<ZONERECORD> zoneTable;
public static final int ID = 73;
public static final String NAME = "DefineFontAlignZones";
/**
* Constructor
*

View File

@@ -38,6 +38,10 @@ import java.util.List;
*/
public class DefineFontInfo2Tag extends Tag implements CharacterIdTag {
public static final int ID = 62;
public static final String NAME = "DefineFontInfo2";
@SWFType(BasicType.UI16)
public int fontID;
@@ -64,10 +68,6 @@ public class DefineFontInfo2Tag extends Tag implements CharacterIdTag {
@SWFType(BasicType.UI16)
public List<Integer> codeTable;
public static final int ID = 62;
public static final String NAME = "DefineFontInfo2";
/**
* Gets data bytes
*

View File

@@ -37,6 +37,10 @@ import java.util.List;
*/
public class DefineFontInfoTag extends Tag implements CharacterIdTag {
public static final int ID = 13;
public static final String NAME = "DefineFontInfo";
@SWFType(BasicType.UI16)
public int fontId;
@@ -61,10 +65,6 @@ public class DefineFontInfoTag extends Tag implements CharacterIdTag {
@SWFType(value = BasicType.UI8, alternateValue = BasicType.UI16, alternateCondition = "fontFlagsWideCodes")
public List<Integer> codeTable;
public static final int ID = 13;
public static final String NAME = "DefineFontInfo";
/**
* Gets data bytes
*

View File

@@ -33,6 +33,10 @@ import java.io.OutputStream;
*/
public class DefineFontNameTag extends Tag implements CharacterIdTag {
public static final int ID = 88;
public static final String NAME = "DefineFontName";
@SWFType(BasicType.UI16)
public int fontId;
@@ -40,10 +44,6 @@ public class DefineFontNameTag extends Tag implements CharacterIdTag {
public String fontCopyright;
public static final int ID = 88;
public static final String NAME = "DefineFontName";
/**
* Constructor
*

View File

@@ -39,6 +39,10 @@ import java.util.List;
*/
public class DefineFontTag extends FontTag {
public static final int ID = 10;
public static final String NAME = "DefineFont";
@SWFType(BasicType.UI16)
public int fontId;
@@ -50,10 +54,6 @@ public class DefineFontTag extends FontTag {
@Internal
private DefineFontInfo2Tag fontInfo2Tag = null;
public static final int ID = 10;
public static final String NAME = "DefineFont";
@Override
public boolean isSmall() {
return false;

View File

@@ -40,6 +40,10 @@ import java.io.OutputStream;
*/
public class DefineMorphShape2Tag extends MorphShapeTag {
public static final int ID = 84;
public static final String NAME = "DefineMorphShape2";
public RECT startEdgeBounds;
public RECT endEdgeBounds;
@@ -52,10 +56,6 @@ public class DefineMorphShape2Tag extends MorphShapeTag {
public boolean usesScalingStrokes;
public static final int ID = 84;
public static final String NAME = "DefineMorphShape2";
/**
* Gets data bytes
*

View File

@@ -34,15 +34,15 @@ import java.io.OutputStream;
*/
public class DefineScalingGridTag extends Tag implements CharacterIdTag {
public static final int ID = 78;
public static final String NAME = "DefineScalingGrid";
@SWFType(BasicType.UI16)
public int characterId;
public RECT splitter;
public static final int ID = 78;
public static final String NAME = "DefineScalingGrid";
/**
* Constructor
*

View File

@@ -33,6 +33,10 @@ import java.io.OutputStream;
*/
public class DefineSceneAndFrameLabelDataTag extends Tag {
public static final int ID = 86;
public static final String NAME = "DefineSceneAndFrameLabelData";
@SWFType(value = BasicType.EncodedU32)
@SWFArray(value = "offset", countField = "sceneCount")
public long[] sceneOffsets;
@@ -47,10 +51,6 @@ public class DefineSceneAndFrameLabelDataTag extends Tag {
@SWFArray(countField = "frameLabelCount")
public String[] frameNames;
public static final int ID = 86;
public static final String NAME = "DefineSceneAndFrameLabelData";
/**
* Gets data bytes
*

View File

@@ -19,16 +19,12 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
import com.jpexs.helpers.ByteArrayRange;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
@@ -40,57 +36,6 @@ public class DefineShape2Tag extends ShapeTag {
public static final String NAME = "DefineShape2";
private ByteArrayRange shapeData;
@Override
public int getShapeNum() {
return 2;
}
@Override
public SHAPEWITHSTYLE getShapes() {
if (shapes == null && shapeData != null) {
try {
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
sis.seek(shapeData.getPos());
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
shapeData = null; // not needed anymore, give it to GC
} catch (IOException ex) {
Logger.getLogger(DefineShape2Tag.class.getName()).log(Level.SEVERE, null, ex);
}
}
return shapes;
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
getShapes().getNeededCharacters(needed);
}
@Override
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
if (modified) {
setModified(true);
}
return modified;
}
@Override
public boolean removeCharacter(int characterId) {
boolean modified = getShapes().removeCharacter(characterId);
if (modified) {
setModified(true);
}
return modified;
}
@Override
public RECT getRect(Set<BoundedTag> added) {
return shapeBounds;
}
/**
* Constructor
*
@@ -139,22 +84,7 @@ public class DefineShape2Tag extends ShapeTag {
}
@Override
public int getNumFrames() {
return 1;
}
@Override
public boolean isSingleFrame() {
return true;
}
@Override
public int getCharacterId() {
return shapeId;
}
@Override
public void setCharacterId(int characterId) {
this.shapeId = characterId;
public int getShapeNum() {
return 2;
}
}

View File

@@ -19,17 +19,12 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
import com.jpexs.helpers.ByteArrayRange;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
@@ -41,57 +36,6 @@ public class DefineShape3Tag extends ShapeTag {
public static final String NAME = "DefineShape3";
private ByteArrayRange shapeData;
@Override
public int getShapeNum() {
return 3;
}
@Override
public SHAPEWITHSTYLE getShapes() {
if (shapes == null && shapeData != null) {
try {
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
sis.seek(shapeData.getPos());
shapes = sis.readSHAPEWITHSTYLE(3, false, "shapes");
shapeData = null; // not needed anymore, give it to GC
} catch (IOException ex) {
Logger.getLogger(DefineShape3Tag.class.getName()).log(Level.SEVERE, null, ex);
}
}
return shapes;
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
getShapes().getNeededCharacters(needed);
}
@Override
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
if (modified) {
setModified(true);
}
return modified;
}
@Override
public boolean removeCharacter(int characterId) {
boolean modified = getShapes().removeCharacter(characterId);
if (modified) {
setModified(true);
}
return modified;
}
@Override
public RECT getRect(Set<BoundedTag> added) {
return shapeBounds;
}
/**
* Constructor
*
@@ -114,7 +58,7 @@ public class DefineShape3Tag extends ShapeTag {
shapeId = sis.readUI16("shapeId");
shapeBounds = sis.readRECT("shapeBounds");
if (!lazy) {
shapes = sis.readSHAPEWITHSTYLE(3, false, "shapes");
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
} else {
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
}
@@ -128,12 +72,11 @@ public class DefineShape3Tag extends ShapeTag {
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
SWFOutputStream sos = new SWFOutputStream(baos, getVersion());
try {
sos.writeUI16(shapeId);
sos.writeRECT(shapeBounds);
sos.writeSHAPEWITHSTYLE(getShapes(), 3);
sos.writeSHAPEWITHSTYLE(getShapes(), getShapeNum());
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
@@ -141,22 +84,7 @@ public class DefineShape3Tag extends ShapeTag {
}
@Override
public int getNumFrames() {
return 1;
}
@Override
public boolean isSingleFrame() {
return true;
}
@Override
public int getCharacterId() {
return shapeId;
}
@Override
public void setCharacterId(int characterId) {
this.shapeId = characterId;
public int getShapeNum() {
return 3;
}
}

View File

@@ -19,7 +19,6 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.RECT;
@@ -29,10 +28,6 @@ import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
@@ -40,6 +35,10 @@ import java.util.logging.Logger;
*/
public class DefineShape4Tag extends ShapeTag {
public static final int ID = 83;
public static final String NAME = "DefineShape4";
public RECT edgeBounds;
@Reserved
@@ -52,61 +51,6 @@ public class DefineShape4Tag extends ShapeTag {
public boolean usesScalingStrokes;
public static final int ID = 83;
public static final String NAME = "DefineShape4";
private ByteArrayRange shapeData;
@Override
public int getShapeNum() {
return 4;
}
@Override
public SHAPEWITHSTYLE getShapes() {
if (shapes == null && shapeData != null) {
try {
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
sis.seek(shapeData.getPos());
shapes = sis.readSHAPEWITHSTYLE(4, false, "shapes");
shapeData = null; // not needed anymore, give it to GC
} catch (IOException ex) {
Logger.getLogger(DefineShape4Tag.class.getName()).log(Level.SEVERE, null, ex);
}
}
return shapes;
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
getShapes().getNeededCharacters(needed);
}
@Override
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
if (modified) {
setModified(true);
}
return modified;
}
@Override
public boolean removeCharacter(int characterId) {
boolean modified = getShapes().removeCharacter(characterId);
if (modified) {
setModified(true);
}
return modified;
}
@Override
public RECT getRect(Set<BoundedTag> added) {
return shapeBounds;
}
/**
* Constructor
*
@@ -135,7 +79,7 @@ public class DefineShape4Tag extends ShapeTag {
usesNonScalingStrokes = sis.readUB(1, "usesNonScalingStrokes") == 1;
usesScalingStrokes = sis.readUB(1, "usesScalingStrokes") == 1;
if (!lazy) {
shapes = sis.readSHAPEWITHSTYLE(4, false, "shapes");
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
} else {
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
}
@@ -149,8 +93,7 @@ public class DefineShape4Tag extends ShapeTag {
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
SWFOutputStream sos = new SWFOutputStream(baos, getVersion());
try {
sos.writeUI16(shapeId);
sos.writeRECT(shapeBounds);
@@ -159,7 +102,7 @@ public class DefineShape4Tag extends ShapeTag {
sos.writeUB(1, usesFillWindingRule ? 1 : 0);
sos.writeUB(1, usesNonScalingStrokes ? 1 : 0);
sos.writeUB(1, usesScalingStrokes ? 1 : 0);
sos.writeSHAPEWITHSTYLE(getShapes(), 4);
sos.writeSHAPEWITHSTYLE(getShapes(), getShapeNum());
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
@@ -167,22 +110,7 @@ public class DefineShape4Tag extends ShapeTag {
}
@Override
public int getNumFrames() {
return 1;
}
@Override
public boolean isSingleFrame() {
return true;
}
@Override
public int getCharacterId() {
return shapeId;
}
@Override
public void setCharacterId(int characterId) {
this.shapeId = characterId;
public int getShapeNum() {
return 4;
}
}

View File

@@ -19,16 +19,12 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
import com.jpexs.helpers.ByteArrayRange;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
@@ -40,57 +36,6 @@ public class DefineShapeTag extends ShapeTag {
public static final String NAME = "DefineShape";
private ByteArrayRange shapeData;
@Override
public int getShapeNum() {
return 1;
}
@Override
public SHAPEWITHSTYLE getShapes() {
if (shapes == null && shapeData != null) {
try {
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
sis.seek(shapeData.getPos());
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
shapeData = null; // not needed anymore, give it to GC
} catch (IOException ex) {
Logger.getLogger(DefineShapeTag.class.getName()).log(Level.SEVERE, null, ex);
}
}
return shapes;
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
getShapes().getNeededCharacters(needed);
}
@Override
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
if (modified) {
setModified(true);
}
return modified;
}
@Override
public boolean removeCharacter(int characterId) {
boolean modified = getShapes().removeCharacter(characterId);
if (modified) {
setModified(true);
}
return modified;
}
@Override
public RECT getRect(Set<BoundedTag> added) {
return shapeBounds;
}
/**
* Constructor
*
@@ -139,22 +84,7 @@ public class DefineShapeTag extends ShapeTag {
}
@Override
public int getNumFrames() {
public int getShapeNum() {
return 1;
}
@Override
public boolean isSingleFrame() {
return true;
}
@Override
public int getCharacterId() {
return shapeId;
}
@Override
public void setCharacterId(int characterId) {
this.shapeId = characterId;
}
}

View File

@@ -47,6 +47,10 @@ import javax.sound.sampled.UnsupportedAudioFileException;
*/
public class DefineSoundTag extends CharacterTag implements SoundTag {
public static final int ID = 14;
public static final String NAME = "DefineSound";
@SWFType(BasicType.UI16)
public int soundId;
@@ -65,10 +69,6 @@ public class DefineSoundTag extends CharacterTag implements SoundTag {
public ByteArrayRange soundData;
public static final int ID = 14;
public static final String NAME = "DefineSound";
@Override
public int getCharacterId() {
return soundId;

View File

@@ -58,6 +58,10 @@ import java.util.Set;
*/
public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timelined {
public static final int ID = 39;
public static final String NAME = "DefineSprite";
/**
* Character ID of sprite
*/
@@ -77,10 +81,6 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
public boolean hasEndTag;
public static final int ID = 39;
public static final String NAME = "DefineSprite";
private Timeline timeline;
private boolean isSingleFrameInitialized;

View File

@@ -37,6 +37,10 @@ import java.util.Set;
*/
public class DefineVideoStreamTag extends CharacterTag implements BoundedTag {
public static final int ID = 60;
public static final String NAME = "DefineVideoStream";
@SWFType(BasicType.UI16)
public int characterID;
@@ -69,45 +73,6 @@ public class DefineVideoStreamTag extends CharacterTag implements BoundedTag {
public static final int CODEC_VP6_ALPHA = 5;
public static final int ID = 60;
public static final String NAME = "DefineVideoStream";
@Override
public int getCharacterId() {
return characterID;
}
@Override
public void setCharacterId(int characterId) {
this.characterID = characterId;
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(characterID);
sos.writeUI16(numFrames);
sos.writeUI16(width);
sos.writeUI16(height);
sos.writeUB(4, reserved);
sos.writeUB(3, videoFlagsDeblocking);
sos.writeUB(1, videoFlagsSmoothing ? 1 : 0);
sos.writeUI8(codecID);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -142,6 +107,41 @@ public class DefineVideoStreamTag extends CharacterTag implements BoundedTag {
codecID = sis.readUI8("codecID");
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(characterID);
sos.writeUI16(numFrames);
sos.writeUI16(width);
sos.writeUI16(height);
sos.writeUB(4, reserved);
sos.writeUB(3, videoFlagsDeblocking);
sos.writeUB(1, videoFlagsSmoothing ? 1 : 0);
sos.writeUI8(codecID);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getCharacterId() {
return characterID;
}
@Override
public void setCharacterId(int characterId) {
this.characterID = characterId;
}
@Override
public RECT getRect() {
return getRect(null); // parameter not used

View File

@@ -41,6 +41,10 @@ import java.io.OutputStream;
*/
public class DoABCDefineTag extends Tag implements ABCContainerTag {
public static final int ID = 82;
public static final String NAME = "DoABCDefine";
/**
* ActionScript 3 bytecodes
*/
@@ -62,20 +66,6 @@ public class DoABCDefineTag extends Tag implements ABCContainerTag {
*/
public String name;
public static final int ID = 82;
public static final String NAME = "DoABCDefine";
@Override
public ABC getABC() {
return abc;
}
@Override
public String getName() {
return super.getName() + " (" + name + ")";
}
/**
* Constructor
*
@@ -134,6 +124,16 @@ public class DoABCDefineTag extends Tag implements ABCContainerTag {
}
}
@Override
public ABC getABC() {
return abc;
}
@Override
public String getName() {
return super.getName() + " (" + name + ")";
}
@Override
public int compareTo(ABCContainerTag o) {
if (o instanceof DoABCDefineTag) {

View File

@@ -39,6 +39,10 @@ import java.io.OutputStream;
*/
public class DoABCTag extends Tag implements ABCContainerTag {
public static final int ID = 72;
public static final String NAME = "DoABC";
/**
* ActionScript 3 bytecodes
*/
@@ -46,15 +50,6 @@ public class DoABCTag extends Tag implements ABCContainerTag {
@SWFField
private ABC abc;
public static final int ID = 72;
public static final String NAME = "DoABC";
@Override
public ABC getABC() {
return abc;
}
/**
* Constructor
*
@@ -107,6 +102,11 @@ public class DoABCTag extends Tag implements ABCContainerTag {
}
}
@Override
public ABC getABC() {
return abc;
}
@Override
public int compareTo(ABCContainerTag o) {
return 0;

View File

@@ -42,6 +42,10 @@ import java.util.logging.Logger;
*/
public class DoActionTag extends Tag implements ASMSource {
public static final int ID = 12;
public static final String NAME = "DoAction";
/**
* List of actions to perform
*/
@@ -49,10 +53,6 @@ public class DoActionTag extends Tag implements ASMSource {
@HideInRawEdit
public ByteArrayRange actionBytes;
public static final int ID = 12;
public static final String NAME = "DoAction";
/**
* Constructor
*
@@ -62,6 +62,17 @@ public class DoActionTag extends Tag implements ASMSource {
super(swf, ID, NAME, null);
}
/**
* Constructor
*
* @param swf
* @param data
*/
public DoActionTag(SWF swf, ByteArrayRange data) {
super(swf, ID, NAME, data);
actionBytes = ByteArrayRange.EMPTY;
}
/**
* Constructor
*
@@ -79,17 +90,6 @@ public class DoActionTag extends Tag implements ASMSource {
actionBytes = sis.readByteRangeEx(sis.available(), "actionBytes");
}
/**
* Constructor
*
* @param swf
* @param data
*/
public DoActionTag(SWF swf, ByteArrayRange data) {
super(swf, ID, NAME, data);
actionBytes = ByteArrayRange.EMPTY;
}
/**
* Gets data bytes
*

View File

@@ -45,6 +45,10 @@ import java.util.logging.Logger;
*/
public class DoInitActionTag extends Tag implements CharacterIdTag, ASMSource {
public static final int ID = 59;
public static final String NAME = "DoInitAction";
/**
* Identifier of Sprite
*/
@@ -58,10 +62,6 @@ public class DoInitActionTag extends Tag implements CharacterIdTag, ASMSource {
@HideInRawEdit
public ByteArrayRange actionBytes;
public static final int ID = 59;
public static final String NAME = "DoInitAction";
/**
* Constructor
*

View File

@@ -34,6 +34,10 @@ import java.io.OutputStream;
*/
public class EnableDebugger2Tag extends Tag {
public static final int ID = 64;
public static final String NAME = "EnableDebugger2";
@Reserved
@SWFType(BasicType.UI16)
public int reserved;
@@ -43,30 +47,6 @@ public class EnableDebugger2Tag extends Tag {
*/
public String passwordHash;
public static final int ID = 64;
public static final String NAME = "EnableDebugger2";
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(reserved);
sos.writeString(passwordHash);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -94,4 +74,24 @@ public class EnableDebugger2Tag extends Tag {
reserved = sis.readUI16("reserved");
passwordHash = sis.readString("passwordHash");
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(reserved);
sos.writeString(passwordHash);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
}

View File

@@ -31,34 +31,14 @@ import java.io.OutputStream;
*/
public class EnableDebuggerTag extends Tag {
/**
* MD5 hash of password
*/
public String passwordHash;
public static final int ID = 58;
public static final String NAME = "EnableDebugger";
/**
* Gets data bytes
*
* @return Bytes of data
* MD5 hash of password
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
if (passwordHash != null) {
sos.writeString(passwordHash);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
public String passwordHash;
/**
* Constructor
@@ -86,4 +66,24 @@ public class EnableDebuggerTag extends Tag {
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
passwordHash = sis.readString("passwordHash");
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
if (passwordHash != null) {
sos.writeString(passwordHash);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
}

View File

@@ -47,27 +47,6 @@ public class EnableTelemetryTag extends Tag {
@SWFType(value = BasicType.UI8, count = 32)
public byte[] passwordHash;
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUB(16, reserved);
if (passwordHash != null) {
sos.write(passwordHash);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -97,4 +76,25 @@ public class EnableTelemetryTag extends Tag {
passwordHash = sis.readBytesEx(32, "passwordHash");
}
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUB(16, reserved);
if (passwordHash != null) {
sos.write(passwordHash);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
}

View File

@@ -28,16 +28,6 @@ import java.io.IOException;
*/
public class EndTag extends Tag {
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
return new byte[0];
}
public static final int ID = 0;
public static final String NAME = "End";
@@ -66,4 +56,14 @@ public class EndTag extends Tag {
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
return new byte[0];
}
}

View File

@@ -37,6 +37,10 @@ import java.util.List;
*/
public class ExportAssetsTag extends SymbolClassTypeTag {
public static final int ID = 56;
public static final String NAME = "ExportAssets";
/**
* HashMap with assets
*/
@@ -47,10 +51,6 @@ public class ExportAssetsTag extends SymbolClassTypeTag {
@SWFArray(value = "name", countField = "count")
public List<String> names;
public static final int ID = 56;
public static final String NAME = "ExportAssets";
/**
* Constructor
*

View File

@@ -29,6 +29,10 @@ import java.io.OutputStream;
public class FileAttributesTag extends Tag {
public static final int ID = 69;
public static final String NAME = "FileAttributes";
public boolean useDirectBlit;
public boolean useGPU;
@@ -51,10 +55,6 @@ public class FileAttributesTag extends Tag {
@Reserved
public int reserved3;
public static final int ID = 69;
public static final String NAME = "FileAttributes";
/**
* Constructor
*

View File

@@ -26,21 +26,13 @@ import java.io.OutputStream;
public class FrameLabelTag extends Tag {
public String name;
public boolean namedAnchor = false;
public static final int ID = 43;
public static final String NAME = "FrameLabel";
public String getLabelName() {
return name;
}
public String name;
public boolean isNamedAnchor() {
return namedAnchor;
}
public boolean namedAnchor = false;
/**
* Constructor
@@ -87,4 +79,12 @@ public class FrameLabelTag extends Tag {
}
return baos.toByteArray();
}
public String getLabelName() {
return name;
}
public boolean isNamedAnchor() {
return namedAnchor;
}
}

View File

@@ -40,6 +40,10 @@ import java.util.Map;
*/
public class ImportAssets2Tag extends Tag implements ImportTag {
public static final int ID = 71;
public static final String NAME = "ImportAssets2";
public String url;
@Reserved
@@ -60,10 +64,6 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
@SWFArray(value = "name", countField = "count")
public List<String> names;
public static final int ID = 71;
public static final String NAME = "ImportAssets2";
/**
* Constructor
*

View File

@@ -39,6 +39,10 @@ import java.util.Map;
*/
public class ImportAssetsTag extends Tag implements ImportTag {
public static final int ID = 57;
public static final String NAME = "ImportAssets";
public String url;
/**
@@ -51,10 +55,6 @@ public class ImportAssetsTag extends Tag implements ImportTag {
@SWFArray(value = "name", countField = "count")
public List<String> names;
public static final int ID = 57;
public static final String NAME = "ImportAssets";
/**
* Constructor
*

View File

@@ -27,13 +27,13 @@ import java.io.OutputStream;
public class MetadataTag extends Tag {
@Multiline
public String xmlMetadata;
public static final int ID = 77;
public static final String NAME = "Metadata";
@Multiline
public String xmlMetadata;
/**
* Constructor
*

View File

@@ -50,6 +50,10 @@ import java.util.Set;
*/
public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceContainer {
public static final int ID = 26;
public static final String NAME = "PlaceObject2";
/**
* @since SWF 5 Has clip actions (sprite characters only)
*/
@@ -141,74 +145,6 @@ public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceCont
@HideInRawEdit //TODO: make editable
public CLIPACTIONS clipActions;
public static final int ID = 26;
public static final String NAME = "PlaceObject2";
@Override
public int getClipDepth() {
if (placeFlagHasClipDepth) {
return clipDepth;
}
return -1;
}
@Override
public List<FILTER> getFilters() {
return null;
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
if (Configuration.debugCopy.get()) {
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
}
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUB(1, placeFlagHasClipActions ? 1 : 0);
sos.writeUB(1, placeFlagHasClipDepth ? 1 : 0);
sos.writeUB(1, placeFlagHasName ? 1 : 0);
sos.writeUB(1, placeFlagHasRatio ? 1 : 0);
sos.writeUB(1, placeFlagHasColorTransform ? 1 : 0);
sos.writeUB(1, placeFlagHasMatrix ? 1 : 0);
sos.writeUB(1, placeFlagHasCharacter ? 1 : 0);
sos.writeUB(1, placeFlagMove ? 1 : 0);
sos.writeUI16(depth);
if (placeFlagHasCharacter) {
sos.writeUI16(characterId);
}
if (placeFlagHasMatrix) {
sos.writeMatrix(matrix);
}
if (placeFlagHasColorTransform) {
sos.writeCXFORMWITHALPHA(colorTransform);
}
if (placeFlagHasRatio) {
sos.writeUI16(ratio);
}
if (placeFlagHasName) {
sos.writeString(name);
}
if (placeFlagHasClipDepth) {
sos.writeUI16(clipDepth);
}
if (placeFlagHasClipActions) {
sos.writeCLIPACTIONS(clipActions);
}
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -285,6 +221,70 @@ public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceCont
}
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
if (Configuration.debugCopy.get()) {
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
}
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUB(1, placeFlagHasClipActions ? 1 : 0);
sos.writeUB(1, placeFlagHasClipDepth ? 1 : 0);
sos.writeUB(1, placeFlagHasName ? 1 : 0);
sos.writeUB(1, placeFlagHasRatio ? 1 : 0);
sos.writeUB(1, placeFlagHasColorTransform ? 1 : 0);
sos.writeUB(1, placeFlagHasMatrix ? 1 : 0);
sos.writeUB(1, placeFlagHasCharacter ? 1 : 0);
sos.writeUB(1, placeFlagMove ? 1 : 0);
sos.writeUI16(depth);
if (placeFlagHasCharacter) {
sos.writeUI16(characterId);
}
if (placeFlagHasMatrix) {
sos.writeMatrix(matrix);
}
if (placeFlagHasColorTransform) {
sos.writeCXFORMWITHALPHA(colorTransform);
}
if (placeFlagHasRatio) {
sos.writeUI16(ratio);
}
if (placeFlagHasName) {
sos.writeString(name);
}
if (placeFlagHasClipDepth) {
sos.writeUI16(clipDepth);
}
if (placeFlagHasClipActions) {
sos.writeCLIPACTIONS(clipActions);
}
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getClipDepth() {
if (placeFlagHasClipDepth) {
return clipDepth;
}
return -1;
}
@Override
public List<FILTER> getFilters() {
return null;
}
/**
* Returns all sub-items
*

View File

@@ -53,6 +53,10 @@ import java.util.Set;
*/
public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceContainer {
public static final int ID = 70;
public static final String NAME = "PlaceObject3";
/**
* @since SWF 5 has clip actions (sprite characters only)
*/
@@ -229,107 +233,6 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont
@Reserved
public boolean reserved;
public static final int ID = 70;
public static final String NAME = "PlaceObject3";
@Override
public List<FILTER> getFilters() {
if (placeFlagHasFilterList) {
return surfaceFilterList;
} else {
return null;
}
}
@Override
public int getClipDepth() {
if (placeFlagHasClipDepth) {
return clipDepth;
}
return -1;
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
if (Configuration.debugCopy.get()) {
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
}
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUB(1, placeFlagHasClipActions ? 1 : 0);
sos.writeUB(1, placeFlagHasClipDepth ? 1 : 0);
sos.writeUB(1, placeFlagHasName ? 1 : 0);
sos.writeUB(1, placeFlagHasRatio ? 1 : 0);
sos.writeUB(1, placeFlagHasColorTransform ? 1 : 0);
sos.writeUB(1, placeFlagHasMatrix ? 1 : 0);
sos.writeUB(1, placeFlagHasCharacter ? 1 : 0);
sos.writeUB(1, placeFlagMove ? 1 : 0);
sos.writeUB(1, reserved ? 1 : 0);
sos.writeUB(1, placeFlagOpaqueBackground ? 1 : 0); //SWF11
sos.writeUB(1, placeFlagHasVisible ? 1 : 0); //SWF11
sos.writeUB(1, placeFlagHasImage ? 1 : 0);
sos.writeUB(1, placeFlagHasClassName ? 1 : 0);
sos.writeUB(1, placeFlagHasCacheAsBitmap ? 1 : 0);
sos.writeUB(1, placeFlagHasBlendMode ? 1 : 0);
sos.writeUB(1, placeFlagHasFilterList ? 1 : 0);
sos.writeUI16(depth);
if (placeFlagHasClassName) {
sos.writeString(className);
}
if (placeFlagHasCharacter) {
sos.writeUI16(characterId);
}
if (placeFlagHasMatrix) {
sos.writeMatrix(matrix);
}
if (placeFlagHasColorTransform) {
sos.writeCXFORMWITHALPHA(colorTransform);
}
if (placeFlagHasRatio) {
sos.writeUI16(ratio);
}
if (placeFlagHasName) {
sos.writeString(name);
}
if (placeFlagHasClipDepth) {
sos.writeUI16(clipDepth);
}
if (placeFlagHasFilterList) {
sos.writeFILTERLIST(surfaceFilterList);
}
if (placeFlagHasBlendMode) {
sos.writeUI8(blendMode);
}
if (placeFlagHasCacheAsBitmap) {
if (!bitmapCacheBug) {
sos.writeUI8(bitmapCache);
}
}
if (placeFlagHasVisible) {
sos.writeUI8(visible);
}
if (placeFlagOpaqueBackground) {
sos.writeRGBA(backgroundColor);
}
if (placeFlagHasClipActions) {
sos.writeCLIPACTIONS(clipActions);
}
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -420,6 +323,103 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont
}
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
if (Configuration.debugCopy.get()) {
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
}
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUB(1, placeFlagHasClipActions ? 1 : 0);
sos.writeUB(1, placeFlagHasClipDepth ? 1 : 0);
sos.writeUB(1, placeFlagHasName ? 1 : 0);
sos.writeUB(1, placeFlagHasRatio ? 1 : 0);
sos.writeUB(1, placeFlagHasColorTransform ? 1 : 0);
sos.writeUB(1, placeFlagHasMatrix ? 1 : 0);
sos.writeUB(1, placeFlagHasCharacter ? 1 : 0);
sos.writeUB(1, placeFlagMove ? 1 : 0);
sos.writeUB(1, reserved ? 1 : 0);
sos.writeUB(1, placeFlagOpaqueBackground ? 1 : 0); //SWF11
sos.writeUB(1, placeFlagHasVisible ? 1 : 0); //SWF11
sos.writeUB(1, placeFlagHasImage ? 1 : 0);
sos.writeUB(1, placeFlagHasClassName ? 1 : 0);
sos.writeUB(1, placeFlagHasCacheAsBitmap ? 1 : 0);
sos.writeUB(1, placeFlagHasBlendMode ? 1 : 0);
sos.writeUB(1, placeFlagHasFilterList ? 1 : 0);
sos.writeUI16(depth);
if (placeFlagHasClassName) {
sos.writeString(className);
}
if (placeFlagHasCharacter) {
sos.writeUI16(characterId);
}
if (placeFlagHasMatrix) {
sos.writeMatrix(matrix);
}
if (placeFlagHasColorTransform) {
sos.writeCXFORMWITHALPHA(colorTransform);
}
if (placeFlagHasRatio) {
sos.writeUI16(ratio);
}
if (placeFlagHasName) {
sos.writeString(name);
}
if (placeFlagHasClipDepth) {
sos.writeUI16(clipDepth);
}
if (placeFlagHasFilterList) {
sos.writeFILTERLIST(surfaceFilterList);
}
if (placeFlagHasBlendMode) {
sos.writeUI8(blendMode);
}
if (placeFlagHasCacheAsBitmap) {
if (!bitmapCacheBug) {
sos.writeUI8(bitmapCache);
}
}
if (placeFlagHasVisible) {
sos.writeUI8(visible);
}
if (placeFlagOpaqueBackground) {
sos.writeRGBA(backgroundColor);
}
if (placeFlagHasClipActions) {
sos.writeCLIPACTIONS(clipActions);
}
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public List<FILTER> getFilters() {
if (placeFlagHasFilterList) {
return surfaceFilterList;
} else {
return null;
}
}
@Override
public int getClipDepth() {
if (placeFlagHasClipDepth) {
return clipDepth;
}
return -1;
}
/**
* Returns all sub-items
*

View File

@@ -53,6 +53,10 @@ import java.util.Set;
*/
public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceContainer {
public static final int ID = 94;
public static final String NAME = "PlaceObject4";
/**
* @since SWF 5 has clip actions (sprite characters only)
*/
@@ -229,109 +233,8 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont
@Reserved
public boolean reserved;
public static final int ID = 94;
public static final String NAME = "PlaceObject4";
public byte[] amfData; //TODO: Parse AMF data?
@Override
public List<FILTER> getFilters() {
if (placeFlagHasFilterList) {
return surfaceFilterList;
} else {
return null;
}
}
@Override
public int getClipDepth() {
if (placeFlagHasClipDepth) {
return clipDepth;
}
return -1;
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
if (Configuration.debugCopy.get()) {
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
}
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUB(1, placeFlagHasClipActions ? 1 : 0);
sos.writeUB(1, placeFlagHasClipDepth ? 1 : 0);
sos.writeUB(1, placeFlagHasName ? 1 : 0);
sos.writeUB(1, placeFlagHasRatio ? 1 : 0);
sos.writeUB(1, placeFlagHasColorTransform ? 1 : 0);
sos.writeUB(1, placeFlagHasMatrix ? 1 : 0);
sos.writeUB(1, placeFlagHasCharacter ? 1 : 0);
sos.writeUB(1, placeFlagMove ? 1 : 0);
sos.writeUB(1, reserved ? 1 : 0);
sos.writeUB(1, placeFlagOpaqueBackground ? 1 : 0); //SWF11
sos.writeUB(1, placeFlagHasVisible ? 1 : 0); //SWF11
sos.writeUB(1, placeFlagHasImage ? 1 : 0);
sos.writeUB(1, placeFlagHasClassName ? 1 : 0);
sos.writeUB(1, placeFlagHasCacheAsBitmap ? 1 : 0);
sos.writeUB(1, placeFlagHasBlendMode ? 1 : 0);
sos.writeUB(1, placeFlagHasFilterList ? 1 : 0);
sos.writeUI16(depth);
if (placeFlagHasClassName) {
sos.writeString(className);
}
if (placeFlagHasCharacter) {
sos.writeUI16(characterId);
}
if (placeFlagHasMatrix) {
sos.writeMatrix(matrix);
}
if (placeFlagHasColorTransform) {
sos.writeCXFORMWITHALPHA(colorTransform);
}
if (placeFlagHasRatio) {
sos.writeUI16(ratio);
}
if (placeFlagHasName) {
sos.writeString(name);
}
if (placeFlagHasClipDepth) {
sos.writeUI16(clipDepth);
}
if (placeFlagHasFilterList) {
sos.writeFILTERLIST(surfaceFilterList);
}
if (placeFlagHasBlendMode) {
sos.writeUI8(blendMode);
}
if (placeFlagHasCacheAsBitmap) {
if (!bitmapCacheBug) {
sos.writeUI8(bitmapCache);
}
}
if (placeFlagHasVisible) {
sos.writeUI8(visible);
}
if (placeFlagOpaqueBackground) {
sos.writeRGBA(backgroundColor);
}
if (placeFlagHasClipActions) {
sos.writeCLIPACTIONS(clipActions);
}
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -423,6 +326,103 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont
amfData = sis.readBytesEx(sis.available(), "amfData");
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
if (Configuration.debugCopy.get()) {
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
}
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUB(1, placeFlagHasClipActions ? 1 : 0);
sos.writeUB(1, placeFlagHasClipDepth ? 1 : 0);
sos.writeUB(1, placeFlagHasName ? 1 : 0);
sos.writeUB(1, placeFlagHasRatio ? 1 : 0);
sos.writeUB(1, placeFlagHasColorTransform ? 1 : 0);
sos.writeUB(1, placeFlagHasMatrix ? 1 : 0);
sos.writeUB(1, placeFlagHasCharacter ? 1 : 0);
sos.writeUB(1, placeFlagMove ? 1 : 0);
sos.writeUB(1, reserved ? 1 : 0);
sos.writeUB(1, placeFlagOpaqueBackground ? 1 : 0); //SWF11
sos.writeUB(1, placeFlagHasVisible ? 1 : 0); //SWF11
sos.writeUB(1, placeFlagHasImage ? 1 : 0);
sos.writeUB(1, placeFlagHasClassName ? 1 : 0);
sos.writeUB(1, placeFlagHasCacheAsBitmap ? 1 : 0);
sos.writeUB(1, placeFlagHasBlendMode ? 1 : 0);
sos.writeUB(1, placeFlagHasFilterList ? 1 : 0);
sos.writeUI16(depth);
if (placeFlagHasClassName) {
sos.writeString(className);
}
if (placeFlagHasCharacter) {
sos.writeUI16(characterId);
}
if (placeFlagHasMatrix) {
sos.writeMatrix(matrix);
}
if (placeFlagHasColorTransform) {
sos.writeCXFORMWITHALPHA(colorTransform);
}
if (placeFlagHasRatio) {
sos.writeUI16(ratio);
}
if (placeFlagHasName) {
sos.writeString(name);
}
if (placeFlagHasClipDepth) {
sos.writeUI16(clipDepth);
}
if (placeFlagHasFilterList) {
sos.writeFILTERLIST(surfaceFilterList);
}
if (placeFlagHasBlendMode) {
sos.writeUI8(blendMode);
}
if (placeFlagHasCacheAsBitmap) {
if (!bitmapCacheBug) {
sos.writeUI8(bitmapCache);
}
}
if (placeFlagHasVisible) {
sos.writeUI8(visible);
}
if (placeFlagOpaqueBackground) {
sos.writeRGBA(backgroundColor);
}
if (placeFlagHasClipActions) {
sos.writeCLIPACTIONS(clipActions);
}
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public List<FILTER> getFilters() {
if (placeFlagHasFilterList) {
return surfaceFilterList;
} else {
return null;
}
}
@Override
public int getClipDepth() {
if (placeFlagHasClipDepth) {
return clipDepth;
}
return -1;
}
/**
* Returns all sub-items
*

View File

@@ -43,41 +43,48 @@ import java.util.Set;
*/
public class PlaceObjectTag extends PlaceObjectTypeTag {
/**
* ID of character to place
*/
@SWFType(BasicType.UI16)
public int characterId;
/**
* Depth of character
*/
@SWFType(BasicType.UI16)
public int depth;
/**
* Transform matrix data
*/
public MATRIX matrix;
/**
* Color transform data
*/
@Optional
public CXFORM colorTransform;
public static final int ID = 4;
public static final String NAME = "PlaceObject";
@Override
public List<FILTER> getFilters() {
return null;
/**
* Constructor
*
* @param swf
*/
public PlaceObjectTag(SWF swf) {
super(swf, ID, NAME, null);
matrix = new MATRIX();
}
public PlaceObjectTag(SWF swf, int characterId, int depth, MATRIX matrix, CXFORM colorTransform) {
super(swf, ID, NAME, null);
this.characterId = characterId;
this.depth = depth;
this.matrix = matrix;
this.colorTransform = colorTransform;
}
/**
* Constructor
*
* @param sis
* @param data
* @throws IOException
*/
public PlaceObjectTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, NAME, data);
readData(sis, data, 0, false, false, false);
}
@Override
public int getClipDepth() {
return -1;
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
characterId = sis.readUI16("characterId");
depth = sis.readUI16("depth");
matrix = sis.readMatrix("matrix");
if (sis.available() > 0) {
colorTransform = sis.readCXFORM("colorTransform");
}
}
/**
@@ -104,43 +111,36 @@ public class PlaceObjectTag extends PlaceObjectTypeTag {
}
/**
* Constructor
*
* @param swf
* ID of character to place
*/
public PlaceObjectTag(SWF swf) {
super(swf, ID, NAME, null);
matrix = new MATRIX();
}
@SWFType(BasicType.UI16)
public int characterId;
/**
* Constructor
*
* @param sis
* @param data
* @throws IOException
* Depth of character
*/
public PlaceObjectTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, NAME, data);
readData(sis, data, 0, false, false, false);
@SWFType(BasicType.UI16)
public int depth;
/**
* Transform matrix data
*/
public MATRIX matrix;
/**
* Color transform data
*/
@Optional
public CXFORM colorTransform;
@Override
public List<FILTER> getFilters() {
return null;
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
characterId = sis.readUI16("characterId");
depth = sis.readUI16("depth");
matrix = sis.readMatrix("matrix");
if (sis.available() > 0) {
colorTransform = sis.readCXFORM("colorTransform");
}
}
public PlaceObjectTag(SWF swf, int characterId, int depth, MATRIX matrix, CXFORM colorTransform) {
super(swf, ID, NAME, null);
this.characterId = characterId;
this.depth = depth;
this.matrix = matrix;
this.colorTransform = colorTransform;
public int getClipDepth() {
return -1;
}
@Override

View File

@@ -28,6 +28,10 @@ import java.io.OutputStream;
public class ProductInfoTag extends Tag {
public static final int ID = 41;
public static final String NAME = "ProductInfo";
@SWFType(BasicType.UI32)
public long productID;
@@ -52,10 +56,6 @@ public class ProductInfoTag extends Tag {
@SWFType(BasicType.UI32)
public long compilationDateHigh;
public static final int ID = 41;
public static final String NAME = "ProductInfo";
/**
* Constructor
*

View File

@@ -31,34 +31,14 @@ import java.io.OutputStream;
*/
public class ProtectTag extends Tag {
/**
* MD5 hash of password
*/
public String passwordHash;
public static final int ID = 24;
public static final String NAME = "Protect";
/**
* Gets data bytes
*
* @return Bytes of data
* MD5 hash of password
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
if (!"".equals(passwordHash)) {
sos.writeString(passwordHash);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
public String passwordHash;
/**
* Constructor
@@ -90,4 +70,24 @@ public class ProtectTag extends Tag {
passwordHash = "";
}
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
if (!"".equals(passwordHash)) {
sos.writeString(passwordHash);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
}

View File

@@ -27,15 +27,19 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
*
* @author JPEXS
*/
public class RemoveObject2Tag extends RemoveTag {
@SWFType(BasicType.UI16)
public int depth;
public static final int ID = 28;
public static final String NAME = "RemoveObject2";
@SWFType(BasicType.UI16)
public int depth;
/**
* Constructor
*
@@ -45,6 +49,13 @@ public class RemoveObject2Tag extends RemoveTag {
super(swf, ID, NAME, null);
}
/**
* Constructor
*
* @param sis
* @param data
* @throws IOException
*/
public RemoveObject2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, NAME, data);
readData(sis, data, 0, false, false, false);

View File

@@ -35,6 +35,10 @@ import java.io.OutputStream;
*/
public class RemoveObjectTag extends RemoveTag implements CharacterIdTag {
public static final int ID = 5;
public static final String NAME = "RemoveObject";
/**
* ID of character to place
*/
@@ -47,29 +51,6 @@ public class RemoveObjectTag extends RemoveTag implements CharacterIdTag {
@SWFType(BasicType.UI16)
public int depth;
public static final int ID = 5;
public static final String NAME = "RemoveObject";
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(characterId);
sos.writeUI16(depth);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -98,6 +79,25 @@ public class RemoveObjectTag extends RemoveTag implements CharacterIdTag {
depth = sis.readUI16("depth");
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(characterId);
sos.writeUI16(depth);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getDepth() {
return depth;

View File

@@ -28,16 +28,16 @@ import java.io.OutputStream;
public class ScriptLimitsTag extends Tag {
public static final int ID = 65;
public static final String NAME = "ScriptLimits";
@SWFType(BasicType.UI16)
public int maxRecursionDepth;
@SWFType(BasicType.UI16)
public int scriptTimeoutSeconds;
public static final int ID = 65;
public static final String NAME = "ScriptLimits";
/**
* Constructor
*

View File

@@ -26,12 +26,12 @@ import java.io.IOException;
public class SetBackgroundColorTag extends Tag {
public RGB backgroundColor;
public static final int ID = 9;
public static final String NAME = "SetBackgroundColor";
public RGB backgroundColor;
/**
* Constructor
*

View File

@@ -33,6 +33,10 @@ import java.io.OutputStream;
*/
public class SetTabIndexTag extends Tag {
public static final int ID = 66;
public static final String NAME = "SetTabIndex";
/**
* Depth of character
*/
@@ -45,29 +49,6 @@ public class SetTabIndexTag extends Tag {
@SWFType(BasicType.UI16)
public int tabIndex;
public static final int ID = 66;
public static final String NAME = "SetTabIndex";
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(depth);
sos.writeUI16(tabIndex);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -94,4 +75,23 @@ public class SetTabIndexTag extends Tag {
depth = sis.readUI16("depth");
tabIndex = sis.readUI16("tabIndex");
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(depth);
sos.writeUI16(tabIndex);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
}

View File

@@ -41,6 +41,10 @@ import java.util.List;
*/
public class SoundStreamHead2Tag extends Tag implements SoundStreamHeadTypeTag {
public static final int ID = 45;
public static final String NAME = "SoundStreamHead2";
@Reserved
@SWFType(value = BasicType.UB, count = 4)
public int reserved;
@@ -72,9 +76,71 @@ public class SoundStreamHead2Tag extends Tag implements SoundStreamHeadTypeTag {
@Internal
private int virtualCharacterId = 0;
public static final int ID = 45;
/**
* Constructor
*
* @param swf
*/
public SoundStreamHead2Tag(SWF swf) {
super(swf, ID, NAME, null);
}
public static final String NAME = "SoundStreamHead2";
/**
* Constructor
*
* @param sis
* @param data
* @throws IOException
*/
public SoundStreamHead2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, NAME, data);
readData(sis, data, 0, false, false, false);
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
reserved = (int) sis.readUB(4, "reserved");
playBackSoundRate = (int) sis.readUB(2, "playBackSoundRate");
playBackSoundSize = sis.readUB(1, "playBackSoundSize") == 1;
playBackSoundType = sis.readUB(1, "playBackSoundType") == 1;
streamSoundCompression = (int) sis.readUB(4, "streamSoundCompression");
streamSoundRate = (int) sis.readUB(2, "streamSoundRate");
streamSoundSize = sis.readUB(1, "streamSoundSize") == 1;
streamSoundType = sis.readUB(1, "streamSoundType") == 1;
streamSoundSampleCount = sis.readUI16("streamSoundSampleCount");
if (streamSoundCompression == 2) {
latencySeek = sis.readSI16("latencySeek");
}
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUB(4, reserved);
sos.writeUB(2, playBackSoundRate);
sos.writeUB(1, playBackSoundSize ? 1 : 0);
sos.writeUB(1, playBackSoundType ? 1 : 0);
sos.writeUB(4, streamSoundCompression);
sos.writeUB(2, streamSoundRate);
sos.writeUB(1, streamSoundSize ? 1 : 0);
sos.writeUB(1, streamSoundType ? 1 : 0);
sos.writeUI16(streamSoundSampleCount);
if (streamSoundCompression == 2) {
sos.writeSI16(latencySeek);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getCharacterId() {
@@ -116,72 +182,6 @@ public class SoundStreamHead2Tag extends Tag implements SoundStreamHeadTypeTag {
virtualCharacterId = ch;
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUB(4, reserved);
sos.writeUB(2, playBackSoundRate);
sos.writeUB(1, playBackSoundSize ? 1 : 0);
sos.writeUB(1, playBackSoundType ? 1 : 0);
sos.writeUB(4, streamSoundCompression);
sos.writeUB(2, streamSoundRate);
sos.writeUB(1, streamSoundSize ? 1 : 0);
sos.writeUB(1, streamSoundType ? 1 : 0);
sos.writeUI16(streamSoundSampleCount);
if (streamSoundCompression == 2) {
sos.writeSI16(latencySeek);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
* @param swf
*/
public SoundStreamHead2Tag(SWF swf) {
super(swf, ID, NAME, null);
}
/**
* Constructor
*
* @param sis
* @param data
* @throws IOException
*/
public SoundStreamHead2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, NAME, data);
readData(sis, data, 0, false, false, false);
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
reserved = (int) sis.readUB(4, "reserved");
playBackSoundRate = (int) sis.readUB(2, "playBackSoundRate");
playBackSoundSize = sis.readUB(1, "playBackSoundSize") == 1;
playBackSoundType = sis.readUB(1, "playBackSoundType") == 1;
streamSoundCompression = (int) sis.readUB(4, "streamSoundCompression");
streamSoundRate = (int) sis.readUB(2, "streamSoundRate");
streamSoundSize = sis.readUB(1, "streamSoundSize") == 1;
streamSoundType = sis.readUB(1, "streamSoundType") == 1;
streamSoundSampleCount = sis.readUI16("streamSoundSampleCount");
if (streamSoundCompression == 2) {
latencySeek = sis.readSI16("latencySeek");
}
}
@Override
public int getSoundFormatId() {
return streamSoundCompression;

View File

@@ -41,6 +41,10 @@ import java.util.List;
*/
public class SoundStreamHeadTag extends Tag implements SoundStreamHeadTypeTag {
public static final int ID = 18;
public static final String NAME = "SoundStreamHead";
@Reserved
@SWFType(value = BasicType.UB, count = 4)
public int reserved;
@@ -71,9 +75,71 @@ public class SoundStreamHeadTag extends Tag implements SoundStreamHeadTypeTag {
@Internal
private int virtualCharacterId = 0;
public static final int ID = 18;
/**
* Constructor
*
* @param swf
*/
public SoundStreamHeadTag(SWF swf) {
super(swf, ID, NAME, null);
}
public static final String NAME = "SoundStreamHead";
/**
* Constructor
*
* @param sis
* @param data
* @throws IOException
*/
public SoundStreamHeadTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, NAME, data);
readData(sis, data, 0, false, false, false);
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
reserved = (int) sis.readUB(4, "reserved");
playBackSoundRate = (int) sis.readUB(2, "playBackSoundRate");
playBackSoundSize = sis.readUB(1, "playBackSoundSize") == 1;
playBackSoundType = sis.readUB(1, "playBackSoundType") == 1;
streamSoundCompression = (int) sis.readUB(4, "streamSoundCompression");
streamSoundRate = (int) sis.readUB(2, "streamSoundRate");
streamSoundSize = sis.readUB(1, "streamSoundSize") == 1;
streamSoundType = sis.readUB(1, "streamSoundType") == 1;
streamSoundSampleCount = sis.readUI16("streamSoundSampleCount");
if (streamSoundCompression == 2) {
latencySeek = sis.readSI16("latencySeek");
}
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUB(4, reserved);
sos.writeUB(2, playBackSoundRate);
sos.writeUB(1, playBackSoundSize ? 1 : 0);
sos.writeUB(1, playBackSoundType ? 1 : 0);
sos.writeUB(4, streamSoundCompression);
sos.writeUB(2, streamSoundRate);
sos.writeUB(1, streamSoundSize ? 1 : 0);
sos.writeUB(1, streamSoundType ? 1 : 0);
sos.writeUI16(streamSoundSampleCount);
if (streamSoundCompression == 2) {
sos.writeSI16(latencySeek);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public String getExportFormat() {
@@ -115,72 +181,6 @@ public class SoundStreamHeadTag extends Tag implements SoundStreamHeadTypeTag {
return streamSoundSampleCount;
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUB(4, reserved);
sos.writeUB(2, playBackSoundRate);
sos.writeUB(1, playBackSoundSize ? 1 : 0);
sos.writeUB(1, playBackSoundType ? 1 : 0);
sos.writeUB(4, streamSoundCompression);
sos.writeUB(2, streamSoundRate);
sos.writeUB(1, streamSoundSize ? 1 : 0);
sos.writeUB(1, streamSoundType ? 1 : 0);
sos.writeUI16(streamSoundSampleCount);
if (streamSoundCompression == 2) {
sos.writeSI16(latencySeek);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
* @param swf
*/
public SoundStreamHeadTag(SWF swf) {
super(swf, ID, NAME, null);
}
/**
* Constructor
*
* @param sis
* @param data
* @throws IOException
*/
public SoundStreamHeadTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, NAME, data);
readData(sis, data, 0, false, false, false);
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
reserved = (int) sis.readUB(4, "reserved");
playBackSoundRate = (int) sis.readUB(2, "playBackSoundRate");
playBackSoundSize = sis.readUB(1, "playBackSoundSize") == 1;
playBackSoundType = sis.readUB(1, "playBackSoundType") == 1;
streamSoundCompression = (int) sis.readUB(4, "streamSoundCompression");
streamSoundRate = (int) sis.readUB(2, "streamSoundRate");
streamSoundSize = sis.readUB(1, "streamSoundSize") == 1;
streamSoundType = sis.readUB(1, "streamSoundType") == 1;
streamSoundSampleCount = sis.readUI16("streamSoundSampleCount");
if (streamSoundCompression == 2) {
latencySeek = sis.readSI16("latencySeek");
}
}
@Override
public int getSoundFormatId() {
return streamSoundCompression;

View File

@@ -31,32 +31,13 @@ import java.io.OutputStream;
*/
public class StartSound2Tag extends Tag {
public String soundClassName;
public SOUNDINFO soundInfo;
public static final int ID = 89;
public static final String NAME = "StartSound2";
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeString(soundClassName);
sos.writeSOUNDINFO(soundInfo);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
public String soundClassName;
public SOUNDINFO soundInfo;
/**
* Constructor
@@ -86,4 +67,23 @@ public class StartSound2Tag extends Tag {
soundClassName = sis.readString("soundClassName");
soundInfo = sis.readSOUNDINFO("soundInfo");
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeString(soundClassName);
sos.writeSOUNDINFO(soundInfo);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
}

View File

@@ -34,33 +34,14 @@ import java.io.OutputStream;
*/
public class StartSoundTag extends Tag {
@SWFType(BasicType.UI16)
public int soundId;
public SOUNDINFO soundInfo;
public static final int ID = 15;
public static final String NAME = "StartSound";
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(soundId);
sos.writeSOUNDINFO(soundInfo);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@SWFType(BasicType.UI16)
public int soundId;
public SOUNDINFO soundInfo;
/**
* Constructor
@@ -89,4 +70,23 @@ public class StartSoundTag extends Tag {
soundId = sis.readUI16("soundId");
soundInfo = sis.readSOUNDINFO("soundInfo");
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(soundId);
sos.writeSOUNDINFO(soundInfo);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
}

View File

@@ -32,6 +32,10 @@ import java.util.List;
public class SymbolClassTag extends SymbolClassTypeTag {
public static final int ID = 76;
public static final String NAME = "SymbolClass";
@SWFType(value = BasicType.UI16)
@SWFArray(value = "tag", countField = "numSymbols")
public List<Integer> tags;
@@ -39,10 +43,6 @@ public class SymbolClassTag extends SymbolClassTypeTag {
@SWFArray(value = "name", countField = "numSymbols")
public List<String> names;
public static final int ID = 76;
public static final String NAME = "SymbolClass";
/**
* Constructor
*

View File

@@ -83,6 +83,27 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
private final HashSet<TagChangedListener> listeners = new HashSet<>();
/**
* Constructor
*
* @param swf The SWF
* @param id Tag type identifier
* @param name Tag name
* @param data Original tag data
*/
public Tag(SWF swf, int id, String name, ByteArrayRange data) {
this.id = id;
this.tagName = name;
this.originalRange = data;
this.swf = swf;
if (swf == null) {
throw new Error("swf parameter cannot be null.");
}
if (data == null) { // it is tag build by constructor
modified = true;
}
}
public String getTagName() {
return tagName;
}
@@ -134,27 +155,6 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
this.timelined = timelined;
}
/**
* Constructor
*
* @param swf The SWF
* @param id Tag type identifier
* @param name Tag name
* @param data Original tag data
*/
public Tag(SWF swf, int id, String name, ByteArrayRange data) {
this.id = id;
this.tagName = name;
this.originalRange = data;
this.swf = swf;
if (swf == null) {
throw new Error("swf parameter cannot be null.");
}
if (data == null) { // it is tag build by constructor
modified = true;
}
}
public abstract void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException, InterruptedException;
private static final Object lockObject = new Object();

View File

@@ -22,15 +22,27 @@ package com.jpexs.decompiler.flash.tags;
*/
public class TagInfo {
public int id;
private final int id;
public Class cls;
private final Class cls;
public String name;
private final String name;
public TagInfo(int id, Class cls, String name) {
this.id = id;
this.cls = cls;
this.name = name;
}
public int getId() {
return id;
}
public Class getCls() {
return cls;
}
public String getName() {
return name;
}
}

View File

@@ -34,6 +34,10 @@ import java.io.OutputStream;
*/
public class VideoFrameTag extends Tag implements CharacterIdTag {
public static final int ID = 61;
public static final String NAME = "VideoFrame";
@SWFType(BasicType.UI16)
public int streamID;
@@ -42,30 +46,6 @@ public class VideoFrameTag extends Tag implements CharacterIdTag {
public ByteArrayRange videoData;
public static final int ID = 61;
public static final String NAME = "VideoFrame";
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(streamID);
sos.writeUI16(frameNum);
sos.write(videoData);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -95,6 +75,26 @@ public class VideoFrameTag extends Tag implements CharacterIdTag {
videoData = sis.readByteRangeEx(sis.available(), "videoData"); //TODO: Parse video packets
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(streamID);
sos.writeUI16(frameNum);
sos.write(videoData);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getCharacterId() {
return streamID;

View File

@@ -1,159 +1,210 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.exporters.shape.BitmapExporter;
import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter;
import com.jpexs.decompiler.flash.exporters.shape.PathExporter;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.helpers.LazyObject;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.SerializableImage;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.io.IOException;
import java.util.List;
import java.util.Set;
/**
*
* @author JPEXS
*/
public abstract class ShapeTag extends CharacterTag implements DrawableTag, LazyObject {
@SWFType(BasicType.UI16)
public int shapeId;
public RECT shapeBounds;
public SHAPEWITHSTYLE shapes;
private final int markerSize = 10;
public ShapeTag(SWF swf, int id, String name, ByteArrayRange data) {
super(swf, id, name, data);
}
public abstract SHAPEWITHSTYLE getShapes();
@Override
public void load() {
getShapes();
}
public abstract int getShapeNum();
@Override
public RECT getRect() {
return getRect(null); // parameter not used
}
@Override
public int getUsedParameters() {
return 0;
}
@Override
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
return transformation.toTransform().createTransformedShape(getShapes().getOutline());
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
BitmapExporter.export(swf, getShapes(), null, image, transformation, colorTransform);
if (Configuration.debugMode.get()) { // show control points
List<GeneralPath> paths = PathExporter.export(getShapes());
double[] coords = new double[6];
AffineTransform at = transformation.toTransform();
at.preConcatenate(AffineTransform.getScaleInstance(1 / SWF.unitDivisor, 1 / SWF.unitDivisor));
// get the graphics from the inner image object, because it creates a new Graphics object
Graphics2D graphics = (Graphics2D) image.getBufferedImage().getGraphics();
graphics.setPaint(Color.black);
for (GeneralPath path : paths) {
PathIterator iterator = path.getPathIterator(at);
while (!iterator.isDone()) {
int type = iterator.currentSegment(coords);
double x = coords[0];
double y = coords[1];
switch (type) {
case PathIterator.SEG_MOVETO:
graphics.drawRect((int) (x - markerSize / 2), (int) (y - markerSize / 2), markerSize, markerSize);
break;
case PathIterator.SEG_LINETO:
graphics.drawRect((int) (x - markerSize / 2), (int) (y - markerSize / 2), markerSize, markerSize);
break;
case PathIterator.SEG_QUADTO:
graphics.drawRect((int) (x - markerSize / 2), (int) (y - markerSize / 2), markerSize, markerSize);
x = coords[2];
y = coords[3];
graphics.drawRect((int) (x - markerSize / 2), (int) (y - markerSize / 2), markerSize, markerSize);
break;
case PathIterator.SEG_CUBICTO:
System.out.print("CUBICTO NOT SUPPORTED. ");
break;
case PathIterator.SEG_CLOSE:
System.out.print("CLOSE NOT SUPPORTED. ");
break;
}
iterator.next();
}
}
}
}
@Override
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) throws IOException {
SVGShapeExporter shapeExporter = new SVGShapeExporter(swf, getShapes(), exporter, null, colorTransform, zoom);
shapeExporter.export();
}
@Override
public String toHtmlCanvas(double unitDivisor) {
CanvasShapeExporter cse = new CanvasShapeExporter(null, unitDivisor, swf, getShapes(), new ColorTransform(), 0, 0);
cse.export();
return cse.getShapeData();
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
getShapes().getNeededCharacters(needed);
}
@Override
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
return getShapes().replaceCharacter(oldCharacterId, newCharacterId);
}
@Override
public boolean removeCharacter(int characterId) {
return getShapes().removeCharacter(characterId);
}
}
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.exporters.shape.BitmapExporter;
import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter;
import com.jpexs.decompiler.flash.exporters.shape.PathExporter;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.helpers.LazyObject;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.SerializableImage;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public abstract class ShapeTag extends CharacterTag implements DrawableTag, LazyObject {
@SWFType(BasicType.UI16)
public int shapeId;
public RECT shapeBounds;
public SHAPEWITHSTYLE shapes;
protected ByteArrayRange shapeData;
private final int markerSize = 10;
public ShapeTag(SWF swf, int id, String name, ByteArrayRange data) {
super(swf, id, name, data);
}
@Override
public void load() {
getShapes();
}
public abstract int getShapeNum();
public SHAPEWITHSTYLE getShapes() {
if (shapes == null && shapeData != null) {
try {
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
sis.seek(shapeData.getPos());
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
shapeData = null; // not needed anymore, give it to GC
} catch (IOException ex) {
Logger.getLogger(ShapeTag.class.getName()).log(Level.SEVERE, null, ex);
}
}
return shapes;
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
getShapes().getNeededCharacters(needed);
}
@Override
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
if (modified) {
setModified(true);
}
return modified;
}
@Override
public boolean removeCharacter(int characterId) {
boolean modified = getShapes().removeCharacter(characterId);
if (modified) {
setModified(true);
}
return modified;
}
@Override
public RECT getRect(Set<BoundedTag> added) {
return shapeBounds;
}
@Override
public RECT getRect() {
return getRect(null); // parameter not used
}
@Override
public int getUsedParameters() {
return 0;
}
@Override
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
return transformation.toTransform().createTransformedShape(getShapes().getOutline());
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
BitmapExporter.export(swf, getShapes(), null, image, transformation, colorTransform);
if (Configuration.debugMode.get()) { // show control points
List<GeneralPath> paths = PathExporter.export(getShapes());
double[] coords = new double[6];
AffineTransform at = transformation.toTransform();
at.preConcatenate(AffineTransform.getScaleInstance(1 / SWF.unitDivisor, 1 / SWF.unitDivisor));
// get the graphics from the inner image object, because it creates a new Graphics object
Graphics2D graphics = (Graphics2D) image.getBufferedImage().getGraphics();
graphics.setPaint(Color.black);
for (GeneralPath path : paths) {
PathIterator iterator = path.getPathIterator(at);
while (!iterator.isDone()) {
int type = iterator.currentSegment(coords);
double x = coords[0];
double y = coords[1];
switch (type) {
case PathIterator.SEG_MOVETO:
graphics.drawRect((int) (x - markerSize / 2), (int) (y - markerSize / 2), markerSize, markerSize);
break;
case PathIterator.SEG_LINETO:
graphics.drawRect((int) (x - markerSize / 2), (int) (y - markerSize / 2), markerSize, markerSize);
break;
case PathIterator.SEG_QUADTO:
graphics.drawRect((int) (x - markerSize / 2), (int) (y - markerSize / 2), markerSize, markerSize);
x = coords[2];
y = coords[3];
graphics.drawRect((int) (x - markerSize / 2), (int) (y - markerSize / 2), markerSize, markerSize);
break;
case PathIterator.SEG_CUBICTO:
System.out.print("CUBICTO NOT SUPPORTED. ");
break;
case PathIterator.SEG_CLOSE:
System.out.print("CLOSE NOT SUPPORTED. ");
break;
}
iterator.next();
}
}
}
}
@Override
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) throws IOException {
SVGShapeExporter shapeExporter = new SVGShapeExporter(swf, getShapes(), exporter, null, colorTransform, zoom);
shapeExporter.export();
}
@Override
public String toHtmlCanvas(double unitDivisor) {
CanvasShapeExporter cse = new CanvasShapeExporter(null, unitDivisor, swf, getShapes(), new ColorTransform(), 0, 0);
cse.export();
return cse.getShapeData();
}
@Override
public int getNumFrames() {
return 1;
}
@Override
public boolean isSingleFrame() {
return true;
}
@Override
public int getCharacterId() {
return shapeId;
}
@Override
public void setCharacterId(int characterId) {
this.shapeId = characterId;
}
}

View File

@@ -1,82 +1,82 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Set;
/**
*
* @author JPEXS
*/
public class SHAPEWITHSTYLE extends SHAPE implements NeedsCharacters, Serializable {
public FILLSTYLEARRAY fillStyles;
public LINESTYLEARRAY lineStyles;
@Override
public void getNeededCharacters(Set<Integer> needed) {
fillStyles.getNeededCharacters(needed);
lineStyles.getNeededCharacters(needed);
for (SHAPERECORD r : shapeRecords) {
r.getNeededCharacters(needed);
}
}
@Override
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
boolean modified = false;
modified |= fillStyles.replaceCharacter(oldCharacterId, newCharacterId);
modified |= lineStyles.replaceCharacter(oldCharacterId, newCharacterId);
for (SHAPERECORD r : shapeRecords) {
modified |= r.replaceCharacter(oldCharacterId, newCharacterId);
}
return modified;
}
@Override
public boolean removeCharacter(int characterId) {
boolean modified = false;
modified |= fillStyles.removeCharacter(characterId);
modified |= lineStyles.removeCharacter(characterId);
for (SHAPERECORD r : shapeRecords) {
modified |= r.removeCharacter(characterId);
}
return modified;
}
public static SHAPEWITHSTYLE createEmpty(int shapeNum) {
SHAPEWITHSTYLE ret = new SHAPEWITHSTYLE();
ret.shapeRecords = new ArrayList<>();
ret.shapeRecords.add(new EndShapeRecord());
ret.fillStyles = new FILLSTYLEARRAY();
ret.fillStyles.fillStyles = new FILLSTYLE[0];
ret.lineStyles = new LINESTYLEARRAY();
if ((shapeNum == 1 || shapeNum == 2 || shapeNum == 3)) {
ret.lineStyles.lineStyles = new LINESTYLE[0];
} else if (shapeNum == 4) {
ret.lineStyles.lineStyles = new LINESTYLE2[0];
}
return ret;
}
}
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Set;
/**
*
* @author JPEXS
*/
public class SHAPEWITHSTYLE extends SHAPE implements NeedsCharacters, Serializable {
public FILLSTYLEARRAY fillStyles;
public LINESTYLEARRAY lineStyles;
@Override
public void getNeededCharacters(Set<Integer> needed) {
fillStyles.getNeededCharacters(needed);
lineStyles.getNeededCharacters(needed);
for (SHAPERECORD r : shapeRecords) {
r.getNeededCharacters(needed);
}
}
@Override
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
boolean modified = false;
modified |= fillStyles.replaceCharacter(oldCharacterId, newCharacterId);
modified |= lineStyles.replaceCharacter(oldCharacterId, newCharacterId);
for (SHAPERECORD r : shapeRecords) {
modified |= r.replaceCharacter(oldCharacterId, newCharacterId);
}
return modified;
}
@Override
public boolean removeCharacter(int characterId) {
boolean modified = false;
modified |= fillStyles.removeCharacter(characterId);
modified |= lineStyles.removeCharacter(characterId);
for (SHAPERECORD r : shapeRecords) {
modified |= r.removeCharacter(characterId);
}
return modified;
}
public static SHAPEWITHSTYLE createEmpty(int shapeNum) {
SHAPEWITHSTYLE ret = new SHAPEWITHSTYLE();
ret.shapeRecords = new ArrayList<>();
ret.shapeRecords.add(new EndShapeRecord());
ret.fillStyles = new FILLSTYLEARRAY();
ret.fillStyles.fillStyles = new FILLSTYLE[0];
ret.lineStyles = new LINESTYLEARRAY();
if (shapeNum <= 3) {
ret.lineStyles.lineStyles = new LINESTYLE[0];
} else {
ret.lineStyles.lineStyles = new LINESTYLE2[0];
}
return ret;
}
}