better shapes viewer

not parsing tags at unusal places (define tags in sprite, AS1/2 tags where file is AS3...)
This commit is contained in:
Jindra Petk
2013-07-08 14:46:12 +02:00
parent d0cd3ad3de
commit ebbb1a5689
79 changed files with 525 additions and 221 deletions

View File

@@ -62,17 +62,19 @@ import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
import com.jpexs.decompiler.flash.tags.DefineButton2Tag;
import com.jpexs.decompiler.flash.tags.DefineButtonTag;
import com.jpexs.decompiler.flash.tags.DefineShapeTag;
import com.jpexs.decompiler.flash.tags.DefineSoundTag;
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
import com.jpexs.decompiler.flash.tags.DefineTextTag;
import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag;
import com.jpexs.decompiler.flash.tags.DoInitActionTag;
import com.jpexs.decompiler.flash.tags.ExportAssetsTag;
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
import com.jpexs.decompiler.flash.tags.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
import com.jpexs.decompiler.flash.tags.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.tags.SymbolClassTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.VideoFrameTag;
@@ -325,7 +327,7 @@ public class SWF {
sis.readUI8(); //tmpFirstByetOfFrameRate
frameRate = sis.readUI8();
frameCount = sis.readUI16();
tags = sis.readTagList(0, paralelRead);
tags = sis.readTagList(0, paralelRead, true);
assignExportNamesToSymbols();
assignClassesToSymbols();
for (Tag t : tags) {
@@ -503,7 +505,6 @@ public class SWF {
private List<KeyValue<ClassPath, ScriptPack>> uniqueAS3Packs(List<KeyValue<ClassPath, ScriptPack>> packs) {
List<KeyValue<ClassPath, ScriptPack>> ret = new ArrayList<>();
for (KeyValue<ClassPath, ScriptPack> item : packs) {
System.err.println(item.key);
for (KeyValue<ClassPath, ScriptPack> itemOld : ret) {
if (item.key.equals(itemOld.key)) {
Logger.getLogger(SWF.class.getName()).log(Level.SEVERE, "Duplicate pack path found!");
@@ -2051,7 +2052,11 @@ public class SWF {
return ret;
}
public static BufferedImage frameToImage(int containerId, int maxDepth, HashMap<Integer, Layer> layers, Color backgroundColor, HashMap<Integer, CharacterTag> characters, int frame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect) {
public static BufferedImage frameToImage(int containerId, int maxDepth, HashMap<Integer, Layer> layers, Color backgroundColor, HashMap<Integer, CharacterTag> characters, int frame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, Stack<Integer> visited) {
int fixX = 0;
int fixY = 0;
fixX = -displayRect.Xmin / 20;
fixY = -displayRect.Ymin / 20;
displayRect = fixRect(displayRect);
String key = "frame_" + frame + "_" + containerId;
@@ -2083,6 +2088,8 @@ public class SWF {
MATRIX mat = new MATRIX(layer.matrix);
mat.translateX /= 20;
mat.translateY /= 20;
mat.translateX += fixX;
mat.translateY += fixY;
AffineTransform trans = matrixToTransform(mat);
@@ -2090,9 +2097,7 @@ public class SWF {
g.setTransform(trans);
if (character instanceof DrawableTag) {
DrawableTag drawable = (DrawableTag) character;
BufferedImage img = drawable.toImage(layer.ratio < 0 ? 0 : layer.ratio/*layer.duration*/, allTags, displayRect, characters);
BufferedImage img = drawable.toImage(layer.ratio < 0 ? 0 : layer.ratio/*layer.duration*/, allTags, displayRect, characters, visited);
if (layer.filters != null) {
for (FILTER filter : layer.filters) {
img = filter.apply(img);
@@ -2105,68 +2110,70 @@ public class SWF {
if (layer.colorTransFormAlpha != null) {
img = layer.colorTransFormAlpha.apply(img);
}
Point imgPos = drawable.getImagePos(layer.ratio < 0 ? 0 : layer.ratio, characters);
if (imgPos.x < 0) {
imgPos.x = 0;
}
if (imgPos.y < 0) {
imgPos.y = 0;
}
switch (layer.blendMode) {
case 0:
case 1:
g.setComposite(AlphaComposite.SrcOver);
break;
case 2: //TODO:Layer
g.setComposite(AlphaComposite.SrcOver);
break;
case 3:
g.setComposite(BlendComposite.Multiply);
break;
case 4:
g.setComposite(BlendComposite.Screen);
break;
case 5:
g.setComposite(BlendComposite.Lighten);
break;
case 6:
g.setComposite(BlendComposite.Darken);
break;
case 7:
g.setComposite(BlendComposite.Difference);
break;
case 8:
g.setComposite(BlendComposite.Add);
break;
case 9:
g.setComposite(BlendComposite.Subtract);
break;
case 10:
g.setComposite(BlendComposite.Invert);
break;
case 11:
g.setComposite(BlendComposite.Alpha);
break;
case 12:
g.setComposite(BlendComposite.Erase);
break;
case 13:
g.setComposite(BlendComposite.Overlay);
break;
case 14:
g.setComposite(BlendComposite.HardLight);
break;
default: //Not implemented
g.setComposite(AlphaComposite.SrcOver);
break;
}
Point imgPos = drawable.getImagePos(layer.ratio < 0 ? 0 : layer.ratio, characters, visited);
//imgPos.x+=fixX;
//imgPos.y+=fixY;
/*if (imgPos.x < 0) {
imgPos.x = 0;
}
if (imgPos.y < 0) {
imgPos.y = 0;
}*/
/*switch (layer.blendMode) {
case 0:
case 1:
g.setComposite(AlphaComposite.SrcOver);
break;
case 2: //TODO:Layer
g.setComposite(AlphaComposite.SrcOver);
break;
case 3:
g.setComposite(BlendComposite.Multiply);
break;
case 4:
g.setComposite(BlendComposite.Screen);
break;
case 5:
g.setComposite(BlendComposite.Lighten);
break;
case 6:
g.setComposite(BlendComposite.Darken);
break;
case 7:
g.setComposite(BlendComposite.Difference);
break;
case 8:
g.setComposite(BlendComposite.Add);
break;
case 9:
g.setComposite(BlendComposite.Subtract);
break;
case 10:
g.setComposite(BlendComposite.Invert);
break;
case 11:
g.setComposite(BlendComposite.Alpha);
break;
case 12:
g.setComposite(BlendComposite.Erase);
break;
case 13:
g.setComposite(BlendComposite.Overlay);
break;
case 14:
g.setComposite(BlendComposite.HardLight);
break;
default: //Not implemented
g.setComposite(AlphaComposite.SrcOver);
break;
}*/
g.drawImage(img, imgPos.x, imgPos.y, null);
} else if (character instanceof BoundedTag) {
BoundedTag b = (BoundedTag) character;
g.setPaint(new Color(255, 255, 255, 128));
g.setComposite(BlendComposite.Invert);
RECT r = b.getRect(characters);
RECT r = b.getRect(characters, visited);
g.drawString(character.toString(), (r.Xmin) / 20 + 3, (r.Ymin) / 20 + 15);
g.draw(new Rectangle(r.Xmin / 20, r.Ymin / 20, r.getWidth() / 20, r.getHeight() / 20));
g.drawLine(r.Xmin / 20, r.Ymin / 20, r.Xmax / 20, r.Ymax / 20);
@@ -2181,16 +2188,16 @@ public class SWF {
return ret;
}
public static BufferedImage frameToImage(int containerId, int frame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount) {
public static BufferedImage frameToImage(int containerId, int frame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount, Stack<Integer> visited) {
List<BufferedImage> ret = new ArrayList<>();
framesToImage(containerId, ret, frame, frame, allTags, controlTags, displayRect, totalFrameCount);
framesToImage(containerId, ret, frame, frame, allTags, controlTags, displayRect, totalFrameCount, visited);
if (ret.isEmpty()) {
return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
}
return ret.get(0);
}
public static void framesToImage(int containerId, List<BufferedImage> ret, int startFrame, int stopFrame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount) {
public static void framesToImage(int containerId, List<BufferedImage> ret, int startFrame, int stopFrame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount, Stack<Integer> visited) {
for (int i = startFrame; i <= stopFrame; i++) {
String key = "frame_" + i + "_" + containerId;
if (cache.contains(key)) {
@@ -2308,7 +2315,7 @@ public class SWF {
break;
}
if ((f >= startFrame) && (f <= stopFrame)) {
ret.add(frameToImage(containerId, maxDepth, layers, backgroundColor, characters, f, allTags, controlTags, displayRect));
ret.add(frameToImage(containerId, maxDepth, layers, backgroundColor, characters, f, allTags, controlTags, displayRect, visited));
}
f++;
}

View File

@@ -1148,18 +1148,20 @@ public class SWFInputStream extends InputStream {
private final int version;
private final int level;
private boolean paralel;
private boolean skipUnusualTags;
public TagResolutionTask(Tag tag, int version, int level, boolean paralel) {
public TagResolutionTask(Tag tag, int version, int level, boolean paralel, boolean skipUnusualTags) {
this.tag = tag;
this.version = version;
this.level = level;
this.paralel = paralel;
this.skipUnusualTags = skipUnusualTags;
}
@Override
public Tag call() throws Exception {
try {
return SWFInputStream.resolveTag(tag, version, level, paralel);
return SWFInputStream.resolveTag(tag, version, level, paralel, skipUnusualTags);
} catch (Exception ex) {
return null;
}
@@ -1176,6 +1178,20 @@ public class SWFInputStream extends InputStream {
* @throws IOException
*/
public List<Tag> readTagList(int level, boolean paralel) throws IOException {
return readTagList(level, paralel, false);
}
/**
* Reads list of tags from the stream. Reading ends with End tag(=0) or end
* of the stream. Optinally can skip AS1/2 tags when file is AS3
*
* @param level
* @param paralel
* @param skipUnusualTags
* @return List of tags
* @throws IOException
*/
public List<Tag> readTagList(int level, boolean paralel, boolean skipUnusualTags) throws IOException {
ExecutorService executor = null;
if (paralel) {
executor = Executors.newFixedThreadPool(20);
@@ -1186,10 +1202,11 @@ public class SWFInputStream extends InputStream {
List<Tag> tags = new ArrayList<>();
Tag tag;
Tag previousTag = null;
boolean isAS3 = false;
while (true) {
long pos = getPos();
try {
tag = readTag(level, pos, false, paralel);
tag = readTag(level, pos, false, paralel, skipUnusualTags);
} catch (EndOfStreamException ex) {
tag = null;
}
@@ -1201,9 +1218,53 @@ public class SWFInputStream extends InputStream {
}
tag.previousTag = previousTag;
previousTag = tag;
boolean doParse = false;
if (!skipUnusualTags) {
doParse = true;
} else {
switch (tag.getId()) {
case FileAttributesTag.ID: //FileAttributes
FileAttributesTag fileAttributes = (FileAttributesTag) resolveTag(tag, version, level, paralel, skipUnusualTags);
if (fileAttributes.actionScript3) {
isAS3 = true;
}
break;
case DoActionTag.ID:
case DoInitActionTag.ID:
if (isAS3) {
doParse = false;
} else {
doParse = true;
}
break;
case ShowFrameTag.ID:
case PlaceObjectTag.ID:
case PlaceObject2Tag.ID:
case RemoveObjectTag.ID:
case RemoveObject2Tag.ID:
case PlaceObject3Tag.ID: //?
case StartSoundTag.ID:
case FrameLabelTag.ID:
case SoundStreamHeadTag.ID:
case SoundStreamHead2Tag.ID:
case SoundStreamBlockTag.ID:
doParse = true;
break;
default:
if (level > 0) { //No such tags in DefineSprite allowed
Logger.getLogger(SWFInputStream.class.getName()).log(Level.FINE, "Tag({0}) found in DefineSprite => Ignored", tag.getId());
doParse = false;
} else {
doParse = true;
}
Future<Tag> future = executor.submit(new TagResolutionTask(tag, version, level, paralel));
futureResults.add(future);
}
}
if (doParse) {
Future<Tag> future = executor.submit(new TagResolutionTask(tag, version, level, paralel, skipUnusualTags));
futureResults.add(future);
}
}
for (Future<Tag> future : futureResults) {
@@ -1217,7 +1278,7 @@ public class SWFInputStream extends InputStream {
return tags;
}
public static Tag resolveTag(Tag tag, int version, int level, boolean paralel) {
public static Tag resolveTag(Tag tag, int version, int level, boolean paralel, boolean skipUnusualTags) {
Tag ret;
byte data[] = tag.getData(version);
@@ -1326,7 +1387,7 @@ public class SWFInputStream extends InputStream {
break;
//case 38:
case 39:
ret = new DefineSpriteTag(data, version, level, pos, paralel);
ret = new DefineSpriteTag(data, version, level, pos, paralel, skipUnusualTags);
break;
//case 40:
case 41:
@@ -1459,11 +1520,12 @@ public class SWFInputStream extends InputStream {
* @param level
* @param pos
* @param paralel
* @param skipUnusualTags
* @return Tag or null when End tag
* @throws IOException
*/
public Tag readTag(int level, long pos, boolean paralel) throws IOException {
return readTag(level, pos, true, paralel);
public Tag readTag(int level, long pos, boolean paralel, boolean skipUnusualTags) throws IOException {
return readTag(level, pos, true, paralel, skipUnusualTags);
}
/**
@@ -1474,10 +1536,11 @@ public class SWFInputStream extends InputStream {
* @param pos
* @param resolve
* @param paralel
* @param skipUnusualTags
* @return Tag or null when End tag
* @throws IOException
*/
public Tag readTag(int level, long pos, boolean resolve, boolean paralel) throws IOException {
public Tag readTag(int level, long pos, boolean resolve, boolean paralel, boolean skipUnusualTags) throws IOException {
int tagIDTagLength = readUI16();
int tagID = (tagIDTagLength) >> 6;
if (tagID == 0) {
@@ -1526,7 +1589,7 @@ public class SWFInputStream extends InputStream {
}
}
if (resolve) {
return resolveTag(ret, version, level, paralel);
return resolveTag(ret, version, level, paralel, skipUnusualTags);
}
return ret;
}

View File

@@ -21,7 +21,9 @@ import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import java.awt.BorderLayout;
import java.awt.Image;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Stack;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
@@ -61,7 +63,7 @@ public class ImagePanel extends JPanel {
return;
}
if (drawable.getNumFrames() == 1) {
setImage(drawable.toImage(0, swf.tags, swf.displayRect, characters));
setImage(drawable.toImage(0, swf.tags, swf.displayRect, characters, new Stack<Integer>()));
return;
}
timer = new Timer();
@@ -72,7 +74,7 @@ public class ImagePanel extends JPanel {
public void run() {
int nframe = percent * drawable.getNumFrames() / 100;
if (nframe != frame) {
ImageIcon icon = new ImageIcon(drawable.toImage(nframe, swf.tags, swf.displayRect, characters));
ImageIcon icon = new ImageIcon(drawable.toImage(nframe, swf.tags, swf.displayRect, characters, new Stack<Integer>()));
label.setIcon(icon);
}
if (percent == 100) {

View File

@@ -66,13 +66,13 @@ import com.jpexs.decompiler.flash.tags.EndTag;
import com.jpexs.decompiler.flash.tags.ExportAssetsTag;
import com.jpexs.decompiler.flash.tags.JPEGTablesTag;
import com.jpexs.decompiler.flash.tags.PlaceObject2Tag;
import com.jpexs.decompiler.flash.tags.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
import com.jpexs.decompiler.flash.tags.SoundStreamHead2Tag;
import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag;
import com.jpexs.decompiler.flash.tags.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.tags.SymbolClassTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
@@ -133,6 +133,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
@@ -2243,9 +2244,9 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection
if (fn.getParent() instanceof DefineSpriteTag) {
controlTags = ((DefineSpriteTag) fn.getParent()).subTags;
containerId = ((DefineSpriteTag) fn.getParent()).spriteId;
rect = ((DefineSpriteTag) fn.getParent()).getRect(characters);
rect = ((DefineSpriteTag) fn.getParent()).getRect(characters, new Stack<Integer>());
}
previewImagePanel.setImage(SWF.frameToImage(containerId, ((FrameNode) tagObj).getFrame() - 1, swf.tags, controlTags, rect, swf.frameCount));
previewImagePanel.setImage(SWF.frameToImage(containerId, ((FrameNode) tagObj).getFrame() - 1, swf.tags, controlTags, rect, swf.frameCount, new Stack<Integer>()));
} else if (((tagObj instanceof FrameNode) && ((FrameNode) tagObj).isDisplayed()) || ((tagObj instanceof CharacterTag) || (tagObj instanceof FontTag)) && (tagObj instanceof Tag)) {
try {
@@ -2291,7 +2292,7 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection
break;
}
Tag t = (Tag) o;
Set<Integer> needed = t.getDeepNeededCharacters(characters);
Set<Integer> needed = t.getDeepNeededCharacters(characters,new ArrayList<Integer>());
for (int n : needed) {
if (!doneCharacters.contains(n)) {
sos2.writeTag(characters.get(n));
@@ -2314,7 +2315,7 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection
}
mat = (MATRIX) Helper.deepCopy(mat);
if (parent instanceof BoundedTag) {
RECT r = ((BoundedTag) parent).getRect(characters);
RECT r = ((BoundedTag) parent).getRect(characters, new Stack<Integer>());
mat.translateX = mat.translateX + width / 2 - r.getWidth() / 2;
mat.translateY = mat.translateY + height / 2 - r.getHeight() / 2;
} else {
@@ -2335,7 +2336,7 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection
}
} else if (tagObj instanceof AloneTag) {
} else {
Set<Integer> needed = ((Tag) tagObj).getDeepNeededCharacters(characters);
Set<Integer> needed = ((Tag) tagObj).getDeepNeededCharacters(characters,new ArrayList<Integer>());
for (int n : needed) {
sos2.writeTag(characters.get(n));
}
@@ -2354,7 +2355,7 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection
mat.translateX = 0;
mat.translateY = 0;
if (tagObj instanceof BoundedTag) {
RECT r = ((BoundedTag) tagObj).getRect(characters);
RECT r = ((BoundedTag) tagObj).getRect(characters, new Stack<Integer>());
mat.translateX = -r.Xmin;
mat.translateY = -r.Ymin;
mat.translateX = mat.translateX + width / 2 - r.getWidth() / 2;

View File

@@ -22,6 +22,7 @@ import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JLabel;
@@ -61,7 +62,7 @@ public class SWFPreviwPanel extends JPanel {
@Override
public void run() {
buffering.setVisible(true);
SWF.framesToImage(0, frameImages, 1, swf.frameCount, swf.tags, swf.tags, swf.displayRect, swf.frameCount);
SWF.framesToImage(0, frameImages, 1, swf.frameCount, swf.tags, swf.tags, swf.displayRect, swf.frameCount, new Stack<Integer>());
buffering.setVisible(false);
}
}.start();

View File

@@ -29,6 +29,7 @@ public class DefineBinaryDataTag extends CharacterTag {
public int tag;
public byte binaryData[];
public long reserved;
public static final int ID = 87;
/**
* Gets data bytes
@@ -51,7 +52,7 @@ public class DefineBinaryDataTag extends CharacterTag {
}
public DefineBinaryDataTag(byte[] data, int version, long pos) throws IOException {
super(87, "DefineBinaryData", data, pos);
super(ID, "DefineBinaryData", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
tag = sis.readUI16();
reserved = sis.readUI32();

View File

@@ -32,6 +32,7 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
public int characterID;
public byte[] imageData;
public static final int ID = 21;
@Override
public int getCharacterID() {
@@ -53,7 +54,7 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
}
public DefineBitsJPEG2Tag(byte[] data, int version, long pos) throws IOException {
super(21, "DefineBitsJPEG2", data, pos);
super(ID, "DefineBitsJPEG2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterID = sis.readUI16();
imageData = sis.readBytes(sis.available());

View File

@@ -37,6 +37,7 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
public int characterID;
public byte imageData[];
public byte bitmapAlphaData[];
public static final int ID = 35;
@Override
public int getCharacterID() {
@@ -94,7 +95,7 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
}
public DefineBitsJPEG3Tag(byte[] data, int version, long pos) throws IOException {
super(35, "DefineBitsJPEG3", data, pos);
super(ID, "DefineBitsJPEG3", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterID = sis.readUI16();
long alphaDataOffset = sis.readUI32();

View File

@@ -43,6 +43,7 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
public int deblockParam;
public byte imageData[];
public byte bitmapAlphaData[];
public static final int ID = 90;
@Override
public int getCharacterID() {
@@ -129,7 +130,7 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
* @throws IOException
*/
public DefineBitsJPEG4Tag(byte data[], int version, long pos) throws IOException {
super(90, "DefineBitsJPEG4", data, pos);
super(ID, "DefineBitsJPEG4", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterID = sis.readUI16();
long alphaDataOffset = sis.readUI32();

View File

@@ -46,6 +46,7 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
public byte zlibBitmapData[]; //TODO: Parse ALPHACOLORMAPDATA,ALPHABITMAPDATA
public static final int FORMAT_8BIT_COLORMAPPED = 3;
public static final int FORMAT_32BIT_ARGB = 5;
public static final int ID = 36;
@Override
public int getCharacterID() {
@@ -87,7 +88,7 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
}
public DefineBitsLossless2Tag(byte[] data, int version, long pos) throws IOException {
super(36, "DefineBitsLossless2", data, pos);
super(ID, "DefineBitsLossless2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterID = sis.readUI16();
bitmapFormat = sis.readUI8();

View File

@@ -50,6 +50,7 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
private COLORMAPDATA colorMapData;
private BITMAPDATA bitmapData;
private boolean decompressed = false;
public static final int ID = 20;
@Override
public void setImage(byte data[]) throws IOException {
@@ -154,7 +155,7 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
}
public DefineBitsLosslessTag(byte[] data, int version, long pos) throws IOException {
super(20, "DefineBitsLossless", data, pos);
super(ID, "DefineBitsLossless", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterID = sis.readUI16();
bitmapFormat = sis.readUI8();

View File

@@ -33,6 +33,7 @@ public class DefineBitsTag extends ImageTag {
public int characterID;
public byte jpegData[];
private JPEGTablesTag jtt = null;
public static final int ID = 6;
@Override
public void setImage(byte data[]) {
@@ -45,7 +46,7 @@ public class DefineBitsTag extends ImageTag {
}
public DefineBitsTag(byte[] data, int version, long pos) throws IOException {
super(6, "DefineBits", data, pos);
super(ID, "DefineBits", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterID = sis.readUI16();
jpegData = sis.readBytes(sis.available());

View File

@@ -22,12 +22,14 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
import com.jpexs.decompiler.flash.helpers.Cache;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.Container;
import com.jpexs.decompiler.flash.types.BUTTONCONDACTION;
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
import com.jpexs.decompiler.flash.types.MATRIX;
import com.jpexs.decompiler.flash.types.RECT;
import java.awt.Color;
import java.awt.Point;
@@ -41,6 +43,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -68,6 +71,7 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
* Actions to execute at particular button events
*/
public List<BUTTONCONDACTION> actions = new ArrayList<>();
public static final int ID = 34;
@Override
public int getCharacterID() {
@@ -84,10 +88,11 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
*
* @param data Data bytes
* @param version SWF version
* @param pos
* @throws IOException
*/
public DefineButton2Tag(byte data[], int version, long pos) throws IOException {
super(34, "DefineButton2", data, pos);
super(ID, "DefineButton2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
buttonId = sis.readUI16();
sis.readUB(7); //reserved
@@ -196,20 +201,37 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
}
return needed;
}
private static Cache rectCache = new Cache(true);
@Override
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters) {
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {
if (rectCache.contains(this)) {
return (RECT) rectCache.get(this);
}
if (visited.contains(buttonId)) {
return new RECT();
}
visited.push(buttonId);
RECT rect = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
for (BUTTONRECORD r : characters) {
CharacterTag ch = allCharacters.get(r.characterId);
if (ch instanceof BoundedTag) {
RECT r2 = ((BoundedTag) ch).getRect(allCharacters);
if (visited.contains(ch.getCharacterID())) {
continue;
}
RECT r2 = ((BoundedTag) ch).getRect(allCharacters, visited);
MATRIX mat = r.placeMatrix;
if (mat != null) {
r2 = mat.apply(r2);
}
rect.Xmin = Math.min(r2.Xmin, rect.Xmin);
rect.Ymin = Math.min(r2.Ymin, rect.Ymin);
rect.Xmax = Math.max(r2.Xmax, rect.Xmax);
rect.Ymax = Math.max(r2.Ymax, rect.Ymax);
}
}
visited.pop();
rectCache.put(this, rect);
return rect;
}
@@ -219,7 +241,11 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters) {
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
if (visited.contains(buttonId)) {
return new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
}
visited.push(buttonId);
HashMap<Integer, Layer> layers = new HashMap<>();
int maxDepth = 0;
for (BUTTONRECORD r : this.characters) {
@@ -236,12 +262,18 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
layers.put(r.placeDepth, layer);
}
}
return SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect);
visited.pop();
displayRect = getRect(characters, visited);
visited.push(buttonId);
BufferedImage ret = SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect, visited);
return ret;
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters) {
return new Point(0, 0);
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
RECT r=getRect(characters, visited);
return new Point(r.Xmin/20, r.Ymin/20);
}
@Override

View File

@@ -33,6 +33,7 @@ public class DefineButtonCxformTag extends Tag {
public int buttonId;
public CXFORM buttonColorTransform;
public static final int ID = 23;
/**
* Gets data bytes
@@ -61,7 +62,7 @@ public class DefineButtonCxformTag extends Tag {
* @throws IOException
*/
public DefineButtonCxformTag(byte data[], int version, long pos) throws IOException {
super(23, "DefineButtonCxform", data, pos);
super(ID, "DefineButtonCxform", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
buttonId = sis.readUI16();
buttonColorTransform = sis.readCXFORM();

View File

@@ -41,6 +41,7 @@ public class DefineButtonSoundTag extends CharacterTag {
public SOUNDINFO buttonSoundInfo2;
public int buttonSoundChar3;
public SOUNDINFO buttonSoundInfo3;
public static final int ID = 17;
@Override
public int getCharacterID() {
@@ -89,7 +90,7 @@ public class DefineButtonSoundTag extends CharacterTag {
* @throws IOException
*/
public DefineButtonSoundTag(byte data[], int version, long pos) throws IOException {
super(17, "DefineButtonSound", data, pos);
super(ID, "DefineButtonSound", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
buttonId = sis.readUI16();
buttonSoundChar0 = sis.readUI16();

View File

@@ -25,11 +25,13 @@ import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.helpers.Cache;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
import com.jpexs.decompiler.flash.types.MATRIX;
import com.jpexs.decompiler.flash.types.RECT;
import java.awt.Color;
import java.awt.Point;
@@ -43,6 +45,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -66,6 +69,7 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
*/
//public List<Action> actions;
public byte[] actionBytes;
public static final int ID = 7;
@Override
public int getCharacterID() {
@@ -87,7 +91,7 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
* @throws IOException
*/
public DefineButtonTag(byte[] data, int version, long pos) throws IOException {
super(7, "DefineButton", data, pos);
super(ID, "DefineButton", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
buttonId = sis.readUI16();
characters = sis.readBUTTONRECORDList(false);
@@ -200,20 +204,37 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
}
return needed;
}
private static Cache rectCache = new Cache(true);
@Override
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters) {
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {
if (rectCache.contains(this)) {
return (RECT) rectCache.get(this);
}
if (visited.contains(buttonId)) {
return new RECT();
}
visited.push(buttonId);
RECT rect = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
for (BUTTONRECORD r : characters) {
CharacterTag ch = allCharacters.get(r.characterId);
if (ch instanceof BoundedTag) {
RECT r2 = ((BoundedTag) ch).getRect(allCharacters);
if (visited.contains(ch.getCharacterID())) {
continue;
}
RECT r2 = ((BoundedTag) ch).getRect(allCharacters, visited);
MATRIX mat = r.placeMatrix;
if (mat != null) {
r2 = mat.apply(r2);
}
rect.Xmin = Math.min(r2.Xmin, rect.Xmin);
rect.Ymin = Math.min(r2.Ymin, rect.Ymin);
rect.Xmax = Math.max(r2.Xmax, rect.Xmax);
rect.Ymax = Math.max(r2.Ymax, rect.Ymax);
}
}
visited.pop();
rectCache.put(this, rect);
return rect;
}
List<DisassemblyListener> listeners = new ArrayList<>();
@@ -234,7 +255,11 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters) {
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
if (visited.contains(buttonId)) {
return new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
}
visited.push(buttonId);
HashMap<Integer, Layer> layers = new HashMap<>();
int maxDepth = 0;
for (BUTTONRECORD r : this.characters) {
@@ -251,12 +276,18 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
layers.put(r.placeDepth, layer);
}
}
return SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect);
visited.pop();
displayRect = getRect(characters, visited);
visited.push(buttonId);
BufferedImage ret = SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect, visited);
visited.pop();
return ret;
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters) {
return new Point(0, 0);
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
RECT r=getRect(characters, visited);
return new Point(r.Xmin/20, r.Ymin/20);
}
@Override

View File

@@ -36,6 +36,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
@@ -78,6 +79,7 @@ public class DefineEditTextTag extends CharacterTag implements BoundedTag, TextT
public int leading;
public String variableName;
public String initialText;
public static final int ID = 37;
@Override
public RECT getBounds() {
@@ -381,7 +383,7 @@ public class DefineEditTextTag extends CharacterTag implements BoundedTag, TextT
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters) {
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {
return bounds;
}
@@ -457,10 +459,11 @@ public class DefineEditTextTag extends CharacterTag implements BoundedTag, TextT
*
* @param data Data bytes
* @param version SWF version
* @param pos
* @throws IOException
*/
public DefineEditTextTag(byte data[], int version, long pos) throws IOException {
super(37, "DefineEditText", data, pos);
super(ID, "DefineEditText", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterID = sis.readUI16();
bounds = sis.readRECT();

View File

@@ -58,6 +58,7 @@ public class DefineFont2Tag extends CharacterTag implements FontTag {
public int fontAdvanceTable[];
public RECT fontBoundsTable[];
public KERNINGRECORD fontKerningTable[];
public static final int ID = 48;
@Override
public boolean isSmall() {
@@ -166,7 +167,7 @@ public class DefineFont2Tag extends CharacterTag implements FontTag {
* @throws IOException
*/
public DefineFont2Tag(byte data[], int version, long pos) throws IOException {
super(48, "DefineFont2", data, pos);
super(ID, "DefineFont2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
fontId = sis.readUI16();
fontFlagsHasLayout = sis.readUB(1) == 1;

View File

@@ -56,6 +56,7 @@ public class DefineFont3Tag extends CharacterTag implements FontTag {
public int fontAdvanceTable[];
public RECT fontBoundsTable[];
public KERNINGRECORD fontKerningTable[];
public static final int ID = 75;
@Override
public boolean isSmall() {
@@ -87,7 +88,7 @@ public class DefineFont3Tag extends CharacterTag implements FontTag {
}
public DefineFont3Tag(byte[] data, int version, long pos) throws IOException {
super(75, "DefineFont3", data, pos);
super(ID, "DefineFont3", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
fontId = sis.readUI16();
fontFlagsHasLayout = sis.readUB(1) == 1;

View File

@@ -32,6 +32,7 @@ public class DefineFont4Tag extends CharacterTag {
public boolean fontFlagsBold;
public String fontName;
public byte fontData[];
public static final int ID = 91;
@Override
public int getCharacterID() {
@@ -39,7 +40,7 @@ public class DefineFont4Tag extends CharacterTag {
}
public DefineFont4Tag(byte[] data, int version, long pos) throws IOException {
super(91, "DefineFont4", data, pos);
super(ID, "DefineFont4", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
fontID = sis.readUI16();
sis.readUB(5);

View File

@@ -31,9 +31,10 @@ public class DefineFontAlignZonesTag extends Tag {
public int fontID;
public int CSMTableHint;
public List<ZONERECORD> zoneTable;
public static final int ID = 73;
public DefineFontAlignZonesTag(byte[] data, int version, long pos) throws IOException {
super(73, "DefineFontAlignZones", data, pos);
super(ID, "DefineFontAlignZones", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
fontID = sis.readUI16();
CSMTableHint = (int) sis.readUB(2);

View File

@@ -43,6 +43,7 @@ public class DefineFontInfo2Tag extends Tag {
public boolean fontFlagsWideCodes;
public LANGCODE languageCode;
public List<Integer> codeTable;
public static final int ID = 62;
/**
* Gets data bytes
@@ -83,7 +84,7 @@ public class DefineFontInfo2Tag extends Tag {
* @throws IOException
*/
public DefineFontInfo2Tag(byte data[], int version, long pos) throws IOException {
super(62, "DefineFontInfo2", data, pos);
super(ID, "DefineFontInfo2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
fontID = sis.readUI16();
int fontNameLen = sis.readUI8();

View File

@@ -41,6 +41,7 @@ public class DefineFontInfoTag extends Tag {
public boolean fontFlagsBold;
public boolean fontFlagsWideCodes;
public List<Integer> codeTable;
public static final int ID = 13;
/**
* Gets data bytes
@@ -81,10 +82,11 @@ public class DefineFontInfoTag extends Tag {
*
* @param data Data bytes
* @param version SWF version
* @param pos
* @throws IOException
*/
public DefineFontInfoTag(byte data[], int version, long pos) throws IOException {
super(13, "DefineFontInfo", data, pos);
super(ID, "DefineFontInfo", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
fontId = sis.readUI16();
int fontNameLen = sis.readUI8();

View File

@@ -25,9 +25,10 @@ public class DefineFontNameTag extends Tag {
public int fontId;
public String fontName;
public String fontCopyright;
public static final int ID = 88;
public DefineFontNameTag(byte[] data, int version, long pos) throws IOException {
super(88, "DefineFontName", data, pos);
super(ID, "DefineFontName", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
fontId = sis.readUI16();
fontName = sis.readString();

View File

@@ -25,6 +25,9 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
@@ -127,6 +130,7 @@ public class DefineFontTag extends CharacterTag implements FontTag {
*
* @param data Data bytes
* @param version SWF version
* @param pos
* @throws IOException
*/
public DefineFontTag(byte data[], int version, long pos) throws IOException {

View File

@@ -45,6 +45,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
/**
*
@@ -64,6 +65,7 @@ public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, Mo
public MORPHLINESTYLEARRAY morphLineStyles;
public SHAPE startEdges;
public SHAPE endEdges;
public static final int ID = 84;
@Override
public Set<Integer> getNeededCharacters() {
@@ -75,7 +77,7 @@ public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, Mo
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters) {
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
RECT rect = new RECT();
rect.Xmin = Math.min(startBounds.Xmin, endBounds.Xmin);
rect.Ymin = Math.min(startBounds.Ymin, endBounds.Ymin);
@@ -128,10 +130,11 @@ public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, Mo
*
* @param data Data bytes
* @param version SWF version
* @param pos
* @throws IOException
*/
public DefineMorphShape2Tag(byte data[], int version, long pos) throws IOException {
super(84, "DefineMorphShape2", data, pos);
super(ID, "DefineMorphShape2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterId = sis.readUI16();
startBounds = sis.readRECT();
@@ -189,7 +192,7 @@ public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, Mo
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters) {
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
List<SHAPERECORD> finalRecords = new ArrayList<>();
FILLSTYLEARRAY fillStyles = morphFillStyles.getFillStylesAt(frame);
LINESTYLEARRAY lineStyles = morphLineStyles.getLineStylesAt(getShapeNum(), frame);
@@ -262,7 +265,7 @@ public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, Mo
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters) {
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(
(startBounds.Xmin + (endBounds.Xmin - startBounds.Xmin) * frame / 65535) / 20,
(startBounds.Ymin + (endBounds.Ymin - startBounds.Ymin) * frame / 65535) / 20);

View File

@@ -45,6 +45,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
/**
*
@@ -60,6 +61,7 @@ public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, Mor
public MORPHLINESTYLEARRAY morphLineStyles;
public SHAPE startEdges;
public SHAPE endEdges;
public static final int ID = 46;
@Override
public Set<Integer> getNeededCharacters() {
@@ -114,7 +116,7 @@ public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, Mor
* @throws IOException
*/
public DefineMorphShapeTag(byte data[], int version, long pos) throws IOException {
super(46, "DefineMorphShape", data, pos);
super(ID, "DefineMorphShape", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterId = sis.readUI16();
startBounds = sis.readRECT();
@@ -127,7 +129,7 @@ public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, Mor
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters) {
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
RECT rect = new RECT();
rect.Xmin = Math.min(startBounds.Xmin, endBounds.Xmin);
rect.Ymin = Math.min(startBounds.Ymin, endBounds.Ymin);
@@ -177,7 +179,7 @@ public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, Mor
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters) {
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
List<SHAPERECORD> finalRecords = new ArrayList<>();
FILLSTYLEARRAY fillStyles = morphFillStyles.getFillStylesAt(frame);
LINESTYLEARRAY lineStyles = morphLineStyles.getLineStylesAt(getShapeNum(), frame);
@@ -250,7 +252,7 @@ public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, Mor
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters) {
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(
(startBounds.Xmin + (endBounds.Xmin - startBounds.Xmin) * frame / 65535) / 20,
(startBounds.Ymin + (endBounds.Ymin - startBounds.Ymin) * frame / 65535) / 20);

View File

@@ -31,9 +31,10 @@ public class DefineScalingGridTag extends Tag {
private int characterId;
private RECT splitter;
public static final int ID = 78;
public DefineScalingGridTag(byte[] data, int version, long pos) throws IOException {
super(78, "DefineScalingGrid", data, pos);
super(ID, "DefineScalingGrid", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterId = sis.readUI16();
splitter = sis.readRECT();

View File

@@ -34,6 +34,7 @@ public class DefineSceneAndFrameLabelDataTag extends Tag {
public String sceneNames[];
public long frameNums[];
public String frameNames[];
public static final int ID = 86;
/**
* Gets data bytes
@@ -72,7 +73,7 @@ public class DefineSceneAndFrameLabelDataTag extends Tag {
* @throws IOException
*/
public DefineSceneAndFrameLabelDataTag(byte data[], int version, long pos) throws IOException {
super(86, "DefineSceneAndFrameLabelData", data, pos);
super(ID, "DefineSceneAndFrameLabelData", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
int sceneCount = (int) sis.readEncodedU32();
sceneOffsets = new long[sceneCount];

View File

@@ -31,15 +31,17 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Stack;
public class DefineShape2Tag extends CharacterTag implements BoundedTag, ShapeTag {
public int shapeId;
public RECT shapeBounds;
public SHAPEWITHSTYLE shapes;
public static final int ID = 22;
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters) {
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(shapeBounds.Xmin / 20, shapeBounds.Ymin / 20);
}
@@ -64,7 +66,7 @@ public class DefineShape2Tag extends CharacterTag implements BoundedTag, ShapeTa
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters) {
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return shapes.toImage(2, tags);
}
@@ -74,12 +76,12 @@ public class DefineShape2Tag extends CharacterTag implements BoundedTag, ShapeTa
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters) {
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return shapeBounds;
}
public DefineShape2Tag(byte[] data, int version, long pos) throws IOException {
super(22, "DefineShape2", data, pos);
super(ID, "DefineShape2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
shapeId = sis.readUI16();
shapeBounds = sis.readRECT();

View File

@@ -31,15 +31,17 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Stack;
public class DefineShape3Tag extends CharacterTag implements BoundedTag, ShapeTag {
public int shapeId;
public RECT shapeBounds;
public SHAPEWITHSTYLE shapes;
public static final int ID = 32;
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters) {
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(shapeBounds.Xmin / 20, shapeBounds.Ymin / 20);
}
@@ -59,7 +61,7 @@ public class DefineShape3Tag extends CharacterTag implements BoundedTag, ShapeTa
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters) {
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return shapeBounds;
}
@@ -69,7 +71,7 @@ public class DefineShape3Tag extends CharacterTag implements BoundedTag, ShapeTa
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters) {
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return shapes.toImage(3, tags);
}
@@ -79,7 +81,7 @@ public class DefineShape3Tag extends CharacterTag implements BoundedTag, ShapeTa
}
public DefineShape3Tag(byte[] data, int version, long pos) throws IOException {
super(32, "DefineShape3", data, pos);
super(ID, "DefineShape3", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
shapeId = sis.readUI16();
shapeBounds = sis.readRECT();

View File

@@ -31,6 +31,7 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Stack;
public class DefineShape4Tag extends CharacterTag implements BoundedTag, ShapeTag {
@@ -41,9 +42,10 @@ public class DefineShape4Tag extends CharacterTag implements BoundedTag, ShapeTa
public boolean usesNonScalingStrokes;
public boolean usesScalingStrokes;
public SHAPEWITHSTYLE shapes;
public static final int ID = 83;
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters) {
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(shapeBounds.Xmin / 20, shapeBounds.Ymin / 20);
}
@@ -68,7 +70,7 @@ public class DefineShape4Tag extends CharacterTag implements BoundedTag, ShapeTa
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters) {
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return shapes.toImage(4, tags);
}
@@ -78,12 +80,12 @@ public class DefineShape4Tag extends CharacterTag implements BoundedTag, ShapeTa
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters) {
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return shapeBounds;
}
public DefineShape4Tag(byte[] data, int version, long pos) throws IOException {
super(83, "DefineShape4", data, pos);
super(ID, "DefineShape4", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
shapeId = sis.readUI16();
shapeBounds = sis.readRECT();

View File

@@ -31,12 +31,14 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Stack;
public class DefineShapeTag extends CharacterTag implements BoundedTag, ShapeTag {
public int shapeId;
public RECT shapeBounds;
public SHAPEWITHSTYLE shapes;
public static final int ID = 2;
@Override
public int getShapeNum() {
@@ -54,12 +56,12 @@ public class DefineShapeTag extends CharacterTag implements BoundedTag, ShapeTag
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters) {
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return shapeBounds;
}
public DefineShapeTag(byte[] data, int version, long pos) throws IOException {
super(2, "DefineShape", data, pos);
super(ID, "DefineShape", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
shapeId = sis.readUI16();
shapeBounds = sis.readRECT();
@@ -77,12 +79,12 @@ public class DefineShapeTag extends CharacterTag implements BoundedTag, ShapeTag
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters) {
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return shapes.toImage(1, tags);
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters) {
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(shapeBounds.Xmin / 20, shapeBounds.Ymin / 20);
}

View File

@@ -46,6 +46,7 @@ public class DefineSoundTag extends CharacterTag {
public int soundType;
public long soundSampleCount;
public byte soundData[];
public static final int ID = 14;
@Override
public int getCharacterID() {
@@ -84,7 +85,7 @@ public class DefineSoundTag extends CharacterTag {
* @throws IOException
*/
public DefineSoundTag(byte data[], int version, long pos) throws IOException {
super(14, "DefineSound", data, pos);
super(ID, "DefineSound", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
soundId = sis.readUI16();
soundFormat = (int) sis.readUB(4);

View File

@@ -16,11 +16,13 @@
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.Configuration;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
import com.jpexs.decompiler.flash.helpers.Cache;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.Container;
@@ -39,6 +41,9 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Defines a sprite character
@@ -58,20 +63,30 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
*/
public List<Tag> subTags;
private int level;
public static final int ID = 39;
@Override
public int getCharacterID() {
return spriteId;
}
private RECT getCharacterBounds(HashMap<Integer, CharacterTag> allCharacters, Set<Integer> characters) {
private RECT getCharacterBounds(HashMap<Integer, CharacterTag> allCharacters, Set<Integer> characters, Stack<Integer> visited) {
if (visited.contains(spriteId)) {
return new RECT();
}
visited.push(spriteId);
RECT ret = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
boolean foundSomething = false;
for (int c : characters) {
Tag t = allCharacters.get(c);
RECT r = null;
if (t instanceof BoundedTag) {
r = ((BoundedTag) t).getRect(allCharacters);
if (t instanceof CharacterTag) {
if (visited.contains(((CharacterTag) t).getCharacterID())) {
continue;
}
}
r = ((BoundedTag) t).getRect(allCharacters, visited);
}
if (r != null) {
foundSomething = true;
@@ -81,18 +96,30 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
ret.Ymax = Math.max(r.Ymax, ret.Ymax);
}
}
visited.pop();
if (!foundSomething) {
return new RECT();
}
return ret;
}
private static Cache rectCache = new Cache(true);
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters) {
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
if (rectCache.contains(this)) {
return (RECT) rectCache.get(this);
}
if (visited.contains(spriteId)) {
return new RECT();
}
visited.push(spriteId);
RECT emptyRet = new RECT();
RECT ret = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
HashMap<Integer, Integer> depthMap = new HashMap<>();
boolean foundSomething = false;
int pos = 0;
for (Tag t : subTags) {
pos++;
MATRIX m = null;
int characterId = -1;
if (t instanceof PlaceObjectTypeTag) {
@@ -110,8 +137,13 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
continue;
}
HashSet<Integer> need = new HashSet<>();
if (visited.contains(characterId)) {
continue;
}
need.add(characterId);
RECT r = getCharacterBounds(characters, need);
visited.pop();
RECT r = getCharacterBounds(characters, need, visited);
visited.push(spriteId);
if (m != null) {
AffineTransform trans = SWF.matrixToTransform(m);
@@ -137,9 +169,12 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
ret.Ymax = Math.max(r.Ymax, ret.Ymax);
foundSomething = true;
}
visited.pop();
if (!foundSomething) {
return new RECT();
ret = new RECT();
}
rectCache.put(this, ret);
return ret;
}
@@ -148,14 +183,18 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
*
* @param data Data bytes
* @param version SWF version
* @param level
* @param pos
* @param paralel
* @param skipUnusualTags
* @throws IOException
*/
public DefineSpriteTag(byte[] data, int version, int level, long pos, boolean paralel) throws IOException {
super(39, "DefineSprite", data, pos);
public DefineSpriteTag(byte[] data, int version, int level, long pos, boolean paralel, boolean skipUnusualTags) throws IOException {
super(ID, "DefineSprite", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version, pos);
spriteId = sis.readUI16();
frameCount = sis.readUI16();
subTags = sis.readTagList(level + 1, paralel);
subTags = sis.readTagList(level + 1, paralel, skipUnusualTags);
}
static int c = 0;
@@ -229,7 +268,10 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters) {
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
if (visited.contains(spriteId)) {
return new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
}
/*
rect.Xmax=displayRect.Xmin+rect.getWidth();
rect.Ymax=displayRect.Ymin+rect.getWidth();
@@ -237,13 +279,16 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
rect.Ymin=displayRect.Ymin;
RECT rect=getRect(characters);
SWF.fixRect(rect);*/
RECT rect = getRect(characters);
return SWF.frameToImage(spriteId, frame, tags, subTags, rect, frameCount);
RECT rect = getRect(characters, visited);
visited.push(spriteId);
BufferedImage ret = SWF.frameToImage(spriteId, frame, tags, subTags, rect, frameCount, visited);
visited.pop();
return ret;
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters) {
RECT displayRect = getRect(characters);
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
//RECT displayRect = getRect(characters, visited); //use visited
return new Point(0, 0); //displayRect.Xmin,displayRect.Ymin);
}

View File

@@ -51,6 +51,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
@@ -69,6 +70,7 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag,
public int glyphBits;
public int advanceBits;
public List<TEXTRECORD> textRecords;
public static final int ID = 33;
@Override
public RECT getBounds() {
@@ -374,7 +376,7 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag,
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters) {
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return textBounds;
}
@@ -418,7 +420,7 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag,
* @throws IOException
*/
public DefineText2Tag(byte data[], int version, long pos) throws IOException {
super(33, "DefineText2", data, pos);
super(ID, "DefineText2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterID = sis.readUI16();
textBounds = sis.readRECT();
@@ -444,7 +446,7 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag,
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters) {
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
RECT bound = getBounds();
BufferedImage ret = new BufferedImage(bound.Xmax / 20, bound.Ymax / 20, BufferedImage.TYPE_INT_ARGB);
Color textColor = new Color(0, 0, 0);
@@ -493,8 +495,8 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag,
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters) {
return new Point(0, 0);
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(textBounds.Xmin / 20, textBounds.Ymin / 20);
}
@Override

View File

@@ -51,6 +51,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
@@ -69,6 +70,7 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag,
public int glyphBits;
public int advanceBits;
public List<TEXTRECORD> textRecords;
public static final int ID = 11;
@Override
public RECT getBounds() {
@@ -379,7 +381,7 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag,
}
public DefineTextTag(int characterID, RECT textBounds, MATRIX textMatrix, int glyphBits, int advanceBits, List<TEXTRECORD> textRecords) {
super(11, "DefineText", new byte[0], 0);
super(ID, "DefineText", new byte[0], 0);
this.characterID = characterID;
this.textBounds = textBounds;
this.textMatrix = textMatrix;
@@ -438,7 +440,7 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag,
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters) {
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return textBounds;
}
@@ -454,9 +456,11 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag,
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters) {
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
RECT bound = getBounds();
BufferedImage ret = new BufferedImage(bound.Xmax / 20, bound.Ymax / 20, BufferedImage.TYPE_INT_ARGB);
int fixX = -bound.Xmin;
int fixY = -bound.Ymin;
BufferedImage ret = new BufferedImage(bound.getWidth() / 20, bound.getHeight() / 20, BufferedImage.TYPE_INT_ARGB);
Color textColor = new Color(0, 0, 0);
FontTag font = null;
@@ -496,6 +500,7 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag,
float rat = textHeight / 1000f;
tr.translate(rat * x / 20, rat * (y + rect.Ymin) / 20);
tr.scale(rat / font.getDivider(), rat / font.getDivider());
tr.translate(fixX, fixY);
g.drawImage(img, tr, null);
x += entry.glyphAdvance * 1000 / textHeight;
}
@@ -504,8 +509,8 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag,
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters) {
return new Point(0, 0);
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(textBounds.Xmin / 20, textBounds.Ymin / 20);
}
@Override

View File

@@ -42,6 +42,7 @@ public class DefineVideoStreamTag extends CharacterTag {
public static final int CODEC_SCREEN_VIDEO = 3;
public static final int CODEC_VP6 = 4;
public static final int CODEC_VP6_ALPHA = 5;
public static final int ID = 60;
@Override
public int getCharacterID() {
@@ -81,7 +82,7 @@ public class DefineVideoStreamTag extends CharacterTag {
* @throws IOException
*/
public DefineVideoStreamTag(byte data[], int version, long pos) throws IOException {
super(60, "DefineVideoStream", data, pos);
super(ID, "DefineVideoStream", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterID = sis.readUI16();
numFrames = sis.readUI16();

View File

@@ -47,6 +47,7 @@ public class DoABCDefineTag extends Tag implements ABCContainerTag {
* The name assigned to the bytecode.
*/
public String name;
public static final int ID = 82;
@Override
public String getName() {
@@ -61,7 +62,7 @@ public class DoABCDefineTag extends Tag implements ABCContainerTag {
* @throws IOException
*/
public DoABCDefineTag(byte[] data, int version, long pos) throws IOException {
super(82, "DoABCDefine", data, pos);
super(ID, "DoABCDefine", data, pos);
InputStream is = new ByteArrayInputStream(data);
SWFInputStream sis = new SWFInputStream(is, version);
flags = sis.readUI32();

View File

@@ -31,6 +31,7 @@ public class DoABCTag extends Tag implements ABCContainerTag {
* ActionScript 3 bytecodes
*/
private ABC abc;
public static final int ID = 72;
@Override
public ABC getABC() {
@@ -50,7 +51,7 @@ public class DoABCTag extends Tag implements ABCContainerTag {
* @throws IOException
*/
public DoABCTag(byte[] data, int version, long pos) throws IOException {
super(72, "DoABC", data, pos);
super(ID, "DoABC", data, pos);
InputStream is = new ByteArrayInputStream(data);
abc = new ABC(is);
}

View File

@@ -42,16 +42,17 @@ public class DoActionTag extends Tag implements ASMSource {
*/
//public List<Action> actions = new ArrayList<Action>();
public byte[] actionBytes;
public static final int ID = 12;
/**
* Constructor
*
* @param data Data bytes
* @param version SWF version
* @throws IOException
* @param pos
*/
public DoActionTag(byte[] data, int version, long pos) {
super(12, "DoAction", data, pos);
super(ID, "DoAction", data, pos);
actionBytes = data;
}

View File

@@ -44,6 +44,7 @@ public class DoInitActionTag extends CharacterIdTag implements ASMSource {
*/
//public List<Action> actions = new ArrayList<Action>();
public byte[] actionBytes;
public static final int ID = 59;
/**
* Constructor
@@ -53,7 +54,7 @@ public class DoInitActionTag extends CharacterIdTag implements ASMSource {
* @throws IOException
*/
public DoInitActionTag(byte[] data, int version, long pos) throws IOException {
super(59, "DoInitAction", data, pos);
super(ID, "DoInitAction", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
spriteId = sis.readUI16();
//actions = sis.readActionList();

View File

@@ -35,6 +35,7 @@ public class EnableDebugger2Tag extends Tag {
* MD5 hash of password
*/
public String passwordHash;
public static final int ID = 64;
/**
* Gets data bytes
@@ -64,7 +65,7 @@ public class EnableDebugger2Tag extends Tag {
* @throws IOException
*/
public EnableDebugger2Tag(byte data[], int version, long pos) throws IOException {
super(64, "EnableDebugger2", data, pos);
super(ID, "EnableDebugger2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
reserved = sis.readUI16();
passwordHash = sis.readString();

View File

@@ -34,6 +34,7 @@ public class EnableDebuggerTag extends Tag {
* MD5 hash of password
*/
public String passwordHash;
public static final int ID = 58;
/**
* Gets data bytes
@@ -63,7 +64,7 @@ public class EnableDebuggerTag extends Tag {
* @throws IOException
*/
public EnableDebuggerTag(byte data[], int version, long pos) throws IOException {
super(58, "EnableDebugger", data, pos);
super(ID, "EnableDebugger", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
passwordHash = sis.readString();
}

View File

@@ -35,6 +35,7 @@ public class EndTag extends Tag {
public byte[] getData(int version) {
return new byte[0];
}
public static final int ID = 0;
/**
* Constructor
@@ -44,7 +45,7 @@ public class EndTag extends Tag {
* @throws IOException
*/
public EndTag(byte data[], int version, long pos) throws IOException {
super(0, "End", data, pos);
super(ID, "End", data, pos);
}

View File

@@ -37,6 +37,7 @@ public class ExportAssetsTag extends Tag {
*/
public List<Integer> tags;
public List<String> names;
public static final int ID = 56;
/**
* Constructor
@@ -46,7 +47,7 @@ public class ExportAssetsTag extends Tag {
* @throws IOException
*/
public ExportAssetsTag(byte[] data, int version, long pos) throws IOException {
super(56, "ExportAssets", data, pos);
super(ID, "ExportAssets", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
int count = sis.readUI16();
tags = new ArrayList<>();

View File

@@ -34,9 +34,10 @@ public class FileAttributesTag extends Tag {
private int reserved1;
private int reserved2;
private int reserved3;
public static final int ID = 69;
public FileAttributesTag(byte[] data, int version, long pos) throws IOException {
super(69, "FileAttributes", data, pos);
super(ID, "FileAttributes", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
reserved1 = (int) sis.readUB(1); // reserved
// UB[1] == 0 (reserved)

View File

@@ -27,6 +27,7 @@ public class FrameLabelTag extends Tag {
private String name;
private boolean namedAnchor = false;
public static final int ID = 43;
public String getLabelName() {
return name;
@@ -37,7 +38,7 @@ public class FrameLabelTag extends Tag {
}
public FrameLabelTag(byte[] data, int version, long pos) throws IOException {
super(43, "FrameLabel", data, pos);
super(ID, "FrameLabel", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
name = sis.readString();
if (sis.available() > 0) {

View File

@@ -37,6 +37,7 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
* HashMap with assets
*/
public HashMap<Integer, String> assets;
public static final int ID = 71;
/**
* Constructor
@@ -46,7 +47,7 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
* @throws IOException
*/
public ImportAssets2Tag(byte data[], int version, long pos) throws IOException {
super(71, "ImportAssets2", data, pos);
super(ID, "ImportAssets2", data, pos);
assets = new HashMap<>();
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
url = sis.readString();

View File

@@ -37,6 +37,7 @@ public class ImportAssetsTag extends Tag implements ImportTag {
* HashMap with assets
*/
public HashMap<Integer, String> assets;
public static final int ID = 57;
/**
* Constructor
@@ -46,7 +47,7 @@ public class ImportAssetsTag extends Tag implements ImportTag {
* @throws IOException
*/
public ImportAssetsTag(byte data[], int version, long pos) throws IOException {
super(57, "ImportAssets", data, pos);
super(ID, "ImportAssets", data, pos);
assets = new HashMap<>();
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
url = sis.readString();

View File

@@ -20,7 +20,9 @@ import java.io.IOException;
public class JPEGTablesTag extends Tag {
public static final int ID = 8;
public JPEGTablesTag(byte[] data, long pos) throws IOException {
super(8, "JPEGTables", data, pos); //data is JPEG data
super(ID, "JPEGTables", data, pos); //data is JPEG data
}
}

View File

@@ -26,9 +26,10 @@ import java.io.OutputStream;
public class MetadataTag extends Tag {
public String xmlMetadata;
public static final int ID = 77;
public MetadataTag(byte[] data, int version, long pos) {
super(77, "Metadata", data, pos);
super(ID, "Metadata", data, pos);
try {
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
xmlMetadata = sis.readString();

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.Configuration;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
@@ -107,6 +108,7 @@ public class PlaceObject2Tag extends Tag implements Container, PlaceObjectTypeTa
* @since SWF 5 If PlaceFlagHasClipActions, Clip Actions Data
*/
public CLIPACTIONS clipActions;
public static final int ID = 26;
@Override
public int getClipDepth() {
@@ -176,7 +178,7 @@ public class PlaceObject2Tag extends Tag implements Container, PlaceObjectTypeTa
}
public PlaceObject2Tag(boolean placeFlagHasClipActions, boolean placeFlagHasClipDepth, boolean placeFlagHasName, boolean placeFlagHasRatio, boolean placeFlagHasColorTransform, boolean placeFlagHasMatrix, boolean placeFlagHasCharacter, boolean placeFlagMove, int depth, int characterId, MATRIX matrix, CXFORMWITHALPHA colorTransform, int ratio, String name, int clipDepth, CLIPACTIONS clipActions) {
super(26, "PlaceObject2", new byte[0], 0);
super(ID, "PlaceObject2", new byte[0], 0);
this.placeFlagHasClipActions = placeFlagHasClipActions;
this.placeFlagHasClipDepth = placeFlagHasClipDepth;
this.placeFlagHasName = placeFlagHasName;

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.Configuration;
import com.jpexs.decompiler.flash.EndOfStreamException;
import com.jpexs.decompiler.flash.SWFInputStream;
@@ -167,6 +168,7 @@ public class PlaceObject3Tag extends Tag implements Container, PlaceObjectTypeTa
// FIXME bug found in ecoDrive.swf,
private boolean bitmapCacheBug;
private int reserved;
public static final int ID = 70;
@Override
public List<FILTER> getFilters() {
@@ -276,7 +278,7 @@ public class PlaceObject3Tag extends Tag implements Container, PlaceObjectTypeTa
* @throws IOException
*/
public PlaceObject3Tag(byte data[], int version, long pos) throws IOException {
super(70, "PlaceObject3", data, pos);
super(ID, "PlaceObject3", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
placeFlagHasClipActions = sis.readUB(1) == 1;
placeFlagHasClipDepth = sis.readUB(1) == 1;

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.types.CLIPACTIONS;
@@ -55,6 +56,7 @@ public class PlaceObjectTag extends Tag implements PlaceObjectTypeTag {
* Color transform data
*/
public CXFORM colorTransform;
public static final int ID = 4;
@Override
public List<FILTER> getFilters() {
@@ -98,7 +100,7 @@ public class PlaceObjectTag extends Tag implements PlaceObjectTypeTag {
* @throws IOException
*/
public PlaceObjectTag(byte data[], int version, long pos) throws IOException {
super(4, "PlaceObject", data, pos);
super(ID, "PlaceObject", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterId = sis.readUI16();
depth = sis.readUI16();

View File

@@ -29,9 +29,10 @@ public class ProductInfoTag extends Tag {
public long buildLow;
public long buildHigh;
public long compilationDate;
public static final int ID = 41;
public ProductInfoTag(byte[] data, int version, long pos) throws IOException {
super(41, "ProductInfo", data, pos);
super(ID, "ProductInfo", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
/*
* 0: Unknown

View File

@@ -34,6 +34,7 @@ public class ProtectTag extends Tag {
* MD5 hash of password
*/
public String passwordHash;
public static final int ID = 24;
/**
* Gets data bytes
@@ -63,7 +64,7 @@ public class ProtectTag extends Tag {
* @throws IOException
*/
public ProtectTag(byte data[], int version, long pos) throws IOException {
super(24, "Protect", data, pos);
super(ID, "Protect", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
if (sis.available() > 0) {
passwordHash = sis.readString();

View File

@@ -24,9 +24,10 @@ import java.io.IOException;
public class RemoveObject2Tag extends Tag implements RemoveTag {
public int depth;
public static final int ID = 28;
public RemoveObject2Tag(byte[] data, int version, long pos) throws IOException {
super(28, "RemoveObject2", data, pos);
super(ID, "RemoveObject2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
depth = sis.readUI16();
}

View File

@@ -39,6 +39,7 @@ public class RemoveObjectTag extends Tag implements RemoveTag {
* Depth of character
*/
public int depth;
public static final int ID = 5;
/**
* Gets data bytes
@@ -67,7 +68,7 @@ public class RemoveObjectTag extends Tag implements RemoveTag {
* @throws IOException
*/
public RemoveObjectTag(byte data[], int version, long pos) throws IOException {
super(5, "RemoveObject", data, pos);
super(ID, "RemoveObject", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterId = sis.readUI16();
depth = sis.readUI16();

View File

@@ -27,9 +27,10 @@ public class ScriptLimitsTag extends Tag {
public int maxRecursionDepth;
public int scriptTimeoutSeconds;
public static final int ID = 65;
public ScriptLimitsTag(byte[] data, int version, long pos) throws IOException {
super(65, "ScriptLimits", data, pos);
super(ID, "ScriptLimits", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
maxRecursionDepth = sis.readUI16();
scriptTimeoutSeconds = sis.readUI16();

View File

@@ -26,15 +26,16 @@ import java.io.IOException;
public class SetBackgroundColorTag extends Tag {
public RGB backgroundColor;
public static final int ID = 9;
public SetBackgroundColorTag(byte[] data, int version, long pos) throws IOException {
super(9, "SetBackgroundColor", data, pos);
super(ID, "SetBackgroundColor", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
backgroundColor = sis.readRGB();
}
public SetBackgroundColorTag(RGB backgroundColor) {
super(9, "SetBackgroundColor", new byte[0], 0);
super(ID, "SetBackgroundColor", new byte[0], 0);
this.backgroundColor = backgroundColor;
}

View File

@@ -38,6 +38,7 @@ public class SetTabIndexTag extends Tag {
* Tab order value
*/
public int tabIndex;
public static final int ID = 66;
/**
* Gets data bytes
@@ -63,10 +64,11 @@ public class SetTabIndexTag extends Tag {
*
* @param data Data bytes
* @param version SWF version
* @param pos
* @throws IOException
*/
public SetTabIndexTag(byte data[], int version, long pos) throws IOException {
super(66, "SetTabIndex", data, pos);
super(ID, "SetTabIndex", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
depth = sis.readUI16();
tabIndex = sis.readUI16();

View File

@@ -23,15 +23,19 @@ package com.jpexs.decompiler.flash.tags;
*/
public class ShowFrameTag extends Tag {
public static final int ID = 1;
/**
* Constructor
*
* @param pos
*/
public ShowFrameTag(long pos) {
super(1, "ShowFrame", new byte[0], pos);
super(ID, "ShowFrame", new byte[0], pos);
}
public ShowFrameTag() {
super(1, "ShowFrame", new byte[0], 0);
super(ID, "ShowFrame", new byte[0], 0);
}
/**

View File

@@ -25,6 +25,8 @@ import java.io.IOException;
*/
public class SoundStreamBlockTag extends Tag {
public static final int ID = 19;
/**
* Constructor
*
@@ -33,6 +35,6 @@ public class SoundStreamBlockTag extends Tag {
* @throws IOException
*/
public SoundStreamBlockTag(byte data[], int version, long pos) throws IOException {
super(19, "SoundStreamBlock", data, pos); //all data is streamSoundData
super(ID, "SoundStreamBlock", data, pos); //all data is streamSoundData
}
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
@@ -41,6 +42,7 @@ public class SoundStreamHead2Tag extends CharacterTag implements SoundStreamHead
public int streamSoundSampleCount;
public int latencySeek;
private int virtualCharacterId = 0;
public static final int ID = 45;
@Override
public int getCharacterID() {
@@ -105,7 +107,7 @@ public class SoundStreamHead2Tag extends CharacterTag implements SoundStreamHead
* @throws IOException
*/
public SoundStreamHead2Tag(byte data[], int version, long pos) throws IOException {
super(45, "SoundStreamHead2", data, pos);
super(ID, "SoundStreamHead2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
sis.readUB(4);//reserved
playBackSoundRate = (int) sis.readUB(2);

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
@@ -41,6 +42,7 @@ public class SoundStreamHeadTag extends CharacterTag implements SoundStreamHeadT
public int streamSoundSampleCount;
public int latencySeek;
private int virtualCharacterId = 0;
public static final int ID = 18;
@Override
public String getExportFormat() {
@@ -105,7 +107,7 @@ public class SoundStreamHeadTag extends CharacterTag implements SoundStreamHeadT
* @throws IOException
*/
public SoundStreamHeadTag(byte data[], int version, long pos) throws IOException {
super(18, "SoundStreamHead", data, pos);
super(ID, "SoundStreamHead", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
sis.readUB(4);//reserved
playBackSoundRate = (int) sis.readUB(2);

View File

@@ -33,6 +33,7 @@ public class StartSound2Tag extends Tag {
public String soundClassName;
public SOUNDINFO soundInfo;
public static final int ID = 89;
/**
* Gets data bytes
@@ -60,7 +61,7 @@ public class StartSound2Tag extends Tag {
* @throws IOException
*/
public StartSound2Tag(byte data[], int version, long pos) throws IOException {
super(89, "StartSound2", data, pos);
super(ID, "StartSound2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
soundClassName = sis.readString();
soundInfo = sis.readSOUNDINFO();

View File

@@ -33,6 +33,7 @@ public class StartSoundTag extends Tag {
public int soundId;
public SOUNDINFO soundInfo;
public static final int ID = 15;
/**
* Gets data bytes
@@ -61,7 +62,7 @@ public class StartSoundTag extends Tag {
* @throws IOException
*/
public StartSoundTag(byte data[], int version, long pos) throws IOException {
super(15, "StartSound", data, pos);
super(ID, "StartSound", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
soundId = sis.readUI16();
soundInfo = sis.readSOUNDINFO();

View File

@@ -27,9 +27,10 @@ public class SymbolClassTag extends Tag {
public int tagIDs[];
public String classNames[];
public static final int ID = 76;
public SymbolClassTag(byte[] data, int version, long pos) throws IOException {
super(76, "SymbolClass", data, pos);
super(ID, "SymbolClass", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
int numSymbols = sis.readUI16();
tagIDs = new int[numSymbols];

View File

@@ -129,15 +129,20 @@ public class Tag implements NeedsCharacters, Exportable {
return new HashSet<>();
}
public Set<Integer> getDeepNeededCharacters(HashMap<Integer, CharacterTag> characters) {
public Set<Integer> getDeepNeededCharacters(HashMap<Integer, CharacterTag> characters,List<Integer> visited) {
Set<Integer> ret = new HashSet<>();
Set<Integer> needed = getNeededCharacters();
for (int ch : needed) {
for (int ch : needed) {
if (!characters.containsKey(ch)) { //TODO: use Import tag (?)
continue;
}
if(visited.contains(ch)){
continue;
}else{
visited.add(ch);
}
ret.add(ch);
ret.addAll(characters.get(ch).getDeepNeededCharacters(characters));
ret.addAll(characters.get(ch).getDeepNeededCharacters(characters,visited));
}
return ret;
}

View File

@@ -53,6 +53,7 @@ public class TagStub extends Tag {
*
* @param data Data bytes
* @param version SWF version
* @param pos
* @throws IOException
*/
public TagStub(byte data[], int version, long pos) throws IOException {

View File

@@ -33,6 +33,7 @@ public class VideoFrameTag extends Tag {
public int streamID;
public int frameNum;
public byte[] videoData;
public static final int ID = 61;
/**
* Gets data bytes
@@ -62,7 +63,7 @@ public class VideoFrameTag extends Tag {
* @throws IOException
*/
public VideoFrameTag(byte data[], int version, long pos) throws IOException {
super(61, "VideoFrame", data, pos);
super(ID, "VideoFrame", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
streamID = sis.readUI16();
frameNum = sis.readUI16();

View File

@@ -18,6 +18,8 @@ package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.types.RECT;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
/**
*
@@ -25,6 +27,6 @@ import java.util.HashMap;
*/
public interface BoundedTag {
public RECT getRect(HashMap<Integer, CharacterTag> characters);
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited);
//public List<GeneralPath> getPaths(List<Tag> tags);
}

View File

@@ -22,6 +22,7 @@ import java.awt.Point;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
/**
*
@@ -29,9 +30,9 @@ import java.util.List;
*/
public interface DrawableTag {
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters);
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited);
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters);
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited);
public int getNumFrames();
}

View File

@@ -1,4 +1,4 @@
package com.jpexs.decompiler.flash.tags;
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.types.CLIPACTIONS;
import com.jpexs.decompiler.flash.types.CXFORM;

View File

@@ -1,4 +1,4 @@
package com.jpexs.decompiler.flash.tags;
package com.jpexs.decompiler.flash.tags.base;
/**
*

View File

@@ -96,6 +96,17 @@ public class MATRIX implements Serializable {
return ret;
}
public RECT apply(RECT r) {
Point topLeft = apply(r.getTopLeft());
Point bottomRight = apply(r.getBottomRight());
int Xmin = Math.min(topLeft.x, bottomRight.x);
int Ymin = Math.min(topLeft.y, bottomRight.y);
int Xmax = Math.max(topLeft.x, bottomRight.x);
int Ymax = Math.max(topLeft.y, bottomRight.y);
return new RECT(Xmin, Xmax, Ymin, Ymax);
}
public int getRotateSkew0() {
return hasRotate ? rotateSkew0 : 0;
}

View File

@@ -16,12 +16,15 @@
*/
package com.jpexs.decompiler.flash.types;
import java.awt.Point;
import java.io.Serializable;
/**
* A rectangle value represents a rectangular region.
*
* @author JPEXS
*/
public class RECT {
public class RECT implements Serializable {
/**
* X minimum position for rectangle in twips
@@ -70,4 +73,12 @@ public class RECT {
public int getHeight() {
return (Ymax - Ymin) < 0 ? 0 : Ymax - Ymin;
}
public Point getTopLeft() {
return new Point(Xmin, Ymin);
}
public Point getBottomRight() {
return new Point(Xmax, Ymax);
}
}

View File

@@ -35,11 +35,11 @@ import com.jpexs.decompiler.flash.tags.DoInitActionTag;
import com.jpexs.decompiler.flash.tags.ExportAssetsTag;
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
import com.jpexs.decompiler.flash.tags.FrameLabelTag;
import com.jpexs.decompiler.flash.tags.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
import com.jpexs.decompiler.flash.tags.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.tags.StartSoundTag;
import com.jpexs.decompiler.flash.tags.SymbolClassTag;
import com.jpexs.decompiler.flash.tags.Tag;
@@ -1049,7 +1049,7 @@ public class XFLConverter {
ret += " symbolType=\"graphic\" loop=\"loop\"";
} else if (tag instanceof DefineSpriteTag) {
DefineSpriteTag sprite = (DefineSpriteTag) tag;
RECT spriteRect = sprite.getRect(characters);
RECT spriteRect = sprite.getRect(characters, new Stack<Integer>());
double centerPoint3DX = twipToPixel(matrix.translateX + spriteRect.getWidth() / 2);
double centerPoint3DY = twipToPixel(matrix.translateY + spriteRect.getHeight() / 2);
ret += " centerPoint3DX=\"" + centerPoint3DX + "\" centerPoint3DY=\"" + centerPoint3DY + "\"";