- Attach tag menu (Like DefineScaling grid to DefineSprite, etc.)
- Better tag error handling - these tags now got error icon

Changed
- #1455 All tag types are now allowed inside DefineSprite
This commit is contained in:
Jindra Petřík
2022-11-06 21:44:39 +01:00
parent 49f23c04b1
commit 6c964899fb
17 changed files with 199 additions and 151 deletions
@@ -318,11 +318,11 @@ public class SWFInputStream implements AutoCloseable {
private SWF swf;
public DumpInfo dumpInfo;
private byte[] data;
private int limit;
public void addPercentListener(ProgressListener listener) {
listeners.add(listener);
}
@@ -1162,7 +1162,7 @@ public class SWFInputStream implements AutoCloseable {
public Tag call() throws Exception {
DumpInfo di = dumpInfo;
try {
Tag t = resolveTag(tag, level, parallel, skipUnusualTags, lazy);
Tag t = resolveTag(tag, level, parallel, skipUnusualTags, lazy, true);
if (dumpInfo != null && t != null) {
dumpInfo.name = t.getName();
}
@@ -1219,14 +1219,15 @@ public class SWFInputStream implements AutoCloseable {
} else if (tag != null) {
if (tag.getId() == FileAttributesTag.ID && level == 0) { // FileAttributes
if (tag instanceof TagStub) {
tag = resolveTag((TagStub) tag, level, parallel1, skipUnusualTags, lazy);
tag = resolveTag((TagStub) tag, level, parallel1, skipUnusualTags, lazy, true);
}
FileAttributesTag fileAttributes = (FileAttributesTag) tag;
if (fileAttributes.actionScript3) {
isAS3 = true;
}
}
switch (tag.getId()) {
doParse = true;
/*switch (tag.getId()) {
case DoActionTag.ID:
case DoInitActionTag.ID:
doParse = !isAS3;
@@ -1254,11 +1255,11 @@ public class SWFInputStream implements AutoCloseable {
} else {
doParse = true;
}
}
}*/
}
if (parseTags && !parallel1 && doParse && (tag instanceof TagStub)) {
tag = resolveTag((TagStub) tag, level, parallel, skipUnusualTags, lazy);
tag = resolveTag((TagStub) tag, level, parallel, skipUnusualTags, lazy, true);
}
DumpInfo di = dumpInfo;
if (di != null && tag != null) {
@@ -1313,7 +1314,7 @@ public class SWFInputStream implements AutoCloseable {
return tags;
}
public static Tag resolveTag(TagStub tag, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws InterruptedException {
public static Tag resolveTag(TagStub tag, int level, boolean parallel, boolean skipUnusualTags, boolean lazy, boolean logErrors) throws InterruptedException {
Tag ret;
ByteArrayRange data = tag.getOriginalRange();
@@ -1609,8 +1610,10 @@ public class SWFInputStream implements AutoCloseable {
ret.remainingData = sis.readByteRangeEx(sis.available(), "remaining");
}
} catch (IOException ex) {
logger.log(Level.SEVERE, "Error during tag reading. SWF: " + swf.getShortFileName() + " ID: " + tag.getId() + " name: " + tag.getName() + " pos: " + data.getPos(), ex);
ret = new TagStub(swf, tag.getId(), "ErrorTag", data, null);
if (logErrors) {
logger.log(Level.SEVERE, "Error during tag reading. SWF: " + swf.getShortFileName() + " ID: " + tag.getId() + " name: " + tag.getName() + " pos: " + data.getPos(), ex);
}
ret = new TagStub(swf, tag.getId(), "Error", data, null);
}
ret.forceWriteAsLong = tag.forceWriteAsLong;
ret.setTimelined(tag.getTimelined());
@@ -1665,7 +1668,7 @@ public class SWFInputStream implements AutoCloseable {
if (resolve) {
DumpInfo di = dumpInfo;
try {
ret = resolveTag(tagStub, level, parallel, skipUnusualTags, lazy);
ret = resolveTag(tagStub, level, parallel, skipUnusualTags, lazy, true);
} catch (Exception ex) {
tagDataStream.endDumpLevelUntil(di);
logger.log(Level.SEVERE, "Problem in " + timelined.toString(), ex);
@@ -133,7 +133,7 @@ public class DumpInfo implements TreeItem {
SWFInputStream sis = tagStub.getDataStream();
sis.seek(tagStub.getDataPos());
sis.dumpInfo = this;
resolvedTag = SWFInputStream.resolveTag(tagStub, 0, false, true, false);
resolvedTag = SWFInputStream.resolveTag(tagStub, 0, false, true, false, false);
} catch (InterruptedException | IOException ex) {
Logger.getLogger(DumpInfo.class.getName()).log(Level.SEVERE, null, ex);
}
@@ -16,10 +16,13 @@
*/
package com.jpexs.decompiler.flash.helpers;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.RGBA;
import com.jpexs.helpers.Helper;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
@@ -67,6 +70,14 @@ public class ImageHelper {
}
}
if (in == null) {
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = img.getGraphics();
g.setColor(SWF.ERROR_COLOR);
g.fillRect(0, 0, 1, 1);
return img;
}
int type = in.getType();
if (type != BufferedImage.TYPE_INT_ARGB_PRE && type != BufferedImage.TYPE_INT_RGB) {
// convert to ARGB
@@ -30,6 +30,7 @@ import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.JpegFixer;
import com.jpexs.helpers.SerializableImage;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -152,7 +153,11 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
Logger.getLogger(DefineBitsJPEG2Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
}
return null;
SerializableImage img = new SerializableImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = img.getGraphics();
g.setColor(SWF.ERROR_COLOR);
g.fillRect(0, 0, 1, 1);
return img;
}
@Override
@@ -167,6 +172,6 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
Logger.getLogger(DefineBitsJPEG2Tag.class.getName()).log(Level.SEVERE, "Failed to get image dimension", ex);
}
return null;
return new Dimension(1, 1);
}
}
@@ -31,6 +31,7 @@ import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.JpegFixer;
import com.jpexs.helpers.SerializableImage;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
@@ -244,7 +245,12 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
} catch (IOException ex) {
Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
}
return null;
SerializableImage img = new SerializableImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = img.getGraphics();
g.setColor(SWF.ERROR_COLOR);
g.fillRect(0, 0, 1, 1);
return img;
}
@Override
@@ -261,6 +267,6 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to get image dimension", ex);
}
return null;
return new Dimension(1, 1);
}
}
@@ -31,6 +31,7 @@ import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.JpegFixer;
import com.jpexs.helpers.SerializableImage;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
@@ -250,7 +251,12 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
} catch (IOException ex) {
Logger.getLogger(DefineBitsJPEG4Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
}
return null;
SerializableImage img = new SerializableImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = img.getGraphics();
g.setColor(SWF.ERROR_COLOR);
g.fillRect(0, 0, 1, 1);
return img;
}
@Override
@@ -266,6 +272,6 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to get image dimension", ex);
}
return null;
return new Dimension(1, 1);
}
}
@@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.SerializableImage;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -209,7 +210,11 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener {
}
}
return null;
SerializableImage img = new SerializableImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = img.getGraphics();
g.setColor(SWF.ERROR_COLOR);
g.fillRect(0, 0, 1, 1);
return img;
}
@Override
@@ -227,7 +232,7 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener {
}
}
return null;
return new Dimension(1, 1);
}
@Override
@@ -189,10 +189,12 @@ public class DefineFont2Tag extends FontTag {
for (int i = 0; i < numGlyphs; i++) {
fontBoundsTable.add(sis.readRECT("rect"));
}
int kerningCount = sis.readUI16("kerningCount");
fontKerningTable = new ArrayList<>();
for (int i = 0; i < kerningCount; i++) {
fontKerningTable.add(sis.readKERNINGRECORD(fontFlagsWideCodes, "record"));
if (sis.available() > 0) { //should always be available, but happened in #1455, god knows why
int kerningCount = sis.readUI16("kerningCount");
for (int i = 0; i < kerningCount; i++) {
fontKerningTable.add(sis.readKERNINGRECORD(fontFlagsWideCodes, "record"));
}
}
}
}
@@ -429,7 +429,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
SWFInputStream tagDataStream = new SWFInputStream(swf, data, getDataPos(), data.length);
TagStub copy = new TagStub(swf, getId(), "Unresolved", getOriginalRange(), tagDataStream);
copy.forceWriteAsLong = forceWriteAsLong;
return SWFInputStream.resolveTag(copy, 0, false, true, false);
return SWFInputStream.resolveTag(copy, 0, false, true, false, false);
}
public Tag getOriginalTag() throws InterruptedException, IOException {
@@ -437,7 +437,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
SWFInputStream tagDataStream = new SWFInputStream(swf, data, getDataPos(), data.length);
TagStub copy = new TagStub(swf, getId(), "Unresolved", getOriginalRange(), tagDataStream);
copy.forceWriteAsLong = forceWriteAsLong;
return SWFInputStream.resolveTag(copy, 0, false, true, false);
return SWFInputStream.resolveTag(copy, 0, false, true, false, false);
}
public boolean canUndo() {
@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.helpers.ByteArrayRange;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -67,4 +68,13 @@ public class TagStub extends Tag {
public SWFInputStream getDataStream() {
return dataStream;
}
@Override
public String toString() {
Map<Integer, TagTypeInfo> classes = Tag.getKnownClasses();
if (classes.containsKey(id)) {
return tagName + " - " + classes.get(id).getName();
}
return tagName + " [ID = " + id + "]";
}
}