diff --git a/src/com/jpexs/decompiler/flash/BinarySWFBundle.java b/src/com/jpexs/decompiler/flash/BinarySWFBundle.java index 89dee6d37..61b070df6 100644 --- a/src/com/jpexs/decompiler/flash/BinarySWFBundle.java +++ b/src/com/jpexs/decompiler/flash/BinarySWFBundle.java @@ -1,85 +1,85 @@ -/* - * Copyright (C) 2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash; - -import com.jpexs.helpers.SwfHeaderStreamSearch; -import com.jpexs.helpers.streams.SeekableInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * - * @author JPEXS - */ -public class BinarySWFBundle implements SWFBundle { - - private final SWFSearch search; - - public BinarySWFBundle(InputStream is, boolean noCheck, SearchMode searchMode) { - search = new SWFSearch(new SwfHeaderStreamSearch(is), noCheck, searchMode); - search.process(); - } - - @Override - public int length() { - return search.length(); - } - - @Override - public Set getKeys() { - Set ret = new HashSet<>(); - for (Long address : search.getAddresses()) { - ret.add("[" + address + "]"); - } - return ret; - } - - @Override - public SeekableInputStream getSWF(String key) { - if (!key.startsWith("[")) { - return null; - } - if (!key.endsWith("]")) { - return null; - } - key = key.substring(1, key.length() - 1); - try { - int address = Integer.parseInt(key); - return search.get(null, address); - } catch (IOException | NumberFormatException iex) { - return null; - } - } - - @Override - public Map getAll() { - Map ret = new HashMap<>(); - for (String key : getKeys()) { - ret.put(key, getSWF(key)); - } - return ret; - } - - @Override - public String getExtension() { - return "bin"; - } -} +/* + * Copyright (C) 2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash; + +import com.jpexs.helpers.SwfHeaderStreamSearch; +import com.jpexs.helpers.streams.SeekableInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * + * @author JPEXS + */ +public class BinarySWFBundle implements SWFBundle { + + private final SWFSearch search; + + public BinarySWFBundle(InputStream is, boolean noCheck, SearchMode searchMode) throws IOException { + search = new SWFSearch(new SwfHeaderStreamSearch(is), noCheck, searchMode); + search.process(); + } + + @Override + public int length() { + return search.length(); + } + + @Override + public Set getKeys() { + Set ret = new HashSet<>(); + for (Long address : search.getAddresses()) { + ret.add("[" + address + "]"); + } + return ret; + } + + @Override + public SeekableInputStream getSWF(String key) { + if (!key.startsWith("[")) { + return null; + } + if (!key.endsWith("]")) { + return null; + } + key = key.substring(1, key.length() - 1); + try { + int address = Integer.parseInt(key); + return search.get(null, address); + } catch (IOException | NumberFormatException iex) { + return null; + } + } + + @Override + public Map getAll() { + Map ret = new HashMap<>(); + for (String key : getKeys()) { + ret.put(key, getSWF(key)); + } + return ret; + } + + @Override + public String getExtension() { + return "bin"; + } +} diff --git a/src/com/jpexs/decompiler/flash/SWF.java b/src/com/jpexs/decompiler/flash/SWF.java index 77d1c001c..32a2c58df 100644 --- a/src/com/jpexs/decompiler/flash/SWF.java +++ b/src/com/jpexs/decompiler/flash/SWF.java @@ -52,6 +52,7 @@ import com.jpexs.decompiler.flash.action.swf5.ActionNewObject; import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.dumpview.DumpInfo; import com.jpexs.decompiler.flash.ecma.Null; import com.jpexs.decompiler.flash.exporters.BinaryDataExporter; import com.jpexs.decompiler.flash.exporters.FontExporter; @@ -90,6 +91,7 @@ import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; import com.jpexs.decompiler.flash.tags.ShowFrameTag; import com.jpexs.decompiler.flash.tags.SymbolClassTag; import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.TagStub; import com.jpexs.decompiler.flash.tags.VideoFrameTag; import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.decompiler.flash.tags.base.BoundedTag; @@ -268,6 +270,8 @@ public final class SWF implements TreeItem, Timelined { public static final double unitDivisor = 20; private Timeline timeline; + + public DumpInfo dumpInfo; public void updateCharacters() { characters.clear(); @@ -304,7 +308,7 @@ public final class SWF implements TreeItem, Timelined { Tag t = tags.get(i); if (t instanceof DefineSpriteTag) { if (!isSpriteValid((DefineSpriteTag) t, new ArrayList())) { - tags.set(i, new Tag(this, t.getId(), "InvalidSprite", t.getPos(), t.getOriginalLength())); + tags.set(i, new TagStub(this, t.getId(), "InvalidSprite", t.getPos(), t.getOriginalLength(), null)); } } } @@ -503,14 +507,17 @@ public final class SWF implements TreeItem, Timelined { public SWF(InputStream is, ProgressListener listener, boolean parallelRead, boolean checkOnly) throws IOException, InterruptedException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); SWFHeader header = decompress(is, baos, true); - version = header.version; - fileSize = header.fileSize; gfx = header.gfx; compression = header.compression; uncompressedData = baos.toByteArray(); SWFInputStream sis = new SWFInputStream(this, uncompressedData); - sis.read(new byte[8], 0, 8); // skip the header + dumpInfo = new DumpInfo("rootswf", "", null, 0, 0); + sis.dumpInfo = dumpInfo; + sis.readBytesEx(3); // skip siganture + version = sis.readUI8(); + fileSize = sis.readUI32(); + sis.dumpInfo.lengthBytes = fileSize; if (listener != null) { sis.addPercentListener(listener); } @@ -520,7 +527,7 @@ public final class SWF implements TreeItem, Timelined { sis.readUI8(); //tmpFirstByetOfFrameRate frameRate = sis.readUI8(); frameCount = sis.readUI16(); - List tags = sis.readTagList(this, this, 0, parallelRead, true, !checkOnly, gfx); + List tags = sis.readTagList(this, 0, parallelRead, true, !checkOnly, gfx); if (tags.get(tags.size() - 1).getId() == EndTag.ID) { hasEndTag = true; tags.remove(tags.size() - 1); @@ -705,7 +712,7 @@ public final class SWF implements TreeItem, Timelined { } int version = hdr[3]; - SWFInputStream sis = new SWFInputStream(null, Arrays.copyOfRange(hdr, 4, 8), 4); + SWFInputStream sis = new SWFInputStream(null, Arrays.copyOfRange(hdr, 4, 8), 4, 4); long fileSize = sis.readUI32(); SWFHeader header = new SWFHeader(); header.version = version; @@ -730,8 +737,8 @@ public final class SWF implements TreeItem, Timelined { sis.readUI32(); // compressed LZMA data size = compressed SWF - 17 byte, // where 17 = 8 byte header + this 4 byte + 5 bytes decoder properties int propertiesSize = 5; - byte[] lzmaProperties = new byte[propertiesSize]; - if (sis.read(lzmaProperties, 0, propertiesSize) != propertiesSize) { + byte[] lzmaProperties = sis.readBytes(propertiesSize); + if (lzmaProperties.length != propertiesSize) { throw new IOException("LZMA:input .lzma file is too short"); } SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder(); diff --git a/src/com/jpexs/decompiler/flash/SWFInputStream.java b/src/com/jpexs/decompiler/flash/SWFInputStream.java index 8b1ed6f2e..778895cae 100644 --- a/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -120,6 +120,7 @@ import com.jpexs.decompiler.flash.action.swf7.ActionImplementsOp; import com.jpexs.decompiler.flash.action.swf7.ActionThrow; import com.jpexs.decompiler.flash.action.swf7.ActionTry; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.dumpview.DumpInfo; import com.jpexs.decompiler.flash.tags.CSMTextSettingsTag; import com.jpexs.decompiler.flash.tags.DebugIDTag; import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; @@ -189,6 +190,7 @@ import com.jpexs.decompiler.flash.tags.StartSound2Tag; import com.jpexs.decompiler.flash.tags.StartSoundTag; import com.jpexs.decompiler.flash.tags.SymbolClassTag; import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.TagStub; import com.jpexs.decompiler.flash.tags.UnknownTag; import com.jpexs.decompiler.flash.tags.VideoFrameTag; import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; @@ -263,7 +265,6 @@ import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; import com.jpexs.helpers.Helper; import com.jpexs.helpers.MemoryInputStream; import com.jpexs.helpers.ProgressListener; -import com.jpexs.helpers.streams.SeekableInputStream; import com.jpexs.helpers.utf8.Utf8Helper; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -289,12 +290,13 @@ import java.util.zip.InflaterInputStream; */ public class SWFInputStream implements AutoCloseable { - private SeekableInputStream is; - private long pos; + private MemoryInputStream is; + private long startingPos; private static final Logger logger = Logger.getLogger(SWFInputStream.class.getName()); private final List listeners = new ArrayList<>(); private long percentMax; - public SWF swf; + private SWF swf; + public DumpInfo dumpInfo; public void addPercentListener(ProgressListener listener) { listeners.add(listener); @@ -317,11 +319,13 @@ public class SWFInputStream implements AutoCloseable { * @param swf SWF to read * @param data SWF data * @param startingPos + * @param limit + * @throws java.io.IOException */ - public SWFInputStream(SWF swf, byte[] data, long startingPos) { + public SWFInputStream(SWF swf, byte[] data, long startingPos, int limit) throws IOException { this.swf = swf; - this.is = new MemoryInputStream(data); - pos = startingPos; + this.startingPos = startingPos; + is = new MemoryInputStream(data, 0, limit); } /** @@ -329,9 +333,14 @@ public class SWFInputStream implements AutoCloseable { * * @param swf SWF to read * @param data SWF data + * @throws java.io.IOException */ - public SWFInputStream(SWF swf, byte[] data) { - this(swf, data, 0L); + public SWFInputStream(SWF swf, byte[] data) throws IOException { + this(swf, data, 0L, data.length); + } + + public SWF getSwf() { + return swf; } /** @@ -340,7 +349,7 @@ public class SWFInputStream implements AutoCloseable { * @return Number of bytes */ public long getPos() { - return pos; + return startingPos + is.getPos(); } /** @@ -350,51 +359,48 @@ public class SWFInputStream implements AutoCloseable { * @throws java.io.IOException */ public void seek(long pos) throws IOException { - if (is instanceof SeekableInputStream) { - SeekableInputStream sis = (SeekableInputStream) is; - sis.seek(pos); - } else { - throw new IOException("Underlying stream is not a SeekableInputStream"); - } + is.seek(pos - startingPos); } + private void newDumpLevel(String name) { + String type = name; + if (dumpInfo != null) { + DumpInfo di = new DumpInfo(name, type, null, is.getPos(), 0); + di.parent = dumpInfo; + dumpInfo.childInfos.add(di); + dumpInfo = di; + } + } + + private void endDumpLevel() { + if (dumpInfo != null) { + if (dumpInfo.lengthBits == 0) { + dumpInfo.lengthBytes = is.getPos() - dumpInfo.startByte; + } + dumpInfo = dumpInfo.parent; + } + } + /** * Reads one byte from the stream * - * @return byte or -1 on error + * @return byte * @throws IOException */ - public int read() throws IOException { - bitPos = 0; - try { - return readNoBitReset(); - } catch (EOFException | EndOfStreamException ex) { - logger.log(Level.SEVERE, null, ex); - } - return -1; - } - - public int readEx() throws IOException { + private int readEx() throws IOException { bitPos = 0; return readNoBitReset(); } - public int read(byte[] b, int off, int len) throws IOException { - int bytesRead = is.read(b, off, len); - bitPos = 0; - pos += bytesRead; - return bytesRead; - } - - public void alignByte() { + private void alignByte() { bitPos = 0; } + private int lastPercent = -1; private int readNoBitReset() throws IOException, EndOfStreamException { - pos++; - if (percentMax > 0) { - int percent = (int) (pos * 100 / percentMax); + if (listeners.size() > 0 && percentMax > 0) { + int percent = (int) (getPos() * 100 / percentMax); if (lastPercent != percent) { for (ProgressListener pl : listeners) { pl.progress(percent); @@ -416,7 +422,10 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public int readUI8() throws IOException { - return readEx(); + newDumpLevel("UI8"); + int ret = readEx(); + endDumpLevel(); + return ret; } /** @@ -426,11 +435,13 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public String readString() throws IOException { + newDumpLevel("string"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int r; while (true) { r = readEx(); if (r == 0) { + endDumpLevel(); return new String(baos.toByteArray(), Utf8Helper.charset); } baos.write(r); @@ -444,7 +455,10 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public long readUI32() throws IOException { - return (readEx() + (readEx() << 8) + (readEx() << 16) + (readEx() << 24)) & 0xffffffff; + newDumpLevel("UI8"); + long ret = (readEx() + (readEx() << 8) + (readEx() << 16) + (readEx() << 24)) & 0xffffffff; + endDumpLevel(); + return ret; } /** @@ -454,11 +468,17 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public int readUI16() throws IOException { - return readEx() + (readEx() << 8); + newDumpLevel("UI16"); + int ret = readEx() + (readEx() << 8); + endDumpLevel(); + return ret; } public int readUI24() throws IOException { - return readEx() + (readEx() << 8) + (readEx() << 16); + newDumpLevel("UI24"); + int ret = readEx() + (readEx() << 8) + (readEx() << 16); + endDumpLevel(); + return ret; } /** @@ -468,7 +488,9 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public long readSI32() throws IOException { + newDumpLevel("SI32"); long uval = readEx() + (readEx() << 8) + (readEx() << 16) + (readEx() << 24); + endDumpLevel(); if (uval >= 0x80000000) { return -(((~uval) & 0xffffffff) + 1); } else { @@ -483,7 +505,9 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public int readSI16() throws IOException { + newDumpLevel("SI16"); int uval = readEx() + (readEx() << 8); + endDumpLevel(); if (uval >= 0x8000) { return -(((~uval) & 0xffff) + 1); } else { @@ -498,7 +522,9 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public int readSI8() throws IOException { + newDumpLevel("SI8"); int uval = readEx(); + endDumpLevel(); if (uval >= 0x80) { return -(((~uval) & 0xff) + 1); } else { @@ -513,8 +539,10 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public double readFIXED() throws IOException { + newDumpLevel("FIXED"); int afterPoint = readUI16(); int beforePoint = readUI16(); + endDumpLevel(); return ((double) ((beforePoint << 16) + afterPoint)) / 65536; } @@ -525,8 +553,10 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public float readFIXED8() throws IOException { + newDumpLevel("FIXED8"); int afterPoint = readEx(); int beforePoint = readEx(); + endDumpLevel(); return beforePoint + (((float) afterPoint) / 256); } @@ -550,7 +580,9 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public double readDOUBLE() throws IOException { + newDumpLevel("DOUBLE"); long el = readLong(); + endDumpLevel(); double ret = Double.longBitsToDouble(el); return ret; } @@ -598,10 +630,12 @@ public class SWFInputStream implements AutoCloseable { if (count <= 0) { return new byte[0]; } + newDumpLevel("bytes"); byte[] ret = new byte[(int) count]; for (int i = 0; i < count; i++) { ret[i] = (byte) readEx(); } + endDumpLevel(); return ret; } @@ -633,6 +667,7 @@ public class SWFInputStream implements AutoCloseable { if (count <= 0) { return new byte[0]; } + newDumpLevel("bytes"); byte[] ret = new byte[count]; int i = 0; try { @@ -643,6 +678,7 @@ public class SWFInputStream implements AutoCloseable { ret = Arrays.copyOf(ret, i); // truncate array logger.log(Level.SEVERE, null, ex); } + endDumpLevel(); return ret; } @@ -665,23 +701,29 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public long readEncodedU32() throws IOException { + newDumpLevel("encodedU32"); int result = readEx(); if ((result & 0x00000080) == 0) { + endDumpLevel(); return result; } result = (result & 0x0000007f) | (readEx()) << 7; if ((result & 0x00004000) == 0) { + endDumpLevel(); return result; } result = (result & 0x00003fff) | (readEx()) << 14; if ((result & 0x00200000) == 0) { + endDumpLevel(); return result; } result = (result & 0x001fffff) | (readEx()) << 21; if ((result & 0x10000000) == 0) { + endDumpLevel(); return result; } result = (result & 0x0fffffff) | (readEx()) << 28; + endDumpLevel(); return result; } private int bitPos = 0; @@ -702,6 +744,7 @@ public class SWFInputStream implements AutoCloseable { if (bitPos == 0) { tempByte = readNoBitReset(); } + newDumpLevel("UB"); for (int bit = 0; bit < nBits; bit++) { int nb = (tempByte >> (7 - bitPos)) & 1; ret += (nb << (nBits - 1 - bit)); @@ -713,6 +756,7 @@ public class SWFInputStream implements AutoCloseable { } } } + endDumpLevel(); return ret; } @@ -756,6 +800,7 @@ public class SWFInputStream implements AutoCloseable { */ public RECT readRECT() throws IOException { RECT ret = new RECT(); + newDumpLevel("RECT"); int NBits = (int) readUB(5); ret.Xmin = (int) readSB(NBits); ret.Xmax = (int) readSB(NBits); @@ -763,6 +808,7 @@ public class SWFInputStream implements AutoCloseable { ret.Ymax = (int) readSB(NBits); ret.nbits = NBits; alignByte(); + endDumpLevel(); return ret; } @@ -797,22 +843,20 @@ public class SWFInputStream implements AutoCloseable { private final int level; private final boolean parallel; private final boolean skipUnusualTags; - private final SWF swf; private final boolean gfx; - public TagResolutionTask(SWF swf, Tag tag, int level, boolean parallel, boolean skipUnusualTags, boolean gfx) { + public TagResolutionTask(Tag tag, int level, boolean parallel, boolean skipUnusualTags, boolean gfx) { this.tag = tag; this.level = level; this.parallel = parallel; this.skipUnusualTags = skipUnusualTags; - this.swf = swf; this.gfx = gfx; } @Override public Tag call() throws Exception { try { - return resolveTag(swf, tag, level, parallel, skipUnusualTags, gfx); + return resolveTag(tag, level, parallel, skipUnusualTags, gfx); } catch (EndOfStreamException ex) { logger.log(Level.SEVERE, null, ex); return tag; @@ -824,7 +868,6 @@ public class SWFInputStream implements AutoCloseable { * Reads list of tags from the stream. Reading ends with End tag(=0) or end * of the stream. Optionally can skip AS1/2 tags when file is AS3 * - * @param swf * @param timelined * @param level * @param parallel @@ -835,7 +878,7 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException * @throws java.lang.InterruptedException */ - public List readTagList(SWF swf, Timelined timelined, int level, boolean parallel, boolean skipUnusualTags, boolean parseTags, boolean gfx) throws IOException, InterruptedException { + public List readTagList(Timelined timelined, int level, boolean parallel, boolean skipUnusualTags, boolean parseTags, boolean gfx) throws IOException, InterruptedException { ExecutorService executor = null; List> futureResults = new ArrayList<>(); if (parallel) { @@ -847,11 +890,13 @@ public class SWFInputStream implements AutoCloseable { boolean isAS3 = false; while (true) { long pos = getPos(); + newDumpLevel("TAG"); try { - tag = readTag(swf, level, pos, parseTags && !parallel, parallel, skipUnusualTags, gfx); + tag = readTag(level, pos, parseTags && !parallel, parallel, skipUnusualTags, gfx); } catch (EOFException | EndOfStreamException ex) { tag = null; } + endDumpLevel(); if (tag == null) { break; } @@ -870,7 +915,7 @@ public class SWFInputStream implements AutoCloseable { } else { switch (tag.getId()) { case FileAttributesTag.ID: //FileAttributes - FileAttributesTag fileAttributes = (FileAttributesTag) resolveTag(swf, tag, level, parallel, skipUnusualTags, gfx); + FileAttributesTag fileAttributes = (FileAttributesTag) resolveTag(tag, level, parallel, skipUnusualTags, gfx); if (fileAttributes.actionScript3) { isAS3 = true; } @@ -911,7 +956,7 @@ public class SWFInputStream implements AutoCloseable { } if (parseTags && doParse) { if (parallel) { - Future future = executor.submit(new TagResolutionTask(swf, tag, level, parallel, skipUnusualTags, gfx)); + Future future = executor.submit(new TagResolutionTask(tag, level, parallel, skipUnusualTags, gfx)); futureResults.add(future); } } @@ -937,13 +982,18 @@ public class SWFInputStream implements AutoCloseable { return tags; } - public static Tag resolveTag(SWF swf, Tag tag, int level, boolean parallel, boolean skipUnusualTags, boolean gfx) throws InterruptedException { + public static Tag resolveTag(Tag tag, int level, boolean parallel, boolean skipUnusualTags, boolean gfx) throws InterruptedException { Tag ret; - byte[] data = tag.getData(); + if (!(tag instanceof TagStub)) { + return tag; + } + long pos = tag.getPos(); int length = tag.getOriginalLength(); - SWFLimitedInputStream sis = new SWFLimitedInputStream(swf, new SWFInputStream(swf, data, tag.getDataPos()), length); + SWF swf = tag.getSwf(); + TagStub tagStub = (TagStub) tag; + SWFInputStream sis = tagStub.getDataStream(); try { switch (tag.getId()) { @@ -1217,7 +1267,7 @@ public class SWFInputStream implements AutoCloseable { } } catch (IOException ex) { logger.log(Level.SEVERE, "Error during tag reading", ex); - ret = new Tag(swf, tag.getId(), "ErrorTag", pos, length); + ret = new TagStub(swf, tag.getId(), "ErrorTag", pos, length, null); } ret.forceWriteAsLong = tag.forceWriteAsLong; ret.setTimelined(tag.getTimelined()); @@ -1228,7 +1278,6 @@ public class SWFInputStream implements AutoCloseable { * Reads one Tag from the stream with optional resolving (= reading tag * content) * - * @param swf * @param level * @param pos * @param resolve @@ -1239,7 +1288,7 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException * @throws java.lang.InterruptedException */ - public Tag readTag(SWF swf, int level, long pos, boolean resolve, boolean parallel, boolean skipUnusualTags, boolean gfx) throws IOException, InterruptedException { + public Tag readTag(int level, long pos, boolean resolve, boolean parallel, boolean skipUnusualTags, boolean gfx) throws IOException, InterruptedException { int tagIDTagLength = readUI16(); int tagID = (tagIDTagLength) >> 6; @@ -1251,13 +1300,16 @@ public class SWFInputStream implements AutoCloseable { tagLength = readSI32(); readLong = true; } - skipBytes((int) tagLength); - Tag ret = new Tag(swf, tagID, "Unresolved", pos, (int) (tagLength + (readLong ? 6 : 2))); + int headerLength = readLong ? 6 : 2; + SWFInputStream tagDataStream = getLimitedStream((int) tagLength); + TagStub tagStub = new TagStub(swf, tagID, "Unresolved", pos, (int) (tagLength + headerLength), tagDataStream); + Tag ret = tagStub; ret.forceWriteAsLong = readLong; + skipBytes((int) tagLength); if (resolve) { try { - ret = resolveTag(swf, ret, level, parallel, skipUnusualTags, gfx); + ret = resolveTag(ret, level, parallel, skipUnusualTags, gfx); } catch (EndOfStreamException ex) { logger.log(Level.SEVERE, null, ex); } @@ -1550,6 +1602,7 @@ public class SWFInputStream implements AutoCloseable { */ public MATRIX readMatrix() throws IOException { MATRIX ret = new MATRIX(); + newDumpLevel("MATRIX"); ret.hasScale = readUB(1) == 1; if (ret.hasScale) { int NScaleBits = (int) readUB(5); @@ -1569,6 +1622,7 @@ public class SWFInputStream implements AutoCloseable { ret.translateY = (int) readSB(NTranslateBits); ret.nTranslateBits = NTranslateBits; alignByte(); + endDumpLevel(); return ret; } @@ -1580,6 +1634,7 @@ public class SWFInputStream implements AutoCloseable { */ public CXFORMWITHALPHA readCXFORMWITHALPHA() throws IOException { CXFORMWITHALPHA ret = new CXFORMWITHALPHA(); + newDumpLevel("CXFORMWITHALPHA"); ret.hasAddTerms = readUB(1) == 1; ret.hasMultTerms = readUB(1) == 1; int Nbits = (int) readUB(4); @@ -1597,6 +1652,7 @@ public class SWFInputStream implements AutoCloseable { ret.alphaAddTerm = (int) readSB(Nbits); } alignByte(); + endDumpLevel(); return ret; } @@ -1608,6 +1664,7 @@ public class SWFInputStream implements AutoCloseable { */ public CXFORM readCXFORM() throws IOException { CXFORM ret = new CXFORM(); + newDumpLevel("CXFORM"); ret.hasAddTerms = readUB(1) == 1; ret.hasMultTerms = readUB(1) == 1; int Nbits = (int) readUB(4); @@ -1623,6 +1680,7 @@ public class SWFInputStream implements AutoCloseable { ret.blueAddTerm = (int) readSB(Nbits); } alignByte(); + endDumpLevel(); return ret; } @@ -1634,6 +1692,7 @@ public class SWFInputStream implements AutoCloseable { */ public CLIPEVENTFLAGS readCLIPEVENTFLAGS() throws IOException { CLIPEVENTFLAGS ret = new CLIPEVENTFLAGS(); + newDumpLevel("CLIPEVENTFLAGS"); ret.clipEventKeyUp = readUB(1) == 1; ret.clipEventKeyDown = readUB(1) == 1; ret.clipEventMouseUp = readUB(1) == 1; @@ -1657,6 +1716,7 @@ public class SWFInputStream implements AutoCloseable { ret.clipEventDragOut = readUB(1) == 1; ret.reserved2 = (int) readUB(8); } + endDumpLevel(); return ret; } @@ -1669,7 +1729,9 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public CLIPACTIONRECORD readCLIPACTIONRECORD(SWF swf, Tag tag) throws IOException { + newDumpLevel("CLIPACTIONRECORD"); CLIPACTIONRECORD ret = new CLIPACTIONRECORD(swf, this, getPos(), tag); + endDumpLevel(); if (ret.eventFlags.isClear()) { return null; } @@ -1686,6 +1748,7 @@ public class SWFInputStream implements AutoCloseable { */ public CLIPACTIONS readCLIPACTIONS(SWF swf, Tag tag) throws IOException { CLIPACTIONS ret = new CLIPACTIONS(); + newDumpLevel("CLIPACTIONS"); ret.reserved = readUI16(); ret.allEventFlags = readCLIPEVENTFLAGS(); CLIPACTIONRECORD cr; @@ -1693,6 +1756,7 @@ public class SWFInputStream implements AutoCloseable { while ((cr = readCLIPACTIONRECORD(swf, tag)) != null) { ret.clipActionRecords.add(cr); } + endDumpLevel(); return ret; } @@ -1704,10 +1768,12 @@ public class SWFInputStream implements AutoCloseable { */ public COLORMATRIXFILTER readCOLORMATRIXFILTER() throws IOException { COLORMATRIXFILTER ret = new COLORMATRIXFILTER(); + newDumpLevel("COLORMATRIXFILTER"); ret.matrix = new float[20]; for (int i = 0; i < 20; i++) { ret.matrix[i] = readFLOAT(); } + endDumpLevel(); return ret; } @@ -1719,10 +1785,12 @@ public class SWFInputStream implements AutoCloseable { */ public RGBA readRGBA() throws IOException { RGBA ret = new RGBA(); + newDumpLevel("RGBA"); ret.red = readUI8(); ret.green = readUI8(); ret.blue = readUI8(); ret.alpha = readUI8(); + endDumpLevel(); return ret; } @@ -1734,10 +1802,12 @@ public class SWFInputStream implements AutoCloseable { */ public ARGB readARGB() throws IOException { ARGB ret = new ARGB(); + newDumpLevel("ARGB"); ret.alpha = readUI8(); ret.red = readUI8(); ret.green = readUI8(); ret.blue = readUI8(); + endDumpLevel(); return ret; } @@ -1749,9 +1819,11 @@ public class SWFInputStream implements AutoCloseable { */ public RGB readRGB() throws IOException { RGB ret = new RGB(); + newDumpLevel("RGB"); ret.red = readUI8(); ret.green = readUI8(); ret.blue = readUI8(); + endDumpLevel(); return ret; } @@ -1763,6 +1835,7 @@ public class SWFInputStream implements AutoCloseable { */ public CONVOLUTIONFILTER readCONVOLUTIONFILTER() throws IOException { CONVOLUTIONFILTER ret = new CONVOLUTIONFILTER(); + newDumpLevel("CONVOLUTIONFILTER"); ret.matrixX = readUI8(); ret.matrixY = readUI8(); ret.divisor = readFLOAT(); @@ -1777,6 +1850,7 @@ public class SWFInputStream implements AutoCloseable { ret.reserved = (int) readUB(6); ret.clamp = readUB(1) == 1; ret.preserveAlpha = readUB(1) == 1; + endDumpLevel(); return ret; } @@ -1788,10 +1862,12 @@ public class SWFInputStream implements AutoCloseable { */ public BLURFILTER readBLURFILTER() throws IOException { BLURFILTER ret = new BLURFILTER(); + newDumpLevel("BLURFILTER"); ret.blurX = readFIXED(); ret.blurY = readFIXED(); ret.passes = (int) readUB(5); ret.reserved = (int) readUB(3); + endDumpLevel(); return ret; } @@ -1803,6 +1879,7 @@ public class SWFInputStream implements AutoCloseable { */ public DROPSHADOWFILTER readDROPSHADOWFILTER() throws IOException { DROPSHADOWFILTER ret = new DROPSHADOWFILTER(); + newDumpLevel("DROPSHADOWFILTER"); ret.dropShadowColor = readRGBA(); ret.blurX = readFIXED(); ret.blurY = readFIXED(); @@ -1813,6 +1890,7 @@ public class SWFInputStream implements AutoCloseable { ret.knockout = readUB(1) == 1; ret.compositeSource = readUB(1) == 1; ret.passes = (int) readUB(5); + endDumpLevel(); return ret; } @@ -1824,6 +1902,7 @@ public class SWFInputStream implements AutoCloseable { */ public GLOWFILTER readGLOWFILTER() throws IOException { GLOWFILTER ret = new GLOWFILTER(); + newDumpLevel("GLOWFILTER"); ret.glowColor = readRGBA(); ret.blurX = readFIXED(); ret.blurY = readFIXED(); @@ -1832,6 +1911,7 @@ public class SWFInputStream implements AutoCloseable { ret.knockout = readUB(1) == 1; ret.compositeSource = readUB(1) == 1; ret.passes = (int) readUB(5); + endDumpLevel(); return ret; } @@ -1843,6 +1923,7 @@ public class SWFInputStream implements AutoCloseable { */ public BEVELFILTER readBEVELFILTER() throws IOException { BEVELFILTER ret = new BEVELFILTER(); + newDumpLevel("BEVELFILTER"); ret.highlightColor = readRGBA(); //Highlight color first. It it opposite of the documentation ret.shadowColor = readRGBA(); ret.blurX = readFIXED(); @@ -1855,6 +1936,7 @@ public class SWFInputStream implements AutoCloseable { ret.compositeSource = readUB(1) == 1; ret.onTop = readUB(1) == 1; ret.passes = (int) readUB(4); + endDumpLevel(); return ret; } @@ -1866,6 +1948,7 @@ public class SWFInputStream implements AutoCloseable { */ public GRADIENTGLOWFILTER readGRADIENTGLOWFILTER() throws IOException { GRADIENTGLOWFILTER ret = new GRADIENTGLOWFILTER(); + newDumpLevel("GRADIENTGLOWFILTER"); int numColors = readUI8(); ret.gradientColors = new RGBA[numColors]; ret.gradientRatio = new int[numColors]; @@ -1885,6 +1968,7 @@ public class SWFInputStream implements AutoCloseable { ret.compositeSource = readUB(1) == 1; ret.onTop = readUB(1) == 1; ret.passes = (int) readUB(4); + endDumpLevel(); return ret; } @@ -1896,6 +1980,7 @@ public class SWFInputStream implements AutoCloseable { */ public GRADIENTBEVELFILTER readGRADIENTBEVELFILTER() throws IOException { GRADIENTBEVELFILTER ret = new GRADIENTBEVELFILTER(); + newDumpLevel("GRADIENTBEVELFILTER"); int numColors = readUI8(); ret.gradientColors = new RGBA[numColors]; ret.gradientRatio = new int[numColors]; @@ -1915,6 +2000,7 @@ public class SWFInputStream implements AutoCloseable { ret.compositeSource = readUB(1) == 1; ret.onTop = readUB(1) == 1; ret.passes = (int) readUB(4); + endDumpLevel(); return ret; } @@ -1926,10 +2012,12 @@ public class SWFInputStream implements AutoCloseable { */ public List readFILTERLIST() throws IOException { List ret = new ArrayList<>(); + newDumpLevel("FILTERLIST"); int numberOfFilters = readUI8(); for (int i = 0; i < numberOfFilters; i++) { ret.add(readFILTER()); } + endDumpLevel(); return ret; } @@ -1940,27 +2028,37 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public FILTER readFILTER() throws IOException { + newDumpLevel("FILTER"); int filterId = readUI8(); + FILTER ret = null; switch (filterId) { case 0: - return readDROPSHADOWFILTER(); + ret = readDROPSHADOWFILTER(); + break; case 1: - return readBLURFILTER(); + ret = readBLURFILTER(); + break; case 2: - return readGLOWFILTER(); + ret = readGLOWFILTER(); + break; case 3: - return readBEVELFILTER(); + ret = readBEVELFILTER(); + break; case 4: - return readGRADIENTGLOWFILTER(); + ret = readGRADIENTGLOWFILTER(); + break; case 5: - return readCONVOLUTIONFILTER(); + ret = readCONVOLUTIONFILTER(); + break; case 6: - return readCOLORMATRIXFILTER(); + ret = readCOLORMATRIXFILTER(); + break; case 7: - return readGRADIENTBEVELFILTER(); - default: - return null; + ret = readGRADIENTBEVELFILTER(); + break; } + endDumpLevel(); + return ret; } /** @@ -1973,10 +2071,12 @@ public class SWFInputStream implements AutoCloseable { */ public List readBUTTONRECORDList(boolean inDefineButton2) throws IOException { List ret = new ArrayList<>(); + newDumpLevel("BUTTONRECORDList"); BUTTONRECORD br; while ((br = readBUTTONRECORD(inDefineButton2)) != null) { ret.add(br); } + endDumpLevel(); return ret; } @@ -1989,6 +2089,7 @@ public class SWFInputStream implements AutoCloseable { */ public BUTTONRECORD readBUTTONRECORD(boolean inDefineButton2) throws IOException { BUTTONRECORD ret = new BUTTONRECORD(); + newDumpLevel("BUTTONRECORD"); ret.reserved = (int) readUB(2); ret.buttonHasBlendMode = readUB(1) == 1; ret.buttonHasFilterList = readUB(1) == 1; @@ -2015,6 +2116,7 @@ public class SWFInputStream implements AutoCloseable { ret.blendMode = readUI8(); } } + endDumpLevel(); return ret; } @@ -2028,11 +2130,13 @@ public class SWFInputStream implements AutoCloseable { */ public List readBUTTONCONDACTIONList(SWF swf, Tag tag) throws IOException { List ret = new ArrayList<>(); + newDumpLevel("BUTTONCONDACTIONList"); BUTTONCONDACTION bc; while (!(bc = readBUTTONCONDACTION(swf, tag)).isLast) { ret.add(bc); } ret.add(bc); + endDumpLevel(); return ret; } @@ -2045,8 +2149,10 @@ public class SWFInputStream implements AutoCloseable { * @throws IOException */ public BUTTONCONDACTION readBUTTONCONDACTION(SWF swf, Tag tag) throws IOException { + newDumpLevel("BUTTONCONDACTION"); BUTTONCONDACTION ret = new BUTTONCONDACTION(swf, this, getPos(), tag); //ret.actions = readActionList(); + endDumpLevel(); return ret; } @@ -2059,12 +2165,14 @@ public class SWFInputStream implements AutoCloseable { */ public GRADRECORD readGRADRECORD(int shapeNum) throws IOException { GRADRECORD ret = new GRADRECORD(); + newDumpLevel("GRADRECORD"); ret.ratio = readUI8(); if (shapeNum >= 3) { ret.color = readRGBA(); } else { ret.color = readRGB(); } + endDumpLevel(); return ret; } @@ -2077,6 +2185,7 @@ public class SWFInputStream implements AutoCloseable { */ public GRADIENT readGRADIENT(int shapeNum) throws IOException { GRADIENT ret = new GRADIENT(); + newDumpLevel("GRADIENT"); ret.spreadMode = (int) readUB(2); ret.interpolationMode = (int) readUB(2); int numGradients = (int) readUB(4); @@ -2085,6 +2194,7 @@ public class SWFInputStream implements AutoCloseable { ret.gradientRecords[i] = readGRADRECORD(shapeNum); } + endDumpLevel(); return ret; } @@ -2097,6 +2207,7 @@ public class SWFInputStream implements AutoCloseable { */ public FOCALGRADIENT readFOCALGRADIENT(int shapeNum) throws IOException { FOCALGRADIENT ret = new FOCALGRADIENT(); + newDumpLevel("FOCALGRADIENT"); ret.spreadMode = (int) readUB(2); ret.interpolationMode = (int) readUB(2); int numGradients = (int) readUB(4); @@ -2105,6 +2216,7 @@ public class SWFInputStream implements AutoCloseable { ret.gradientRecords[i] = readGRADRECORD(shapeNum); } ret.focalPoint = readFIXED8(); + endDumpLevel(); return ret; } @@ -2117,6 +2229,7 @@ public class SWFInputStream implements AutoCloseable { */ public FILLSTYLE readFILLSTYLE(int shapeNum) throws IOException { FILLSTYLE ret = new FILLSTYLE(); + newDumpLevel("FILLSTYLE"); ret.fillStyleType = readUI8(); if (ret.fillStyleType == FILLSTYLE.SOLID) { if (shapeNum >= 3) { @@ -2145,6 +2258,7 @@ public class SWFInputStream implements AutoCloseable { ret.bitmapId = readUI16(); ret.bitmapMatrix = readMatrix(); } + endDumpLevel(); return ret; } @@ -2158,6 +2272,7 @@ public class SWFInputStream implements AutoCloseable { public FILLSTYLEARRAY readFILLSTYLEARRAY(int shapeNum) throws IOException { FILLSTYLEARRAY ret = new FILLSTYLEARRAY(); + newDumpLevel("FILLSTYLEARRAY"); int fillStyleCount = readUI8(); if (((shapeNum == 2) || (shapeNum == 3) || (shapeNum == 4/*?*/)) && (fillStyleCount == 0xff)) { fillStyleCount = readUI16(); @@ -2166,6 +2281,7 @@ public class SWFInputStream implements AutoCloseable { for (int i = 0; i < fillStyleCount; i++) { ret.fillStyles[i] = readFILLSTYLE(shapeNum); } + endDumpLevel(); return ret; } @@ -2178,6 +2294,7 @@ public class SWFInputStream implements AutoCloseable { */ public LINESTYLE readLINESTYLE(int shapeNum) throws IOException { LINESTYLE ret = new LINESTYLE(); + newDumpLevel("LINESTYLE"); ret.width = readUI16(); if ((shapeNum == 1) || (shapeNum == 2)) { ret.color = readRGB(); @@ -2185,6 +2302,7 @@ public class SWFInputStream implements AutoCloseable { if (shapeNum == 3) { ret.color = readRGBA(); } + endDumpLevel(); return ret; } @@ -2197,6 +2315,7 @@ public class SWFInputStream implements AutoCloseable { */ public LINESTYLE2 readLINESTYLE2(int shapeNum) throws IOException { LINESTYLE2 ret = new LINESTYLE2(); + newDumpLevel("LINESTYLE2"); ret.width = readUI16(); ret.startCapStyle = (int) readUB(2); ret.joinStyle = (int) readUB(2); @@ -2215,6 +2334,7 @@ public class SWFInputStream implements AutoCloseable { } else { ret.fillType = readFILLSTYLE(shapeNum); } + endDumpLevel(); return ret; } @@ -2227,6 +2347,7 @@ public class SWFInputStream implements AutoCloseable { */ public LINESTYLEARRAY readLINESTYLEARRAY(int shapeNum) throws IOException { LINESTYLEARRAY ret = new LINESTYLEARRAY(); + newDumpLevel("LINESTYLEARRAY"); int lineStyleCount = readUI8(); if (lineStyleCount == 0xff) { lineStyleCount = readUI16(); @@ -2242,6 +2363,7 @@ public class SWFInputStream implements AutoCloseable { ret.lineStyles[i] = readLINESTYLE2(shapeNum); } } + endDumpLevel(); return ret; } @@ -2256,6 +2378,7 @@ public class SWFInputStream implements AutoCloseable { */ private SHAPERECORD readSHAPERECORD(int fillBits, int lineBits, int shapeNum, boolean morphShape) throws IOException { SHAPERECORD ret; + newDumpLevel("SHAPERECORD"); int typeFlag = (int) readUB(1); if (typeFlag == 0) { boolean stateNewStyles = readUB(1) == 1; @@ -2324,6 +2447,7 @@ public class SWFInputStream implements AutoCloseable { ret = cer; } } + endDumpLevel(); return ret; } @@ -2337,9 +2461,11 @@ public class SWFInputStream implements AutoCloseable { */ public SHAPE readSHAPE(int shapeNum, boolean morphShape) throws IOException { SHAPE ret = new SHAPE(); + newDumpLevel("SHAPE"); ret.numFillBits = (int) readUB(4); ret.numLineBits = (int) readUB(4); ret.shapeRecords = readSHAPERECORDS(shapeNum, ret.numFillBits, ret.numLineBits, morphShape); + endDumpLevel(); return ret; } @@ -2353,11 +2479,13 @@ public class SWFInputStream implements AutoCloseable { */ public SHAPEWITHSTYLE readSHAPEWITHSTYLE(int shapeNum, boolean morphShape) throws IOException { SHAPEWITHSTYLE ret = new SHAPEWITHSTYLE(); + newDumpLevel("SHAPEWITHSTYLE"); ret.fillStyles = readFILLSTYLEARRAY(shapeNum); ret.lineStyles = readLINESTYLEARRAY(shapeNum); ret.numFillBits = (int) readUB(4); ret.numLineBits = (int) readUB(4); ret.shapeRecords = readSHAPERECORDS(shapeNum, ret.numFillBits, ret.numLineBits, morphShape); + endDumpLevel(); return ret; } @@ -2372,6 +2500,7 @@ public class SWFInputStream implements AutoCloseable { */ private List readSHAPERECORDS(int shapeNum, int fillBits, int lineBits, boolean morphShape) throws IOException { List ret = new ArrayList<>(); + newDumpLevel("SHAPERECORDS"); SHAPERECORD rec; do { rec = readSHAPERECORD(fillBits, lineBits, shapeNum, morphShape); @@ -2385,6 +2514,7 @@ public class SWFInputStream implements AutoCloseable { ret.add(rec); } while (!(rec instanceof EndShapeRecord)); alignByte(); + endDumpLevel(); return ret; } @@ -2396,6 +2526,7 @@ public class SWFInputStream implements AutoCloseable { */ public SOUNDINFO readSOUNDINFO() throws IOException { SOUNDINFO ret = new SOUNDINFO(); + newDumpLevel("SOUNDINFO"); ret.reserved = (int) readUB(2); ret.syncStop = readUB(1) == 1; ret.syncNoMultiple = readUB(1) == 1; @@ -2419,6 +2550,7 @@ public class SWFInputStream implements AutoCloseable { ret.envelopeRecords[i] = readSOUNDENVELOPE(); } } + endDumpLevel(); return ret; } @@ -2430,9 +2562,11 @@ public class SWFInputStream implements AutoCloseable { */ public SOUNDENVELOPE readSOUNDENVELOPE() throws IOException { SOUNDENVELOPE ret = new SOUNDENVELOPE(); + newDumpLevel("SOUNDENVELOPE"); ret.pos44 = readUI32(); ret.leftLevel = readUI16(); ret.rightLevel = readUI16(); + endDumpLevel(); return ret; } @@ -2446,8 +2580,10 @@ public class SWFInputStream implements AutoCloseable { */ public GLYPHENTRY readGLYPHENTRY(int glyphBits, int advanceBits) throws IOException { GLYPHENTRY ret = new GLYPHENTRY(); + newDumpLevel("GLYPHENTRY"); ret.glyphIndex = (int) readUB(glyphBits); ret.glyphAdvance = (int) readUB(advanceBits); + endDumpLevel(); return ret; } @@ -2462,6 +2598,7 @@ public class SWFInputStream implements AutoCloseable { */ public TEXTRECORD readTEXTRECORD(boolean inDefineText2, int glyphBits, int advanceBits) throws IOException { TEXTRECORD ret = new TEXTRECORD(); + newDumpLevel("TEXTRECORD"); int first = (int) readUB(1); //always 1 readUB(3); //always 0 ret.styleFlagsHasFont = readUB(1) == 1; @@ -2469,6 +2606,7 @@ public class SWFInputStream implements AutoCloseable { ret.styleFlagsHasYOffset = readUB(1) == 1; ret.styleFlagsHasXOffset = readUB(1) == 1; if ((!ret.styleFlagsHasFont) && (!ret.styleFlagsHasColor) && (!ret.styleFlagsHasYOffset) && (!ret.styleFlagsHasXOffset) && (first == 0)) { //final text record + endDumpLevel(); return null; } if (ret.styleFlagsHasFont) { @@ -2496,6 +2634,7 @@ public class SWFInputStream implements AutoCloseable { ret.glyphEntries[i] = readGLYPHENTRY(glyphBits, advanceBits); } alignByte(); + endDumpLevel(); return ret; } @@ -2507,10 +2646,12 @@ public class SWFInputStream implements AutoCloseable { */ public MORPHGRADRECORD readMORPHGRADRECORD() throws IOException { MORPHGRADRECORD ret = new MORPHGRADRECORD(); + newDumpLevel("MORPHGRADRECORD"); ret.startRatio = readUI8(); ret.startColor = readRGBA(); ret.endRatio = readUI8(); ret.endColor = readRGBA(); + endDumpLevel(); return ret; } @@ -2522,6 +2663,7 @@ public class SWFInputStream implements AutoCloseable { */ public MORPHGRADIENT readMORPHGRADIENT() throws IOException { MORPHGRADIENT ret = new MORPHGRADIENT(); + newDumpLevel("MORPHGRADIENT"); //Despite of documentation (UI8 1-8), there are two fields // spreadMode and interPolationMode which are same as in GRADIENT ret.spreadMode = (int) readUB(2); @@ -2531,6 +2673,7 @@ public class SWFInputStream implements AutoCloseable { for (int i = 0; i < numGradients; i++) { ret.gradientRecords[i] = readMORPHGRADRECORD(); } + endDumpLevel(); return ret; } @@ -2544,6 +2687,7 @@ public class SWFInputStream implements AutoCloseable { */ public MORPHFOCALGRADIENT readMORPHFOCALGRADIENT() throws IOException { MORPHFOCALGRADIENT ret = new MORPHFOCALGRADIENT(); + newDumpLevel("MORPHFOCALGRADIENT"); ret.spreadMode = (int) readUB(2); ret.interPolationMode = (int) readUB(2); int numGradients = (int) readUB(4); @@ -2553,6 +2697,7 @@ public class SWFInputStream implements AutoCloseable { } ret.startFocalPoint = readFIXED8(); ret.endFocalPoint = readFIXED8(); + endDumpLevel(); return ret; } @@ -2564,6 +2709,7 @@ public class SWFInputStream implements AutoCloseable { */ public MORPHFILLSTYLE readMORPHFILLSTYLE() throws IOException { MORPHFILLSTYLE ret = new MORPHFILLSTYLE(); + newDumpLevel("MORPHFILLSTYLE"); ret.fillStyleType = readUI8(); if (ret.fillStyleType == MORPHFILLSTYLE.SOLID) { ret.startColor = readRGBA(); @@ -2591,6 +2737,7 @@ public class SWFInputStream implements AutoCloseable { ret.startBitmapMatrix = readMatrix(); ret.endBitmapMatrix = readMatrix(); } + endDumpLevel(); return ret; } @@ -2603,6 +2750,7 @@ public class SWFInputStream implements AutoCloseable { public MORPHFILLSTYLEARRAY readMORPHFILLSTYLEARRAY() throws IOException { MORPHFILLSTYLEARRAY ret = new MORPHFILLSTYLEARRAY(); + newDumpLevel("MORPHFILLSTYLEARRAY"); int fillStyleCount = readUI8(); if (fillStyleCount == 0xff) { fillStyleCount = readUI16(); @@ -2611,6 +2759,7 @@ public class SWFInputStream implements AutoCloseable { for (int i = 0; i < fillStyleCount; i++) { ret.fillStyles[i] = readMORPHFILLSTYLE(); } + endDumpLevel(); return ret; } @@ -2622,10 +2771,12 @@ public class SWFInputStream implements AutoCloseable { */ public MORPHLINESTYLE readMORPHLINESTYLE() throws IOException { MORPHLINESTYLE ret = new MORPHLINESTYLE(); + newDumpLevel("MORPHLINESTYLE"); ret.startWidth = readUI16(); ret.endWidth = readUI16(); ret.startColor = readRGBA(); ret.endColor = readRGBA(); + endDumpLevel(); return ret; } @@ -2637,6 +2788,7 @@ public class SWFInputStream implements AutoCloseable { */ public MORPHLINESTYLE2 readMORPHLINESTYLE2() throws IOException { MORPHLINESTYLE2 ret = new MORPHLINESTYLE2(); + newDumpLevel("MORPHLINESTYLE2"); ret.startWidth = readUI16(); ret.endWidth = readUI16(); ret.startCapStyle = (int) readUB(2); @@ -2657,6 +2809,7 @@ public class SWFInputStream implements AutoCloseable { } else { ret.fillType = readMORPHFILLSTYLE(); } + endDumpLevel(); return ret; } @@ -2669,6 +2822,7 @@ public class SWFInputStream implements AutoCloseable { */ public MORPHLINESTYLEARRAY readMORPHLINESTYLEARRAY(int morphShapeNum) throws IOException { MORPHLINESTYLEARRAY ret = new MORPHLINESTYLEARRAY(); + newDumpLevel("MORPHLINESTYLEARRAY"); int lineStyleCount = readUI8(); if (lineStyleCount == 0xff) { lineStyleCount = readUI16(); @@ -2684,6 +2838,7 @@ public class SWFInputStream implements AutoCloseable { ret.lineStyles2[i] = readMORPHLINESTYLE2(); } } + endDumpLevel(); return ret; } @@ -2696,6 +2851,7 @@ public class SWFInputStream implements AutoCloseable { */ public KERNINGRECORD readKERNINGRECORD(boolean fontFlagsWideCodes) throws IOException { KERNINGRECORD ret = new KERNINGRECORD(); + newDumpLevel("KERNINGRECORD"); if (fontFlagsWideCodes) { ret.fontKerningCode1 = readUI16(); ret.fontKerningCode2 = readUI16(); @@ -2704,6 +2860,7 @@ public class SWFInputStream implements AutoCloseable { ret.fontKerningCode2 = readUI8(); } ret.fontKerningAdjustment = readSI16(); + endDumpLevel(); return ret; } @@ -2715,7 +2872,9 @@ public class SWFInputStream implements AutoCloseable { */ public LANGCODE readLANGCODE() throws IOException { LANGCODE ret = new LANGCODE(); + newDumpLevel("LANGCODE"); ret.languageCode = readUI8(); + endDumpLevel(); return ret; } @@ -2727,6 +2886,7 @@ public class SWFInputStream implements AutoCloseable { */ public ZONERECORD readZONERECORD() throws IOException { ZONERECORD ret = new ZONERECORD(); + newDumpLevel("ZONERECORD"); int numZoneData = readUI8(); ret.zonedata = new ZONEDATA[numZoneData]; for (int i = 0; i < numZoneData; i++) { @@ -2735,6 +2895,7 @@ public class SWFInputStream implements AutoCloseable { readUB(6); ret.zoneMaskY = readUB(1) == 1; ret.zoneMaskX = readUB(1) == 1; + endDumpLevel(); return ret; } @@ -2746,8 +2907,10 @@ public class SWFInputStream implements AutoCloseable { */ public ZONEDATA readZONEDATA() throws IOException { ZONEDATA ret = new ZONEDATA(); + newDumpLevel("ZONEDATA"); ret.alignmentCoordinate = readUI16(); ret.range = readUI16(); + endDumpLevel(); return ret; } @@ -2759,10 +2922,12 @@ public class SWFInputStream implements AutoCloseable { */ public PIX15 readPIX15() throws IOException { PIX15 ret = new PIX15(); + newDumpLevel("PIX15"); readUB(1); ret.red = (int) readUB(5); ret.green = (int) readUB(5); ret.blue = (int) readUB(5); + endDumpLevel(); return ret; } @@ -2774,10 +2939,12 @@ public class SWFInputStream implements AutoCloseable { */ public PIX24 readPIX24() throws IOException { PIX24 ret = new PIX24(); + newDumpLevel("PIX24"); ret.reserved = readUI8(); ret.red = readUI8(); ret.green = readUI8(); ret.blue = readUI8(); + endDumpLevel(); return ret; } @@ -2792,6 +2959,7 @@ public class SWFInputStream implements AutoCloseable { */ public COLORMAPDATA readCOLORMAPDATA(int colorTableSize, int bitmapWidth, int bitmapHeight) throws IOException { COLORMAPDATA ret = new COLORMAPDATA(); + newDumpLevel("COLORMAPDATA"); ret.colorTableRGB = new RGB[colorTableSize + 1]; for (int i = 0; i < colorTableSize + 1; i++) { ret.colorTableRGB[i] = readRGB(); @@ -2808,6 +2976,7 @@ public class SWFInputStream implements AutoCloseable { } } ret.colorMapPixelData = readBytesEx(dataLen); + endDumpLevel(); return ret; } @@ -2822,6 +2991,7 @@ public class SWFInputStream implements AutoCloseable { */ public BITMAPDATA readBITMAPDATA(int bitmapFormat, int bitmapWidth, int bitmapHeight) throws IOException { BITMAPDATA ret = new BITMAPDATA(); + newDumpLevel("BITMAPDATA"); List pix15 = new ArrayList<>(); List pix24 = new ArrayList<>(); int dataLen = 0; @@ -2847,6 +3017,7 @@ public class SWFInputStream implements AutoCloseable { } else if (bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB) { ret.bitmapPixelDataPix24 = pix24.toArray(new PIX24[pix24.size()]); } + endDumpLevel(); return ret; } @@ -2861,12 +3032,14 @@ public class SWFInputStream implements AutoCloseable { */ public ALPHABITMAPDATA readALPHABITMAPDATA(int bitmapFormat, int bitmapWidth, int bitmapHeight) throws IOException { ALPHABITMAPDATA ret = new ALPHABITMAPDATA(); + newDumpLevel("ALPHABITMAPDATA"); ret.bitmapPixelData = new ARGB[bitmapWidth * bitmapHeight]; for (int y = 0; y < bitmapHeight; y++) { for (int x = 0; x < bitmapWidth; x++) { ret.bitmapPixelData[y * bitmapWidth + x] = readARGB(); } } + endDumpLevel(); return ret; } @@ -2881,6 +3054,7 @@ public class SWFInputStream implements AutoCloseable { */ public ALPHACOLORMAPDATA readALPHACOLORMAPDATA(int colorTableSize, int bitmapWidth, int bitmapHeight) throws IOException { ALPHACOLORMAPDATA ret = new ALPHACOLORMAPDATA(); + newDumpLevel("ALPHACOLORMAPDATA"); ret.colorTableRGB = new RGBA[colorTableSize + 1]; for (int i = 0; i < colorTableSize + 1; i++) { ret.colorTableRGB[i] = readRGBA(); @@ -2897,6 +3071,7 @@ public class SWFInputStream implements AutoCloseable { } } ret.colorMapPixelData = readBytesEx(dataLen); + endDumpLevel(); return ret; } @@ -2911,7 +3086,15 @@ public class SWFInputStream implements AutoCloseable { return available() * 8; } - public SeekableInputStream getBaseStream() { - return is; + public MemoryInputStream getBaseStream() throws IOException { + int pos = (int) is.getPos(); + return new MemoryInputStream(is.getAllRead(), pos, pos + is.available()); + } + + public SWFInputStream getLimitedStream(int limit) throws IOException { + SWFInputStream sis = new SWFInputStream(swf, is.getAllRead(), startingPos, (int) (is.getPos() + limit)); + sis.dumpInfo = dumpInfo; + sis.seek(is.getPos() + startingPos); + return sis; } } diff --git a/src/com/jpexs/decompiler/flash/SWFLimitedInputStream.java b/src/com/jpexs/decompiler/flash/SWFLimitedInputStream.java deleted file mode 100644 index 07629f96e..000000000 --- a/src/com/jpexs/decompiler/flash/SWFLimitedInputStream.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash; - -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.timeline.Timelined; -import com.jpexs.decompiler.flash.types.BUTTONCONDACTION; -import com.jpexs.decompiler.flash.types.BUTTONRECORD; -import com.jpexs.decompiler.flash.types.CLIPACTIONS; -import com.jpexs.decompiler.flash.types.CXFORM; -import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA; -import com.jpexs.decompiler.flash.types.KERNINGRECORD; -import com.jpexs.decompiler.flash.types.LANGCODE; -import com.jpexs.decompiler.flash.types.MATRIX; -import com.jpexs.decompiler.flash.types.MORPHFILLSTYLEARRAY; -import com.jpexs.decompiler.flash.types.MORPHLINESTYLEARRAY; -import com.jpexs.decompiler.flash.types.RECT; -import com.jpexs.decompiler.flash.types.RGB; -import com.jpexs.decompiler.flash.types.RGBA; -import com.jpexs.decompiler.flash.types.SHAPE; -import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE; -import com.jpexs.decompiler.flash.types.SOUNDINFO; -import com.jpexs.decompiler.flash.types.TEXTRECORD; -import com.jpexs.decompiler.flash.types.ZONERECORD; -import com.jpexs.decompiler.flash.types.filters.FILTER; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class SWFLimitedInputStream { - - private SWFInputStream sis; - private long limit; - public SWF swf; - - public SWFLimitedInputStream(SWF swf, SWFInputStream sis, long limit) { - this.swf = swf; - this.limit = limit; - this.sis = sis; - } - - public int available() throws IOException { - return sis.available(); - } - - public long readUB(int nBits) throws IOException { - return sis.readUB(nBits); - } - - public int readUI8() throws IOException { - return sis.readUI8(); - } - - public int readUI16() throws IOException { - return sis.readUI16(); - } - - public long readUI32() throws IOException { - return sis.readUI32(); - } - - public int readSI16() throws IOException { - return sis.readSI16(); - } - - public long readEncodedU32() throws IOException { - return sis.readEncodedU32(); - } - - public float readFLOAT() throws IOException { - return sis.readFLOAT(); - } - - public byte[] readBytesEx(long count) throws IOException { - return sis.readBytesEx(count); - } - - public byte[] readBytesZlib(long count) throws IOException { - return sis.readBytesZlib(count); - } - - public String readString() throws IOException { - return sis.readString(); - } - - public MATRIX readMatrix() throws IOException { - return sis.readMatrix(); - } - - public List readTagList(SWF swf, Timelined timelined, int level, boolean parallel, boolean skipUnusualTags, boolean parseTags, boolean gfx) throws IOException, InterruptedException { - return sis.readTagList(swf, timelined, level, parallel, skipUnusualTags, parseTags, gfx); - } - - public List readBUTTONRECORDList(boolean inDefineButton2) throws IOException { - return sis.readBUTTONRECORDList(inDefineButton2); - } - - public List readBUTTONCONDACTIONList(SWF swf, Tag tag) throws IOException { - return sis.readBUTTONCONDACTIONList(swf, tag); - } - - public CLIPACTIONS readCLIPACTIONS(SWF swf, Tag tag) throws IOException { - return sis.readCLIPACTIONS(swf, tag); - } - - public CXFORM readCXFORM() throws IOException { - return sis.readCXFORM(); - } - - public CXFORMWITHALPHA readCXFORMWITHALPHA() throws IOException { - return sis.readCXFORMWITHALPHA(); - } - - public List readFILTERLIST() throws IOException { - return sis.readFILTERLIST(); - } - - public LANGCODE readLANGCODE() throws IOException { - return sis.readLANGCODE(); - } - - public MORPHFILLSTYLEARRAY readMORPHFILLSTYLEARRAY() throws IOException { - return sis.readMORPHFILLSTYLEARRAY(); - } - - public MORPHLINESTYLEARRAY readMORPHLINESTYLEARRAY(int morphShapeNum) throws IOException { - return sis.readMORPHLINESTYLEARRAY(morphShapeNum); - } - - public RGB readRGB() throws IOException { - return sis.readRGB(); - } - - public RGBA readRGBA() throws IOException { - return sis.readRGBA(); - } - - public SHAPE readSHAPE(int shapeNum, boolean morphShape) throws IOException { - return sis.readSHAPE(shapeNum, morphShape); - } - - public SHAPEWITHSTYLE readSHAPEWITHSTYLE(int shapeNum, boolean morphShape) throws IOException { - return sis.readSHAPEWITHSTYLE(shapeNum, morphShape); - } - - public KERNINGRECORD readKERNINGRECORD(boolean fontFlagsWideCodes) throws IOException { - return sis.readKERNINGRECORD(fontFlagsWideCodes); - } - - public TEXTRECORD readTEXTRECORD(boolean inDefineText2, int glyphBits, int advanceBits) throws IOException { - return sis.readTEXTRECORD(inDefineText2, glyphBits, advanceBits); - } - - public RECT readRECT() throws IOException { - return sis.readRECT(); - } - - public SOUNDINFO readSOUNDINFO() throws IOException { - return sis.readSOUNDINFO(); - } - - public ZONERECORD readZONERECORD() throws IOException { - return sis.readZONERECORD(); - } - - public long getPos() { - return sis.getPos(); - } - - public InputStream getBaseStream() { - return sis.getBaseStream(); - } - -} diff --git a/src/com/jpexs/decompiler/flash/SWFOutputStream.java b/src/com/jpexs/decompiler/flash/SWFOutputStream.java index f6378b660..d74b0be4c 100644 --- a/src/com/jpexs/decompiler/flash/SWFOutputStream.java +++ b/src/com/jpexs/decompiler/flash/SWFOutputStream.java @@ -427,6 +427,8 @@ public class SWFOutputStream extends OutputStream { tagPositions.put(tag, pos); tagLengths.put(tag, length); } + + // todo: honfika: update tag position and lengths. Currently the 2nd save fails } /** diff --git a/src/com/jpexs/decompiler/flash/abc/ABC.java b/src/com/jpexs/decompiler/flash/abc/ABC.java index f938c39b3..4bb36ca8e 100644 --- a/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.abc; import com.jpexs.decompiler.flash.EventListener; import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.AVM2Deobfuscation; import com.jpexs.decompiler.flash.abc.avm2.ConstantPool; @@ -58,7 +59,6 @@ import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.helpers.utf8.Utf8PrintWriter; import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; @@ -336,10 +336,10 @@ public class ABC { } } - public ABC(InputStream is, SWF swf, ABCContainerTag tag) throws IOException { + public ABC(SWFInputStream is, SWF swf, ABCContainerTag tag) throws IOException { this.swf = swf; this.parentTag = tag; - ABCInputStream ais = new ABCInputStream(is); + ABCInputStream ais = new ABCInputStream(is.getBaseStream()); minor_version = ais.readU16(); major_version = ais.readU16(); logger.log(Level.FINE, "ABC minor_version: {0}, major_version: {1}", new Object[]{minor_version, major_version}); diff --git a/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java b/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java index 17dd8834c..63eca896a 100644 --- a/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java +++ b/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java @@ -77,7 +77,7 @@ public class ActionPush extends Action { super(0x96, actionLength); int type; values = new ArrayList<>(); - sis = new SWFInputStream(sis.swf, sis.readBytesEx(actionLength)); + sis = new SWFInputStream(sis.getSwf(), sis.readBytesEx(actionLength)); try { while (sis.available() > 0) { type = sis.readUI8(); diff --git a/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/src/com/jpexs/decompiler/flash/configuration/Configuration.java index ddb5cbd17..07a9da360 100644 --- a/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -90,6 +90,10 @@ public class Configuration { @ConfigurationCategory("display") public static final ConfigurationItem internalFlashViewer = null; + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("display") + public static final ConfigurationItem dumpView = null; + @ConfigurationDefaultBoolean(false) @ConfigurationCategory("ui") public static final ConfigurationItem gotoMainClassOnStartup = null; diff --git a/src/com/jpexs/decompiler/flash/dumpview/DumpInfo.java b/src/com/jpexs/decompiler/flash/dumpview/DumpInfo.java index f31a78a41..f8754da65 100644 --- a/src/com/jpexs/decompiler/flash/dumpview/DumpInfo.java +++ b/src/com/jpexs/decompiler/flash/dumpview/DumpInfo.java @@ -16,6 +16,9 @@ */ package com.jpexs.decompiler.flash.dumpview; +import java.util.ArrayList; +import java.util.List; + /** * * @author JPEXS @@ -23,28 +26,45 @@ package com.jpexs.decompiler.flash.dumpview; public class DumpInfo { public String name; + public String type; public Object previewValue; - public int startByte; + public long startByte; public int startBit; - public int lengthBytes; + public long lengthBytes; public int lengthBits; - public DumpInfo(int startByte, int lengthBytes) { + public DumpInfo parent; + + public List childInfos = new ArrayList<>(); + + public DumpInfo(String name, String type, Object value, long startByte, int lengthBytes) { + this.name = name; + this.type = type; + this.previewValue = value; this.startByte = startByte; this.lengthBytes = lengthBytes; } - public DumpInfo(int startByte, int startBit, int lengthBytes, int lengthBits) { + public DumpInfo(String name, String type, Object value, long startByte, int startBit, long lengthBytes, int lengthBits) { + this.name = name; + this.type = type; + this.previewValue = value; this.startByte = startByte; this.lengthBytes = lengthBytes; this.startBit = startBit; this.lengthBits = lengthBits; } + + @Override + public String toString() { + String value = previewValue == null ? "" : previewValue.toString(); + return name + "(" + type + ")" + (value.isEmpty() ? "" : " = " + value); + } } diff --git a/src/com/jpexs/decompiler/flash/dumpview/Dumpable.java b/src/com/jpexs/decompiler/flash/dumpview/Dumpable.java deleted file mode 100644 index 4f97c46a9..000000000 --- a/src/com/jpexs/decompiler/flash/dumpview/Dumpable.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.dumpview; - -import java.util.List; - -/** - * - * @author JPEXS - */ -public interface Dumpable { - - public List getNeededCharacters(); -} diff --git a/src/com/jpexs/decompiler/flash/dumpview/DumpableItem.java b/src/com/jpexs/decompiler/flash/dumpview/DumpableItem.java deleted file mode 100644 index 96fd98158..000000000 --- a/src/com/jpexs/decompiler/flash/dumpview/DumpableItem.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.dumpview; - -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.treeitems.TreeItem; - -/** - * - * @author JPEXS - */ -public class DumpableItem implements TreeItem { - - private final SWF swf; - - public DumpableItem(SWF swf) { - this.swf = swf; - } - - @Override - public SWF getSwf() { - return swf; - } - -} diff --git a/src/com/jpexs/decompiler/flash/dumpview/DumpableNode.java b/src/com/jpexs/decompiler/flash/dumpview/DumpableNode.java deleted file mode 100644 index a348cf116..000000000 --- a/src/com/jpexs/decompiler/flash/dumpview/DumpableNode.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.dumpview; - -import com.jpexs.decompiler.flash.treenodes.TreeNode; - -/** - * - * @author JPEXS - */ -public class DumpableNode extends TreeNode { - - public DumpableNode(DumpableItem item) { - super(item); - } - - @Override - public DumpableItem getItem() { - return (DumpableItem) item; - } - -} diff --git a/src/com/jpexs/decompiler/flash/exporters/SoundExporter.java b/src/com/jpexs/decompiler/flash/exporters/SoundExporter.java index ffc33a24d..b118290c1 100644 --- a/src/com/jpexs/decompiler/flash/exporters/SoundExporter.java +++ b/src/com/jpexs/decompiler/flash/exporters/SoundExporter.java @@ -19,6 +19,8 @@ package com.jpexs.decompiler.flash.exporters; import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; import com.jpexs.decompiler.flash.RetryTask; import com.jpexs.decompiler.flash.RunnableIOEx; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode; import com.jpexs.decompiler.flash.exporters.settings.SoundExportSettings; import com.jpexs.decompiler.flash.flv.AUDIODATA; @@ -139,7 +141,9 @@ public class SoundExporter { } } } else { - fmt.createWav(st.getRawSoundData(), fos); + byte[] soundData = st.getRawSoundData(); + SWF swf = ((Tag) st).getSwf(); + fmt.createWav(new SWFInputStream(swf, soundData), fos); } } diff --git a/src/com/jpexs/decompiler/flash/gui/DumpTree.java b/src/com/jpexs/decompiler/flash/gui/DumpTree.java new file mode 100644 index 000000000..d30f0518b --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/DumpTree.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.JTree; +import javax.swing.plaf.basic.BasicLabelUI; +import javax.swing.plaf.basic.BasicTreeUI; +import javax.swing.tree.DefaultTreeCellRenderer; + +/** + * + * @author JPEXS + */ +public class DumpTree extends JTree { + + public class DumpTreeCellRenderer extends DefaultTreeCellRenderer { + + @Override + public Component getTreeCellRendererComponent( + JTree tree, + Object value, + boolean sel, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + + super.getTreeCellRendererComponent( + tree, value, sel, + expanded, leaf, row, + hasFocus); + + //DumpInfo dumpInfo = (DumpInfo) value; + + setUI(new BasicLabelUI()); + setOpaque(false); + setBackgroundNonSelectionColor(Color.white); + + return this; + } + } + + DumpTree(DumpTreeModel treeModel) { + super(treeModel); + setCellRenderer(new DumpTreeCellRenderer()); + setRootVisible(false); + setBackground(Color.white); + setUI(new BasicTreeUI() { + @Override + public void paint(Graphics g, JComponent c) { + setHashColor(Color.gray); + super.paint(g, c); + } + }); + } + +} diff --git a/src/com/jpexs/decompiler/flash/gui/DumpTreeModel.java b/src/com/jpexs/decompiler/flash/gui/DumpTreeModel.java new file mode 100644 index 000000000..625601d80 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/DumpTreeModel.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.dumpview.DumpInfo; +import com.jpexs.decompiler.flash.treeitems.SWFList; +import java.util.List; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; + +/** + * + * @author JPEXS + */ +public class DumpTreeModel implements TreeModel { + + private final DumpInfo root; + + public DumpTreeModel(List swfs) { + DumpInfo root = new DumpInfo("root", "", null, 0, 0); + for (SWFList swfList : swfs) { + for (SWF swf : swfList) { + swf.dumpInfo.name = swf.getFileTitle(); + root.childInfos.add(swf.dumpInfo); + } + } + this.root = root; + } + + @Override + public Object getRoot() { + return root; + } + + @Override + public Object getChild(Object o, int i) { + return ((DumpInfo) o).childInfos.get(i); + } + + @Override + public int getChildCount(Object o) { + return ((DumpInfo) o).childInfos.size(); + } + + @Override + public boolean isLeaf(Object o) { + return ((DumpInfo) o).childInfos.isEmpty(); + } + + @Override + public void valueForPathChanged(TreePath tp, Object o) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public int getIndexOfChild(Object o, Object o1) { + return ((DumpInfo) o).childInfos.indexOf(o1); + } + + @Override + public void addTreeModelListener(TreeModelListener tl) { + } + + @Override + public void removeTreeModelListener(TreeModelListener tl) { + } + +} diff --git a/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java b/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java index f7d0e6ee8..e0111fe25 100644 --- a/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java @@ -1,896 +1,896 @@ -/* - * Copyright (C) 2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui; - -import com.jpexs.decompiler.flash.AppStrings; -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFInputStream; -import com.jpexs.decompiler.flash.gui.generictageditors.BooleanEditor; -import com.jpexs.decompiler.flash.gui.generictageditors.ColorEditor; -import com.jpexs.decompiler.flash.gui.generictageditors.GenericTagEditor; -import com.jpexs.decompiler.flash.gui.generictageditors.NumberEditor; -import com.jpexs.decompiler.flash.gui.generictageditors.ReflectionTools; -import com.jpexs.decompiler.flash.gui.generictageditors.StringEditor; -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.types.ARGB; -import com.jpexs.decompiler.flash.types.BasicType; -import com.jpexs.decompiler.flash.types.RGB; -import com.jpexs.decompiler.flash.types.RGBA; -import com.jpexs.decompiler.flash.types.annotations.Conditional; -import com.jpexs.decompiler.flash.types.annotations.Internal; -import com.jpexs.decompiler.flash.types.annotations.Multiline; -import com.jpexs.decompiler.flash.types.annotations.SWFArray; -import com.jpexs.decompiler.flash.types.annotations.SWFType; -import com.jpexs.decompiler.flash.types.annotations.parser.ConditionEvaluator; -import com.jpexs.decompiler.flash.types.annotations.parser.ParseException; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.Graphics; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.EventObject; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.swing.AbstractCellEditor; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JScrollPane; -import javax.swing.JTree; -import javax.swing.event.TreeModelListener; -import javax.swing.plaf.basic.BasicLabelUI; -import javax.swing.plaf.basic.BasicTreeUI; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeCellRenderer; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreeCellEditor; -import javax.swing.tree.TreeModel; -import javax.swing.tree.TreePath; - -/** - * - * @author JPEXS - */ -public class GenericTagTreePanel extends GenericTagPanel { - - private JTree tree; - private Tag editedTag; - - private class MyTree extends JTree { - - public MyTree() { - setBackground(Color.white); - setUI(new BasicTreeUI() { - - @Override - public void paint(Graphics g, JComponent c) { - setHashColor(Color.gray); - super.paint(g, c); - } - - }); - setCellRenderer(new MyTreeCellRenderer()); - setCellEditor(new MyTreeCellEditor(this)); - setInvokesStopCellEditing(true); - - } - } - - private class MyTreeCellEditor extends AbstractCellEditor implements TreeCellEditor { - - private GenericTagEditor editor = null; - private final JTree tree; - private FieldNode fnode; - - public MyTreeCellEditor(JTree tree) { - this.tree = tree; - } - - @Override - public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) { - if (value instanceof FieldNode) { - fnode = (FieldNode) value; - Field field = fnode.field; - int index = fnode.index; - Object obj = fnode.obj; - Class type; - try { - type = ReflectionTools.getValue(obj, field, index).getClass(); - } catch (IllegalArgumentException | IllegalAccessException ex) { - ex.printStackTrace(); - return null; - } - SWFType swfType = field.getAnnotation(SWFType.class); - Multiline multiline = field.getAnnotation(Multiline.class); - if (type.equals(int.class) || type.equals(Integer.class) - || type.equals(short.class) || type.equals(Short.class) - || type.equals(long.class) || type.equals(Long.class) - || type.equals(double.class) || type.equals(Double.class) - || type.equals(float.class) || type.equals(Float.class)) { - editor = new NumberEditor(field.getName(), obj, field, index, type, swfType); - } else if (type.equals(boolean.class) || type.equals(Boolean.class)) { - editor = new BooleanEditor(field.getName(), obj, field, index, type); - } else if (type.equals(String.class)) { - editor = new StringEditor(field.getName(), obj, field, index, type, multiline != null); - } else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) { - editor = new ColorEditor(field.getName(), obj, field, index, type); - } - JPanel pan = new JPanel(); - FlowLayout fl = new FlowLayout(FlowLayout.LEFT, 0, 0); - fl.setAlignOnBaseline(true); - pan.setLayout(fl); - JLabel nameLabel = new JLabel(fnode.getNameType() + " = ") { - - @Override - public BaselineResizeBehavior getBaselineResizeBehavior() { - return Component.BaselineResizeBehavior.CONSTANT_ASCENT; - } - - @Override - public int getBaseline(int width, int height) { - return 0; - } - - }; - pan.setBackground(Color.white); - nameLabel.setSize(nameLabel.getWidth(), ((Component) editor).getHeight()); - nameLabel.setAlignmentY(TOP_ALIGNMENT); - ((JComponent) editor).setAlignmentY(TOP_ALIGNMENT); - pan.add(nameLabel); - pan.add((Component) editor); - pan.setPreferredSize(new Dimension((int) nameLabel.getPreferredSize().getWidth() + 5 + (int) ((Component) editor).getPreferredSize().getWidth(), (int) ((Component) editor).getPreferredSize().getHeight())); - return pan; - } - return null; - - } - - @Override - public Object getCellEditorValue() { - return editor.getChangedValue(); - } - - @Override - public boolean isCellEditable(EventObject e) { - if (!(e instanceof MouseEvent)) { - return false; - } - - MouseEvent me = (MouseEvent) e; - TreePath path = tree.getPathForLocation(me.getX(), me.getY()); - - if (path == null) { - return false; - } - Object obj = path.getLastPathComponent(); - - boolean ret = super.isCellEditable(e) - && path != null && (tree.getModel().isLeaf(obj)); - return ret; - } - - @Override - public boolean stopCellEditing() { - super.stopCellEditing(); - - /*List depends = ((MyTreeModel) tree.getModel()).getDependentFields(fnode); - boolean dep = false; - if (!depends.isEmpty()) { - dep = true; - } */ - editor.save(); - ((MyTreeModel) tree.getModel()).vchanged(tree.getSelectionPath()); - refreshTree(); - return true; - } - - } - - public GenericTagTreePanel() { - setLayout(new BorderLayout()); - tree = new MyTree(); - - add(new JScrollPane(tree), BorderLayout.CENTER); - tree.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - if (!tree.isEditable()) { - return; - } - int selRow = tree.getRowForLocation(e.getX(), e.getY()); - TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); - if (selRow != -1 && selPath != null) { - if (e.getClickCount() == 1) { - if (e.getButton() == MouseEvent.BUTTON3) { //right click - Object selObject = selPath.getLastPathComponent(); - if (selObject instanceof FieldNode) { - final FieldNode fnode = (FieldNode) selObject; - SWFArray swfArray = fnode.field.getAnnotation(SWFArray.class); - String itemStr = ""; - if (swfArray != null) { - itemStr = swfArray.value(); - } - if (itemStr.isEmpty()) { - itemStr = AppStrings.translate("generictag.array.item"); - } - if (ReflectionTools.needsIndex(fnode.field)) { - - boolean canAdd = true; - if (!ReflectionTools.canAddToField(fnode.obj, fnode.field)) { - canAdd = false; - } - JPopupMenu p = new JPopupMenu(); - JMenuItem mi; - mi = new JMenuItem(AppStrings.translate("generictag.array.insertbeginning").replace("%item%", itemStr)); - mi.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - addItem(fnode.obj, fnode.field, 0); - } - }); - if (!canAdd) { - mi.setEnabled(false); - } - p.add(mi); - - if (fnode.index > -1) { - mi = new JMenuItem(AppStrings.translate("generictag.array.insertbefore").replace("%item%", itemStr)); - mi.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - addItem(fnode.obj, fnode.field, fnode.index); - } - }); - if (!canAdd) { - mi.setEnabled(false); - } - p.add(mi); - - mi = new JMenuItem(AppStrings.translate("generictag.array.remove").replace("%item%", itemStr)); - mi.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - removeItem(fnode.obj, fnode.field, fnode.index); - } - }); - p.add(mi); - - mi = new JMenuItem(AppStrings.translate("generictag.array.insertafter").replace("%item%", itemStr)); - mi.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - addItem(fnode.obj, fnode.field, fnode.index + 1); - } - }); - if (!canAdd) { - mi.setEnabled(false); - } - p.add(mi); - } - - mi = new JMenuItem(AppStrings.translate("generictag.array.insertend").replace("%item%", itemStr)); - mi.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - addItem(fnode.obj, fnode.field, ReflectionTools.getFieldSubSize(fnode.obj, fnode.field)); - } - }); - if (!canAdd) { - mi.setEnabled(false); - } - p.add(mi); - //} - p.show(tree, e.getX(), e.getY()); - } - } - } - } else if (e.getClickCount() == 2) { - //myDoubleClick(selRow, selPath); - } - } - } - }); - } - - private Tag tag; - - public class MyTreeCellRenderer extends DefaultTreeCellRenderer { - - @Override - public Component getTreeCellRendererComponent( - JTree tree, - Object value, - boolean sel, - boolean expanded, - boolean leaf, - int row, - boolean hasFocus) { - - super.getTreeCellRendererComponent( - tree, value, sel, - expanded, leaf, row, - hasFocus); - - setUI(new BasicLabelUI()); - setOpaque(false); - setBackgroundNonSelectionColor(Color.white); - return this; - } - - } - - @Override - public void clear() { - - } - - private static class FieldNode extends DefaultMutableTreeNode { - - private Object obj; - private Field field; - private int index; - - public FieldNode(Object obj, Field field, int index) { - this.obj = obj; - this.field = field; - this.index = index; - } - - @Override - public void setUserObject(Object userObject) { - - } - - /* - */ - @Override - public String toString() { - - String valStr = ""; - if (ReflectionTools.needsIndex(field) && (index == -1)) { - valStr += ""; - } else if (hasEditor(obj, field, index)) { - Object val = getValue(); - Color color = null; - String colorAdd = ""; - if (val instanceof RGB) { //Note: Can be RGBA too - color = ((RGB) val).toColor(); - } - if (val instanceof ARGB) { - color = ((ARGB) val).toColor(); - } - - if (color != null) { - colorAdd = " "; - } - - valStr += " = " + colorAdd + val.toString(); - } - return "" + getNameType() + valStr + ""; - } - - public String getType() { - SWFType swfType = field.getAnnotation(SWFType.class); - SWFArray swfArray = field.getAnnotation(SWFArray.class); - String typeStr = null; - if ((swfType != null || swfArray != null) && !(ReflectionTools.needsIndex(field) && (index > -1))) { - Class type = field.getType(); - if (ReflectionTools.needsIndex(field)) { - type = ReflectionTools.getFieldSubType(obj, field); - } - typeStr = swfTypeToString(type, swfType, swfArray); - } - return typeStr; - } - - public String getNameType() { - String typeStr = getType(); - return getName() + (typeStr != null ? " : " + typeStr : ""); - } - - public String getName() { - SWFArray swfArray = field.getAnnotation(SWFArray.class); - String name = ""; - if (swfArray != null) { - name = swfArray.value(); - } - return (index > -1 ? name + "[" + index + "]" : field.getName()); - } - - public Object getValue() { - try { - if (ReflectionTools.needsIndex(field) && (index == -1)) { - return obj; - } - Object val = ReflectionTools.getValue(obj, field, index); - if (val == null) { - try { - val = ReflectionTools.newInstanceOf(field.getType()); - ReflectionTools.setValue(obj, field, index, val); - } catch (InstantiationException | IllegalAccessException ex) { - Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); - return null; - } - } - return val; - } catch (IllegalArgumentException | IllegalAccessException ex) { - return null; - } - } - - @Override - public int hashCode() { - int hash = 7; - hash = 11 * hash + Objects.hashCode(this.obj); - hash = 11 * hash + Objects.hashCode(this.field); - hash = 11 * hash + this.index; - return hash; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final FieldNode other = (FieldNode) obj; - if (!Objects.equals(this.obj, other.obj)) { - return false; - } - if (!Objects.equals(this.field, other.field)) { - return false; - } - if (this.index != other.index) { - return false; - } - return true; - } - } - - private static class MyTreeModel extends DefaultTreeModel { - - private final Object mtroot; - private final List listeners = new ArrayList<>(); - private final Map nodeCache = new HashMap<>(); - // it is much faster to store the reverse mappings, too - private final Map nodeCacheReverse = new HashMap<>(); - - private Object getNodeByPath(String path) { - - if (nodeCache.containsKey(path)) { - return nodeCache.get(path); - } - return null; - } - - public String getNodePathName(Object find) { - - if (nodeCacheReverse.containsKey(find)) { - return nodeCacheReverse.get(find); - } - return null; - } - - public List getDependentFields(FieldNode fnode) { - List ret = new ArrayList<>(); - getDependentFields(getNodePathName(fnode), mtroot.getClass().getSimpleName(), mtroot, ret); - return ret; - } - - public void getDependentFields(String dependence, String currentPath, Object node, List ret) { - if (node instanceof FieldNode) { - FieldNode fnode = (FieldNode) node; - Conditional cond = fnode.field.getAnnotation(Conditional.class); - if (cond != null) { - ConditionEvaluator ev = new ConditionEvaluator(cond); - String parentPath = currentPath.indexOf('.') == -1 ? "" : currentPath.substring(0, currentPath.lastIndexOf('.')); - try { - for (String cname : ev.getFields()) { - String fullParh = parentPath + "." + cname; - if (fullParh.equals(dependence)) { - ret.add(fnode); - break; - } - } - } catch (ParseException ex) { - Logger.getLogger(GenericTagTreePanel.class.getName()).log(Level.SEVERE, null, ex); - } - } - } - int count = getChildCount(node); - for (int i = 0; i < count; i++) { - FieldNode f = (FieldNode) getChild(node, i); - getDependentFields(dependence, currentPath + "." + f.getName(), f, ret); - } - } - - public MyTreeModel(Tag root) { - super(new DefaultMutableTreeNode(root)); - this.mtroot = root; - buildCache(root, ""); - } - - private void buildCache(Object obj, String parentPath) { - if (!"".equals(parentPath)) { - parentPath += "."; - } - if (obj instanceof FieldNode) { - FieldNode fn = (FieldNode) obj; - parentPath += fn.getName(); - } else { - parentPath += obj.getClass().getSimpleName(); - } - nodeCache.put(parentPath, obj); - nodeCacheReverse.put(obj, parentPath); - int count = getChildCount(obj, false); - for (int i = 0; i < count; i++) { - buildCache(getChild(obj, i, false), parentPath); - } - } - - @Override - public Object getRoot() { - return mtroot; - } - - private Object getChild(Object parent, int index, boolean limited) { - if (parent == mtroot) { - return new FieldNode(mtroot, filterFields(this, mtroot.getClass().getSimpleName(), mtroot.getClass(), limited).get(index), -1); - } - FieldNode fnode = (FieldNode) parent; - Field field = fnode.field; - if (ReflectionTools.needsIndex(field) && (fnode.index == -1)) { //Arrays ot Lists - return new FieldNode(fnode.obj, field, index); - } - parent = fnode.getValue(); - return new FieldNode(parent, filterFields(this, getNodePathName(fnode), parent.getClass(), limited).get(index), -1); - } - - @Override - public Object getChild(Object parent, int index) { - return getChild(parent, index, true); - } - - @Override - public int getChildCount(Object parent) { - return getChildCount(parent, true); - } - - private int getChildCount(Object parent, boolean limited) { - if (parent == mtroot) { - return filterFields(this, mtroot.getClass().getSimpleName(), mtroot.getClass(), limited).size(); - } - FieldNode fnode = (FieldNode) parent; - if (isLeaf(fnode)) { - return 0; - } - Field field = fnode.field; - if (ReflectionTools.needsIndex(field) && (fnode.index == -1)) { //Arrays or Lists - try { - if (field.get(fnode.obj) == null) { - // todo: instanciate the (Array)List or Array to allow adding items to it - return 0; - } - } catch (IllegalArgumentException | IllegalAccessException ex) { - return 0; - } - - return ReflectionTools.getFieldSubSize(fnode.obj, field); - } - parent = fnode.getValue(); - - return filterFields(this, getNodePathName(fnode), parent.getClass(), limited).size(); - } - - @Override - public boolean isLeaf(Object node) { - if (node == mtroot) { - return false; - } - - FieldNode fnode = (FieldNode) node; - Field field = fnode.field; - if (ReflectionTools.needsIndex(field) && fnode.index == -1) { - return false; - } - boolean r = hasEditor(fnode.obj, field, fnode.index); - return r; - } - - public void vchanged(TreePath path) { - fireTreeNodesChanged(this, path.getPath(), null, null); - } - - @Override - public int getIndexOfChild(Object parent, Object child) { - int cnt = getChildCount(parent); - for (int i = 0; i < cnt; i++) { - if (getChild(parent, i).equals(child)) { - return i; - } - } - return -1; - } - } - - private TreeModel getModel() { - return new MyTreeModel(editedTag); - } - - @Override - public void setEditMode(boolean edit, Tag tag) { - if (tag == null) { - tag = this.tag; - } - this.tag = tag; - SWF swf = tag.getSwf(); - try { - this.editedTag = SWFInputStream.resolveTag(swf, tag, 0, false, true, swf.gfx); - } catch (InterruptedException ex) { - } - tree.setEditable(edit); - if (!edit) { - tree.stopEditing(); - } - refreshTree(); - } - - @Override - public void save() { - tree.stopEditing(); - SWF swf = tag.getSwf(); - assignTag(tag, editedTag); - tag.setModified(true); - tag.setSwf(swf); - } - - private void assignTag(Tag t, Tag assigned) { - if (t.getClass() != assigned.getClass()) { - return; - } - for (Field f : getAvailableFields(t.getClass())) { - try { - f.set(t, f.get(assigned)); - } catch (IllegalArgumentException | IllegalAccessException ex) { - Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); - } - } - } - - @Override - public Tag getTag() { - return tag; - } - - public static String swfArrayToString(SWFArray swfArray) { - String result = ""; - if (swfArray == null) { - return result; - } - if (swfArray.count() > 0) { - result += "[" + swfArray.count() + "]"; - } else if (!swfArray.countField().isEmpty()) { - result += "[" + swfArray.countField() + "]"; - } - return result; - } - - public static String swfTypeToString(Class type, SWFType swfType, SWFArray swfArray) { - String stype = type.getSimpleName(); - if (swfType == null) { - return stype + swfArrayToString(swfArray); - } - String result = swfType.value().toString(); - if (swfType.value() == BasicType.OTHER) { - result = stype; - } - if (swfType.count() > 0) { - result += "[" + swfType.count(); - if (swfType.countAdd() > 0) { - result += " + " + swfType.countAdd(); - } - result += "]"; - } else if (!swfType.countField().isEmpty()) { - result += "[" + swfType.countField(); - if (swfType.countAdd() > 0) { - result += " + " + swfType.countAdd(); - } - result += "]"; - } - return result + swfArrayToString(swfArray); - } - - private static boolean hasEditor(Object obj, Field field, int index) { - if (ReflectionTools.needsIndex(field) && index == -1) { - return false; - } - Class type; - try { - Object val = ReflectionTools.getValue(obj, field, index); - if (val == null) { - return false; - } - type = val.getClass(); - } catch (IllegalArgumentException | IllegalAccessException ex) { - return false; - } - SWFType swfType = field.getAnnotation(SWFType.class); - Multiline multiline = field.getAnnotation(Multiline.class); - - if (type.equals(int.class) || type.equals(Integer.class) - || type.equals(short.class) || type.equals(Short.class) - || type.equals(long.class) || type.equals(Long.class) - || type.equals(double.class) || type.equals(Double.class) - || type.equals(float.class) || type.equals(Float.class)) { - return true; - } else if (type.equals(boolean.class) || type.equals(Boolean.class)) { - return true; - } else if (type.equals(String.class)) { - return true; - } else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) { - return true; - } else { - return false; - } - } - - private static List filterFields(MyTreeModel mod, String parentPath, Class cls, boolean limited) { - List ret = new ArrayList<>(); - List fields = getAvailableFields(cls); - for (Field f : fields) { - if (limited) { - Conditional cond = f.getAnnotation(Conditional.class); - if (cond != null) { - ConditionEvaluator ev = new ConditionEvaluator(cond); - try { - Map fieldMap = new HashMap<>(); - for (String sf : ev.getFields()) { - String fulldf = parentPath + "." + sf; - FieldNode condnode = (FieldNode) (mod).getNodeByPath(fulldf); - - if (condnode != null) { - fieldMap.put(sf, (Boolean) ReflectionTools.getValue(condnode.obj, condnode.field, condnode.index)); - } else { - fieldMap.put(sf, true); - } - } - if (!ev.eval(fieldMap)) { - continue; - } - } catch (ParseException | IllegalArgumentException | IllegalAccessException ex) { - Logger.getLogger(GenericTagTreePanel.class.getName()).log(Level.SEVERE, null, ex); - } - } - } - ret.add(f); - } - return ret; - } - - private static List getAvailableFields(Class cls) { - List ret = new ArrayList<>(); - Field fields[] = cls.getFields(); - for (Field f : fields) { - if (Modifier.isStatic(f.getModifiers())) { - continue; - } - f.setAccessible(true); - Internal inter = f.getAnnotation(Internal.class); - if (inter != null) { - continue; - } - ret.add(f); - } - return ret; - } - - private void addItem(Object obj, Field field, int index) { - SWFArray swfArray = field.getAnnotation(SWFArray.class); - if (swfArray != null && !swfArray.countField().isEmpty()) { //Fields with same countField must be enlarged too - Field fields[] = obj.getClass().getDeclaredFields(); - List sameFlds = new ArrayList<>(); - for (int f = 0; f < fields.length; f++) { - SWFArray fieldSwfArray = fields[f].getAnnotation(SWFArray.class); - if (fieldSwfArray != null && fieldSwfArray.countField().equals(swfArray.countField())) { - sameFlds.add(f); - if (!ReflectionTools.canAddToField(obj, fields[f])) { - JOptionPane.showMessageDialog(this, "This field is abstract, cannot be instantiated, sorry."); //TODO!!! - return; - } - - } - } - for (int f : sameFlds) { - ReflectionTools.addToField(obj, fields[f], index, true); - } - try { - //If countField exists, increment, otherwise do nothing - Field countField = obj.getClass().getDeclaredField(swfArray.countField()); - if (countField != null) { - int cnt = countField.getInt(obj); - cnt++; - countField.setInt(obj, cnt); - } - } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { - //ignored - } - } else { - if (!ReflectionTools.canAddToField(obj, field)) { - JOptionPane.showMessageDialog(this, "This field is abstract, cannot be instantiated, sorry."); //TODO!!! - return; - } - ReflectionTools.addToField(obj, field, index, true); - } - refreshTree(); - } - - public void refreshTree() { - View.refreshTree(tree, getModel()); - revalidate(); - repaint(); - } - - private void removeItem(Object obj, Field field, int index) { - SWFArray swfArray = field.getAnnotation(SWFArray.class); - if (swfArray != null && !swfArray.countField().isEmpty()) { //Fields with same countField must be removed from too - Field fields[] = obj.getClass().getDeclaredFields(); - for (int f = 0; f < fields.length; f++) { - SWFArray fieldSwfArray = fields[f].getAnnotation(SWFArray.class); - if (fieldSwfArray != null && fieldSwfArray.countField().equals(swfArray.countField())) { - ReflectionTools.removeFromField(obj, fields[f], index); - } - } - try { - //If countField exists, decrement, otherwise do nothing - Field countField = obj.getClass().getDeclaredField(swfArray.countField()); - if (countField != null) { - int cnt = countField.getInt(obj); - cnt--; - countField.setInt(obj, cnt); - } - } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { - //ignored - } - } else { - ReflectionTools.removeFromField(obj, field, index); - } - - refreshTree(); - } -} +/* + * Copyright (C) 2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui; + +import com.jpexs.decompiler.flash.AppStrings; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SWFInputStream; +import com.jpexs.decompiler.flash.gui.generictageditors.BooleanEditor; +import com.jpexs.decompiler.flash.gui.generictageditors.ColorEditor; +import com.jpexs.decompiler.flash.gui.generictageditors.GenericTagEditor; +import com.jpexs.decompiler.flash.gui.generictageditors.NumberEditor; +import com.jpexs.decompiler.flash.gui.generictageditors.ReflectionTools; +import com.jpexs.decompiler.flash.gui.generictageditors.StringEditor; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.types.ARGB; +import com.jpexs.decompiler.flash.types.BasicType; +import com.jpexs.decompiler.flash.types.RGB; +import com.jpexs.decompiler.flash.types.RGBA; +import com.jpexs.decompiler.flash.types.annotations.Conditional; +import com.jpexs.decompiler.flash.types.annotations.Internal; +import com.jpexs.decompiler.flash.types.annotations.Multiline; +import com.jpexs.decompiler.flash.types.annotations.SWFArray; +import com.jpexs.decompiler.flash.types.annotations.SWFType; +import com.jpexs.decompiler.flash.types.annotations.parser.ConditionEvaluator; +import com.jpexs.decompiler.flash.types.annotations.parser.ParseException; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.EventObject; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.AbstractCellEditor; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.event.TreeModelListener; +import javax.swing.plaf.basic.BasicLabelUI; +import javax.swing.plaf.basic.BasicTreeUI; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeCellEditor; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; + +/** + * + * @author JPEXS + */ +public class GenericTagTreePanel extends GenericTagPanel { + + private JTree tree; + private Tag editedTag; + + private class MyTree extends JTree { + + public MyTree() { + setBackground(Color.white); + setUI(new BasicTreeUI() { + + @Override + public void paint(Graphics g, JComponent c) { + setHashColor(Color.gray); + super.paint(g, c); + } + + }); + setCellRenderer(new MyTreeCellRenderer()); + setCellEditor(new MyTreeCellEditor(this)); + setInvokesStopCellEditing(true); + + } + } + + private class MyTreeCellEditor extends AbstractCellEditor implements TreeCellEditor { + + private GenericTagEditor editor = null; + private final JTree tree; + private FieldNode fnode; + + public MyTreeCellEditor(JTree tree) { + this.tree = tree; + } + + @Override + public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) { + if (value instanceof FieldNode) { + fnode = (FieldNode) value; + Field field = fnode.field; + int index = fnode.index; + Object obj = fnode.obj; + Class type; + try { + type = ReflectionTools.getValue(obj, field, index).getClass(); + } catch (IllegalArgumentException | IllegalAccessException ex) { + ex.printStackTrace(); + return null; + } + SWFType swfType = field.getAnnotation(SWFType.class); + Multiline multiline = field.getAnnotation(Multiline.class); + if (type.equals(int.class) || type.equals(Integer.class) + || type.equals(short.class) || type.equals(Short.class) + || type.equals(long.class) || type.equals(Long.class) + || type.equals(double.class) || type.equals(Double.class) + || type.equals(float.class) || type.equals(Float.class)) { + editor = new NumberEditor(field.getName(), obj, field, index, type, swfType); + } else if (type.equals(boolean.class) || type.equals(Boolean.class)) { + editor = new BooleanEditor(field.getName(), obj, field, index, type); + } else if (type.equals(String.class)) { + editor = new StringEditor(field.getName(), obj, field, index, type, multiline != null); + } else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) { + editor = new ColorEditor(field.getName(), obj, field, index, type); + } + JPanel pan = new JPanel(); + FlowLayout fl = new FlowLayout(FlowLayout.LEFT, 0, 0); + fl.setAlignOnBaseline(true); + pan.setLayout(fl); + JLabel nameLabel = new JLabel(fnode.getNameType() + " = ") { + + @Override + public BaselineResizeBehavior getBaselineResizeBehavior() { + return Component.BaselineResizeBehavior.CONSTANT_ASCENT; + } + + @Override + public int getBaseline(int width, int height) { + return 0; + } + + }; + pan.setBackground(Color.white); + nameLabel.setSize(nameLabel.getWidth(), ((Component) editor).getHeight()); + nameLabel.setAlignmentY(TOP_ALIGNMENT); + ((JComponent) editor).setAlignmentY(TOP_ALIGNMENT); + pan.add(nameLabel); + pan.add((Component) editor); + pan.setPreferredSize(new Dimension((int) nameLabel.getPreferredSize().getWidth() + 5 + (int) ((Component) editor).getPreferredSize().getWidth(), (int) ((Component) editor).getPreferredSize().getHeight())); + return pan; + } + return null; + + } + + @Override + public Object getCellEditorValue() { + return editor.getChangedValue(); + } + + @Override + public boolean isCellEditable(EventObject e) { + if (!(e instanceof MouseEvent)) { + return false; + } + + MouseEvent me = (MouseEvent) e; + TreePath path = tree.getPathForLocation(me.getX(), me.getY()); + + if (path == null) { + return false; + } + Object obj = path.getLastPathComponent(); + + boolean ret = super.isCellEditable(e) + && path != null && (tree.getModel().isLeaf(obj)); + return ret; + } + + @Override + public boolean stopCellEditing() { + super.stopCellEditing(); + + /*List depends = ((MyTreeModel) tree.getModel()).getDependentFields(fnode); + boolean dep = false; + if (!depends.isEmpty()) { + dep = true; + } */ + editor.save(); + ((MyTreeModel) tree.getModel()).vchanged(tree.getSelectionPath()); + refreshTree(); + return true; + } + + } + + public GenericTagTreePanel() { + setLayout(new BorderLayout()); + tree = new MyTree(); + + add(new JScrollPane(tree), BorderLayout.CENTER); + tree.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + if (!tree.isEditable()) { + return; + } + int selRow = tree.getRowForLocation(e.getX(), e.getY()); + TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); + if (selRow != -1 && selPath != null) { + if (e.getClickCount() == 1) { + if (e.getButton() == MouseEvent.BUTTON3) { //right click + Object selObject = selPath.getLastPathComponent(); + if (selObject instanceof FieldNode) { + final FieldNode fnode = (FieldNode) selObject; + SWFArray swfArray = fnode.field.getAnnotation(SWFArray.class); + String itemStr = ""; + if (swfArray != null) { + itemStr = swfArray.value(); + } + if (itemStr.isEmpty()) { + itemStr = AppStrings.translate("generictag.array.item"); + } + if (ReflectionTools.needsIndex(fnode.field)) { + + boolean canAdd = true; + if (!ReflectionTools.canAddToField(fnode.obj, fnode.field)) { + canAdd = false; + } + JPopupMenu p = new JPopupMenu(); + JMenuItem mi; + mi = new JMenuItem(AppStrings.translate("generictag.array.insertbeginning").replace("%item%", itemStr)); + mi.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + addItem(fnode.obj, fnode.field, 0); + } + }); + if (!canAdd) { + mi.setEnabled(false); + } + p.add(mi); + + if (fnode.index > -1) { + mi = new JMenuItem(AppStrings.translate("generictag.array.insertbefore").replace("%item%", itemStr)); + mi.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + addItem(fnode.obj, fnode.field, fnode.index); + } + }); + if (!canAdd) { + mi.setEnabled(false); + } + p.add(mi); + + mi = new JMenuItem(AppStrings.translate("generictag.array.remove").replace("%item%", itemStr)); + mi.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + removeItem(fnode.obj, fnode.field, fnode.index); + } + }); + p.add(mi); + + mi = new JMenuItem(AppStrings.translate("generictag.array.insertafter").replace("%item%", itemStr)); + mi.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + addItem(fnode.obj, fnode.field, fnode.index + 1); + } + }); + if (!canAdd) { + mi.setEnabled(false); + } + p.add(mi); + } + + mi = new JMenuItem(AppStrings.translate("generictag.array.insertend").replace("%item%", itemStr)); + mi.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + addItem(fnode.obj, fnode.field, ReflectionTools.getFieldSubSize(fnode.obj, fnode.field)); + } + }); + if (!canAdd) { + mi.setEnabled(false); + } + p.add(mi); + //} + p.show(tree, e.getX(), e.getY()); + } + } + } + } else if (e.getClickCount() == 2) { + //myDoubleClick(selRow, selPath); + } + } + } + }); + } + + private Tag tag; + + public class MyTreeCellRenderer extends DefaultTreeCellRenderer { + + @Override + public Component getTreeCellRendererComponent( + JTree tree, + Object value, + boolean sel, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + + super.getTreeCellRendererComponent( + tree, value, sel, + expanded, leaf, row, + hasFocus); + + setUI(new BasicLabelUI()); + setOpaque(false); + setBackgroundNonSelectionColor(Color.white); + return this; + } + + } + + @Override + public void clear() { + + } + + private static class FieldNode extends DefaultMutableTreeNode { + + private Object obj; + private Field field; + private int index; + + public FieldNode(Object obj, Field field, int index) { + this.obj = obj; + this.field = field; + this.index = index; + } + + @Override + public void setUserObject(Object userObject) { + + } + + /* + */ + @Override + public String toString() { + + String valStr = ""; + if (ReflectionTools.needsIndex(field) && (index == -1)) { + valStr += ""; + } else if (hasEditor(obj, field, index)) { + Object val = getValue(); + Color color = null; + String colorAdd = ""; + if (val instanceof RGB) { //Note: Can be RGBA too + color = ((RGB) val).toColor(); + } + if (val instanceof ARGB) { + color = ((ARGB) val).toColor(); + } + + if (color != null) { + colorAdd = " "; + } + + valStr += " = " + colorAdd + val.toString(); + } + return "" + getNameType() + valStr + ""; + } + + public String getType() { + SWFType swfType = field.getAnnotation(SWFType.class); + SWFArray swfArray = field.getAnnotation(SWFArray.class); + String typeStr = null; + if ((swfType != null || swfArray != null) && !(ReflectionTools.needsIndex(field) && (index > -1))) { + Class type = field.getType(); + if (ReflectionTools.needsIndex(field)) { + type = ReflectionTools.getFieldSubType(obj, field); + } + typeStr = swfTypeToString(type, swfType, swfArray); + } + return typeStr; + } + + public String getNameType() { + String typeStr = getType(); + return getName() + (typeStr != null ? " : " + typeStr : ""); + } + + public String getName() { + SWFArray swfArray = field.getAnnotation(SWFArray.class); + String name = ""; + if (swfArray != null) { + name = swfArray.value(); + } + return (index > -1 ? name + "[" + index + "]" : field.getName()); + } + + public Object getValue() { + try { + if (ReflectionTools.needsIndex(field) && (index == -1)) { + return obj; + } + Object val = ReflectionTools.getValue(obj, field, index); + if (val == null) { + try { + val = ReflectionTools.newInstanceOf(field.getType()); + ReflectionTools.setValue(obj, field, index, val); + } catch (InstantiationException | IllegalAccessException ex) { + Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); + return null; + } + } + return val; + } catch (IllegalArgumentException | IllegalAccessException ex) { + return null; + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 11 * hash + Objects.hashCode(this.obj); + hash = 11 * hash + Objects.hashCode(this.field); + hash = 11 * hash + this.index; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final FieldNode other = (FieldNode) obj; + if (!Objects.equals(this.obj, other.obj)) { + return false; + } + if (!Objects.equals(this.field, other.field)) { + return false; + } + if (this.index != other.index) { + return false; + } + return true; + } + } + + private static class MyTreeModel extends DefaultTreeModel { + + private final Object mtroot; + private final List listeners = new ArrayList<>(); + private final Map nodeCache = new HashMap<>(); + // it is much faster to store the reverse mappings, too + private final Map nodeCacheReverse = new HashMap<>(); + + private Object getNodeByPath(String path) { + + if (nodeCache.containsKey(path)) { + return nodeCache.get(path); + } + return null; + } + + public String getNodePathName(Object find) { + + if (nodeCacheReverse.containsKey(find)) { + return nodeCacheReverse.get(find); + } + return null; + } + + public List getDependentFields(FieldNode fnode) { + List ret = new ArrayList<>(); + getDependentFields(getNodePathName(fnode), mtroot.getClass().getSimpleName(), mtroot, ret); + return ret; + } + + public void getDependentFields(String dependence, String currentPath, Object node, List ret) { + if (node instanceof FieldNode) { + FieldNode fnode = (FieldNode) node; + Conditional cond = fnode.field.getAnnotation(Conditional.class); + if (cond != null) { + ConditionEvaluator ev = new ConditionEvaluator(cond); + String parentPath = currentPath.indexOf('.') == -1 ? "" : currentPath.substring(0, currentPath.lastIndexOf('.')); + try { + for (String cname : ev.getFields()) { + String fullParh = parentPath + "." + cname; + if (fullParh.equals(dependence)) { + ret.add(fnode); + break; + } + } + } catch (ParseException ex) { + Logger.getLogger(GenericTagTreePanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + int count = getChildCount(node); + for (int i = 0; i < count; i++) { + FieldNode f = (FieldNode) getChild(node, i); + getDependentFields(dependence, currentPath + "." + f.getName(), f, ret); + } + } + + public MyTreeModel(Tag root) { + super(new DefaultMutableTreeNode(root)); + this.mtroot = root; + buildCache(root, ""); + } + + private void buildCache(Object obj, String parentPath) { + if (!"".equals(parentPath)) { + parentPath += "."; + } + if (obj instanceof FieldNode) { + FieldNode fn = (FieldNode) obj; + parentPath += fn.getName(); + } else { + parentPath += obj.getClass().getSimpleName(); + } + nodeCache.put(parentPath, obj); + nodeCacheReverse.put(obj, parentPath); + int count = getChildCount(obj, false); + for (int i = 0; i < count; i++) { + buildCache(getChild(obj, i, false), parentPath); + } + } + + @Override + public Object getRoot() { + return mtroot; + } + + private Object getChild(Object parent, int index, boolean limited) { + if (parent == mtroot) { + return new FieldNode(mtroot, filterFields(this, mtroot.getClass().getSimpleName(), mtroot.getClass(), limited).get(index), -1); + } + FieldNode fnode = (FieldNode) parent; + Field field = fnode.field; + if (ReflectionTools.needsIndex(field) && (fnode.index == -1)) { //Arrays ot Lists + return new FieldNode(fnode.obj, field, index); + } + parent = fnode.getValue(); + return new FieldNode(parent, filterFields(this, getNodePathName(fnode), parent.getClass(), limited).get(index), -1); + } + + @Override + public Object getChild(Object parent, int index) { + return getChild(parent, index, true); + } + + @Override + public int getChildCount(Object parent) { + return getChildCount(parent, true); + } + + private int getChildCount(Object parent, boolean limited) { + if (parent == mtroot) { + return filterFields(this, mtroot.getClass().getSimpleName(), mtroot.getClass(), limited).size(); + } + FieldNode fnode = (FieldNode) parent; + if (isLeaf(fnode)) { + return 0; + } + Field field = fnode.field; + if (ReflectionTools.needsIndex(field) && (fnode.index == -1)) { //Arrays or Lists + try { + if (field.get(fnode.obj) == null) { + // todo: instanciate the (Array)List or Array to allow adding items to it + return 0; + } + } catch (IllegalArgumentException | IllegalAccessException ex) { + return 0; + } + + return ReflectionTools.getFieldSubSize(fnode.obj, field); + } + parent = fnode.getValue(); + + return filterFields(this, getNodePathName(fnode), parent.getClass(), limited).size(); + } + + @Override + public boolean isLeaf(Object node) { + if (node == mtroot) { + return false; + } + + FieldNode fnode = (FieldNode) node; + Field field = fnode.field; + if (ReflectionTools.needsIndex(field) && fnode.index == -1) { + return false; + } + boolean r = hasEditor(fnode.obj, field, fnode.index); + return r; + } + + public void vchanged(TreePath path) { + fireTreeNodesChanged(this, path.getPath(), null, null); + } + + @Override + public int getIndexOfChild(Object parent, Object child) { + int cnt = getChildCount(parent); + for (int i = 0; i < cnt; i++) { + if (getChild(parent, i).equals(child)) { + return i; + } + } + return -1; + } + } + + private TreeModel getModel() { + return new MyTreeModel(editedTag); + } + + @Override + public void setEditMode(boolean edit, Tag tag) { + if (tag == null) { + tag = this.tag; + } + this.tag = tag; + SWF swf = tag.getSwf(); + try { + this.editedTag = SWFInputStream.resolveTag(tag, 0, false, true, swf.gfx); + } catch (InterruptedException ex) { + } + tree.setEditable(edit); + if (!edit) { + tree.stopEditing(); + } + refreshTree(); + } + + @Override + public void save() { + tree.stopEditing(); + SWF swf = tag.getSwf(); + assignTag(tag, editedTag); + tag.setModified(true); + tag.setSwf(swf); + } + + private void assignTag(Tag t, Tag assigned) { + if (t.getClass() != assigned.getClass()) { + return; + } + for (Field f : getAvailableFields(t.getClass())) { + try { + f.set(t, f.get(assigned)); + } catch (IllegalArgumentException | IllegalAccessException ex) { + Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + @Override + public Tag getTag() { + return tag; + } + + public static String swfArrayToString(SWFArray swfArray) { + String result = ""; + if (swfArray == null) { + return result; + } + if (swfArray.count() > 0) { + result += "[" + swfArray.count() + "]"; + } else if (!swfArray.countField().isEmpty()) { + result += "[" + swfArray.countField() + "]"; + } + return result; + } + + public static String swfTypeToString(Class type, SWFType swfType, SWFArray swfArray) { + String stype = type.getSimpleName(); + if (swfType == null) { + return stype + swfArrayToString(swfArray); + } + String result = swfType.value().toString(); + if (swfType.value() == BasicType.OTHER) { + result = stype; + } + if (swfType.count() > 0) { + result += "[" + swfType.count(); + if (swfType.countAdd() > 0) { + result += " + " + swfType.countAdd(); + } + result += "]"; + } else if (!swfType.countField().isEmpty()) { + result += "[" + swfType.countField(); + if (swfType.countAdd() > 0) { + result += " + " + swfType.countAdd(); + } + result += "]"; + } + return result + swfArrayToString(swfArray); + } + + private static boolean hasEditor(Object obj, Field field, int index) { + if (ReflectionTools.needsIndex(field) && index == -1) { + return false; + } + Class type; + try { + Object val = ReflectionTools.getValue(obj, field, index); + if (val == null) { + return false; + } + type = val.getClass(); + } catch (IllegalArgumentException | IllegalAccessException ex) { + return false; + } + SWFType swfType = field.getAnnotation(SWFType.class); + Multiline multiline = field.getAnnotation(Multiline.class); + + if (type.equals(int.class) || type.equals(Integer.class) + || type.equals(short.class) || type.equals(Short.class) + || type.equals(long.class) || type.equals(Long.class) + || type.equals(double.class) || type.equals(Double.class) + || type.equals(float.class) || type.equals(Float.class)) { + return true; + } else if (type.equals(boolean.class) || type.equals(Boolean.class)) { + return true; + } else if (type.equals(String.class)) { + return true; + } else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) { + return true; + } else { + return false; + } + } + + private static List filterFields(MyTreeModel mod, String parentPath, Class cls, boolean limited) { + List ret = new ArrayList<>(); + List fields = getAvailableFields(cls); + for (Field f : fields) { + if (limited) { + Conditional cond = f.getAnnotation(Conditional.class); + if (cond != null) { + ConditionEvaluator ev = new ConditionEvaluator(cond); + try { + Map fieldMap = new HashMap<>(); + for (String sf : ev.getFields()) { + String fulldf = parentPath + "." + sf; + FieldNode condnode = (FieldNode) (mod).getNodeByPath(fulldf); + + if (condnode != null) { + fieldMap.put(sf, (Boolean) ReflectionTools.getValue(condnode.obj, condnode.field, condnode.index)); + } else { + fieldMap.put(sf, true); + } + } + if (!ev.eval(fieldMap)) { + continue; + } + } catch (ParseException | IllegalArgumentException | IllegalAccessException ex) { + Logger.getLogger(GenericTagTreePanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + ret.add(f); + } + return ret; + } + + private static List getAvailableFields(Class cls) { + List ret = new ArrayList<>(); + Field fields[] = cls.getFields(); + for (Field f : fields) { + if (Modifier.isStatic(f.getModifiers())) { + continue; + } + f.setAccessible(true); + Internal inter = f.getAnnotation(Internal.class); + if (inter != null) { + continue; + } + ret.add(f); + } + return ret; + } + + private void addItem(Object obj, Field field, int index) { + SWFArray swfArray = field.getAnnotation(SWFArray.class); + if (swfArray != null && !swfArray.countField().isEmpty()) { //Fields with same countField must be enlarged too + Field fields[] = obj.getClass().getDeclaredFields(); + List sameFlds = new ArrayList<>(); + for (int f = 0; f < fields.length; f++) { + SWFArray fieldSwfArray = fields[f].getAnnotation(SWFArray.class); + if (fieldSwfArray != null && fieldSwfArray.countField().equals(swfArray.countField())) { + sameFlds.add(f); + if (!ReflectionTools.canAddToField(obj, fields[f])) { + JOptionPane.showMessageDialog(this, "This field is abstract, cannot be instantiated, sorry."); //TODO!!! + return; + } + + } + } + for (int f : sameFlds) { + ReflectionTools.addToField(obj, fields[f], index, true); + } + try { + //If countField exists, increment, otherwise do nothing + Field countField = obj.getClass().getDeclaredField(swfArray.countField()); + if (countField != null) { + int cnt = countField.getInt(obj); + cnt++; + countField.setInt(obj, cnt); + } + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { + //ignored + } + } else { + if (!ReflectionTools.canAddToField(obj, field)) { + JOptionPane.showMessageDialog(this, "This field is abstract, cannot be instantiated, sorry."); //TODO!!! + return; + } + ReflectionTools.addToField(obj, field, index, true); + } + refreshTree(); + } + + public void refreshTree() { + View.refreshTree(tree, getModel()); + revalidate(); + repaint(); + } + + private void removeItem(Object obj, Field field, int index) { + SWFArray swfArray = field.getAnnotation(SWFArray.class); + if (swfArray != null && !swfArray.countField().isEmpty()) { //Fields with same countField must be removed from too + Field fields[] = obj.getClass().getDeclaredFields(); + for (int f = 0; f < fields.length; f++) { + SWFArray fieldSwfArray = fields[f].getAnnotation(SWFArray.class); + if (fieldSwfArray != null && fieldSwfArray.countField().equals(swfArray.countField())) { + ReflectionTools.removeFromField(obj, fields[f], index); + } + } + try { + //If countField exists, decrement, otherwise do nothing + Field countField = obj.getClass().getDeclaredField(swfArray.countField()); + if (countField != null) { + int cnt = countField.getInt(obj); + cnt--; + countField.setInt(obj, cnt); + } + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { + //ignored + } + } else { + ReflectionTools.removeFromField(obj, field, index); + } + + refreshTree(); + } +} diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java index b95beb797..6eb19f4df 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java @@ -86,6 +86,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { static final String ACTION_GOTO_DOCUMENT_CLASS = "GOTODOCUMENTCLASS"; static final String ACTION_PARALLEL_SPEED_UP = "PARALLELSPEEDUP"; static final String ACTION_INTERNAL_VIEWER_SWITCH = "INTERNALVIEWERSWITCH"; + static final String ACTION_DUMP_VIEW_SWITCH = "DUMPVIEWSWITCH"; static final String ACTION_SEARCH = "SEARCH"; static final String ACTION_TIMELINE = "TIMELINE"; static final String ACTION_AUTO_DEOBFUSCATE = "AUTODEOBFUSCATE"; @@ -122,6 +123,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { private JCheckBox miAutoDeobfuscation; private JCheckBox miInternalViewer; + private JCheckBox miDumpView; private JCheckBox miParallelSpeedUp; private JCheckBox miAssociate; private JCheckBox miDecompile; @@ -425,6 +427,11 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { miAutoRenameIdentifiers.setActionCommand(ACTION_AUTO_RENAME_IDENTIFIERS); miAutoRenameIdentifiers.addActionListener(this); + miDumpView = new JCheckBox(translate("menu.settings.dumpView")); + miDumpView.setSelected(Configuration.dumpView.get()); + miDumpView.setActionCommand(ACTION_DUMP_VIEW_SWITCH); + miDumpView.addActionListener(this); + settingsBand.addRibbonComponent(new JRibbonComponent(miAutoDeobfuscation)); settingsBand.addRibbonComponent(new JRibbonComponent(miInternalViewer)); settingsBand.addRibbonComponent(new JRibbonComponent(miParallelSpeedUp)); @@ -435,6 +442,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { settingsBand.addRibbonComponent(new JRibbonComponent(miCacheDisk)); settingsBand.addRibbonComponent(new JRibbonComponent(miGotoMainClassOnStartup)); settingsBand.addRibbonComponent(new JRibbonComponent(miAutoRenameIdentifiers)); + settingsBand.addRibbonComponent(new JRibbonComponent(miDumpView)); JRibbonBand languageBand = new JRibbonBand(translate("menu.language"), null); List languageBandResizePolicies = getIconBandResizePolicies(languageBand); @@ -610,6 +618,10 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { Configuration.internalFlashViewer.set(miInternalViewer.isSelected()); mainFrame.panel.reload(true); break; + case ACTION_DUMP_VIEW_SWITCH: + Configuration.internalFlashViewer.set(miDumpView.isSelected()); + mainFrame.panel.showDumpView(miDumpView.isSelected()); + break; case ACTION_SEARCH: mainFrame.panel.searchAs(); break; diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 9bc89fc9a..e28804183 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -26,6 +26,7 @@ import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.dumpview.DumpInfo; import com.jpexs.decompiler.flash.exporters.BinaryDataExporter; import com.jpexs.decompiler.flash.exporters.FontExporter; import com.jpexs.decompiler.flash.exporters.ImageExporter; @@ -221,14 +222,18 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec private final JProgressBar progressBar = new JProgressBar(0, 100); private DeobfuscationDialog deobfuscationDialog; public TagTree tagTree; + public DumpTree dumpTree; private final FlashPlayerPanel flashPanel; private final JPanel contentPanel; private final JPanel displayPanel; private JPanel folderPreviewPanel; + private JPanel dumpViewPanel; + private JLabel dumpViewLabel; // very very simple dump view, todo: hexview with virtual scrolling private boolean isWelcomeScreen = true; private static final String CARDPREVIEWPANEL = "Preview card"; private static final String CARDFOLDERPREVIEWPANEL = "Folder preview card"; private static final String CARDEMPTYPANEL = "Empty card"; + private static final String CARDDUMPVIEW = "Dump view"; private static final String CARDACTIONSCRIPTPANEL = "ActionScript card"; private static final String CARDACTIONSCRIPT3PANEL = "ActionScript3 card"; private static final String DETAILCARDAS3NAVIGATOR = "Traits list"; @@ -242,6 +247,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec private JTextField filterField = new MyTextField(""); private JPanel searchPanel; private PreviewPanel previewPanel; + private JPanel treePanel; private AbortRetryIgnoreHandler errorHandler = new GuiAbortRetryIgnoreHandler(); private CancellableWorker setSourceWorker; public TreeNode oldNode; @@ -494,6 +500,16 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec return folderPreviewCard; } + private JPanel createDumpPreviewCard() { + JPanel dumpViewCard = new JPanel(new BorderLayout()); + dumpViewPanel = new JPanel(new WrapLayout(FlowLayout.LEFT)); + dumpViewLabel = new JLabel(); + dumpViewPanel.add(dumpViewLabel); + dumpViewCard.add(new JScrollPane(dumpViewPanel), BorderLayout.CENTER); + + return dumpViewCard; + } + public String translate(String key) { return mainFrame.translate(key); } @@ -603,6 +619,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec createContextMenu(); + dumpTree = new DumpTree((DumpTreeModel) null); + dumpTree.addTreeSelectionListener(this); + statusPanel = new MainFrameStatusPanel(this); add(statusPanel, BorderLayout.SOUTH); @@ -611,6 +630,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec previewPanel = new PreviewPanel(this, flashPanel); displayPanel.add(previewPanel, CARDPREVIEWPANEL); displayPanel.add(createFolderPreviewCard(), CARDFOLDERPREVIEWPANEL); + displayPanel.add(createDumpPreviewCard(), CARDDUMPVIEW); displayPanel.add(new JPanel(), CARDEMPTYPANEL); showCard(CARDEMPTYPANEL); @@ -629,9 +649,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } }); searchPanel.add(closeSearchButton, BorderLayout.EAST); - JPanel pan1 = new JPanel(new BorderLayout()); - pan1.add(new JScrollPane(tagTree), BorderLayout.CENTER); - pan1.add(searchPanel, BorderLayout.SOUTH); + treePanel = new JPanel(new BorderLayout()); + showDumpView(Configuration.dumpView.get()); + treePanel.add(searchPanel, BorderLayout.SOUTH); filterField.addActionListener(this); @@ -659,7 +679,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec }); //displayPanel.setBorder(BorderFactory.createLineBorder(Color.black)); - splitPane2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, pan1, detailPanel); + splitPane2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, treePanel, detailPanel); splitPane1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, splitPane2, displayPanel); welcomePanel = createWelcomePanel(); @@ -719,6 +739,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec swf.isAS3 = hasAbc; tagTree.setModel(new TagTreeModel(mainFrame, swfs)); + dumpTree.setModel(new DumpTreeModel(swfs)); if (hasAbc) { if (abcPanel == null) { @@ -2363,8 +2384,25 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec cl.show(displayPanel, card); } + private void dumpTreeValueChanged(TreeSelectionEvent e) { + showCard(CARDDUMPVIEW); + DumpInfo dumpInfo = (DumpInfo) e.getPath().getLastPathComponent(); + if (dumpInfo.lengthBytes != 0 || dumpInfo.lengthBits != 0) { + // todo + dumpViewLabel.setText("startByte: " + dumpInfo.startByte + + " startBit: " + dumpInfo.startBit + + " lengthBytes: " + dumpInfo.lengthBytes + + " lengthBits: " + dumpInfo.lengthBits); + } + } + @Override public void valueChanged(TreeSelectionEvent e) { + Object source = e.getSource(); + if (source == dumpTree) { + dumpTreeValueChanged(e); + return; + } TreeNode treeNode = (TreeNode) e.getPath().getLastPathComponent(); TreeItem treeItem = treeNode.getItem(); if (!(treeItem instanceof SWFList)) { @@ -2404,6 +2442,16 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec return mainMenu.isInternalFlashViewerSelected(); } + public void showDumpView(boolean show) { + treePanel.removeAll(); + if (show) { + treePanel.add(new JScrollPane(dumpTree), BorderLayout.CENTER); + } else { + treePanel.add(new JScrollPane(tagTree), BorderLayout.CENTER); + } + treePanel.revalidate(); + } + public void reload(boolean forceReload) { TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent(); if (treeNode == null) { diff --git a/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java b/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java index 77db9564f..56df898a8 100644 --- a/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java +++ b/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java @@ -16,7 +16,10 @@ */ package com.jpexs.decompiler.flash.gui; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.gui.player.MediaDisplay; +import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.SoundTag; import com.jpexs.helpers.SoundPlayer; import java.awt.Color; @@ -67,7 +70,9 @@ public class SoundTagPlayer implements MediaDisplay { this.tag = tag; this.loops = loops; ByteArrayOutputStream baos = new ByteArrayOutputStream(); - tag.getSoundFormat().createWav(tag.getRawSoundData(), baos); + byte[] soundData = tag.getRawSoundData(); + SWF swf = ((Tag) tag).getSwf(); + tag.getSoundFormat().createWav(new SWFInputStream(swf, soundData), baos); player = new SoundPlayer(new ByteArrayInputStream(baos.toByteArray())); } diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index 8f750f0ed..69f14c709 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -486,3 +486,5 @@ abc.action.find-declaration = Find declaration contextmenu.rawEdit = Raw edit contextmenu.jumpToCharacter = Jump to character + +menu.settings.dumpView = Dump view diff --git a/src/com/jpexs/decompiler/flash/tags/CSMTextSettingsTag.java b/src/com/jpexs/decompiler/flash/tags/CSMTextSettingsTag.java index 3fb0d4449..a13c8c3aa 100644 --- a/src/com/jpexs/decompiler/flash/tags/CSMTextSettingsTag.java +++ b/src/com/jpexs/decompiler/flash/tags/CSMTextSettingsTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.Reserved; @@ -88,8 +88,8 @@ public class CSMTextSettingsTag extends Tag { * @param pos * @throws IOException */ - public CSMTextSettingsTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "CSMTextSettings", pos, length); + public CSMTextSettingsTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "CSMTextSettings", pos, length); textID = sis.readUI16(); useFlashType = (int) sis.readUB(2); gridFit = (int) sis.readUB(3); diff --git a/src/com/jpexs/decompiler/flash/tags/DebugIDTag.java b/src/com/jpexs/decompiler/flash/tags/DebugIDTag.java index d4ad11238..b2028bb30 100644 --- a/src/com/jpexs/decompiler/flash/tags/DebugIDTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DebugIDTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFType; @@ -61,8 +61,8 @@ public class DebugIDTag extends Tag { * @param pos * @throws IOException */ - public DebugIDTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DebugID", pos, length); + public DebugIDTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DebugID", pos, length); debugId = sis.readBytesEx(16); } } diff --git a/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java b/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java index 5ddd9cf1b..98c2cfb78 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.types.BasicType; @@ -58,8 +58,8 @@ public class DefineBinaryDataTag extends CharacterTag { return baos.toByteArray(); } - public DefineBinaryDataTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineBinaryData", pos, length); + public DefineBinaryDataTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineBinaryData", pos, length); tag = sis.readUI16(); reserved = sis.readUI32(); binaryData = sis.readBytesEx(sis.available()); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java index fd207d221..998a60035 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.AloneTag; import com.jpexs.decompiler.flash.tags.base.ImageTag; @@ -68,8 +68,8 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag { return null; } - public DefineBitsJPEG2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineBitsJPEG2", pos, length); + public DefineBitsJPEG2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineBitsJPEG2", pos, length); characterID = sis.readUI16(); imageData = sis.readBytesEx(sis.available()); } diff --git a/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java index ef207be2d..b04e2182b 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.AloneTag; import com.jpexs.decompiler.flash.tags.base.ImageTag; @@ -107,8 +107,8 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { return null; } - public DefineBitsJPEG3Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineBitsJPEG3", pos, length); + public DefineBitsJPEG3Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineBitsJPEG3", pos, length); characterID = sis.readUI16(); long alphaDataOffset = sis.readUI32(); imageData = sis.readBytesEx(alphaDataOffset); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java index 1f02075c9..c37250f6e 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.AloneTag; import com.jpexs.decompiler.flash.tags.base.ImageTag; @@ -137,8 +137,8 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag { * @param pos * @throws IOException */ - public DefineBitsJPEG4Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineBitsJPEG4", pos, length); + public DefineBitsJPEG4Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineBitsJPEG4", pos, length); characterID = sis.readUI16(); long alphaDataOffset = sis.readUI32(); deblockParam = sis.readUI16(); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java index 015fbc48a..87792e68c 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java @@ -17,7 +17,6 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWFInputStream; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.AloneTag; import com.jpexs.decompiler.flash.tags.base.ImageTag; @@ -108,8 +107,8 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag { setModified(true); } - public DefineBitsLossless2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineBitsLossless2", pos, length); + public DefineBitsLossless2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineBitsLossless2", pos, length); characterID = sis.readUI16(); bitmapFormat = sis.readUI8(); bitmapWidth = sis.readUI16(); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java b/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java index ed3e77249..78f1bb3d2 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java @@ -17,7 +17,6 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWFInputStream; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.AloneTag; import com.jpexs.decompiler.flash.tags.base.ImageTag; @@ -182,8 +181,8 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag { decompressed = true; } - public DefineBitsLosslessTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineBitsLossless", pos, length); + public DefineBitsLosslessTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineBitsLossless", pos, length); characterID = sis.readUI16(); bitmapFormat = sis.readUI8(); bitmapWidth = sis.readUI16(); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java b/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java index 513ffb46b..42b8f6c2d 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.ImageTag; import com.jpexs.decompiler.flash.types.BasicType; @@ -54,8 +54,8 @@ public class DefineBitsTag extends ImageTag { return true; } - public DefineBitsTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineBits", pos, length); + public DefineBitsTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineBits", pos, length); characterID = sis.readUI16(); jpegData = sis.readBytesEx(sis.available()); } diff --git a/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java index 5fcaf7dfa..9e2ca4aba 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.abc.CopyOutputStream; import com.jpexs.decompiler.flash.configuration.Configuration; @@ -101,8 +101,8 @@ public class DefineButton2Tag extends ButtonTag implements Container { * @param pos * @throws IOException */ - public DefineButton2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineButton2", pos, length); + public DefineButton2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineButton2", pos, length); buttonId = sis.readUI16(); reserved = (int) sis.readUB(7); trackAsMenu = sis.readUB(1) == 1; diff --git a/src/com/jpexs/decompiler/flash/tags/DefineButtonCxformTag.java b/src/com/jpexs/decompiler/flash/tags/DefineButtonCxformTag.java index 77f9093f8..63f935ec5 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineButtonCxformTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineButtonCxformTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.CXFORM; @@ -63,8 +63,8 @@ public class DefineButtonCxformTag extends Tag { * @param pos * @throws IOException */ - public DefineButtonCxformTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineButtonCxform", pos, length); + public DefineButtonCxformTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineButtonCxform", pos, length); buttonId = sis.readUI16(); buttonColorTransform = sis.readCXFORM(); } diff --git a/src/com/jpexs/decompiler/flash/tags/DefineButtonSoundTag.java b/src/com/jpexs/decompiler/flash/tags/DefineButtonSoundTag.java index bb1bf7b67..02bf558f8 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineButtonSoundTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineButtonSoundTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; import com.jpexs.decompiler.flash.types.BasicType; @@ -103,8 +103,8 @@ public class DefineButtonSoundTag extends CharacterIdTag { * @param pos * @throws IOException */ - public DefineButtonSoundTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineButtonSound", pos, length); + public DefineButtonSoundTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineButtonSound", pos, length); buttonId = sis.readUI16(); buttonSoundChar0 = sis.readUI16(); if (buttonSoundChar0 != 0) { diff --git a/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java b/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java index eb99742b9..bb1a3d2b9 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java @@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.DisassemblyListener; import com.jpexs.decompiler.flash.SWFInputStream; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.abc.CopyOutputStream; import com.jpexs.decompiler.flash.action.Action; @@ -100,8 +99,8 @@ public class DefineButtonTag extends ButtonTag implements ASMSource { * @param pos * @throws IOException */ - public DefineButtonTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineButton", pos, length); + public DefineButtonTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineButton", pos, length); buttonId = sis.readUI16(); characters = sis.readBUTTONRECORDList(false); hdrSize = sis.getPos(); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java b/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java index baedecd37..dfc1b1af2 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; @@ -699,8 +699,8 @@ public class DefineEditTextTag extends TextTag { * @param pos * @throws IOException */ - public DefineEditTextTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineEditText", pos, length); + public DefineEditTextTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineEditText", pos, length); characterID = sis.readUI16(); bounds = sis.readRECT(); hasText = sis.readUB(1) == 1; diff --git a/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java index e8153d237..f11f79528 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.types.BasicType; @@ -196,8 +196,8 @@ public class DefineFont2Tag extends FontTag { * @param pos * @throws IOException */ - public DefineFont2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineFont2", pos, length); + public DefineFont2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineFont2", pos, length); fontId = sis.readUI16(); fontFlagsHasLayout = sis.readUB(1) == 1; fontFlagsShiftJIS = sis.readUB(1) == 1; diff --git a/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java index 624497d46..2e12ca786 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.abc.CopyOutputStream; import com.jpexs.decompiler.flash.configuration.Configuration; @@ -110,8 +110,8 @@ public class DefineFont3Tag extends FontTag { return codeTable.indexOf((int) c); } - public DefineFont3Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineFont3", pos, length); + public DefineFont3Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineFont3", pos, length); fontId = sis.readUI16(); fontFlagsHasLayout = sis.readUB(1) == 1; fontFlagsShiftJIS = sis.readUB(1) == 1; diff --git a/src/com/jpexs/decompiler/flash/tags/DefineFont4Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineFont4Tag.java index c6f73af30..99dfd3de8 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineFont4Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineFont4Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.types.BasicType; @@ -46,8 +46,8 @@ public class DefineFont4Tag extends CharacterTag { return fontID; } - public DefineFont4Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineFont4", pos, length); + public DefineFont4Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineFont4", pos, length); fontID = sis.readUI16(); reserved = (int) sis.readUB(5); fontFlagsHasFontData = sis.readUB(1) == 1; diff --git a/src/com/jpexs/decompiler/flash/tags/DefineFontAlignZonesTag.java b/src/com/jpexs/decompiler/flash/tags/DefineFontAlignZonesTag.java index d2783fdac..bc4315c64 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineFontAlignZonesTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineFontAlignZonesTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.ZONERECORD; @@ -42,8 +42,8 @@ public class DefineFontAlignZonesTag extends Tag { public List zoneTable; public static final int ID = 73; - public DefineFontAlignZonesTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineFontAlignZones", pos, length); + public DefineFontAlignZonesTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineFontAlignZones", pos, length); fontID = sis.readUI16(); CSMTableHint = (int) sis.readUB(2); reserved = (int) sis.readUB(6); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineFontInfo2Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineFontInfo2Tag.java index 1951d9400..99c9291a9 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineFontInfo2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineFontInfo2Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.LANGCODE; @@ -92,8 +92,8 @@ public class DefineFontInfo2Tag extends Tag { * @param pos * @throws IOException */ - public DefineFontInfo2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineFontInfo2", pos, length); + public DefineFontInfo2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineFontInfo2", pos, length); fontID = sis.readUI16(); int fontNameLen = sis.readUI8(); if (swf.version >= 6) { diff --git a/src/com/jpexs/decompiler/flash/tags/DefineFontInfoTag.java b/src/com/jpexs/decompiler/flash/tags/DefineFontInfoTag.java index e9f8e7296..5d313beab 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineFontInfoTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineFontInfoTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.Reserved; @@ -93,8 +93,8 @@ public class DefineFontInfoTag extends Tag { * @param pos * @throws IOException */ - public DefineFontInfoTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineFontInfo", pos, length); + public DefineFontInfoTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineFontInfo", pos, length); fontId = sis.readUI16(); int fontNameLen = sis.readUI8(); if (swf.version >= 6) { diff --git a/src/com/jpexs/decompiler/flash/tags/DefineFontNameTag.java b/src/com/jpexs/decompiler/flash/tags/DefineFontNameTag.java index 7eaf56065..f6c73c331 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineFontNameTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineFontNameTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFType; import java.io.IOException; @@ -29,8 +29,8 @@ public class DefineFontNameTag extends Tag { public String fontCopyright; public static final int ID = 88; - public DefineFontNameTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineFontName", pos, length); + public DefineFontNameTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineFontName", pos, length); fontId = sis.readUI16(); fontName = sis.readString(); fontCopyright = sis.readString(); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java b/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java index fbefab67b..3317f7c34 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.types.BasicType; @@ -140,8 +140,8 @@ public class DefineFontTag extends FontTag { * @param pos * @throws IOException */ - public DefineFontTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineFont", pos, length); + public DefineFontTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineFont", pos, length); fontId = sis.readUI16(); int firstOffset = sis.readUI16(); int nGlyphs = firstOffset / 2; diff --git a/src/com/jpexs/decompiler/flash/tags/DefineMorphShape2Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineMorphShape2Tag.java index c4eb1f0d3..67d209e72 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineMorphShape2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineMorphShape2Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; @@ -152,8 +152,8 @@ public class DefineMorphShape2Tag extends CharacterTag implements MorphShapeTag * @param pos * @throws IOException */ - public DefineMorphShape2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineMorphShape2", pos, length); + public DefineMorphShape2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineMorphShape2", pos, length); characterId = sis.readUI16(); startBounds = sis.readRECT(); endBounds = sis.readRECT(); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineMorphShapeTag.java b/src/com/jpexs/decompiler/flash/tags/DefineMorphShapeTag.java index 65890c9a4..18da30c50 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineMorphShapeTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineMorphShapeTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; @@ -130,8 +130,8 @@ public class DefineMorphShapeTag extends CharacterTag implements MorphShapeTag { * @param pos * @throws IOException */ - public DefineMorphShapeTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineMorphShape", pos, length); + public DefineMorphShapeTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineMorphShape", pos, length); characterId = sis.readUI16(); startBounds = sis.readRECT(); endBounds = sis.readRECT(); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineScalingGridTag.java b/src/com/jpexs/decompiler/flash/tags/DefineScalingGridTag.java index dc05286ac..81866cbfa 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineScalingGridTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineScalingGridTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.RECT; @@ -35,8 +35,8 @@ public class DefineScalingGridTag extends Tag { public RECT splitter; public static final int ID = 78; - public DefineScalingGridTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineScalingGrid", pos, length); + public DefineScalingGridTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineScalingGrid", pos, length); characterId = sis.readUI16(); splitter = sis.readRECT(); } diff --git a/src/com/jpexs/decompiler/flash/tags/DefineSceneAndFrameLabelDataTag.java b/src/com/jpexs/decompiler/flash/tags/DefineSceneAndFrameLabelDataTag.java index e39bb25c8..ee14bd304 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineSceneAndFrameLabelDataTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineSceneAndFrameLabelDataTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFArray; @@ -82,8 +82,8 @@ public class DefineSceneAndFrameLabelDataTag extends Tag { * @param pos * @throws IOException */ - public DefineSceneAndFrameLabelDataTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineSceneAndFrameLabelData", pos, length); + public DefineSceneAndFrameLabelDataTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineSceneAndFrameLabelData", pos, length); int sceneCount = (int) sis.readEncodedU32(); sceneOffsets = new long[sceneCount]; sceneNames = new String[sceneCount]; diff --git a/src/com/jpexs/decompiler/flash/tags/DefineShape2Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineShape2Tag.java index e63b4c065..3c8e2b855 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineShape2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineShape2Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.RECT; @@ -67,8 +67,8 @@ public class DefineShape2Tag extends ShapeTag { return shapeBounds; } - public DefineShape2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineShape2", pos, length); + public DefineShape2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineShape2", pos, length); shapeId = sis.readUI16(); shapeBounds = sis.readRECT(); shapes = sis.readSHAPEWITHSTYLE(2, false); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineShape3Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineShape3Tag.java index 903674cef..1d75a0b9f 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineShape3Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineShape3Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.RECT; @@ -67,8 +67,8 @@ public class DefineShape3Tag extends ShapeTag { return shapeId; } - public DefineShape3Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineShape3", pos, length); + public DefineShape3Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineShape3", pos, length); shapeId = sis.readUI16(); shapeBounds = sis.readRECT(); shapes = sis.readSHAPEWITHSTYLE(3, false); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineShape4Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineShape4Tag.java index e12ba6367..96b979773 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineShape4Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineShape4Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.RECT; @@ -75,8 +75,8 @@ public class DefineShape4Tag extends ShapeTag { return shapeBounds; } - public DefineShape4Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineShape4", pos, length); + public DefineShape4Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineShape4", pos, length); shapeId = sis.readUI16(); shapeBounds = sis.readRECT(); edgeBounds = sis.readRECT(); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineShapeTag.java b/src/com/jpexs/decompiler/flash/tags/DefineShapeTag.java index 933b57e52..976f14c93 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineShapeTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineShapeTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.types.BasicType; @@ -64,8 +64,8 @@ public class DefineShapeTag extends ShapeTag { return shapeBounds; } - public DefineShapeTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineShape", pos, length); + public DefineShapeTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineShape", pos, length); shapeId = sis.readUI16(); shapeBounds = sis.readRECT(); shapes = sis.readSHAPEWITHSTYLE(1, false); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineSoundTag.java b/src/com/jpexs/decompiler/flash/tags/DefineSoundTag.java index d958ae8f6..7a55a09a2 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineSoundTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineSoundTag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.SoundTag; @@ -100,8 +100,8 @@ public class DefineSoundTag extends CharacterTag implements SoundTag { * @param pos * @throws IOException */ - public DefineSoundTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineSound", pos, length); + public DefineSoundTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineSound", pos, length); soundId = sis.readUI16(); soundFormat = (int) sis.readUB(4); soundRate = (int) sis.readUB(2); @@ -235,7 +235,7 @@ public class DefineSoundTag extends CharacterTag implements SoundTag { } } try { - MP3SOUNDDATA snd = new MP3SOUNDDATA(swf, mp3data, true); + MP3SOUNDDATA snd = new MP3SOUNDDATA(new SWFInputStream(swf, mp3data), true); if (!snd.frames.isEmpty()) { MP3FRAME fr = snd.frames.get(0); newSoundRate = fr.getSamplingRate(); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java b/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java index b8d798c2b..f4f847ab1 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.abc.CopyOutputStream; import com.jpexs.decompiler.flash.configuration.Configuration; @@ -201,11 +201,11 @@ public class DefineSpriteTag extends CharacterTag implements Container, Drawable * @throws IOException * @throws java.lang.InterruptedException */ - public DefineSpriteTag(SWFLimitedInputStream sis, int level, long pos, int length, boolean parallel, boolean skipUnusualTags) throws IOException, InterruptedException { - super(sis.swf, ID, "DefineSprite", pos, length); + public DefineSpriteTag(SWFInputStream sis, int level, long pos, int length, boolean parallel, boolean skipUnusualTags) throws IOException, InterruptedException { + super(sis.getSwf(), ID, "DefineSprite", pos, length); spriteId = sis.readUI16(); frameCount = sis.readUI16(); - List subTags = sis.readTagList(swf, this, level + 1, parallel, skipUnusualTags, true, swf.gfx); + List subTags = sis.readTagList(this, level + 1, parallel, skipUnusualTags, true, swf.gfx); if (subTags.get(subTags.size() - 1).getId() == EndTag.ID) { hasEndTag = true; subTags.remove(subTags.size() - 1); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java b/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java index 2f41304f1..28ed26b28 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; @@ -464,8 +464,8 @@ public class DefineText2Tag extends TextTag { * @param pos * @throws IOException */ - public DefineText2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineText2", pos, length); + public DefineText2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineText2", pos, length); characterID = sis.readUI16(); textBounds = sis.readRECT(); textMatrix = sis.readMatrix(); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java b/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java index 1c1bedc44..342665acf 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java @@ -18,7 +18,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.AppStrings; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; @@ -475,8 +475,8 @@ public class DefineTextTag extends TextTag { * @param pos * @throws IOException */ - public DefineTextTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineText", pos, length); + public DefineTextTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineText", pos, length); characterID = sis.readUI16(); textBounds = sis.readRECT(); textMatrix = sis.readMatrix(); diff --git a/src/com/jpexs/decompiler/flash/tags/DefineVideoStreamTag.java b/src/com/jpexs/decompiler/flash/tags/DefineVideoStreamTag.java index 3d1d948bd..b6179bf8b 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineVideoStreamTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineVideoStreamTag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; @@ -103,8 +103,8 @@ public class DefineVideoStreamTag extends CharacterTag implements BoundedTag { * @param pos * @throws IOException */ - public DefineVideoStreamTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineVideoStream", pos, length); + public DefineVideoStreamTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineVideoStream", pos, length); characterID = sis.readUI16(); numFrames = sis.readUI16(); width = sis.readUI16(); diff --git a/src/com/jpexs/decompiler/flash/tags/DoABCDefineTag.java b/src/com/jpexs/decompiler/flash/tags/DoABCDefineTag.java index 02949df0a..6c60e5ea4 100644 --- a/src/com/jpexs/decompiler/flash/tags/DoABCDefineTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DoABCDefineTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.CopyOutputStream; @@ -70,11 +70,11 @@ public class DoABCDefineTag extends Tag implements ABCContainerTag { * @param pos * @throws IOException */ - public DoABCDefineTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DoABCDefine", pos, length); + public DoABCDefineTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DoABCDefine", pos, length); flags = sis.readUI32(); name = sis.readString(); - abc = new ABC(sis.getBaseStream(), swf, this); + abc = new ABC(sis, swf, this); } /** diff --git a/src/com/jpexs/decompiler/flash/tags/DoABCTag.java b/src/com/jpexs/decompiler/flash/tags/DoABCTag.java index d1f96fdac..90e069bfe 100644 --- a/src/com/jpexs/decompiler/flash/tags/DoABCTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DoABCTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.CopyOutputStream; @@ -57,9 +57,9 @@ public class DoABCTag extends Tag implements ABCContainerTag { * @param pos * @throws IOException */ - public DoABCTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DoABC", pos, length); - abc = new ABC(sis.getBaseStream(), swf, this); + public DoABCTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DoABC", pos, length); + abc = new ABC(sis, swf, this); } /** diff --git a/src/com/jpexs/decompiler/flash/tags/DoActionTag.java b/src/com/jpexs/decompiler/flash/tags/DoActionTag.java index 7d92a5d57..20863a926 100644 --- a/src/com/jpexs/decompiler/flash/tags/DoActionTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DoActionTag.java @@ -19,7 +19,6 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.DisassemblyListener; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionListReader; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; @@ -55,8 +54,8 @@ public class DoActionTag extends Tag implements ASMSource { * @param pos * @throws java.io.IOException */ - public DoActionTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DoAction", pos, length); + public DoActionTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DoAction", pos, length); //do not load actionBytes. Disassebler will use the original SWF stream in this case //actionBytes = sis.readBytesEx(sis.available()); } diff --git a/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java b/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java index 6265f9327..7e352f5b0 100644 --- a/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java @@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.DisassemblyListener; import com.jpexs.decompiler.flash.SWFInputStream; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionListReader; @@ -60,8 +59,8 @@ public class DoInitActionTag extends CharacterIdTag implements ASMSource { * @param pos * @throws IOException */ - public DoInitActionTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DoInitAction", pos, length); + public DoInitActionTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DoInitAction", pos, length); spriteId = sis.readUI16(); //actions = sis.readActionList(); actionBytes = sis.readBytesEx(sis.available()); diff --git a/src/com/jpexs/decompiler/flash/tags/EnableDebugger2Tag.java b/src/com/jpexs/decompiler/flash/tags/EnableDebugger2Tag.java index d98fed5cb..adb1684d5 100644 --- a/src/com/jpexs/decompiler/flash/tags/EnableDebugger2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/EnableDebugger2Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.Reserved; @@ -68,8 +68,8 @@ public class EnableDebugger2Tag extends Tag { * @param pos * @throws IOException */ - public EnableDebugger2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "EnableDebugger2", pos, length); + public EnableDebugger2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "EnableDebugger2", pos, length); reserved = sis.readUI16(); passwordHash = sis.readString(); } diff --git a/src/com/jpexs/decompiler/flash/tags/EnableDebuggerTag.java b/src/com/jpexs/decompiler/flash/tags/EnableDebuggerTag.java index 20a3a2a26..f97e72923 100644 --- a/src/com/jpexs/decompiler/flash/tags/EnableDebuggerTag.java +++ b/src/com/jpexs/decompiler/flash/tags/EnableDebuggerTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -62,8 +62,8 @@ public class EnableDebuggerTag extends Tag { * @param pos * @throws IOException */ - public EnableDebuggerTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "EnableDebugger", pos, length); + public EnableDebuggerTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "EnableDebugger", pos, length); passwordHash = sis.readString(); } } diff --git a/src/com/jpexs/decompiler/flash/tags/EnableTelemetryTag.java b/src/com/jpexs/decompiler/flash/tags/EnableTelemetryTag.java index c874a399a..3811d7e77 100644 --- a/src/com/jpexs/decompiler/flash/tags/EnableTelemetryTag.java +++ b/src/com/jpexs/decompiler/flash/tags/EnableTelemetryTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.Optional; @@ -71,8 +71,8 @@ public class EnableTelemetryTag extends Tag { * @param pos * @throws IOException */ - public EnableTelemetryTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "", pos, length); + public EnableTelemetryTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "", pos, length); reserved = (int) sis.readUB(16); if (sis.available() > 0) { passwordHash = sis.readBytesEx(32); diff --git a/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java b/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java index aa263a6c9..700226a33 100644 --- a/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java +++ b/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFArray; @@ -60,8 +60,8 @@ public class ExportAssetsTag extends Tag { * @param pos * @throws IOException */ - public ExportAssetsTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "ExportAssets", pos, length); + public ExportAssetsTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "ExportAssets", pos, length); int count = sis.readUI16(); tags = new ArrayList<>(); names = new ArrayList<>(); diff --git a/src/com/jpexs/decompiler/flash/tags/FileAttributesTag.java b/src/com/jpexs/decompiler/flash/tags/FileAttributesTag.java index 35fd66ff7..64f96dd00 100644 --- a/src/com/jpexs/decompiler/flash/tags/FileAttributesTag.java +++ b/src/com/jpexs/decompiler/flash/tags/FileAttributesTag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.Reserved; @@ -48,8 +48,8 @@ public class FileAttributesTag extends Tag { super(swf, ID, "FileAttributes", 0, 0); } - public FileAttributesTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "FileAttributes", pos, length); + public FileAttributesTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "FileAttributes", pos, length); reserved1 = sis.readUB(1) == 1; // reserved // UB[1] == 0 (reserved) useDirectBlit = sis.readUB(1) != 0; diff --git a/src/com/jpexs/decompiler/flash/tags/FrameLabelTag.java b/src/com/jpexs/decompiler/flash/tags/FrameLabelTag.java index 08eaf8b0d..f91d4927e 100644 --- a/src/com/jpexs/decompiler/flash/tags/FrameLabelTag.java +++ b/src/com/jpexs/decompiler/flash/tags/FrameLabelTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -36,8 +36,8 @@ public class FrameLabelTag extends Tag { return namedAnchor; } - public FrameLabelTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "FrameLabel", pos, length); + public FrameLabelTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "FrameLabel", pos, length); name = sis.readString(); if (sis.available() > 0) { if (sis.readUI8() == 1) { diff --git a/src/com/jpexs/decompiler/flash/tags/ImportAssets2Tag.java b/src/com/jpexs/decompiler/flash/tags/ImportAssets2Tag.java index 7fafabb26..db98cc70b 100644 --- a/src/com/jpexs/decompiler/flash/tags/ImportAssets2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/ImportAssets2Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.ImportTag; import com.jpexs.decompiler.flash.types.BasicType; @@ -63,8 +63,8 @@ public class ImportAssets2Tag extends Tag implements ImportTag { * @param pos * @throws IOException */ - public ImportAssets2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "ImportAssets2", pos, length); + public ImportAssets2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "ImportAssets2", pos, length); tags = new ArrayList<>(); names = new ArrayList<>(); url = sis.readString(); diff --git a/src/com/jpexs/decompiler/flash/tags/ImportAssetsTag.java b/src/com/jpexs/decompiler/flash/tags/ImportAssetsTag.java index ef4632ead..0109f27d8 100644 --- a/src/com/jpexs/decompiler/flash/tags/ImportAssetsTag.java +++ b/src/com/jpexs/decompiler/flash/tags/ImportAssetsTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.ImportTag; import com.jpexs.decompiler.flash.types.BasicType; @@ -56,8 +56,8 @@ public class ImportAssetsTag extends Tag implements ImportTag { * @param pos * @throws IOException */ - public ImportAssetsTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "ImportAssets", pos, length); + public ImportAssetsTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "ImportAssets", pos, length); tags = new ArrayList<>(); names = new ArrayList<>(); url = sis.readString(); diff --git a/src/com/jpexs/decompiler/flash/tags/JPEGTablesTag.java b/src/com/jpexs/decompiler/flash/tags/JPEGTablesTag.java index 577715ebc..124dad1dc 100644 --- a/src/com/jpexs/decompiler/flash/tags/JPEGTablesTag.java +++ b/src/com/jpexs/decompiler/flash/tags/JPEGTablesTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.types.annotations.Internal; import java.io.IOException; @@ -26,8 +26,8 @@ public class JPEGTablesTag extends Tag { @Internal public byte[] jpegData; - public JPEGTablesTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "JPEGTables", pos, length); + public JPEGTablesTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "JPEGTables", pos, length); jpegData = sis.readBytesEx(sis.available()); } } diff --git a/src/com/jpexs/decompiler/flash/tags/MetadataTag.java b/src/com/jpexs/decompiler/flash/tags/MetadataTag.java index e95f47947..39ab9ef97 100644 --- a/src/com/jpexs/decompiler/flash/tags/MetadataTag.java +++ b/src/com/jpexs/decompiler/flash/tags/MetadataTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.annotations.Multiline; import java.io.ByteArrayOutputStream; @@ -29,8 +29,8 @@ public class MetadataTag extends Tag { public String xmlMetadata; public static final int ID = 77; - public MetadataTag(SWFLimitedInputStream sis, long pos, int length) { - super(sis.swf, ID, "Metadata", pos, length); + public MetadataTag(SWFInputStream sis, long pos, int length) { + super(sis.getSwf(), ID, "Metadata", pos, length); try { xmlMetadata = sis.readString(); } catch (IOException ex) { diff --git a/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java b/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java index a63aeff4f..7d7cc000d 100644 --- a/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.abc.CopyOutputStream; import com.jpexs.decompiler.flash.configuration.Configuration; @@ -218,8 +218,8 @@ public class PlaceObject2Tag extends CharacterIdTag implements Container, PlaceO * @param pos * @throws IOException */ - public PlaceObject2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "PlaceObject2", pos, length); + public PlaceObject2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "PlaceObject2", pos, length); placeFlagHasClipActions = sis.readUB(1) == 1; placeFlagHasClipDepth = sis.readUB(1) == 1; placeFlagHasName = sis.readUB(1) == 1; diff --git a/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java b/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java index cf2eb74a3..bcab5c965 100644 --- a/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.EndOfStreamException; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.abc.CopyOutputStream; import com.jpexs.decompiler.flash.configuration.Configuration; @@ -302,8 +302,8 @@ public class PlaceObject3Tag extends CharacterIdTag implements Container, PlaceO * @param pos * @throws IOException */ - public PlaceObject3Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "PlaceObject3", pos, length); + public PlaceObject3Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "PlaceObject3", pos, length); placeFlagHasClipActions = sis.readUB(1) == 1; placeFlagHasClipDepth = sis.readUB(1) == 1; placeFlagHasName = sis.readUB(1) == 1; diff --git a/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java b/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java index dce9d30ac..eff1c5fb1 100644 --- a/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.EndOfStreamException; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.abc.CopyOutputStream; import com.jpexs.decompiler.flash.configuration.Configuration; @@ -303,8 +303,8 @@ public class PlaceObject4Tag extends CharacterIdTag implements Container, PlaceO * @param pos * @throws IOException */ - public PlaceObject4Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "PlaceObject4", pos, length); + public PlaceObject4Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "PlaceObject4", pos, length); placeFlagHasClipActions = sis.readUB(1) == 1; placeFlagHasClipDepth = sis.readUB(1) == 1; placeFlagHasName = sis.readUB(1) == 1; diff --git a/src/com/jpexs/decompiler/flash/tags/PlaceObjectTag.java b/src/com/jpexs/decompiler/flash/tags/PlaceObjectTag.java index ae1a7e251..84cc3e193 100644 --- a/src/com/jpexs/decompiler/flash/tags/PlaceObjectTag.java +++ b/src/com/jpexs/decompiler/flash/tags/PlaceObjectTag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; @@ -104,8 +104,8 @@ public class PlaceObjectTag extends CharacterIdTag implements PlaceObjectTypeTag * @param pos * @throws IOException */ - public PlaceObjectTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "PlaceObject", pos, length); + public PlaceObjectTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "PlaceObject", pos, length); characterId = sis.readUI16(); depth = sis.readUI16(); matrix = sis.readMatrix(); diff --git a/src/com/jpexs/decompiler/flash/tags/ProductInfoTag.java b/src/com/jpexs/decompiler/flash/tags/ProductInfoTag.java index a55f50d7e..f7ed26494 100644 --- a/src/com/jpexs/decompiler/flash/tags/ProductInfoTag.java +++ b/src/com/jpexs/decompiler/flash/tags/ProductInfoTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFType; @@ -44,8 +44,8 @@ public class ProductInfoTag extends Tag { public long compilationDateHigh; public static final int ID = 41; - public ProductInfoTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "ProductInfo", pos, length); + public ProductInfoTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "ProductInfo", pos, length); /* * 0: Unknown * 1: Macromedia Flex for J2EE diff --git a/src/com/jpexs/decompiler/flash/tags/ProtectTag.java b/src/com/jpexs/decompiler/flash/tags/ProtectTag.java index 3be488b3c..98058c292 100644 --- a/src/com/jpexs/decompiler/flash/tags/ProtectTag.java +++ b/src/com/jpexs/decompiler/flash/tags/ProtectTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -62,8 +62,8 @@ public class ProtectTag extends Tag { * @param pos * @throws IOException */ - public ProtectTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "Protect", pos, length); + public ProtectTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "Protect", pos, length); if (sis.available() > 0) { passwordHash = sis.readString(); } else { diff --git a/src/com/jpexs/decompiler/flash/tags/RemoveObject2Tag.java b/src/com/jpexs/decompiler/flash/tags/RemoveObject2Tag.java index 98a05e995..b63cb804a 100644 --- a/src/com/jpexs/decompiler/flash/tags/RemoveObject2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/RemoveObject2Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.tags.base.RemoveTag; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFType; @@ -28,8 +28,8 @@ public class RemoveObject2Tag extends Tag implements RemoveTag { public int depth; public static final int ID = 28; - public RemoveObject2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "RemoveObject2", pos, length); + public RemoveObject2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "RemoveObject2", pos, length); depth = sis.readUI16(); } diff --git a/src/com/jpexs/decompiler/flash/tags/RemoveObjectTag.java b/src/com/jpexs/decompiler/flash/tags/RemoveObjectTag.java index 97987afcf..cdeeb70d5 100644 --- a/src/com/jpexs/decompiler/flash/tags/RemoveObjectTag.java +++ b/src/com/jpexs/decompiler/flash/tags/RemoveObjectTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; import com.jpexs.decompiler.flash.tags.base.RemoveTag; @@ -71,8 +71,8 @@ public class RemoveObjectTag extends CharacterIdTag implements RemoveTag { * @param pos * @throws IOException */ - public RemoveObjectTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "RemoveObject", pos, length); + public RemoveObjectTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "RemoveObject", pos, length); characterId = sis.readUI16(); depth = sis.readUI16(); } diff --git a/src/com/jpexs/decompiler/flash/tags/ScriptLimitsTag.java b/src/com/jpexs/decompiler/flash/tags/ScriptLimitsTag.java index 285e4f629..93ccd37bb 100644 --- a/src/com/jpexs/decompiler/flash/tags/ScriptLimitsTag.java +++ b/src/com/jpexs/decompiler/flash/tags/ScriptLimitsTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFType; @@ -34,8 +34,8 @@ public class ScriptLimitsTag extends Tag { public static final int ID = 65; - public ScriptLimitsTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "ScriptLimits", pos, length); + public ScriptLimitsTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "ScriptLimits", pos, length); maxRecursionDepth = sis.readUI16(); scriptTimeoutSeconds = sis.readUI16(); } diff --git a/src/com/jpexs/decompiler/flash/tags/SetBackgroundColorTag.java b/src/com/jpexs/decompiler/flash/tags/SetBackgroundColorTag.java index af29acbee..047be2784 100644 --- a/src/com/jpexs/decompiler/flash/tags/SetBackgroundColorTag.java +++ b/src/com/jpexs/decompiler/flash/tags/SetBackgroundColorTag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.RGB; import java.io.ByteArrayOutputStream; @@ -28,8 +28,8 @@ public class SetBackgroundColorTag extends Tag { public RGB backgroundColor; public static final int ID = 9; - public SetBackgroundColorTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "SetBackgroundColor", pos, length); + public SetBackgroundColorTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "SetBackgroundColor", pos, length); backgroundColor = sis.readRGB(); } diff --git a/src/com/jpexs/decompiler/flash/tags/SetTabIndexTag.java b/src/com/jpexs/decompiler/flash/tags/SetTabIndexTag.java index 44be7f654..8581d0ad1 100644 --- a/src/com/jpexs/decompiler/flash/tags/SetTabIndexTag.java +++ b/src/com/jpexs/decompiler/flash/tags/SetTabIndexTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFType; @@ -69,8 +69,8 @@ public class SetTabIndexTag extends Tag { * @param pos * @throws IOException */ - public SetTabIndexTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "SetTabIndex", pos, length); + public SetTabIndexTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "SetTabIndex", pos, length); depth = sis.readUI16(); tabIndex = sis.readUI16(); } diff --git a/src/com/jpexs/decompiler/flash/tags/SoundStreamBlockTag.java b/src/com/jpexs/decompiler/flash/tags/SoundStreamBlockTag.java index 3e690c7a7..535456c75 100644 --- a/src/com/jpexs/decompiler/flash/tags/SoundStreamBlockTag.java +++ b/src/com/jpexs/decompiler/flash/tags/SoundStreamBlockTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.types.annotations.Internal; import java.io.IOException; @@ -40,8 +40,8 @@ public class SoundStreamBlockTag extends Tag { * @param pos * @throws IOException */ - public SoundStreamBlockTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "SoundStreamBlock", pos, length); + public SoundStreamBlockTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "SoundStreamBlock", pos, length); //all data is streamSoundData streamSoundData = sis.readBytesEx(sis.available()); } diff --git a/src/com/jpexs/decompiler/flash/tags/SoundStreamHead2Tag.java b/src/com/jpexs/decompiler/flash/tags/SoundStreamHead2Tag.java index c7e12126c..eb2158ad0 100644 --- a/src/com/jpexs/decompiler/flash/tags/SoundStreamHead2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/SoundStreamHead2Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag; @@ -141,8 +141,8 @@ public class SoundStreamHead2Tag extends CharacterIdTag implements SoundStreamHe * @param pos * @throws IOException */ - public SoundStreamHead2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "SoundStreamHead2", pos, length); + public SoundStreamHead2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "SoundStreamHead2", pos, length); reserved = (int) sis.readUB(4); playBackSoundRate = (int) sis.readUB(2); playBackSoundSize = sis.readUB(1) == 1; diff --git a/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTag.java b/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTag.java index 8062c903a..149648b75 100644 --- a/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTag.java +++ b/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; import com.jpexs.decompiler.flash.tags.base.Container; @@ -134,8 +134,8 @@ public class SoundStreamHeadTag extends CharacterIdTag implements SoundStreamHea * @param pos * @throws IOException */ - public SoundStreamHeadTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "SoundStreamHead", pos, length); + public SoundStreamHeadTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "SoundStreamHead", pos, length); reserved = (int) sis.readUB(4); playBackSoundRate = (int) sis.readUB(2); playBackSoundSize = sis.readUB(1) == 1; diff --git a/src/com/jpexs/decompiler/flash/tags/StartSound2Tag.java b/src/com/jpexs/decompiler/flash/tags/StartSound2Tag.java index ab1d3b6c9..b87fab685 100644 --- a/src/com/jpexs/decompiler/flash/tags/StartSound2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/StartSound2Tag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.SOUNDINFO; import java.io.ByteArrayOutputStream; @@ -59,8 +59,8 @@ public class StartSound2Tag extends Tag { * @param pos * @throws IOException */ - public StartSound2Tag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "StartSound2", pos, length); + public StartSound2Tag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "StartSound2", pos, length); soundClassName = sis.readString(); soundInfo = sis.readSOUNDINFO(); } diff --git a/src/com/jpexs/decompiler/flash/tags/StartSoundTag.java b/src/com/jpexs/decompiler/flash/tags/StartSoundTag.java index 0b78c3d1d..1ddb9c853 100644 --- a/src/com/jpexs/decompiler/flash/tags/StartSoundTag.java +++ b/src/com/jpexs/decompiler/flash/tags/StartSoundTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.SOUNDINFO; @@ -63,8 +63,8 @@ public class StartSoundTag extends Tag { * @param pos * @throws IOException */ - public StartSoundTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "StartSound", pos, length); + public StartSoundTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "StartSound", pos, length); soundId = sis.readUI16(); soundInfo = sis.readSOUNDINFO(); } diff --git a/src/com/jpexs/decompiler/flash/tags/SymbolClassTag.java b/src/com/jpexs/decompiler/flash/tags/SymbolClassTag.java index b6c0fe46d..ce87dc504 100644 --- a/src/com/jpexs/decompiler/flash/tags/SymbolClassTag.java +++ b/src/com/jpexs/decompiler/flash/tags/SymbolClassTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFArray; @@ -34,8 +34,8 @@ public class SymbolClassTag extends Tag { public String[] names; public static final int ID = 76; - public SymbolClassTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "SymbolClass", pos, length); + public SymbolClassTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "SymbolClass", pos, length); int numSymbols = sis.readUI16(); tags = new int[numSymbols]; names = new String[numSymbols]; diff --git a/src/com/jpexs/decompiler/flash/tags/Tag.java b/src/com/jpexs/decompiler/flash/tags/Tag.java index 85fa1c603..ac8314206 100644 --- a/src/com/jpexs/decompiler/flash/tags/Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/Tag.java @@ -44,7 +44,7 @@ import java.util.Set; /** * Represents Tag inside SWF file */ -public class Tag implements NeedsCharacters, Exportable, ContainerItem, Serializable { +public abstract class Tag implements NeedsCharacters, Exportable, ContainerItem, Serializable { /** * Identifier of tag type @@ -213,7 +213,6 @@ public class Tag implements NeedsCharacters, Exportable, ContainerItem, Serializ StartSound2Tag.ID, StartSoundTag.ID, SymbolClassTag.ID, - TagStub.ID, VideoFrameTag.ID, DefineCompactedFont.ID, DefineExternalGradient.ID, @@ -339,8 +338,6 @@ public class Tag implements NeedsCharacters, Exportable, ContainerItem, Serializ } else { sos.write(swf.uncompressedData, (int) pos, length); } - - //todo: honfika: update pos and length during save } /** diff --git a/src/com/jpexs/decompiler/flash/tags/TagStub.java b/src/com/jpexs/decompiler/flash/tags/TagStub.java index 987ff7ea4..adbd54b68 100644 --- a/src/com/jpexs/decompiler/flash/tags/TagStub.java +++ b/src/com/jpexs/decompiler/flash/tags/TagStub.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; -import java.io.IOException; +import com.jpexs.decompiler.flash.SWFInputStream; /** * @@ -26,28 +26,24 @@ import java.io.IOException; */ public class TagStub extends Tag { - public static final int ID = -1; //TODO: Enter correct ID - - /** - * Gets data bytes - * - * @return Bytes of data - */ - @Override - public byte[] getData() { - return getOriginalData(); - } - + private SWFInputStream dataStream; + /** * Constructor * * @param swf + * @param id * @param length + * @param name * @param pos - * @throws IOException + * @param sis */ - public TagStub(SWF swf, long pos, int length) throws IOException { - super(swf, ID, "" /*TODO:Insert name here*/, pos, length); + public TagStub(SWF swf, int id, String name, long pos, int length, SWFInputStream sis) { + super(swf, id, name, pos, length); + dataStream = sis; + } + public SWFInputStream getDataStream() { + return dataStream; } } diff --git a/src/com/jpexs/decompiler/flash/tags/VideoFrameTag.java b/src/com/jpexs/decompiler/flash/tags/VideoFrameTag.java index 7582a5446..ae7bd48ad 100644 --- a/src/com/jpexs/decompiler/flash/tags/VideoFrameTag.java +++ b/src/com/jpexs/decompiler/flash/tags/VideoFrameTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFType; @@ -65,8 +65,8 @@ public class VideoFrameTag extends Tag { * @param pos * @throws IOException */ - public VideoFrameTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "VideoFrame", pos, length); + public VideoFrameTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "VideoFrame", pos, length); streamID = sis.readUI16(); frameNum = sis.readUI16(); videoData = sis.readBytesEx(sis.available()); //TODO: Parse video packets diff --git a/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java b/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java index 564e30d6e..3f766f4c7 100644 --- a/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java +++ b/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.tags.gfx; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.DefineFont2Tag; import com.jpexs.decompiler.flash.tags.Tag; @@ -88,8 +88,8 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { * @param pos * @throws IOException */ - public DefineCompactedFont(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineCompactedFont", pos, length); + public DefineCompactedFont(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineCompactedFont", pos, length); fontId = sis.readUI16(); fonts = new ArrayList<>(); diff --git a/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalGradient.java b/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalGradient.java index 0c09eea5a..1f4d81405 100644 --- a/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalGradient.java +++ b/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalGradient.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags.gfx; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.Tag; import java.io.ByteArrayOutputStream; @@ -69,8 +69,8 @@ public class DefineExternalGradient extends Tag { * @param pos * @throws IOException */ - public DefineExternalGradient(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineExternalGradient", pos, length); + public DefineExternalGradient(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineExternalGradient", pos, length); gradientId = sis.readUI16(); bitmapsFormat = sis.readUI16(); gradientSize = sis.readUI16(); diff --git a/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage.java b/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage.java index a0dd38c2a..a79d940f8 100644 --- a/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage.java +++ b/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags.gfx; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.Tag; import java.io.ByteArrayOutputStream; @@ -71,8 +71,8 @@ public class DefineExternalImage extends Tag { * @param pos * @throws IOException */ - public DefineExternalImage(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineExternalImage", pos, length); + public DefineExternalImage(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineExternalImage", pos, length); characterId = sis.readUI16(); bitmapFormat = sis.readUI16(); targetWidth = sis.readUI16(); diff --git a/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage2.java b/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage2.java index 0c3d32690..75f69ef60 100644 --- a/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage2.java +++ b/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage2.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags.gfx; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.Tag; import java.io.ByteArrayOutputStream; @@ -79,8 +79,8 @@ public class DefineExternalImage2 extends Tag { * @param pos * @throws IOException */ - public DefineExternalImage2(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineExternalImage2", pos, length); + public DefineExternalImage2(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineExternalImage2", pos, length); characterId = sis.readUI32(); bitmapFormat = sis.readUI16(); targetWidth = sis.readUI16(); diff --git a/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalSound.java b/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalSound.java index d7152fd1f..0581ec9d0 100644 --- a/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalSound.java +++ b/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalSound.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags.gfx; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.Tag; import java.io.ByteArrayOutputStream; @@ -79,8 +79,8 @@ public class DefineExternalSound extends Tag { * @param pos * @throws IOException */ - public DefineExternalSound(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineExternalSound", pos, length); + public DefineExternalSound(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineExternalSound", pos, length); characterId = sis.readUI16(); soundFormat = sis.readUI16(); bits = sis.readUI16(); diff --git a/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalStreamSound.java b/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalStreamSound.java index e9d00b979..516483434 100644 --- a/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalStreamSound.java +++ b/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalStreamSound.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags.gfx; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.Tag; import java.io.ByteArrayOutputStream; @@ -77,8 +77,8 @@ public class DefineExternalStreamSound extends Tag { * @param pos * @throws IOException */ - public DefineExternalStreamSound(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineExternalStreamSound", pos, length); + public DefineExternalStreamSound(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineExternalStreamSound", pos, length); soundFormat = sis.readUI16(); bits = sis.readUI16(); channels = sis.readUI16(); diff --git a/src/com/jpexs/decompiler/flash/tags/gfx/DefineGradientMap.java b/src/com/jpexs/decompiler/flash/tags/gfx/DefineGradientMap.java index 7d5f9f6f5..4b61458a8 100644 --- a/src/com/jpexs/decompiler/flash/tags/gfx/DefineGradientMap.java +++ b/src/com/jpexs/decompiler/flash/tags/gfx/DefineGradientMap.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags.gfx; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.Tag; import java.io.ByteArrayOutputStream; @@ -61,8 +61,8 @@ public class DefineGradientMap extends Tag { * @param pos * @throws IOException */ - public DefineGradientMap(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineGradientMap", pos, length); + public DefineGradientMap(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineGradientMap", pos, length); int numGradients = sis.readUI16(); indices = new int[numGradients]; for (int i = 0; i < numGradients; i++) { diff --git a/src/com/jpexs/decompiler/flash/tags/gfx/DefineSubImage.java b/src/com/jpexs/decompiler/flash/tags/gfx/DefineSubImage.java index fad0ca99f..37baa3ce3 100644 --- a/src/com/jpexs/decompiler/flash/tags/gfx/DefineSubImage.java +++ b/src/com/jpexs/decompiler/flash/tags/gfx/DefineSubImage.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags.gfx; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.Tag; import java.io.ByteArrayOutputStream; @@ -68,8 +68,8 @@ public class DefineSubImage extends Tag { * @param pos * @throws IOException */ - public DefineSubImage(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "DefineSubImage", pos, length); + public DefineSubImage(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "DefineSubImage", pos, length); characterId = sis.readUI16(); imageCharacterId = sis.readUI16(); x1 = sis.readUI16(); diff --git a/src/com/jpexs/decompiler/flash/tags/gfx/ExporterInfoTag.java b/src/com/jpexs/decompiler/flash/tags/gfx/ExporterInfoTag.java index 568237d7a..055b3709d 100644 --- a/src/com/jpexs/decompiler/flash/tags/gfx/ExporterInfoTag.java +++ b/src/com/jpexs/decompiler/flash/tags/gfx/ExporterInfoTag.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags.gfx; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.Tag; import java.io.ByteArrayOutputStream; @@ -87,8 +87,8 @@ public class ExporterInfoTag extends Tag { * @param pos * @throws IOException */ - public ExporterInfoTag(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "ExporterInfo", pos, length); + public ExporterInfoTag(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "ExporterInfo", pos, length); this.version = sis.readUI16(); if (this.version >= 0x10a) { flags = sis.readUI32(); diff --git a/src/com/jpexs/decompiler/flash/tags/gfx/FontTextureInfo.java b/src/com/jpexs/decompiler/flash/tags/gfx/FontTextureInfo.java index 3ae340aa9..e8c7ee906 100644 --- a/src/com/jpexs/decompiler/flash/tags/gfx/FontTextureInfo.java +++ b/src/com/jpexs/decompiler/flash/tags/gfx/FontTextureInfo.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.tags.gfx; -import com.jpexs.decompiler.flash.SWFLimitedInputStream; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.types.gfx.FONTINFO; @@ -89,8 +89,8 @@ public class FontTextureInfo extends Tag { * @param pos * @throws IOException */ - public FontTextureInfo(SWFLimitedInputStream sis, long pos, int length) throws IOException { - super(sis.swf, ID, "FontTextureInfo", pos, length); + public FontTextureInfo(SWFInputStream sis, long pos, int length) throws IOException { + super(sis.getSwf(), ID, "FontTextureInfo", pos, length); textureID = sis.readUI32(); textureFormat = sis.readUI16(); int fileNameLen = sis.readUI8(); diff --git a/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java b/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java index 4e3edbe0e..2ab1edefc 100644 --- a/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java +++ b/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java @@ -200,7 +200,7 @@ public class CLIPACTIONRECORD implements ASMSource, Exportable, ContainerItem, S @Override public List getActions() throws InterruptedException { try { - List list = ActionListReader.readActionListTimeout(listeners, getPos() + hdrPos, new SWFInputStream(swf, actionBytes, 0), swf.version, 0, -1, toString()/*FIXME?*/); + List list = ActionListReader.readActionListTimeout(listeners, getPos() + hdrPos, new SWFInputStream(swf, actionBytes), swf.version, 0, -1, toString()/*FIXME?*/); return list; } catch (InterruptedException ex) { throw ex; diff --git a/src/com/jpexs/decompiler/flash/types/gfx/GFxInputStream.java b/src/com/jpexs/decompiler/flash/types/gfx/GFxInputStream.java index 001168436..a0aeb9836 100644 --- a/src/com/jpexs/decompiler/flash/types/gfx/GFxInputStream.java +++ b/src/com/jpexs/decompiler/flash/types/gfx/GFxInputStream.java @@ -16,9 +16,8 @@ */ package com.jpexs.decompiler.flash.types.gfx; -import com.jpexs.helpers.ReReadableInputStream; +import com.jpexs.helpers.MemoryInputStream; import java.io.IOException; -import java.io.InputStream; /** * @@ -26,11 +25,11 @@ import java.io.InputStream; */ public class GFxInputStream { - private final ReReadableInputStream is; + private final MemoryInputStream is; private static final int MaxUInt7 = (1 << 7) - 1; - public GFxInputStream(InputStream is) { - this.is = new ReReadableInputStream(is); + public GFxInputStream(MemoryInputStream is) { + this.is = is; } public int available() throws IOException { diff --git a/src/com/jpexs/decompiler/flash/types/sound/AdpcmDecoder.java b/src/com/jpexs/decompiler/flash/types/sound/AdpcmDecoder.java index 92190873b..7fae1359c 100644 --- a/src/com/jpexs/decompiler/flash/types/sound/AdpcmDecoder.java +++ b/src/com/jpexs/decompiler/flash/types/sound/AdpcmDecoder.java @@ -202,9 +202,8 @@ public class AdpcmDecoder extends SoundDecoder { } @Override - public void decode(byte[] data, OutputStream os) throws IOException { + public void decode(SWFInputStream sis, OutputStream os) throws IOException { int adpcm_code_size; - SWFInputStream sis = new SWFInputStream(null, data); SWFOutputStream sos = new SWFOutputStream(os, SWF.DEFAULT_VERSION); adpcm_code_size = (int) sis.readUB(2); int bits_per_code = adpcm_code_size + 2; diff --git a/src/com/jpexs/decompiler/flash/types/sound/MP3Decoder.java b/src/com/jpexs/decompiler/flash/types/sound/MP3Decoder.java index 996d610d2..b2bfeec3e 100644 --- a/src/com/jpexs/decompiler/flash/types/sound/MP3Decoder.java +++ b/src/com/jpexs/decompiler/flash/types/sound/MP3Decoder.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.types.sound; +import com.jpexs.decompiler.flash.SWFInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; @@ -37,9 +38,9 @@ public class MP3Decoder extends SoundDecoder { } @Override - public void decode(byte[] data, OutputStream os) throws IOException { + public void decode(SWFInputStream sis, OutputStream os) throws IOException { Decoder decoder = new Decoder(); - Bitstream bitstream = new Bitstream(new ByteArrayInputStream(data)); + Bitstream bitstream = new Bitstream(new ByteArrayInputStream(sis.readBytesEx(sis.available()))); SampleBuffer buf; while ((buf = readFrame(decoder, bitstream)) != null) { short audio[] = buf.getBuffer(); diff --git a/src/com/jpexs/decompiler/flash/types/sound/MP3SOUNDDATA.java b/src/com/jpexs/decompiler/flash/types/sound/MP3SOUNDDATA.java index 4ca3464b4..89afd380e 100644 --- a/src/com/jpexs/decompiler/flash/types/sound/MP3SOUNDDATA.java +++ b/src/com/jpexs/decompiler/flash/types/sound/MP3SOUNDDATA.java @@ -16,7 +16,6 @@ */ package com.jpexs.decompiler.flash.types.sound; -import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -34,15 +33,14 @@ public class MP3SOUNDDATA { public int seekSamples; public List frames; - public MP3SOUNDDATA(SWF swf, byte[] data, boolean raw) throws IOException { - SWFInputStream sis = new SWFInputStream(swf, data); + public MP3SOUNDDATA(SWFInputStream sis, boolean raw) throws IOException { if (!raw) { seekSamples = sis.readSI16(); } frames = new ArrayList<>(); MP3FRAME f; Decoder decoder = new Decoder(); - Bitstream bitstream = new Bitstream(new ByteArrayInputStream(data, 2, data.length - 2)); + Bitstream bitstream = new Bitstream(new ByteArrayInputStream(sis.readBytesEx(sis.available()))); while ((f = MP3FRAME.readFrame(bitstream, decoder)) != null) { frames.add(f); } diff --git a/src/com/jpexs/decompiler/flash/types/sound/NellyMoserDecoder.java b/src/com/jpexs/decompiler/flash/types/sound/NellyMoserDecoder.java index 6f739007a..a786cb905 100644 --- a/src/com/jpexs/decompiler/flash/types/sound/NellyMoserDecoder.java +++ b/src/com/jpexs/decompiler/flash/types/sound/NellyMoserDecoder.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.types.sound; +import com.jpexs.decompiler.flash.SWFInputStream; import java.io.IOException; import java.io.OutputStream; import lt.dkd.nellymoser.CodecImpl; @@ -35,16 +36,15 @@ public class NellyMoserDecoder extends SoundDecoder { } @Override - public void decode(byte[] data, OutputStream os) throws IOException { + public void decode(SWFInputStream sis, OutputStream os) throws IOException { soundFormat.stereo = false; float audioD[] = new float[NELLY_SAMPLES]; final float[] state = new float[64]; - byte[] block = new byte[NELLY_BLOCK_LEN]; - int blockCount = data.length / NELLY_BLOCK_LEN; + int blockCount = sis.available() / NELLY_BLOCK_LEN; for (int j = 0; j < blockCount; j++) { - System.arraycopy(data, j * NELLY_BLOCK_LEN, block, 0, NELLY_BLOCK_LEN); + byte[] block = sis.readBytesEx(NELLY_BLOCK_LEN); CodecImpl.decode(state, block, audioD); short audio[] = new short[NELLY_SAMPLES]; for (int i = 0; i < audioD.length; i++) { diff --git a/src/com/jpexs/decompiler/flash/types/sound/NoDecoder.java b/src/com/jpexs/decompiler/flash/types/sound/NoDecoder.java index 3bc78ce10..048abf505 100644 --- a/src/com/jpexs/decompiler/flash/types/sound/NoDecoder.java +++ b/src/com/jpexs/decompiler/flash/types/sound/NoDecoder.java @@ -17,6 +17,7 @@ */ package com.jpexs.decompiler.flash.types.sound; +import com.jpexs.decompiler.flash.SWFInputStream; import java.io.IOException; import java.io.OutputStream; @@ -31,8 +32,8 @@ public class NoDecoder extends SoundDecoder { } @Override - public void decode(byte[] data, OutputStream os) throws IOException { - os.write(data); + public void decode(SWFInputStream sis, OutputStream os) throws IOException { + os.write(sis.readBytesEx(sis.available())); } } diff --git a/src/com/jpexs/decompiler/flash/types/sound/SoundDecoder.java b/src/com/jpexs/decompiler/flash/types/sound/SoundDecoder.java index 36d1534f8..471ceab47 100644 --- a/src/com/jpexs/decompiler/flash/types/sound/SoundDecoder.java +++ b/src/com/jpexs/decompiler/flash/types/sound/SoundDecoder.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.types.sound; +import com.jpexs.decompiler.flash.SWFInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -32,11 +33,11 @@ public abstract class SoundDecoder { this.soundFormat = soundFormat; } - public byte[] decode(byte[] data) throws IOException { + public byte[] decode(SWFInputStream sis) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); - decode(data, baos); + decode(sis, baos); return baos.toByteArray(); } - public abstract void decode(byte[] data, OutputStream os) throws IOException; + public abstract void decode(SWFInputStream sis, OutputStream os) throws IOException; } diff --git a/src/com/jpexs/decompiler/flash/types/sound/SoundFormat.java b/src/com/jpexs/decompiler/flash/types/sound/SoundFormat.java index 680493890..40967d361 100644 --- a/src/com/jpexs/decompiler/flash/types/sound/SoundFormat.java +++ b/src/com/jpexs/decompiler/flash/types/sound/SoundFormat.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.types.sound; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.helpers.utf8.Utf8Helper; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -79,26 +80,26 @@ public class SoundFormat { ensureFormat(); } - public byte[] decode(byte data[]) { + public byte[] decode(SWFInputStream sis) { try { - return getDecoder().decode(data); + return getDecoder().decode(sis); } catch (IOException ex) { return null; } } - public boolean decode(byte[] data, OutputStream os) { + public boolean decode(SWFInputStream sis, OutputStream os) { try { - getDecoder().decode(data, os); + getDecoder().decode(sis, os); return true; } catch (IOException ex) { return false; } } - public boolean play(byte[] data) { + public boolean play(SWFInputStream sis) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); - if (!decode(data, baos)) { + if (!decode(sis, baos)) { return false; } @@ -161,10 +162,10 @@ public class SoundFormat { } } - public boolean createWav(byte[] data, OutputStream os) { + public boolean createWav(SWFInputStream sis, OutputStream os) { ensureFormat(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - decode(data, baos); + decode(sis, baos); try { createWavFromPcmData(os, samplingRate, true, stereo, baos.toByteArray()); return true; diff --git a/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java b/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java index eeb24ec0c..06ef07967 100644 --- a/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java +++ b/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java @@ -1437,9 +1437,9 @@ public class XFLConverter { bits = 18; } if (soundFormat == SoundFormat.FORMAT_ADPCM) { - SWFInputStream sis = new SWFInputStream(swf, soundData); exportFormat = "wav"; try { + SWFInputStream sis = new SWFInputStream(swf, soundData); int adpcmCodeSize = (int) sis.readUB(2); bits = 2 + adpcmCodeSize; } catch (IOException ex) { @@ -1453,7 +1453,7 @@ public class XFLConverter { } format += 4; //quality best try { - MP3SOUNDDATA s = new MP3SOUNDDATA(swf, soundData, false); + MP3SOUNDDATA s = new MP3SOUNDDATA(new SWFInputStream(swf, soundData), false); //sis.readSI16(); //MP3FRAME frame = new MP3FRAME(sis); MP3FRAME frame = s.frames.get(0); diff --git a/src/com/jpexs/helpers/MemoryInputStream.java b/src/com/jpexs/helpers/MemoryInputStream.java index 69ceecf24..abc28118b 100644 --- a/src/com/jpexs/helpers/MemoryInputStream.java +++ b/src/com/jpexs/helpers/MemoryInputStream.java @@ -1,110 +1,99 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.helpers; - -import com.jpexs.helpers.streams.SeekableInputStream; -import java.io.IOException; - -/** - * - * @author JPEXS - */ -public class MemoryInputStream extends SeekableInputStream { - - private final byte[] buffer; - private long pos = 0; - private int count = 0; - private int startPos = 0; - private int maxLength = -1; - - public MemoryInputStream(byte[] buffer) { - this.buffer = buffer; - } - - public MemoryInputStream(byte[] buffer, int startPos) throws IOException { - this.buffer = buffer; - if (startPos >= buffer.length) { - throw new IOException("Invalid startPos"); - } - this.startPos = startPos; - } - - public MemoryInputStream(byte[] buffer, int startPos, int maxLength) throws IOException { - this.buffer = buffer; - this.startPos = startPos; - if (startPos >= buffer.length) { - throw new IOException("Invalid startPos"); - } - this.maxLength = maxLength; - if (startPos + maxLength >= buffer.length) { - this.maxLength = buffer.length - startPos - 1; - } - } - - public int getCount() { - return count; - } - - public byte[] getAllRead() { - return buffer; - } - - public long getPos() { - return pos; - } - - @Override - public void seek(long pos) throws IOException { - this.pos = pos; - } - - @Override - public synchronized void reset() throws IOException { - seek(0); - } - - @Override - public int read() throws IOException { - if (pos > count) { - count = (int) pos; - } - - if (pos < getLength()) { - int ret = buffer[(int) pos + startPos] & 0xff; - pos++; - return ret; - } - - return -1; - } - - private int getLength() { - if (maxLength == -1) { - return buffer.length - startPos; - } - return maxLength; - } - - @Override - public int available() throws IOException { - return buffer.length - (int) pos; - } - - public long length() throws IOException { - return buffer.length; - } -} +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.helpers; + +import com.jpexs.helpers.streams.SeekableInputStream; +import java.io.IOException; + +/** + * + * @author JPEXS + */ +public class MemoryInputStream extends SeekableInputStream { + + private final byte[] buffer; + private long pos; + private int count; + private int startPos; + private int maxLength; + + public MemoryInputStream(byte[] buffer) throws IOException { + this(buffer, 0, buffer.length); + } + + public MemoryInputStream(byte[] buffer, int startPos) throws IOException { + this(buffer, startPos, buffer.length - startPos); + } + + public MemoryInputStream(byte[] buffer, int startPos, int maxLength) throws IOException { + this.buffer = buffer; + this.startPos = startPos; + if (startPos >= buffer.length) { + throw new IOException("Invalid startPos"); + } + this.maxLength = maxLength; + if (startPos + maxLength >= buffer.length) { + this.maxLength = buffer.length - startPos; + } + } + + public int getCount() { + return count; + } + + public byte[] getAllRead() { + return buffer; + } + + public long getPos() { + return pos; + } + + @Override + public void seek(long pos) throws IOException { + this.pos = pos; + } + + @Override + public synchronized void reset() throws IOException { + seek(0); + } + + @Override + public int read() throws IOException { + if (pos > count) { + count = (int) pos; + } + + if (pos < length()) { + int ret = buffer[(int) pos + startPos] & 0xff; + pos++; + return ret; + } + + return -1; + } + + private int length() { + return maxLength; + } + + @Override + public int available() throws IOException { + return maxLength - (int) pos; + } +} diff --git a/src/com/jpexs/helpers/StreamSearch.java b/src/com/jpexs/helpers/StreamSearch.java index 1020bcff4..4912201aa 100644 --- a/src/com/jpexs/helpers/StreamSearch.java +++ b/src/com/jpexs/helpers/StreamSearch.java @@ -1,104 +1,104 @@ -/* - * Copyright (C) 2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.helpers; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * - * @author JPEXS - */ -public class StreamSearch implements Searchable { - - private final MemoryInputStream is; - - public StreamSearch(InputStream is) { - this.is = new MemoryInputStream(Helper.readStream(is)); - } - - @Override - public Map search(byte[] - ... data) { - return search(null, data); - } - - @Override - public Map search(ProgressListener progListener, byte[] - ... data) { - Map ret = new HashMap<>(); - int maxFindLen = 0; - for (int i = 0; i < data.length; i++) { - if (data[i].length > maxFindLen) { - maxFindLen = data[i].length; - } - } - try { - is.seek(0); - - byte[] buf = new byte[4096]; - byte[] last = null; - int cnt = 0; - long pos = 0; - while ((cnt = is.read(buf)) > 0) { - - for (int i = -maxFindLen + 1; i < cnt; i++) { - - loopdata: - for (byte[] onedata : data) { - boolean match = true; - for (int d = 0; d < onedata.length; d++) { - byte b; - if (i + d < 0) { - if (last != null) { - b = last[last.length + i + d]; - } else { - continue; - } - } else if (i + d >= buf.length) { - continue; - } else { - b = buf[i + d]; - } - - if (b != onedata[d]) { - match = false; - break; - } - } - if (match) { - // todo: support > 2GB files - InputStream fis = new MemoryInputStream(is.getAllRead(), (int) pos + i); - ret.put(pos + i, fis); - continue loopdata; - } - } - } - pos = pos + cnt; - } - - } catch (IOException ex) { - Logger.getLogger(StreamSearch.class.getName()).log(Level.SEVERE, null, ex); - } - return ret; - } - -} +/* + * Copyright (C) 2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.helpers; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author JPEXS + */ +public class StreamSearch implements Searchable { + + private final MemoryInputStream is; + + public StreamSearch(InputStream is) throws IOException { + this.is = new MemoryInputStream(Helper.readStream(is)); + } + + @Override + public Map search(byte[] + ... data) { + return search(null, data); + } + + @Override + public Map search(ProgressListener progListener, byte[] + ... data) { + Map ret = new HashMap<>(); + int maxFindLen = 0; + for (int i = 0; i < data.length; i++) { + if (data[i].length > maxFindLen) { + maxFindLen = data[i].length; + } + } + try { + is.seek(0); + + byte[] buf = new byte[4096]; + byte[] last = null; + int cnt = 0; + long pos = 0; + while ((cnt = is.read(buf)) > 0) { + + for (int i = -maxFindLen + 1; i < cnt; i++) { + + loopdata: + for (byte[] onedata : data) { + boolean match = true; + for (int d = 0; d < onedata.length; d++) { + byte b; + if (i + d < 0) { + if (last != null) { + b = last[last.length + i + d]; + } else { + continue; + } + } else if (i + d >= buf.length) { + continue; + } else { + b = buf[i + d]; + } + + if (b != onedata[d]) { + match = false; + break; + } + } + if (match) { + // todo: support > 2GB files + InputStream fis = new MemoryInputStream(is.getAllRead(), (int) pos + i); + ret.put(pos + i, fis); + continue loopdata; + } + } + } + pos = pos + cnt; + } + + } catch (IOException ex) { + Logger.getLogger(StreamSearch.class.getName()).log(Level.SEVERE, null, ex); + } + return ret; + } + +} diff --git a/src/com/jpexs/helpers/SwfHeaderStreamSearch.java b/src/com/jpexs/helpers/SwfHeaderStreamSearch.java index a968f0515..41f2ad30f 100644 --- a/src/com/jpexs/helpers/SwfHeaderStreamSearch.java +++ b/src/com/jpexs/helpers/SwfHeaderStreamSearch.java @@ -1,81 +1,81 @@ -/* - * Copyright (C) 2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.helpers; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * - * @author JPEXS - */ -public class SwfHeaderStreamSearch implements Searchable { - - private final MemoryInputStream is; - - public SwfHeaderStreamSearch(InputStream is) { - this.is = new MemoryInputStream(Helper.readStream(is)); - } - - @Override - public Map search(byte[] - ... data) { - return search(null, data); - } - - @Override - public Map search(ProgressListener progListener, byte[] - ... data) { - // Ignore data parameter, find only FWS, CWS, ZWS, GFX and CFX - - Map ret = new HashMap<>(); - byte[] buf = is.getAllRead(); - byte byte2 = buf[0], byte3 = buf[1]; - boolean match = false; - for (int i = 2; i < buf.length - 2; i++) { - byte b = byte2; - byte2 = byte3; - byte3 = buf[i]; - if (byte2 == 'W' && byte3 == 'S') { - if (b == 'F' || b == 'C' || b == 'Z') { - match = true; - } - } else if (byte2 == 'F' && byte3 == 'X') { - if (b == 'G' || b == 'C') { - match = true; - } - } - if (match) { - // todo: support > 2GB files - InputStream fis; - try { - fis = new MemoryInputStream(buf, i - 2); - ret.put((long) i - 2, fis); - match = false; - } catch (IOException ex) { - Logger.getLogger(SwfHeaderStreamSearch.class.getName()).log(Level.SEVERE, null, ex); - } - } - } - return ret; - } - -} +/* + * Copyright (C) 2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.helpers; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author JPEXS + */ +public class SwfHeaderStreamSearch implements Searchable { + + private final MemoryInputStream is; + + public SwfHeaderStreamSearch(InputStream is) throws IOException { + this.is = new MemoryInputStream(Helper.readStream(is)); + } + + @Override + public Map search(byte[] + ... data) { + return search(null, data); + } + + @Override + public Map search(ProgressListener progListener, byte[] + ... data) { + // Ignore data parameter, find only FWS, CWS, ZWS, GFX and CFX + + Map ret = new HashMap<>(); + byte[] buf = is.getAllRead(); + byte byte2 = buf[0], byte3 = buf[1]; + boolean match = false; + for (int i = 2; i < buf.length - 2; i++) { + byte b = byte2; + byte2 = byte3; + byte3 = buf[i]; + if (byte2 == 'W' && byte3 == 'S') { + if (b == 'F' || b == 'C' || b == 'Z') { + match = true; + } + } else if (byte2 == 'F' && byte3 == 'X') { + if (b == 'G' || b == 'C') { + match = true; + } + } + if (match) { + // todo: support > 2GB files + InputStream fis; + try { + fis = new MemoryInputStream(buf, i - 2); + ret.put((long) i - 2, fis); + match = false; + } catch (IOException ex) { + Logger.getLogger(SwfHeaderStreamSearch.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + return ret; + } + +}