mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-17 21:38:10 +00:00
tag names moved to constants
This commit is contained in:
@@ -2564,7 +2564,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
FILLSTYLEARRAY ret = new FILLSTYLEARRAY();
|
||||
newDumpLevel(name, "FILLSTYLEARRAY");
|
||||
int fillStyleCount = readUI8("fillStyleCount");
|
||||
if (((shapeNum == 2) || (shapeNum == 3) || (shapeNum == 4/*?*/)) && (fillStyleCount == 0xff)) {
|
||||
if (shapeNum > 1 && fillStyleCount == 0xff) {
|
||||
fillStyleCount = readUI16("fillStyleCount");
|
||||
}
|
||||
ret.fillStyles = new FILLSTYLE[fillStyleCount];
|
||||
@@ -2645,7 +2645,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
if (lineStyleCount == 0xff) {
|
||||
lineStyleCount = readUI16("lineStyleCount");
|
||||
}
|
||||
if ((shapeNum == 1 || shapeNum == 2 || shapeNum == 3)) {
|
||||
if (shapeNum <= 3) {
|
||||
ret.lineStyles = new LINESTYLE[lineStyleCount];
|
||||
for (int i = 0; i < lineStyleCount; i++) {
|
||||
ret.lineStyles[i] = readLINESTYLE(shapeNum, "lineStyle");
|
||||
|
||||
@@ -1186,7 +1186,7 @@ public class SWFOutputStream extends OutputStream {
|
||||
*/
|
||||
public void writeFILLSTYLEARRAY(FILLSTYLEARRAY value, int shapeNum) throws IOException {
|
||||
int fillStyleCount = value.fillStyles.length;
|
||||
if (shapeNum == 2 || shapeNum == 3) {
|
||||
if (shapeNum > 1) {
|
||||
if (fillStyleCount >= 0xff) {
|
||||
writeUI8(0xff);
|
||||
writeUI16(fillStyleCount);
|
||||
@@ -1303,7 +1303,7 @@ public class SWFOutputStream extends OutputStream {
|
||||
*/
|
||||
public void writeLINESTYLEARRAY(LINESTYLEARRAY value, int shapeNum) throws IOException {
|
||||
int lineStyleCount;
|
||||
if (shapeNum == 1 || shapeNum == 2 || shapeNum == 3) {
|
||||
if (shapeNum <= 3) {
|
||||
lineStyleCount = value.lineStyles.length;
|
||||
if (lineStyleCount >= 0xff) {
|
||||
writeUI8(0xff);
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.TagInfo;
|
||||
import com.jpexs.decompiler.flash.types.ALPHABITMAPDATA;
|
||||
import com.jpexs.decompiler.flash.types.ALPHACOLORMAPDATA;
|
||||
import com.jpexs.decompiler.flash.types.ARGB;
|
||||
@@ -240,9 +241,9 @@ public class SwfXmlImporter {
|
||||
private Object createObject(String type, SWF swf, Tag tag) throws NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||
if (swfTags == null) {
|
||||
Map<String, Class> tags = new HashMap<>();
|
||||
Map<Integer, Class> knownTags = Tag.getKnownClasses();
|
||||
Map<Integer, TagInfo> knownTags = Tag.getKnownClasses();
|
||||
for (Integer key : knownTags.keySet()) {
|
||||
Class cls = knownTags.get(key);
|
||||
Class cls = knownTags.get(key).cls;
|
||||
if (!ReflectionTools.canInstantiate(cls)) {
|
||||
System.err.println("Can't instantiate: " + cls.getName());
|
||||
}
|
||||
|
||||
@@ -1,127 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class CSMTextSettingsTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int textID;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int useFlashType;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 3)
|
||||
public int gridFit;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 3)
|
||||
public int reserved;
|
||||
|
||||
@SWFType(value = BasicType.FLOAT) //F32 = FLOAT
|
||||
public float thickness;
|
||||
|
||||
@SWFType(value = BasicType.FLOAT) //F32 = FLOAT
|
||||
public float sharpness;
|
||||
|
||||
@Reserved
|
||||
@SWFType(BasicType.UI8)
|
||||
public int reserved2;
|
||||
|
||||
public static final int ID = 74;
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(textID);
|
||||
sos.writeUB(2, useFlashType);
|
||||
sos.writeUB(3, gridFit);
|
||||
sos.writeUB(3, reserved);
|
||||
sos.writeFLOAT(thickness); //F32 = FLOAT
|
||||
sos.writeFLOAT(sharpness); //F32 = FLOAT
|
||||
sos.writeUI8(reserved2);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public CSMTextSettingsTag(SWF swf) {
|
||||
super(swf, ID, "CSMTextSettings", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public CSMTextSettingsTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "CSMTextSettings", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
textID = sis.readUI16("textID");
|
||||
useFlashType = (int) sis.readUB(2, "useFlashType");
|
||||
gridFit = (int) sis.readUB(3, "gridFit");
|
||||
reserved = (int) sis.readUB(3, "reserved");
|
||||
thickness = sis.readFLOAT("thickness"); //F32 = FLOAT
|
||||
sharpness = sis.readFLOAT("sharpness"); //F32 = FLOAT
|
||||
reserved2 = sis.readUI8("reserved2"); //reserved
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return textID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.textID = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class CSMTextSettingsTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int textID;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int useFlashType;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 3)
|
||||
public int gridFit;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 3)
|
||||
public int reserved;
|
||||
|
||||
@SWFType(value = BasicType.FLOAT) //F32 = FLOAT
|
||||
public float thickness;
|
||||
|
||||
@SWFType(value = BasicType.FLOAT) //F32 = FLOAT
|
||||
public float sharpness;
|
||||
|
||||
@Reserved
|
||||
@SWFType(BasicType.UI8)
|
||||
public int reserved2;
|
||||
|
||||
public static final int ID = 74;
|
||||
|
||||
public static final String NAME = "CSMTextSettings";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(textID);
|
||||
sos.writeUB(2, useFlashType);
|
||||
sos.writeUB(3, gridFit);
|
||||
sos.writeUB(3, reserved);
|
||||
sos.writeFLOAT(thickness); //F32 = FLOAT
|
||||
sos.writeFLOAT(sharpness); //F32 = FLOAT
|
||||
sos.writeUI8(reserved2);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public CSMTextSettingsTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public CSMTextSettingsTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
textID = sis.readUI16("textID");
|
||||
useFlashType = (int) sis.readUB(2, "useFlashType");
|
||||
gridFit = (int) sis.readUB(3, "gridFit");
|
||||
reserved = (int) sis.readUB(3, "reserved");
|
||||
thickness = sis.readFLOAT("thickness"); //F32 = FLOAT
|
||||
sharpness = sis.readFLOAT("sharpness"); //F32 = FLOAT
|
||||
reserved2 = sis.readUI8("reserved2"); //reserved
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return textID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.textID = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ public class DebugIDTag extends Tag {
|
||||
|
||||
public static final int ID = 63;
|
||||
|
||||
public static final String NAME = "DebugID";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
@@ -61,7 +63,7 @@ public class DebugIDTag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public DebugIDTag(SWF swf) {
|
||||
super(swf, ID, "DebugID", null);
|
||||
super(swf, ID, NAME, null);
|
||||
debugId = new byte[16];
|
||||
}
|
||||
|
||||
@@ -73,7 +75,7 @@ public class DebugIDTag extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public DebugIDTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DebugID", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,151 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineBinaryDataTag extends CharacterTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int tag;
|
||||
|
||||
public ByteArrayRange binaryData;
|
||||
|
||||
@Reserved
|
||||
@SWFType(BasicType.UI32)
|
||||
public long reserved;
|
||||
|
||||
public static final int ID = 87;
|
||||
|
||||
@Internal
|
||||
public SWF innerSwf;
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(tag);
|
||||
sos.writeUI32(reserved);
|
||||
sos.write(binaryData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBinaryDataTag(SWF swf) {
|
||||
super(swf, ID, "DefineBinaryData", null);
|
||||
tag = swf.getNextCharacterId();
|
||||
binaryData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
public DefineBinaryDataTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineBinaryData", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
tag = sis.readUI16("tag");
|
||||
reserved = sis.readUI32("reserved");
|
||||
binaryData = sis.readByteRangeEx(sis.available(), "binaryData");
|
||||
|
||||
if (Configuration.autoLoadEmbeddedSwfs.get()) {
|
||||
try {
|
||||
InputStream is = new ByteArrayInputStream(binaryData.getArray(), binaryData.getPos(), binaryData.getLength());
|
||||
SWF bswf = new SWF(is, null, "(SWF Data)", Configuration.parallelSpeedUp.get());
|
||||
innerSwf = bswf;
|
||||
bswf.binaryData = this;
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.tag = characterId;
|
||||
}
|
||||
|
||||
public boolean isSwfData() {
|
||||
try {
|
||||
if (binaryData.getLength() > 8) {
|
||||
String signature = new String(binaryData.getRangeData(0, 3), Utf8Helper.charset);
|
||||
if (Arrays.asList(
|
||||
"FWS", //Uncompressed Flash
|
||||
"CWS", //ZLib compressed Flash
|
||||
"ZWS", //LZMA compressed Flash
|
||||
"GFX", //Uncompressed ScaleForm GFx
|
||||
"CFX" //Compressed ScaleForm GFx
|
||||
).contains(signature)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
if (super.isModified()) {
|
||||
return true;
|
||||
}
|
||||
if (innerSwf != null) {
|
||||
return innerSwf.isModified();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineBinaryDataTag extends CharacterTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int tag;
|
||||
|
||||
public ByteArrayRange binaryData;
|
||||
|
||||
@Reserved
|
||||
@SWFType(BasicType.UI32)
|
||||
public long reserved;
|
||||
|
||||
public static final int ID = 87;
|
||||
|
||||
public static final String NAME = "DefineBinaryData";
|
||||
|
||||
@Internal
|
||||
public SWF innerSwf;
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(tag);
|
||||
sos.writeUI32(reserved);
|
||||
sos.write(binaryData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBinaryDataTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
tag = swf.getNextCharacterId();
|
||||
binaryData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
public DefineBinaryDataTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
tag = sis.readUI16("tag");
|
||||
reserved = sis.readUI32("reserved");
|
||||
binaryData = sis.readByteRangeEx(sis.available(), "binaryData");
|
||||
|
||||
if (Configuration.autoLoadEmbeddedSwfs.get()) {
|
||||
try {
|
||||
InputStream is = new ByteArrayInputStream(binaryData.getArray(), binaryData.getPos(), binaryData.getLength());
|
||||
SWF bswf = new SWF(is, null, "(SWF Data)", Configuration.parallelSpeedUp.get());
|
||||
innerSwf = bswf;
|
||||
bswf.binaryData = this;
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.tag = characterId;
|
||||
}
|
||||
|
||||
public boolean isSwfData() {
|
||||
try {
|
||||
if (binaryData.getLength() > 8) {
|
||||
String signature = new String(binaryData.getRangeData(0, 3), Utf8Helper.charset);
|
||||
if (Arrays.asList(
|
||||
"FWS", //Uncompressed Flash
|
||||
"CWS", //ZLib compressed Flash
|
||||
"ZWS", //LZMA compressed Flash
|
||||
"GFX", //Uncompressed ScaleForm GFx
|
||||
"CFX" //Compressed ScaleForm GFx
|
||||
).contains(signature)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
if (super.isModified()) {
|
||||
return true;
|
||||
}
|
||||
if (innerSwf != null) {
|
||||
return innerSwf.isModified();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,142 +1,144 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.AloneTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterID;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public ByteArrayRange imageData;
|
||||
|
||||
public static final int ID = 21;
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterID = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageFormat() {
|
||||
return ImageTag.getImageFormat(imageData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getImageData() {
|
||||
int errorLength = hasErrorHeader(imageData) ? 4 : 0;
|
||||
return new ByteArrayInputStream(imageData.getArray(), imageData.getPos() + errorLength, imageData.getLength() - errorLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializableImage getImage() {
|
||||
if (cachedImage != null) {
|
||||
return cachedImage;
|
||||
}
|
||||
try {
|
||||
BufferedImage image = ImageHelper.read(getImageData());
|
||||
if (image == null) {
|
||||
Logger.getLogger(DefineBitsJPEG2Tag.class.getName()).log(Level.SEVERE, "Failed to load image");
|
||||
return null;
|
||||
}
|
||||
|
||||
SerializableImage ret = new SerializableImage(image);
|
||||
cachedImage = ret;
|
||||
return ret;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsJPEG2Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBitsJPEG2Tag(SWF swf) {
|
||||
super(swf, ID, "DefineBitsJPEG2", null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
imageData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
public DefineBitsJPEG2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineBitsJPEG2", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterID = sis.readUI16("characterID");
|
||||
imageData = sis.readByteRangeEx(sis.available(), "imageData");
|
||||
}
|
||||
|
||||
public DefineBitsJPEG2Tag(SWF swf, ByteArrayRange data, int characterID, byte[] imageData) throws IOException {
|
||||
super(swf, ID, "DefineBitsJPEG2", data);
|
||||
this.characterID = characterID;
|
||||
this.imageData = new ByteArrayRange(imageData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(byte[] data) {
|
||||
imageData = new ByteArrayRange(data);
|
||||
clearCache();
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterID);
|
||||
sos.write(imageData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.AloneTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterID;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public ByteArrayRange imageData;
|
||||
|
||||
public static final int ID = 21;
|
||||
|
||||
public static final String NAME = "DefineBitsJPEG2";
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterID = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageFormat() {
|
||||
return ImageTag.getImageFormat(imageData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getImageData() {
|
||||
int errorLength = hasErrorHeader(imageData) ? 4 : 0;
|
||||
return new ByteArrayInputStream(imageData.getArray(), imageData.getPos() + errorLength, imageData.getLength() - errorLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializableImage getImage() {
|
||||
if (cachedImage != null) {
|
||||
return cachedImage;
|
||||
}
|
||||
try {
|
||||
BufferedImage image = ImageHelper.read(getImageData());
|
||||
if (image == null) {
|
||||
Logger.getLogger(DefineBitsJPEG2Tag.class.getName()).log(Level.SEVERE, "Failed to load image");
|
||||
return null;
|
||||
}
|
||||
|
||||
SerializableImage ret = new SerializableImage(image);
|
||||
cachedImage = ret;
|
||||
return ret;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsJPEG2Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBitsJPEG2Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
imageData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
public DefineBitsJPEG2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterID = sis.readUI16("characterID");
|
||||
imageData = sis.readByteRangeEx(sis.available(), "imageData");
|
||||
}
|
||||
|
||||
public DefineBitsJPEG2Tag(SWF swf, ByteArrayRange data, int characterID, byte[] imageData) throws IOException {
|
||||
super(swf, ID, NAME, data);
|
||||
this.characterID = characterID;
|
||||
this.imageData = new ByteArrayRange(imageData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(byte[] data) {
|
||||
imageData = new ByteArrayRange(data);
|
||||
clearCache();
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterID);
|
||||
sos.write(imageData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,175 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.AloneTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterID;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public ByteArrayRange imageData;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public byte[] bitmapAlphaData;
|
||||
|
||||
public static final int ID = 35;
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterID = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(byte[] data) throws IOException {
|
||||
if (ImageTag.getImageFormat(data).equals("jpg")) {
|
||||
SerializableImage image = new SerializableImage(ImageHelper.read(data));
|
||||
byte[] ba = new byte[image.getWidth() * image.getHeight()];
|
||||
for (int i = 0; i < ba.length; i++) {
|
||||
ba[i] = (byte) 255;
|
||||
}
|
||||
bitmapAlphaData = ba;
|
||||
} else {
|
||||
bitmapAlphaData = new byte[0];
|
||||
}
|
||||
imageData = new ByteArrayRange(data);
|
||||
clearCache();
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageFormat() {
|
||||
String fmt = ImageTag.getImageFormat(imageData);
|
||||
if (fmt.equals("jpg")) {
|
||||
fmt = "png"; //transparency
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getImageData() {
|
||||
int errorLength = hasErrorHeader(imageData) ? 4 : 0;
|
||||
return new ByteArrayInputStream(imageData.getArray(), imageData.getPos() + errorLength, imageData.getLength() - errorLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializableImage getImage() {
|
||||
if (cachedImage != null) {
|
||||
return cachedImage;
|
||||
}
|
||||
try {
|
||||
BufferedImage image = ImageHelper.read(getImageData());
|
||||
if (image == null) {
|
||||
Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to load image");
|
||||
return null;
|
||||
}
|
||||
|
||||
SerializableImage img = new SerializableImage(image);
|
||||
if (bitmapAlphaData.length == 0) {
|
||||
cachedImage = img;
|
||||
return img;
|
||||
}
|
||||
|
||||
int[] pixels = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
|
||||
for (int i = 0; i < pixels.length; i++) {
|
||||
int a = bitmapAlphaData[i] & 0xff;
|
||||
pixels[i] = multiplyAlpha((pixels[i] & 0xffffff) | (a << 24));
|
||||
}
|
||||
|
||||
cachedImage = img;
|
||||
return img;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBitsJPEG3Tag(SWF swf) {
|
||||
super(swf, ID, "DefineBitsJPEG3", null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
imageData = ByteArrayRange.EMPTY;
|
||||
bitmapAlphaData = new byte[0];
|
||||
}
|
||||
|
||||
public DefineBitsJPEG3Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineBitsJPEG3", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterID = sis.readUI16("characterID");
|
||||
long alphaDataOffset = sis.readUI32("alphaDataOffset");
|
||||
imageData = sis.readByteRangeEx(alphaDataOffset, "imageData");
|
||||
bitmapAlphaData = sis.readBytesZlib(sis.available(), "bitmapAlphaData");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterID);
|
||||
sos.writeUI32(imageData.getLength());
|
||||
sos.write(imageData);
|
||||
sos.writeBytesZlib(bitmapAlphaData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.AloneTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterID;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public ByteArrayRange imageData;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public byte[] bitmapAlphaData;
|
||||
|
||||
public static final int ID = 35;
|
||||
|
||||
public static final String NAME = "DefineBitsJPEG3";
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterID = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(byte[] data) throws IOException {
|
||||
if (ImageTag.getImageFormat(data).equals("jpg")) {
|
||||
SerializableImage image = new SerializableImage(ImageHelper.read(data));
|
||||
byte[] ba = new byte[image.getWidth() * image.getHeight()];
|
||||
for (int i = 0; i < ba.length; i++) {
|
||||
ba[i] = (byte) 255;
|
||||
}
|
||||
bitmapAlphaData = ba;
|
||||
} else {
|
||||
bitmapAlphaData = new byte[0];
|
||||
}
|
||||
imageData = new ByteArrayRange(data);
|
||||
clearCache();
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageFormat() {
|
||||
String fmt = ImageTag.getImageFormat(imageData);
|
||||
if (fmt.equals("jpg")) {
|
||||
fmt = "png"; //transparency
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getImageData() {
|
||||
int errorLength = hasErrorHeader(imageData) ? 4 : 0;
|
||||
return new ByteArrayInputStream(imageData.getArray(), imageData.getPos() + errorLength, imageData.getLength() - errorLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializableImage getImage() {
|
||||
if (cachedImage != null) {
|
||||
return cachedImage;
|
||||
}
|
||||
try {
|
||||
BufferedImage image = ImageHelper.read(getImageData());
|
||||
if (image == null) {
|
||||
Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to load image");
|
||||
return null;
|
||||
}
|
||||
|
||||
SerializableImage img = new SerializableImage(image);
|
||||
if (bitmapAlphaData.length == 0) {
|
||||
cachedImage = img;
|
||||
return img;
|
||||
}
|
||||
|
||||
int[] pixels = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
|
||||
for (int i = 0; i < pixels.length; i++) {
|
||||
int a = bitmapAlphaData[i] & 0xff;
|
||||
pixels[i] = multiplyAlpha((pixels[i] & 0xffffff) | (a << 24));
|
||||
}
|
||||
|
||||
cachedImage = img;
|
||||
return img;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBitsJPEG3Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
imageData = ByteArrayRange.EMPTY;
|
||||
bitmapAlphaData = new byte[0];
|
||||
}
|
||||
|
||||
public DefineBitsJPEG3Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterID = sis.readUI16("characterID");
|
||||
long alphaDataOffset = sis.readUI32("alphaDataOffset");
|
||||
imageData = sis.readByteRangeEx(alphaDataOffset, "imageData");
|
||||
bitmapAlphaData = sis.readBytesZlib(sis.available(), "bitmapAlphaData");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterID);
|
||||
sos.writeUI32(imageData.getLength());
|
||||
sos.write(imageData);
|
||||
sos.writeBytesZlib(bitmapAlphaData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,186 +1,188 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.AloneTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterID;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int deblockParam;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public ByteArrayRange imageData;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public ByteArrayRange bitmapAlphaData;
|
||||
|
||||
public static final int ID = 90;
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterID = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageFormat() {
|
||||
String fmt = ImageTag.getImageFormat(imageData);
|
||||
if (fmt.equals("jpg")) {
|
||||
fmt = "png"; //transparency
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(byte[] data) {
|
||||
imageData = new ByteArrayRange(data);
|
||||
if (ImageTag.getImageFormat(data).equals("jpg")) {
|
||||
SerializableImage image = getImage();
|
||||
byte[] ba = new byte[image.getWidth() * image.getHeight()];
|
||||
for (int i = 0; i < ba.length; i++) {
|
||||
ba[i] = (byte) 255;
|
||||
}
|
||||
bitmapAlphaData = new ByteArrayRange(ba);
|
||||
} else {
|
||||
bitmapAlphaData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
clearCache();
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getImageData() {
|
||||
return new ByteArrayInputStream(imageData.getArray(), imageData.getPos(), imageData.getLength());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializableImage getImage() {
|
||||
if (cachedImage != null) {
|
||||
return cachedImage;
|
||||
}
|
||||
try {
|
||||
BufferedImage image = ImageHelper.read(getImageData());
|
||||
if (image == null) {
|
||||
Logger.getLogger(DefineBitsJPEG4Tag.class.getName()).log(Level.SEVERE, "Failed to load image");
|
||||
return null;
|
||||
}
|
||||
|
||||
SerializableImage img = new SerializableImage(image);
|
||||
if (bitmapAlphaData.getLength() == 0) {
|
||||
cachedImage = img;
|
||||
return img;
|
||||
}
|
||||
|
||||
int[] pixels = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
|
||||
for (int i = 0; i < pixels.length; i++) {
|
||||
int a = bitmapAlphaData.get(i) & 0xff;
|
||||
pixels[i] = multiplyAlpha((pixels[i] & 0xffffff) | (a << 24));
|
||||
}
|
||||
|
||||
cachedImage = img;
|
||||
return img;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsJPEG4Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterID);
|
||||
sos.writeUI32(imageData.getLength());
|
||||
sos.writeUI16(deblockParam);
|
||||
sos.write(imageData);
|
||||
sos.write(bitmapAlphaData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBitsJPEG4Tag(SWF swf) {
|
||||
super(swf, ID, "DefineBitsJPEG4", null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
imageData = ByteArrayRange.EMPTY;
|
||||
bitmapAlphaData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineBitsJPEG4Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineBitsJPEG4", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterID = sis.readUI16("characterID");
|
||||
long alphaDataOffset = sis.readUI32("alphaDataOffset");
|
||||
deblockParam = sis.readUI16("deblockParam");
|
||||
imageData = sis.readByteRangeEx(alphaDataOffset, "imageData");
|
||||
bitmapAlphaData = sis.readByteRangeEx(sis.available(), "bitmapAlphaData");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.AloneTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterID;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int deblockParam;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public ByteArrayRange imageData;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public ByteArrayRange bitmapAlphaData;
|
||||
|
||||
public static final int ID = 90;
|
||||
|
||||
public static final String NAME = "DefineBitsJPEG4";
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterID = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageFormat() {
|
||||
String fmt = ImageTag.getImageFormat(imageData);
|
||||
if (fmt.equals("jpg")) {
|
||||
fmt = "png"; //transparency
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(byte[] data) {
|
||||
imageData = new ByteArrayRange(data);
|
||||
if (ImageTag.getImageFormat(data).equals("jpg")) {
|
||||
SerializableImage image = getImage();
|
||||
byte[] ba = new byte[image.getWidth() * image.getHeight()];
|
||||
for (int i = 0; i < ba.length; i++) {
|
||||
ba[i] = (byte) 255;
|
||||
}
|
||||
bitmapAlphaData = new ByteArrayRange(ba);
|
||||
} else {
|
||||
bitmapAlphaData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
clearCache();
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getImageData() {
|
||||
return new ByteArrayInputStream(imageData.getArray(), imageData.getPos(), imageData.getLength());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializableImage getImage() {
|
||||
if (cachedImage != null) {
|
||||
return cachedImage;
|
||||
}
|
||||
try {
|
||||
BufferedImage image = ImageHelper.read(getImageData());
|
||||
if (image == null) {
|
||||
Logger.getLogger(DefineBitsJPEG4Tag.class.getName()).log(Level.SEVERE, "Failed to load image");
|
||||
return null;
|
||||
}
|
||||
|
||||
SerializableImage img = new SerializableImage(image);
|
||||
if (bitmapAlphaData.getLength() == 0) {
|
||||
cachedImage = img;
|
||||
return img;
|
||||
}
|
||||
|
||||
int[] pixels = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
|
||||
for (int i = 0; i < pixels.length; i++) {
|
||||
int a = bitmapAlphaData.get(i) & 0xff;
|
||||
pixels[i] = multiplyAlpha((pixels[i] & 0xffffff) | (a << 24));
|
||||
}
|
||||
|
||||
cachedImage = img;
|
||||
return img;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsJPEG4Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterID);
|
||||
sos.writeUI32(imageData.getLength());
|
||||
sos.writeUI16(deblockParam);
|
||||
sos.write(imageData);
|
||||
sos.write(bitmapAlphaData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBitsJPEG4Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
imageData = ByteArrayRange.EMPTY;
|
||||
bitmapAlphaData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineBitsJPEG4Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterID = sis.readUI16("characterID");
|
||||
long alphaDataOffset = sis.readUI32("alphaDataOffset");
|
||||
deblockParam = sis.readUI16("deblockParam");
|
||||
imageData = sis.readByteRangeEx(alphaDataOffset, "imageData");
|
||||
bitmapAlphaData = sis.readByteRangeEx(sis.available(), "bitmapAlphaData");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,8 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
|
||||
|
||||
public static final int ID = 36;
|
||||
|
||||
public static final String NAME = "DefineBitsLossless2";
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterID;
|
||||
@@ -152,7 +154,7 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBitsLossless2Tag(SWF swf) {
|
||||
super(swf, ID, "DefineBitsLossless2", null);
|
||||
super(swf, ID, NAME, null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
bitmapFormat = DefineBitsLossless2Tag.FORMAT_32BIT_ARGB;
|
||||
bitmapWidth = 1;
|
||||
@@ -161,7 +163,7 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
|
||||
}
|
||||
|
||||
public DefineBitsLossless2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineBitsLossless2", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,8 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
|
||||
|
||||
public static final int ID = 20;
|
||||
|
||||
public static final String NAME = "DefineBitsLossless";
|
||||
|
||||
private byte[] createEmptyImage() {
|
||||
try {
|
||||
BITMAPDATA bitmapData = new BITMAPDATA();
|
||||
@@ -230,7 +232,7 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBitsLosslessTag(SWF swf) {
|
||||
super(swf, ID, "DefineBitsLossless", null);
|
||||
super(swf, ID, NAME, null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
bitmapFormat = DefineBitsLosslessTag.FORMAT_24BIT_RGB;
|
||||
bitmapWidth = 1;
|
||||
@@ -239,7 +241,7 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
|
||||
}
|
||||
|
||||
public DefineBitsLosslessTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineBitsLossless", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,158 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineBitsTag extends ImageTag implements TagChangedListener {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterID;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public ByteArrayRange jpegData;
|
||||
|
||||
public static final int ID = 6;
|
||||
|
||||
@Override
|
||||
public void setImage(byte[] data) {
|
||||
throw new UnsupportedOperationException("Set image is not supported for DefineBits");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
// importing a new image will replace the current DefineBitsTag with a new DefineBitsJPEG2Tag
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBitsTag(SWF swf) {
|
||||
super(swf, ID, "DefineBits", null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
jpegData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
public DefineBitsTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineBits", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterID = sis.readUI16("characterID");
|
||||
jpegData = sis.readByteRangeEx(sis.available(), "jpegData");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getImageData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializableImage getImage() {
|
||||
if (cachedImage != null) {
|
||||
return cachedImage;
|
||||
}
|
||||
if (swf.getJtt() != null) {
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
byte[] jttdata = swf.getJtt().jpegData;
|
||||
if (jttdata.length != 0) {
|
||||
int jttErrorLength = hasErrorHeader(jttdata) ? 4 : 0;
|
||||
baos.write(jttdata, jttErrorLength, jttdata.length - jttErrorLength - 2);
|
||||
}
|
||||
|
||||
int errorLength = hasErrorHeader(jpegData) ? 4 : 0;
|
||||
baos.write(jpegData.getArray(), jpegData.getPos() + errorLength, jpegData.getLength() - errorLength);
|
||||
|
||||
BufferedImage image = ImageHelper.read(baos.toByteArray());
|
||||
if (image == null) {
|
||||
Logger.getLogger(DefineBitsTag.class.getName()).log(Level.SEVERE, "Failed to load image");
|
||||
return null;
|
||||
}
|
||||
|
||||
SerializableImage ret = new SerializableImage(image);
|
||||
cachedImage = ret;
|
||||
return ret;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsTag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterID);
|
||||
sos.write(jpegData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterID = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageFormat() {
|
||||
return "jpg";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(Tag tag) {
|
||||
clearCache();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineBitsTag extends ImageTag implements TagChangedListener {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterID;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public ByteArrayRange jpegData;
|
||||
|
||||
public static final int ID = 6;
|
||||
|
||||
public static final String NAME = "DefineBits";
|
||||
|
||||
@Override
|
||||
public void setImage(byte[] data) {
|
||||
throw new UnsupportedOperationException("Set image is not supported for DefineBits");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
// importing a new image will replace the current DefineBitsTag with a new DefineBitsJPEG2Tag
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBitsTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
jpegData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
public DefineBitsTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterID = sis.readUI16("characterID");
|
||||
jpegData = sis.readByteRangeEx(sis.available(), "jpegData");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getImageData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializableImage getImage() {
|
||||
if (cachedImage != null) {
|
||||
return cachedImage;
|
||||
}
|
||||
if (swf.getJtt() != null) {
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
byte[] jttdata = swf.getJtt().jpegData;
|
||||
if (jttdata.length != 0) {
|
||||
int jttErrorLength = hasErrorHeader(jttdata) ? 4 : 0;
|
||||
baos.write(jttdata, jttErrorLength, jttdata.length - jttErrorLength - 2);
|
||||
}
|
||||
|
||||
int errorLength = hasErrorHeader(jpegData) ? 4 : 0;
|
||||
baos.write(jpegData.getArray(), jpegData.getPos() + errorLength, jpegData.getLength() - errorLength);
|
||||
|
||||
BufferedImage image = ImageHelper.read(baos.toByteArray());
|
||||
if (image == null) {
|
||||
Logger.getLogger(DefineBitsTag.class.getName()).log(Level.SEVERE, "Failed to load image");
|
||||
return null;
|
||||
}
|
||||
|
||||
SerializableImage ret = new SerializableImage(image);
|
||||
cachedImage = ret;
|
||||
return ret;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsTag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterID);
|
||||
sos.write(jpegData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterID = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageFormat() {
|
||||
return "jpg";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(Tag tag) {
|
||||
clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,358 +1,360 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSourceContainer;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Frame;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONCONDACTION;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Extends the capabilities of DefineButton by allowing any state transition to
|
||||
* trigger actions
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
|
||||
|
||||
/**
|
||||
* ID for this character
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonId;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 7)
|
||||
public int reserved;
|
||||
|
||||
/**
|
||||
* Track as menu button
|
||||
*/
|
||||
public boolean trackAsMenu;
|
||||
|
||||
/**
|
||||
* Characters that make up the button
|
||||
*/
|
||||
public List<BUTTONRECORD> characters;
|
||||
|
||||
/**
|
||||
* Actions to execute at particular button events
|
||||
*/
|
||||
public List<BUTTONCONDACTION> actions = new ArrayList<>();
|
||||
|
||||
public static final int ID = 34;
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
private boolean isSingleFrameInitialized;
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
private static final Cache<DefineButton2Tag, RECT> rectCache = Cache.getInstance(true, true, "rect_button2");
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return buttonId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.buttonId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BUTTONRECORD> getRecords() {
|
||||
return characters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineButton2Tag(SWF swf) {
|
||||
super(swf, ID, "DefineButton2", null);
|
||||
buttonId = swf.getNextCharacterId();
|
||||
characters = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineButton2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineButton2", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
buttonId = sis.readUI16("buttonId");
|
||||
reserved = (int) sis.readUB(7, "reserved");
|
||||
trackAsMenu = sis.readUB(1, "trackAsMenu") == 1;
|
||||
int actionOffset = sis.readUI16("actionOffset");
|
||||
characters = sis.readBUTTONRECORDList(true, "characters");
|
||||
if (actionOffset > 0) {
|
||||
actions = sis.readBUTTONCONDACTIONList(swf, this, "actions");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
if (Configuration.debugCopy.get()) {
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(getOriginalData());
|
||||
os = new CopyOutputStream(os, bais);
|
||||
}
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(buttonId);
|
||||
sos.writeUB(7, reserved);
|
||||
sos.writeUB(1, trackAsMenu ? 1 : 0);
|
||||
|
||||
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
|
||||
try (SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion())) {
|
||||
sos2.writeBUTTONRECORDList(characters, true);
|
||||
}
|
||||
byte[] brdata = baos2.toByteArray();
|
||||
if ((actions == null) || (actions.isEmpty())) {
|
||||
sos.writeUI16(0);
|
||||
} else {
|
||||
sos.writeUI16(2 + brdata.length);
|
||||
}
|
||||
sos.write(brdata);
|
||||
sos.writeBUTTONCONDACTIONList(actions);
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all sub-items
|
||||
*
|
||||
* @return List of sub-items
|
||||
*/
|
||||
@Override
|
||||
public List<BUTTONCONDACTION> getSubItems() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
for (BUTTONRECORD r : characters) {
|
||||
needed.add(r.characterId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = false;
|
||||
for (int i = 0; i < characters.size(); i++) {
|
||||
BUTTONRECORD character = characters.get(i);
|
||||
if (character.characterId == oldCharacterId) {
|
||||
character.characterId = newCharacterId;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = false;
|
||||
for (int i = 0; i < characters.size(); i++) {
|
||||
if (characters.get(i).characterId == characterId) {
|
||||
characters.remove(i);
|
||||
modified = true;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
if (rectCache.contains(this)) {
|
||||
return rectCache.get(this);
|
||||
}
|
||||
RECT rect = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
for (BUTTONRECORD r : characters) {
|
||||
CharacterTag ch = swf.getCharacter(r.characterId);
|
||||
if (ch instanceof BoundedTag) {
|
||||
BoundedTag bt = (BoundedTag) ch;
|
||||
if (!added.contains(bt)) {
|
||||
added.add(bt);
|
||||
RECT r2 = bt.getRect(added);
|
||||
added.remove(bt);
|
||||
MATRIX mat = r.placeMatrix;
|
||||
if (mat != null) {
|
||||
r2 = mat.apply(r2);
|
||||
}
|
||||
rect.Xmin = Math.min(r2.Xmin, rect.Xmin);
|
||||
rect.Ymin = Math.min(r2.Ymin, rect.Ymin);
|
||||
rect.Xmax = Math.max(r2.Xmax, rect.Xmax);
|
||||
rect.Ymax = Math.max(r2.Ymax, rect.Ymax);
|
||||
}
|
||||
}
|
||||
}
|
||||
rectCache.put(this, rect);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
rectCache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trackAsMenu() {
|
||||
return trackAsMenu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
initialiteIsSingleFrame();
|
||||
}
|
||||
return isSingleFrame;
|
||||
}
|
||||
|
||||
private synchronized void initialiteIsSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
isSingleFrame = getTimeline().isSingleFrame();
|
||||
isSingleFrameInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
if (timeline != null) {
|
||||
return timeline;
|
||||
}
|
||||
|
||||
timeline = new Timeline(swf, this, new ArrayList<Tag>(), buttonId, getRect());
|
||||
initTimeline(timeline);
|
||||
return timeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTimeline() {
|
||||
if (timeline != null) {
|
||||
timeline.reset(swf, this, new ArrayList<Tag>(), buttonId, getRect());
|
||||
initTimeline(timeline);
|
||||
}
|
||||
}
|
||||
|
||||
private void initTimeline(Timeline timeline) {
|
||||
int maxDepth = 0;
|
||||
Frame frameUp = new Frame(timeline, 0);
|
||||
Frame frameDown = new Frame(timeline, 0);
|
||||
Frame frameOver = new Frame(timeline, 0);
|
||||
Frame frameHit = new Frame(timeline, 0);
|
||||
for (BUTTONRECORD r : this.characters) {
|
||||
|
||||
DepthState layer = new DepthState(swf, null);
|
||||
layer.colorTransForm = r.colorTransform;
|
||||
layer.blendMode = r.blendMode;
|
||||
layer.filters = r.filterList;
|
||||
layer.matrix = r.placeMatrix;
|
||||
layer.characterId = r.characterId;
|
||||
if (r.placeDepth > maxDepth) {
|
||||
maxDepth = r.placeDepth;
|
||||
}
|
||||
|
||||
if (r.buttonStateUp) {
|
||||
frameUp.layers.put(r.placeDepth, new DepthState(layer, frameUp, false));
|
||||
}
|
||||
if (r.buttonStateDown) {
|
||||
frameDown.layers.put(r.placeDepth, new DepthState(layer, frameDown, false));
|
||||
}
|
||||
if (r.buttonStateOver) {
|
||||
frameOver.layers.put(r.placeDepth, new DepthState(layer, frameOver, false));
|
||||
}
|
||||
if (r.buttonStateHitTest) {
|
||||
frameHit.layers.put(r.placeDepth, new DepthState(layer, frameHit, false));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
timeline.addFrame(frameUp);
|
||||
|
||||
if (frameOver.layers.isEmpty()) {
|
||||
frameOver = frameUp;
|
||||
}
|
||||
|
||||
timeline.addFrame(frameOver);
|
||||
|
||||
if (frameDown.layers.isEmpty()) {
|
||||
frameDown = frameOver;
|
||||
}
|
||||
|
||||
timeline.addFrame(frameDown);
|
||||
|
||||
if (frameHit.layers.isEmpty()) {
|
||||
frameHit = frameUp;
|
||||
}
|
||||
|
||||
timeline.addFrame(frameHit);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSourceContainer;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Frame;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONCONDACTION;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Extends the capabilities of DefineButton by allowing any state transition to
|
||||
* trigger actions
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
|
||||
|
||||
/**
|
||||
* ID for this character
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonId;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 7)
|
||||
public int reserved;
|
||||
|
||||
/**
|
||||
* Track as menu button
|
||||
*/
|
||||
public boolean trackAsMenu;
|
||||
|
||||
/**
|
||||
* Characters that make up the button
|
||||
*/
|
||||
public List<BUTTONRECORD> characters;
|
||||
|
||||
/**
|
||||
* Actions to execute at particular button events
|
||||
*/
|
||||
public List<BUTTONCONDACTION> actions = new ArrayList<>();
|
||||
|
||||
public static final int ID = 34;
|
||||
|
||||
public static final String NAME = "DefineButton2";
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
private boolean isSingleFrameInitialized;
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
private static final Cache<DefineButton2Tag, RECT> rectCache = Cache.getInstance(true, true, "rect_button2");
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return buttonId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.buttonId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BUTTONRECORD> getRecords() {
|
||||
return characters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineButton2Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
buttonId = swf.getNextCharacterId();
|
||||
characters = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineButton2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
buttonId = sis.readUI16("buttonId");
|
||||
reserved = (int) sis.readUB(7, "reserved");
|
||||
trackAsMenu = sis.readUB(1, "trackAsMenu") == 1;
|
||||
int actionOffset = sis.readUI16("actionOffset");
|
||||
characters = sis.readBUTTONRECORDList(true, "characters");
|
||||
if (actionOffset > 0) {
|
||||
actions = sis.readBUTTONCONDACTIONList(swf, this, "actions");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
if (Configuration.debugCopy.get()) {
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(getOriginalData());
|
||||
os = new CopyOutputStream(os, bais);
|
||||
}
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(buttonId);
|
||||
sos.writeUB(7, reserved);
|
||||
sos.writeUB(1, trackAsMenu ? 1 : 0);
|
||||
|
||||
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
|
||||
try (SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion())) {
|
||||
sos2.writeBUTTONRECORDList(characters, true);
|
||||
}
|
||||
byte[] brdata = baos2.toByteArray();
|
||||
if ((actions == null) || (actions.isEmpty())) {
|
||||
sos.writeUI16(0);
|
||||
} else {
|
||||
sos.writeUI16(2 + brdata.length);
|
||||
}
|
||||
sos.write(brdata);
|
||||
sos.writeBUTTONCONDACTIONList(actions);
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all sub-items
|
||||
*
|
||||
* @return List of sub-items
|
||||
*/
|
||||
@Override
|
||||
public List<BUTTONCONDACTION> getSubItems() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
for (BUTTONRECORD r : characters) {
|
||||
needed.add(r.characterId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = false;
|
||||
for (int i = 0; i < characters.size(); i++) {
|
||||
BUTTONRECORD character = characters.get(i);
|
||||
if (character.characterId == oldCharacterId) {
|
||||
character.characterId = newCharacterId;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = false;
|
||||
for (int i = 0; i < characters.size(); i++) {
|
||||
if (characters.get(i).characterId == characterId) {
|
||||
characters.remove(i);
|
||||
modified = true;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
if (rectCache.contains(this)) {
|
||||
return rectCache.get(this);
|
||||
}
|
||||
RECT rect = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
for (BUTTONRECORD r : characters) {
|
||||
CharacterTag ch = swf.getCharacter(r.characterId);
|
||||
if (ch instanceof BoundedTag) {
|
||||
BoundedTag bt = (BoundedTag) ch;
|
||||
if (!added.contains(bt)) {
|
||||
added.add(bt);
|
||||
RECT r2 = bt.getRect(added);
|
||||
added.remove(bt);
|
||||
MATRIX mat = r.placeMatrix;
|
||||
if (mat != null) {
|
||||
r2 = mat.apply(r2);
|
||||
}
|
||||
rect.Xmin = Math.min(r2.Xmin, rect.Xmin);
|
||||
rect.Ymin = Math.min(r2.Ymin, rect.Ymin);
|
||||
rect.Xmax = Math.max(r2.Xmax, rect.Xmax);
|
||||
rect.Ymax = Math.max(r2.Ymax, rect.Ymax);
|
||||
}
|
||||
}
|
||||
}
|
||||
rectCache.put(this, rect);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
rectCache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trackAsMenu() {
|
||||
return trackAsMenu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
initialiteIsSingleFrame();
|
||||
}
|
||||
return isSingleFrame;
|
||||
}
|
||||
|
||||
private synchronized void initialiteIsSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
isSingleFrame = getTimeline().isSingleFrame();
|
||||
isSingleFrameInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
if (timeline != null) {
|
||||
return timeline;
|
||||
}
|
||||
|
||||
timeline = new Timeline(swf, this, new ArrayList<Tag>(), buttonId, getRect());
|
||||
initTimeline(timeline);
|
||||
return timeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTimeline() {
|
||||
if (timeline != null) {
|
||||
timeline.reset(swf, this, new ArrayList<Tag>(), buttonId, getRect());
|
||||
initTimeline(timeline);
|
||||
}
|
||||
}
|
||||
|
||||
private void initTimeline(Timeline timeline) {
|
||||
int maxDepth = 0;
|
||||
Frame frameUp = new Frame(timeline, 0);
|
||||
Frame frameDown = new Frame(timeline, 0);
|
||||
Frame frameOver = new Frame(timeline, 0);
|
||||
Frame frameHit = new Frame(timeline, 0);
|
||||
for (BUTTONRECORD r : this.characters) {
|
||||
|
||||
DepthState layer = new DepthState(swf, null);
|
||||
layer.colorTransForm = r.colorTransform;
|
||||
layer.blendMode = r.blendMode;
|
||||
layer.filters = r.filterList;
|
||||
layer.matrix = r.placeMatrix;
|
||||
layer.characterId = r.characterId;
|
||||
if (r.placeDepth > maxDepth) {
|
||||
maxDepth = r.placeDepth;
|
||||
}
|
||||
|
||||
if (r.buttonStateUp) {
|
||||
frameUp.layers.put(r.placeDepth, new DepthState(layer, frameUp, false));
|
||||
}
|
||||
if (r.buttonStateDown) {
|
||||
frameDown.layers.put(r.placeDepth, new DepthState(layer, frameDown, false));
|
||||
}
|
||||
if (r.buttonStateOver) {
|
||||
frameOver.layers.put(r.placeDepth, new DepthState(layer, frameOver, false));
|
||||
}
|
||||
if (r.buttonStateHitTest) {
|
||||
frameHit.layers.put(r.placeDepth, new DepthState(layer, frameHit, false));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
timeline.addFrame(frameUp);
|
||||
|
||||
if (frameOver.layers.isEmpty()) {
|
||||
frameOver = frameUp;
|
||||
}
|
||||
|
||||
timeline.addFrame(frameOver);
|
||||
|
||||
if (frameDown.layers.isEmpty()) {
|
||||
frameDown = frameOver;
|
||||
}
|
||||
|
||||
timeline.addFrame(frameDown);
|
||||
|
||||
if (frameHit.layers.isEmpty()) {
|
||||
frameHit = frameUp;
|
||||
}
|
||||
|
||||
timeline.addFrame(frameHit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,100 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.CXFORM;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineButtonCxformTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonId;
|
||||
|
||||
public CXFORM buttonColorTransform;
|
||||
|
||||
public static final int ID = 23;
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(buttonId);
|
||||
sos.writeCXFORM(buttonColorTransform);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineButtonCxformTag(SWF swf) {
|
||||
super(swf, ID, "DefineButtonCxform", null);
|
||||
buttonColorTransform = new CXFORM();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineButtonCxformTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineButtonCxform", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
buttonId = sis.readUI16("buttonId");
|
||||
buttonColorTransform = sis.readCXFORM("buttonColorTransform");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return buttonId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.buttonId = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.CXFORM;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineButtonCxformTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonId;
|
||||
|
||||
public CXFORM buttonColorTransform;
|
||||
|
||||
public static final int ID = 23;
|
||||
|
||||
public static final String NAME = "DefineButtonCxform";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(buttonId);
|
||||
sos.writeCXFORM(buttonColorTransform);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineButtonCxformTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
buttonColorTransform = new CXFORM();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineButtonCxformTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
buttonId = sis.readUI16("buttonId");
|
||||
buttonColorTransform = sis.readCXFORM("buttonColorTransform");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return buttonId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.buttonId = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,147 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.SOUNDINFO;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineButtonSoundTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonId;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonSoundChar0;
|
||||
|
||||
public SOUNDINFO buttonSoundInfo0;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonSoundChar1;
|
||||
|
||||
public SOUNDINFO buttonSoundInfo1;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonSoundChar2;
|
||||
|
||||
public SOUNDINFO buttonSoundInfo2;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonSoundChar3;
|
||||
|
||||
public SOUNDINFO buttonSoundInfo3;
|
||||
|
||||
public static final int ID = 17;
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return buttonId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.buttonId = characterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(buttonId);
|
||||
sos.writeUI16(buttonSoundChar0);
|
||||
if (buttonSoundChar0 != 0) {
|
||||
sos.writeSOUNDINFO(buttonSoundInfo0);
|
||||
}
|
||||
sos.writeUI16(buttonSoundChar1);
|
||||
if (buttonSoundChar1 != 0) {
|
||||
sos.writeSOUNDINFO(buttonSoundInfo1);
|
||||
}
|
||||
sos.writeUI16(buttonSoundChar2);
|
||||
if (buttonSoundChar2 != 0) {
|
||||
sos.writeSOUNDINFO(buttonSoundInfo2);
|
||||
}
|
||||
sos.writeUI16(buttonSoundChar3);
|
||||
if (buttonSoundChar3 != 0) {
|
||||
sos.writeSOUNDINFO(buttonSoundInfo3);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineButtonSoundTag(SWF swf) {
|
||||
super(swf, ID, "DefineButtonSound", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineButtonSoundTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineButtonSound", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
buttonId = sis.readUI16("buttonId");
|
||||
buttonSoundChar0 = sis.readUI16("buttonSoundChar0");
|
||||
if (buttonSoundChar0 != 0) {
|
||||
buttonSoundInfo0 = sis.readSOUNDINFO("buttonSoundInfo0");
|
||||
}
|
||||
buttonSoundChar1 = sis.readUI16("buttonSoundChar1");
|
||||
if (buttonSoundChar1 != 0) {
|
||||
buttonSoundInfo1 = sis.readSOUNDINFO("buttonSoundInfo1");
|
||||
}
|
||||
buttonSoundChar2 = sis.readUI16("buttonSoundChar2");
|
||||
if (buttonSoundChar2 != 0) {
|
||||
buttonSoundInfo2 = sis.readSOUNDINFO("buttonSoundInfo2");
|
||||
}
|
||||
buttonSoundChar3 = sis.readUI16("buttonSoundChar3");
|
||||
if (buttonSoundChar3 != 0) {
|
||||
buttonSoundInfo3 = sis.readSOUNDINFO("buttonSoundInfo3");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.SOUNDINFO;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineButtonSoundTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonId;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonSoundChar0;
|
||||
|
||||
public SOUNDINFO buttonSoundInfo0;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonSoundChar1;
|
||||
|
||||
public SOUNDINFO buttonSoundInfo1;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonSoundChar2;
|
||||
|
||||
public SOUNDINFO buttonSoundInfo2;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonSoundChar3;
|
||||
|
||||
public SOUNDINFO buttonSoundInfo3;
|
||||
|
||||
public static final int ID = 17;
|
||||
|
||||
public static final String NAME = "DefineButtonSound";
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return buttonId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.buttonId = characterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(buttonId);
|
||||
sos.writeUI16(buttonSoundChar0);
|
||||
if (buttonSoundChar0 != 0) {
|
||||
sos.writeSOUNDINFO(buttonSoundInfo0);
|
||||
}
|
||||
sos.writeUI16(buttonSoundChar1);
|
||||
if (buttonSoundChar1 != 0) {
|
||||
sos.writeSOUNDINFO(buttonSoundInfo1);
|
||||
}
|
||||
sos.writeUI16(buttonSoundChar2);
|
||||
if (buttonSoundChar2 != 0) {
|
||||
sos.writeSOUNDINFO(buttonSoundInfo2);
|
||||
}
|
||||
sos.writeUI16(buttonSoundChar3);
|
||||
if (buttonSoundChar3 != 0) {
|
||||
sos.writeSOUNDINFO(buttonSoundInfo3);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineButtonSoundTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineButtonSoundTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
buttonId = sis.readUI16("buttonId");
|
||||
buttonSoundChar0 = sis.readUI16("buttonSoundChar0");
|
||||
if (buttonSoundChar0 != 0) {
|
||||
buttonSoundInfo0 = sis.readSOUNDINFO("buttonSoundInfo0");
|
||||
}
|
||||
buttonSoundChar1 = sis.readUI16("buttonSoundChar1");
|
||||
if (buttonSoundChar1 != 0) {
|
||||
buttonSoundInfo1 = sis.readSOUNDINFO("buttonSoundInfo1");
|
||||
}
|
||||
buttonSoundChar2 = sis.readUI16("buttonSoundChar2");
|
||||
if (buttonSoundChar2 != 0) {
|
||||
buttonSoundInfo2 = sis.readSOUNDINFO("buttonSoundInfo2");
|
||||
}
|
||||
buttonSoundChar3 = sis.readUI16("buttonSoundChar3");
|
||||
if (buttonSoundChar3 != 0) {
|
||||
buttonSoundInfo3 = sis.readSOUNDINFO("buttonSoundInfo3");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,449 +1,451 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.ActionListReader;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Frame;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Defines a button character
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
|
||||
/**
|
||||
* ID for this character
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonId;
|
||||
|
||||
/**
|
||||
* Characters that make up the button
|
||||
*/
|
||||
public List<BUTTONRECORD> characters;
|
||||
|
||||
/**
|
||||
* Actions to perform
|
||||
*/
|
||||
//public List<Action> actions;
|
||||
@HideInRawEdit
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
public static final int ID = 7;
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return buttonId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.buttonId = characterId;
|
||||
}
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
private boolean isSingleFrameInitialized;
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
private static final Cache<DefineButtonTag, RECT> rectCache = Cache.getInstance(true, true, "rect_button");
|
||||
|
||||
@Override
|
||||
public List<BUTTONRECORD> getRecords() {
|
||||
return characters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineButtonTag(SWF swf) {
|
||||
super(swf, ID, "DefineButton", null);
|
||||
buttonId = swf.getNextCharacterId();
|
||||
characters = new ArrayList<>();
|
||||
actionBytes = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineButtonTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineButton", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
buttonId = sis.readUI16("buttonId");
|
||||
characters = sis.readBUTTONRECORDList(false, "characters");
|
||||
actionBytes = sis.readByteRangeEx(sis.available(), "actionBytes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
if (Configuration.debugCopy.get()) {
|
||||
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
|
||||
}
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(buttonId);
|
||||
sos.writeBUTTONRECORDList(characters, false);
|
||||
sos.write(getActionBytes());
|
||||
//sos.write(Action.actionsToBytes(actions, true, version));
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts actions to ASM source
|
||||
*
|
||||
* @param exportMode PCode or hex?
|
||||
* @param writer
|
||||
* @param actions
|
||||
* @return ASM source
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public GraphTextWriter getASMSource(ScriptExportMode exportMode, GraphTextWriter writer, ActionList actions) throws InterruptedException {
|
||||
if (actions == null) {
|
||||
actions = getActions();
|
||||
}
|
||||
return Action.actionsToString(listeners, 0, actions, swf.version, exportMode, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this object contains ASM source
|
||||
*
|
||||
* @return True when contains
|
||||
*/
|
||||
@Override
|
||||
public boolean containsSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns actions associated with this object
|
||||
*
|
||||
* @return List of actions
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public ActionList getActions() throws InterruptedException {
|
||||
try {
|
||||
int prevLength = actionBytes.getPos();
|
||||
SWFInputStream rri = new SWFInputStream(swf, actionBytes.getArray());
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (InterruptedException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DefineButtonTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ActionList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActions(List<Action> actions) {
|
||||
byte[] bytes = Action.actionsToBytes(actions, true, swf.version);
|
||||
actionBytes = new ByteArrayRange(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getActionBytes() {
|
||||
return actionBytes.getRangeData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = new ByteArrayRange(actionBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified() {
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionBytesAsHex(GraphTextWriter writer) {
|
||||
return Helper.byteArrayToHexWithHeader(writer, actionBytes.getRangeData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
for (BUTTONRECORD r : characters) {
|
||||
needed.add(r.characterId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = false;
|
||||
for (int i = 0; i < characters.size(); i++) {
|
||||
BUTTONRECORD character = characters.get(i);
|
||||
if (character.characterId == oldCharacterId) {
|
||||
character.characterId = newCharacterId;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = false;
|
||||
for (int i = 0; i < characters.size(); i++) {
|
||||
if (characters.get(i).characterId == characterId) {
|
||||
characters.remove(i);
|
||||
modified = true;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
if (rectCache.contains(this)) {
|
||||
return rectCache.get(this);
|
||||
}
|
||||
RECT rect = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
for (BUTTONRECORD r : characters) {
|
||||
CharacterTag ch = swf.getCharacter(r.characterId);
|
||||
if (ch instanceof BoundedTag) {
|
||||
BoundedTag bt = (BoundedTag) ch;
|
||||
if (!added.contains(bt)) {
|
||||
added.add(bt);
|
||||
RECT r2 = bt.getRect(added);
|
||||
added.remove(bt);
|
||||
MATRIX mat = r.placeMatrix;
|
||||
if (mat != null) {
|
||||
r2 = mat.apply(r2);
|
||||
}
|
||||
rect.Xmin = Math.min(r2.Xmin, rect.Xmin);
|
||||
rect.Ymin = Math.min(r2.Ymin, rect.Ymin);
|
||||
rect.Xmax = Math.max(r2.Xmax, rect.Xmax);
|
||||
rect.Ymax = Math.max(r2.Ymax, rect.Ymax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rectCache.put(this, rect);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
rectCache.clear();
|
||||
}
|
||||
|
||||
List<DisassemblyListener> listeners = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trackAsMenu() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
initialiteIsSingleFrame();
|
||||
}
|
||||
return isSingleFrame;
|
||||
}
|
||||
|
||||
private synchronized void initialiteIsSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
isSingleFrame = getTimeline().isSingleFrame();
|
||||
isSingleFrameInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourceSuffix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrefixLineCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String removePrefixAndSuffix(String source) {
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
if (timeline != null) {
|
||||
return timeline;
|
||||
}
|
||||
|
||||
timeline = new Timeline(swf, this, new ArrayList<Tag>(), buttonId, getRect());
|
||||
initTimeline(timeline);
|
||||
return timeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTimeline() {
|
||||
if (timeline != null) {
|
||||
timeline.reset(swf, this, new ArrayList<Tag>(), buttonId, getRect());
|
||||
initTimeline(timeline);
|
||||
}
|
||||
}
|
||||
|
||||
private void initTimeline(Timeline timeline) {
|
||||
ColorTransform clrTrans = null;
|
||||
for (Tag t : swf.tags) {
|
||||
if (t instanceof DefineButtonCxformTag) {
|
||||
DefineButtonCxformTag cx = (DefineButtonCxformTag) t;
|
||||
clrTrans = cx.buttonColorTransform;
|
||||
}
|
||||
}
|
||||
int maxDepth = 0;
|
||||
Frame frameUp = new Frame(timeline, 0);
|
||||
Frame frameDown = new Frame(timeline, 0);
|
||||
Frame frameOver = new Frame(timeline, 0);
|
||||
Frame frameHit = new Frame(timeline, 0);
|
||||
for (BUTTONRECORD r : this.characters) {
|
||||
|
||||
DepthState layer = new DepthState(swf, null);
|
||||
layer.colorTransForm = clrTrans;
|
||||
layer.blendMode = r.blendMode;
|
||||
layer.filters = r.filterList;
|
||||
layer.matrix = r.placeMatrix;
|
||||
layer.characterId = r.characterId;
|
||||
if (r.placeDepth > maxDepth) {
|
||||
maxDepth = r.placeDepth;
|
||||
}
|
||||
|
||||
if (r.buttonStateUp) {
|
||||
frameUp.layers.put(r.placeDepth, new DepthState(layer, frameUp, false));
|
||||
}
|
||||
if (r.buttonStateDown) {
|
||||
frameDown.layers.put(r.placeDepth, new DepthState(layer, frameDown, false));
|
||||
}
|
||||
if (r.buttonStateOver) {
|
||||
frameOver.layers.put(r.placeDepth, new DepthState(layer, frameOver, false));
|
||||
}
|
||||
if (r.buttonStateHitTest) {
|
||||
frameHit.layers.put(r.placeDepth, new DepthState(layer, frameHit, false));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
timeline.addFrame(frameUp);
|
||||
if (frameOver.layers.isEmpty()) {
|
||||
frameOver = frameUp;
|
||||
}
|
||||
timeline.addFrame(frameOver);
|
||||
if (frameDown.layers.isEmpty()) {
|
||||
frameDown = frameOver;
|
||||
}
|
||||
timeline.addFrame(frameDown);
|
||||
if (frameHit.layers.isEmpty()) {
|
||||
frameHit = frameUp;
|
||||
}
|
||||
timeline.addFrame(frameHit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getSourceTag() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.ActionListReader;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Frame;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Defines a button character
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
|
||||
/**
|
||||
* ID for this character
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int buttonId;
|
||||
|
||||
/**
|
||||
* Characters that make up the button
|
||||
*/
|
||||
public List<BUTTONRECORD> characters;
|
||||
|
||||
/**
|
||||
* Actions to perform
|
||||
*/
|
||||
//public List<Action> actions;
|
||||
@HideInRawEdit
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
public static final int ID = 7;
|
||||
|
||||
public static final String NAME = "DefineButton";
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return buttonId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.buttonId = characterId;
|
||||
}
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
private boolean isSingleFrameInitialized;
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
private static final Cache<DefineButtonTag, RECT> rectCache = Cache.getInstance(true, true, "rect_button");
|
||||
|
||||
@Override
|
||||
public List<BUTTONRECORD> getRecords() {
|
||||
return characters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineButtonTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
buttonId = swf.getNextCharacterId();
|
||||
characters = new ArrayList<>();
|
||||
actionBytes = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineButtonTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
buttonId = sis.readUI16("buttonId");
|
||||
characters = sis.readBUTTONRECORDList(false, "characters");
|
||||
actionBytes = sis.readByteRangeEx(sis.available(), "actionBytes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
if (Configuration.debugCopy.get()) {
|
||||
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
|
||||
}
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(buttonId);
|
||||
sos.writeBUTTONRECORDList(characters, false);
|
||||
sos.write(getActionBytes());
|
||||
//sos.write(Action.actionsToBytes(actions, true, version));
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts actions to ASM source
|
||||
*
|
||||
* @param exportMode PCode or hex?
|
||||
* @param writer
|
||||
* @param actions
|
||||
* @return ASM source
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public GraphTextWriter getASMSource(ScriptExportMode exportMode, GraphTextWriter writer, ActionList actions) throws InterruptedException {
|
||||
if (actions == null) {
|
||||
actions = getActions();
|
||||
}
|
||||
return Action.actionsToString(listeners, 0, actions, swf.version, exportMode, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this object contains ASM source
|
||||
*
|
||||
* @return True when contains
|
||||
*/
|
||||
@Override
|
||||
public boolean containsSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns actions associated with this object
|
||||
*
|
||||
* @return List of actions
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public ActionList getActions() throws InterruptedException {
|
||||
try {
|
||||
int prevLength = actionBytes.getPos();
|
||||
SWFInputStream rri = new SWFInputStream(swf, actionBytes.getArray());
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (InterruptedException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DefineButtonTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ActionList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActions(List<Action> actions) {
|
||||
byte[] bytes = Action.actionsToBytes(actions, true, swf.version);
|
||||
actionBytes = new ByteArrayRange(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getActionBytes() {
|
||||
return actionBytes.getRangeData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = new ByteArrayRange(actionBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified() {
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionBytesAsHex(GraphTextWriter writer) {
|
||||
return Helper.byteArrayToHexWithHeader(writer, actionBytes.getRangeData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
for (BUTTONRECORD r : characters) {
|
||||
needed.add(r.characterId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = false;
|
||||
for (int i = 0; i < characters.size(); i++) {
|
||||
BUTTONRECORD character = characters.get(i);
|
||||
if (character.characterId == oldCharacterId) {
|
||||
character.characterId = newCharacterId;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = false;
|
||||
for (int i = 0; i < characters.size(); i++) {
|
||||
if (characters.get(i).characterId == characterId) {
|
||||
characters.remove(i);
|
||||
modified = true;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
if (rectCache.contains(this)) {
|
||||
return rectCache.get(this);
|
||||
}
|
||||
RECT rect = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
for (BUTTONRECORD r : characters) {
|
||||
CharacterTag ch = swf.getCharacter(r.characterId);
|
||||
if (ch instanceof BoundedTag) {
|
||||
BoundedTag bt = (BoundedTag) ch;
|
||||
if (!added.contains(bt)) {
|
||||
added.add(bt);
|
||||
RECT r2 = bt.getRect(added);
|
||||
added.remove(bt);
|
||||
MATRIX mat = r.placeMatrix;
|
||||
if (mat != null) {
|
||||
r2 = mat.apply(r2);
|
||||
}
|
||||
rect.Xmin = Math.min(r2.Xmin, rect.Xmin);
|
||||
rect.Ymin = Math.min(r2.Ymin, rect.Ymin);
|
||||
rect.Xmax = Math.max(r2.Xmax, rect.Xmax);
|
||||
rect.Ymax = Math.max(r2.Ymax, rect.Ymax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rectCache.put(this, rect);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
rectCache.clear();
|
||||
}
|
||||
|
||||
List<DisassemblyListener> listeners = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trackAsMenu() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
initialiteIsSingleFrame();
|
||||
}
|
||||
return isSingleFrame;
|
||||
}
|
||||
|
||||
private synchronized void initialiteIsSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
isSingleFrame = getTimeline().isSingleFrame();
|
||||
isSingleFrameInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourceSuffix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrefixLineCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String removePrefixAndSuffix(String source) {
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
if (timeline != null) {
|
||||
return timeline;
|
||||
}
|
||||
|
||||
timeline = new Timeline(swf, this, new ArrayList<Tag>(), buttonId, getRect());
|
||||
initTimeline(timeline);
|
||||
return timeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTimeline() {
|
||||
if (timeline != null) {
|
||||
timeline.reset(swf, this, new ArrayList<Tag>(), buttonId, getRect());
|
||||
initTimeline(timeline);
|
||||
}
|
||||
}
|
||||
|
||||
private void initTimeline(Timeline timeline) {
|
||||
ColorTransform clrTrans = null;
|
||||
for (Tag t : swf.tags) {
|
||||
if (t instanceof DefineButtonCxformTag) {
|
||||
DefineButtonCxformTag cx = (DefineButtonCxformTag) t;
|
||||
clrTrans = cx.buttonColorTransform;
|
||||
}
|
||||
}
|
||||
int maxDepth = 0;
|
||||
Frame frameUp = new Frame(timeline, 0);
|
||||
Frame frameDown = new Frame(timeline, 0);
|
||||
Frame frameOver = new Frame(timeline, 0);
|
||||
Frame frameHit = new Frame(timeline, 0);
|
||||
for (BUTTONRECORD r : this.characters) {
|
||||
|
||||
DepthState layer = new DepthState(swf, null);
|
||||
layer.colorTransForm = clrTrans;
|
||||
layer.blendMode = r.blendMode;
|
||||
layer.filters = r.filterList;
|
||||
layer.matrix = r.placeMatrix;
|
||||
layer.characterId = r.characterId;
|
||||
if (r.placeDepth > maxDepth) {
|
||||
maxDepth = r.placeDepth;
|
||||
}
|
||||
|
||||
if (r.buttonStateUp) {
|
||||
frameUp.layers.put(r.placeDepth, new DepthState(layer, frameUp, false));
|
||||
}
|
||||
if (r.buttonStateDown) {
|
||||
frameDown.layers.put(r.placeDepth, new DepthState(layer, frameDown, false));
|
||||
}
|
||||
if (r.buttonStateOver) {
|
||||
frameOver.layers.put(r.placeDepth, new DepthState(layer, frameOver, false));
|
||||
}
|
||||
if (r.buttonStateHitTest) {
|
||||
frameHit.layers.put(r.placeDepth, new DepthState(layer, frameHit, false));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
timeline.addFrame(frameUp);
|
||||
if (frameOver.layers.isEmpty()) {
|
||||
frameOver = frameUp;
|
||||
}
|
||||
timeline.addFrame(frameOver);
|
||||
if (frameDown.layers.isEmpty()) {
|
||||
frameDown = frameOver;
|
||||
}
|
||||
timeline.addFrame(frameDown);
|
||||
if (frameHit.layers.isEmpty()) {
|
||||
frameHit = frameUp;
|
||||
}
|
||||
timeline.addFrame(frameHit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getSourceTag() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,117 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineFont4Tag extends CharacterTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontID;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 5)
|
||||
public int reserved;
|
||||
|
||||
public boolean fontFlagsHasFontData;
|
||||
|
||||
public boolean fontFlagsItalic;
|
||||
|
||||
public boolean fontFlagsBold;
|
||||
|
||||
public String fontName;
|
||||
|
||||
public byte[] fontData;
|
||||
|
||||
public static final int ID = 91;
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontID = characterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineFont4Tag(SWF swf) {
|
||||
super(swf, ID, "DefineFont4", null);
|
||||
fontID = swf.getNextCharacterId();
|
||||
fontName = "New font";
|
||||
fontData = new byte[0];
|
||||
}
|
||||
|
||||
public DefineFont4Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineFont4", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontID = sis.readUI16("fontID");
|
||||
reserved = (int) sis.readUB(5, "reserved");
|
||||
fontFlagsHasFontData = sis.readUB(1, "fontFlagsHasFontData") == 1;
|
||||
fontFlagsItalic = sis.readUB(1, "fontFlagsItalic") == 1;
|
||||
fontFlagsBold = sis.readUB(1, "fontFlagsBold") == 1;
|
||||
fontName = sis.readString("fontName");
|
||||
fontData = sis.readBytesEx(sis.available(), "fontData");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontID);
|
||||
sos.writeUB(5, reserved);
|
||||
sos.writeUB(1, fontFlagsHasFontData ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsItalic ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsBold ? 1 : 0);
|
||||
sos.writeString(fontName);
|
||||
sos.write(fontData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineFont4Tag extends CharacterTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontID;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 5)
|
||||
public int reserved;
|
||||
|
||||
public boolean fontFlagsHasFontData;
|
||||
|
||||
public boolean fontFlagsItalic;
|
||||
|
||||
public boolean fontFlagsBold;
|
||||
|
||||
public String fontName;
|
||||
|
||||
public byte[] fontData;
|
||||
|
||||
public static final int ID = 91;
|
||||
|
||||
public static final String NAME = "DefineFont4";
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontID = characterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineFont4Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
fontID = swf.getNextCharacterId();
|
||||
fontName = "New font";
|
||||
fontData = new byte[0];
|
||||
}
|
||||
|
||||
public DefineFont4Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontID = sis.readUI16("fontID");
|
||||
reserved = (int) sis.readUB(5, "reserved");
|
||||
fontFlagsHasFontData = sis.readUB(1, "fontFlagsHasFontData") == 1;
|
||||
fontFlagsItalic = sis.readUB(1, "fontFlagsItalic") == 1;
|
||||
fontFlagsBold = sis.readUB(1, "fontFlagsBold") == 1;
|
||||
fontName = sis.readString("fontName");
|
||||
fontData = sis.readBytesEx(sis.available(), "fontData");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontID);
|
||||
sos.writeUB(5, reserved);
|
||||
sos.writeUB(1, fontFlagsHasFontData ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsItalic ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsBold ? 1 : 0);
|
||||
sos.writeString(fontName);
|
||||
sos.write(fontData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,115 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.ZONERECORD;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFArray;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineFontAlignZonesTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontID;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int CSMTableHint;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 6)
|
||||
public int reserved;
|
||||
|
||||
@SWFArray(value = "zone", countField = "glyphCount")
|
||||
public List<ZONERECORD> zoneTable;
|
||||
|
||||
public static final int ID = 73;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineFontAlignZonesTag(SWF swf) {
|
||||
super(swf, ID, "DefineFontAlignZones", null);
|
||||
zoneTable = new ArrayList<>();
|
||||
}
|
||||
|
||||
public DefineFontAlignZonesTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineFontAlignZones", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontID = sis.readUI16("fontID");
|
||||
CSMTableHint = (int) sis.readUB(2, "CSMTableHint");
|
||||
reserved = (int) sis.readUB(6, "reserved");
|
||||
zoneTable = new ArrayList<>();
|
||||
while (sis.available() > 0) {
|
||||
ZONERECORD zr = sis.readZONERECORD("record");
|
||||
zoneTable.add(zr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontID);
|
||||
sos.writeUB(2, CSMTableHint);
|
||||
sos.writeUB(6, reserved);
|
||||
for (ZONERECORD z : zoneTable) {
|
||||
sos.writeZONERECORD(z);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontID = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.ZONERECORD;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFArray;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineFontAlignZonesTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontID;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int CSMTableHint;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 6)
|
||||
public int reserved;
|
||||
|
||||
@SWFArray(value = "zone", countField = "glyphCount")
|
||||
public List<ZONERECORD> zoneTable;
|
||||
|
||||
public static final int ID = 73;
|
||||
|
||||
public static final String NAME = "DefineFontAlignZones";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineFontAlignZonesTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
zoneTable = new ArrayList<>();
|
||||
}
|
||||
|
||||
public DefineFontAlignZonesTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontID = sis.readUI16("fontID");
|
||||
CSMTableHint = (int) sis.readUB(2, "CSMTableHint");
|
||||
reserved = (int) sis.readUB(6, "reserved");
|
||||
zoneTable = new ArrayList<>();
|
||||
while (sis.available() > 0) {
|
||||
ZONERECORD zr = sis.readZONERECORD("record");
|
||||
zoneTable.add(zr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontID);
|
||||
sos.writeUB(2, CSMTableHint);
|
||||
sos.writeUB(6, reserved);
|
||||
for (ZONERECORD z : zoneTable) {
|
||||
sos.writeZONERECORD(z);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontID = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,158 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.LANGCODE;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineFontInfo2Tag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontID;
|
||||
|
||||
public String fontName;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int reserved;
|
||||
|
||||
public boolean fontFlagsSmallText;
|
||||
|
||||
public boolean fontFlagsShiftJIS;
|
||||
|
||||
public boolean fontFlagsANSI;
|
||||
|
||||
public boolean fontFlagsItalic;
|
||||
|
||||
public boolean fontFlagsBold;
|
||||
|
||||
public boolean fontFlagsWideCodes; //always 1
|
||||
|
||||
public LANGCODE languageCode;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public List<Integer> codeTable;
|
||||
|
||||
public static final int ID = 62;
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontID);
|
||||
byte[] fontNameBytes = Utf8Helper.getBytes(fontName);
|
||||
sos.writeUI8(fontNameBytes.length);
|
||||
sos.write(fontNameBytes);
|
||||
sos.writeUB(2, reserved);
|
||||
sos.writeUB(1, fontFlagsSmallText ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsShiftJIS ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsANSI ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsItalic ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsBold ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsWideCodes ? 1 : 0);
|
||||
sos.writeLANGCODE(languageCode);
|
||||
for (int c : codeTable) {
|
||||
sos.writeUI16(c);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineFontInfo2Tag(SWF swf) {
|
||||
super(swf, ID, "DefineFontInfo2", null);
|
||||
fontName = "New Font Info Name";
|
||||
languageCode = new LANGCODE();
|
||||
codeTable = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineFontInfo2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineFontInfo2", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontID = sis.readUI16("fontID");
|
||||
int fontNameLen = sis.readUI8("fontNameLen");
|
||||
if (swf.version >= 6) {
|
||||
fontName = new String(sis.readBytesEx(fontNameLen, "fontName"), Utf8Helper.charset);
|
||||
} else {
|
||||
fontName = new String(sis.readBytesEx(fontNameLen, "fontName"));
|
||||
}
|
||||
reserved = (int) sis.readUB(2, "reserved");
|
||||
fontFlagsSmallText = sis.readUB(1, "fontFlagsSmallText") == 1;
|
||||
fontFlagsShiftJIS = sis.readUB(1, "fontFlagsShiftJIS") == 1;
|
||||
fontFlagsANSI = sis.readUB(1, "fontFlagsANSI") == 1;
|
||||
fontFlagsItalic = sis.readUB(1, "fontFlagsItalic") == 1;
|
||||
fontFlagsBold = sis.readUB(1, "fontFlagsBold") == 1;
|
||||
fontFlagsWideCodes = sis.readUB(1, "fontFlagsWideCodes") == 1; //Always 1
|
||||
languageCode = sis.readLANGCODE("languageCode");
|
||||
int ctLen = sis.available() / 2;
|
||||
codeTable = new ArrayList<>();
|
||||
for (int i = 0; i < ctLen; i++) {
|
||||
codeTable.add(sis.readUI16("code"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontID = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.LANGCODE;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineFontInfo2Tag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontID;
|
||||
|
||||
public String fontName;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int reserved;
|
||||
|
||||
public boolean fontFlagsSmallText;
|
||||
|
||||
public boolean fontFlagsShiftJIS;
|
||||
|
||||
public boolean fontFlagsANSI;
|
||||
|
||||
public boolean fontFlagsItalic;
|
||||
|
||||
public boolean fontFlagsBold;
|
||||
|
||||
public boolean fontFlagsWideCodes; //always 1
|
||||
|
||||
public LANGCODE languageCode;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public List<Integer> codeTable;
|
||||
|
||||
public static final int ID = 62;
|
||||
|
||||
public static final String NAME = "DefineFontInfo2";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontID);
|
||||
byte[] fontNameBytes = Utf8Helper.getBytes(fontName);
|
||||
sos.writeUI8(fontNameBytes.length);
|
||||
sos.write(fontNameBytes);
|
||||
sos.writeUB(2, reserved);
|
||||
sos.writeUB(1, fontFlagsSmallText ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsShiftJIS ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsANSI ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsItalic ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsBold ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsWideCodes ? 1 : 0);
|
||||
sos.writeLANGCODE(languageCode);
|
||||
for (int c : codeTable) {
|
||||
sos.writeUI16(c);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineFontInfo2Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
fontName = "New Font Info Name";
|
||||
languageCode = new LANGCODE();
|
||||
codeTable = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineFontInfo2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontID = sis.readUI16("fontID");
|
||||
int fontNameLen = sis.readUI8("fontNameLen");
|
||||
if (swf.version >= 6) {
|
||||
fontName = new String(sis.readBytesEx(fontNameLen, "fontName"), Utf8Helper.charset);
|
||||
} else {
|
||||
fontName = new String(sis.readBytesEx(fontNameLen, "fontName"));
|
||||
}
|
||||
reserved = (int) sis.readUB(2, "reserved");
|
||||
fontFlagsSmallText = sis.readUB(1, "fontFlagsSmallText") == 1;
|
||||
fontFlagsShiftJIS = sis.readUB(1, "fontFlagsShiftJIS") == 1;
|
||||
fontFlagsANSI = sis.readUB(1, "fontFlagsANSI") == 1;
|
||||
fontFlagsItalic = sis.readUB(1, "fontFlagsItalic") == 1;
|
||||
fontFlagsBold = sis.readUB(1, "fontFlagsBold") == 1;
|
||||
fontFlagsWideCodes = sis.readUB(1, "fontFlagsWideCodes") == 1; //Always 1
|
||||
languageCode = sis.readLANGCODE("languageCode");
|
||||
int ctLen = sis.available() / 2;
|
||||
codeTable = new ArrayList<>();
|
||||
for (int i = 0; i < ctLen; i++) {
|
||||
codeTable.add(sis.readUI16("code"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontID = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,159 +1,161 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineFontInfoTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontId;
|
||||
|
||||
public String fontName;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int reserved;
|
||||
|
||||
public boolean fontFlagsSmallText;
|
||||
|
||||
public boolean fontFlagsShiftJIS;
|
||||
|
||||
public boolean fontFlagsANSI;
|
||||
|
||||
public boolean fontFlagsItalic;
|
||||
|
||||
public boolean fontFlagsBold;
|
||||
|
||||
public boolean fontFlagsWideCodes;
|
||||
|
||||
@SWFType(value = BasicType.UI8, alternateValue = BasicType.UI16, alternateCondition = "fontFlagsWideCodes")
|
||||
public List<Integer> codeTable;
|
||||
|
||||
public static final int ID = 13;
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontId);
|
||||
byte[] fontNameBytes = Utf8Helper.getBytes(fontName);
|
||||
sos.writeUI8(fontNameBytes.length);
|
||||
sos.write(fontNameBytes);
|
||||
sos.writeUB(2, reserved);
|
||||
sos.writeUB(1, fontFlagsSmallText ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsShiftJIS ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsANSI ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsItalic ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsBold ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsWideCodes ? 1 : 0);
|
||||
for (int code : codeTable) {
|
||||
if (fontFlagsWideCodes) {
|
||||
sos.writeUI16(code);
|
||||
} else {
|
||||
sos.writeUI8(code);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineFontInfoTag(SWF swf) {
|
||||
super(swf, ID, "DefineFontInfo", null);
|
||||
fontName = "New Font Info Name";
|
||||
codeTable = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineFontInfoTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineFontInfo", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontId = sis.readUI16("fontId");
|
||||
int fontNameLen = sis.readUI8("fontNameLen");
|
||||
if (swf.version >= 6) {
|
||||
fontName = new String(sis.readBytesEx(fontNameLen, "fontName"), Utf8Helper.charset);
|
||||
} else {
|
||||
fontName = new String(sis.readBytesEx(fontNameLen, "fontName"));
|
||||
}
|
||||
reserved = (int) sis.readUB(2, "reserved");
|
||||
fontFlagsSmallText = sis.readUB(1, "fontFlagsSmallText") == 1;
|
||||
fontFlagsShiftJIS = sis.readUB(1, "fontFlagsShiftJIS") == 1;
|
||||
fontFlagsANSI = sis.readUB(1, "fontFlagsANSI") == 1;
|
||||
fontFlagsItalic = sis.readUB(1, "fontFlagsItalic") == 1;
|
||||
fontFlagsBold = sis.readUB(1, "fontFlagsBold") == 1;
|
||||
fontFlagsWideCodes = sis.readUB(1, "fontFlagsWideCodes") == 1;
|
||||
codeTable = new ArrayList<>();
|
||||
while (sis.available() > 0) {
|
||||
if (fontFlagsWideCodes) {
|
||||
codeTable.add(sis.readUI16("code"));
|
||||
} else {
|
||||
codeTable.add(sis.readUI8("code"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontId = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineFontInfoTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontId;
|
||||
|
||||
public String fontName;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int reserved;
|
||||
|
||||
public boolean fontFlagsSmallText;
|
||||
|
||||
public boolean fontFlagsShiftJIS;
|
||||
|
||||
public boolean fontFlagsANSI;
|
||||
|
||||
public boolean fontFlagsItalic;
|
||||
|
||||
public boolean fontFlagsBold;
|
||||
|
||||
public boolean fontFlagsWideCodes;
|
||||
|
||||
@SWFType(value = BasicType.UI8, alternateValue = BasicType.UI16, alternateCondition = "fontFlagsWideCodes")
|
||||
public List<Integer> codeTable;
|
||||
|
||||
public static final int ID = 13;
|
||||
|
||||
public static final String NAME = "DefineFontInfo";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontId);
|
||||
byte[] fontNameBytes = Utf8Helper.getBytes(fontName);
|
||||
sos.writeUI8(fontNameBytes.length);
|
||||
sos.write(fontNameBytes);
|
||||
sos.writeUB(2, reserved);
|
||||
sos.writeUB(1, fontFlagsSmallText ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsShiftJIS ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsANSI ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsItalic ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsBold ? 1 : 0);
|
||||
sos.writeUB(1, fontFlagsWideCodes ? 1 : 0);
|
||||
for (int code : codeTable) {
|
||||
if (fontFlagsWideCodes) {
|
||||
sos.writeUI16(code);
|
||||
} else {
|
||||
sos.writeUI8(code);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineFontInfoTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
fontName = "New Font Info Name";
|
||||
codeTable = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineFontInfoTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontId = sis.readUI16("fontId");
|
||||
int fontNameLen = sis.readUI8("fontNameLen");
|
||||
if (swf.version >= 6) {
|
||||
fontName = new String(sis.readBytesEx(fontNameLen, "fontName"), Utf8Helper.charset);
|
||||
} else {
|
||||
fontName = new String(sis.readBytesEx(fontNameLen, "fontName"));
|
||||
}
|
||||
reserved = (int) sis.readUB(2, "reserved");
|
||||
fontFlagsSmallText = sis.readUB(1, "fontFlagsSmallText") == 1;
|
||||
fontFlagsShiftJIS = sis.readUB(1, "fontFlagsShiftJIS") == 1;
|
||||
fontFlagsANSI = sis.readUB(1, "fontFlagsANSI") == 1;
|
||||
fontFlagsItalic = sis.readUB(1, "fontFlagsItalic") == 1;
|
||||
fontFlagsBold = sis.readUB(1, "fontFlagsBold") == 1;
|
||||
fontFlagsWideCodes = sis.readUB(1, "fontFlagsWideCodes") == 1;
|
||||
codeTable = new ArrayList<>();
|
||||
while (sis.available() > 0) {
|
||||
if (fontFlagsWideCodes) {
|
||||
codeTable.add(sis.readUI16("code"));
|
||||
} else {
|
||||
codeTable.add(sis.readUI8("code"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontId = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,97 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineFontNameTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontId;
|
||||
|
||||
public String fontName;
|
||||
|
||||
public String fontCopyright;
|
||||
|
||||
public static final int ID = 88;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineFontNameTag(SWF swf) {
|
||||
super(swf, ID, "DefineFontName", null);
|
||||
fontName = "New Font Name";
|
||||
fontCopyright = "Copyright text";
|
||||
}
|
||||
|
||||
public DefineFontNameTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineFontName", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontId = sis.readUI16("fontId");
|
||||
fontName = sis.readString("fontName");
|
||||
fontCopyright = sis.readString("fontCopyright");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontId);
|
||||
sos.writeString(fontName);
|
||||
sos.writeString(fontCopyright);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontId = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineFontNameTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontId;
|
||||
|
||||
public String fontName;
|
||||
|
||||
public String fontCopyright;
|
||||
|
||||
public static final int ID = 88;
|
||||
|
||||
public static final String NAME = "DefineFontName";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineFontNameTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
fontName = "New Font Name";
|
||||
fontCopyright = "Copyright text";
|
||||
}
|
||||
|
||||
public DefineFontNameTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontId = sis.readUI16("fontId");
|
||||
fontName = sis.readString("fontName");
|
||||
fontCopyright = sis.readString("fontCopyright");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontId);
|
||||
sos.writeString(fontName);
|
||||
sos.writeString(fontCopyright);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontId = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,368 +1,370 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.awt.Font;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineFontTag extends FontTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontId;
|
||||
|
||||
public List<SHAPE> glyphShapeTable;
|
||||
|
||||
@Internal
|
||||
private DefineFontInfoTag fontInfoTag = null;
|
||||
|
||||
@Internal
|
||||
private DefineFontInfo2Tag fontInfo2Tag = null;
|
||||
|
||||
public static final int ID = 10;
|
||||
|
||||
@Override
|
||||
public boolean isSmall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getGlyphAdvance(int glyphIndex) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGlyphWidth(int glyphIndex) {
|
||||
return glyphShapeTable.get(glyphIndex).getBounds().getWidth();
|
||||
}
|
||||
|
||||
private void ensureFontInfo() {
|
||||
if (fontInfoTag == null) {
|
||||
for (Tag t : swf.tags) {
|
||||
if (t instanceof DefineFontInfoTag) {
|
||||
if (((DefineFontInfoTag) t).fontId == fontId) {
|
||||
fontInfoTag = (DefineFontInfoTag) t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t instanceof DefineFontInfo2Tag) {
|
||||
if (((DefineFontInfo2Tag) t).fontID == fontId) {
|
||||
fontInfo2Tag = (DefineFontInfo2Tag) t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public char glyphToChar(int glyphIndex) {
|
||||
ensureFontInfo();
|
||||
if (fontInfo2Tag != null) {
|
||||
return (char) (int) fontInfo2Tag.codeTable.get(glyphIndex);
|
||||
} else if (fontInfoTag != null) {
|
||||
return (char) (int) fontInfoTag.codeTable.get(glyphIndex);
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int charToGlyph(char c) {
|
||||
ensureFontInfo();
|
||||
if (fontInfo2Tag != null) {
|
||||
return fontInfo2Tag.codeTable.indexOf((int) c);
|
||||
} else if (fontInfoTag != null) {
|
||||
return fontInfoTag.codeTable.indexOf((int) c);
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontId);
|
||||
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
|
||||
List<Integer> offsetTable = new ArrayList<>();
|
||||
SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion());
|
||||
for (SHAPE shape : glyphShapeTable) {
|
||||
offsetTable.add(glyphShapeTable.size() * 2 + (int) sos2.getPos());
|
||||
sos2.writeSHAPE(shape, 1);
|
||||
}
|
||||
for (int offset : offsetTable) {
|
||||
sos.writeUI16(offset);
|
||||
}
|
||||
sos.write(baos2.toByteArray());
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineFontTag(SWF swf) {
|
||||
super(swf, ID, "DefineFont", null);
|
||||
fontId = swf.getNextCharacterId();
|
||||
glyphShapeTable = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineFontTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineFont", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontId = sis.readUI16("fontId");
|
||||
glyphShapeTable = new ArrayList<>();
|
||||
|
||||
if (sis.available() > 0) {
|
||||
long pos = sis.getPos();
|
||||
int firstOffset = sis.readUI16("firstOffset");
|
||||
int nGlyphs = firstOffset / 2;
|
||||
|
||||
long[] offsetTable = new long[nGlyphs];
|
||||
offsetTable[0] = firstOffset;
|
||||
for (int i = 1; i < nGlyphs; i++) {
|
||||
offsetTable[i] = sis.readUI16("offset");
|
||||
}
|
||||
for (int i = 0; i < nGlyphs; i++) {
|
||||
sis.seek(pos + offsetTable[i]);
|
||||
glyphShapeTable.add(sis.readSHAPE(1, false, "shape"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFontId() {
|
||||
return fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SHAPE> getGlyphShapeTable() {
|
||||
return glyphShapeTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFontNameIntag() {
|
||||
ensureFontInfo();
|
||||
if (fontInfo2Tag != null) {
|
||||
return fontInfo2Tag.fontName;
|
||||
}
|
||||
if (fontInfoTag != null) {
|
||||
return fontInfoTag.fontName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBold() {
|
||||
if (fontInfo2Tag != null) {
|
||||
return fontInfo2Tag.fontFlagsBold;
|
||||
}
|
||||
if (fontInfoTag != null) {
|
||||
return fontInfoTag.fontFlagsBold;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItalic() {
|
||||
if (fontInfo2Tag != null) {
|
||||
return fontInfo2Tag.fontFlagsItalic;
|
||||
}
|
||||
if (fontInfoTag != null) {
|
||||
return fontInfoTag.fontFlagsItalic;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSmallEditable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBoldEditable() {
|
||||
return fontInfo2Tag != null || fontInfoTag != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItalicEditable() {
|
||||
return fontInfo2Tag != null || fontInfoTag != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBold(boolean value) {
|
||||
if (fontInfo2Tag != null) {
|
||||
fontInfo2Tag.fontFlagsBold = value;
|
||||
}
|
||||
if (fontInfoTag != null) {
|
||||
fontInfoTag.fontFlagsBold = value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItalic(boolean value) {
|
||||
if (fontInfo2Tag != null) {
|
||||
fontInfo2Tag.fontFlagsItalic = value;
|
||||
}
|
||||
if (fontInfoTag != null) {
|
||||
fontInfoTag.fontFlagsItalic = value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAscent() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDescent() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLeading() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDivider() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCharacter(char character, Font font) {
|
||||
SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(font, (int) Math.round(getDivider() * 1024), character);
|
||||
List<Integer> codeTable = new ArrayList<>();
|
||||
ensureFontInfo();
|
||||
if (fontInfoTag != null) {
|
||||
codeTable = fontInfoTag.codeTable;
|
||||
}
|
||||
if (fontInfo2Tag != null) {
|
||||
codeTable = fontInfo2Tag.codeTable;
|
||||
}
|
||||
int code = (int) character;
|
||||
int pos = -1;
|
||||
boolean exists = false;
|
||||
for (int i = 0; i < codeTable.size(); i++) {
|
||||
if (codeTable.get(i) >= code) {
|
||||
if (codeTable.get(i) == code) {
|
||||
exists = true;
|
||||
}
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos == -1) {
|
||||
pos = codeTable.size();
|
||||
}
|
||||
if (!exists) {
|
||||
shiftGlyphIndices(fontId, pos);
|
||||
glyphShapeTable.add(pos, shp);
|
||||
codeTable.add(pos, (int) character);
|
||||
} else {
|
||||
glyphShapeTable.set(pos, shp);
|
||||
}
|
||||
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdvanceValues(Font font) {
|
||||
throw new UnsupportedOperationException("Setting the advance values for DefineFontTag is not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacters(List<Tag> tags) {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ensureFontInfo();
|
||||
if (fontInfoTag != null) {
|
||||
for (int i : fontInfoTag.codeTable) {
|
||||
ret.append((char) i);
|
||||
}
|
||||
}
|
||||
if (fontInfo2Tag != null) {
|
||||
for (int i : fontInfo2Tag.codeTable) {
|
||||
ret.append((char) i);
|
||||
}
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharKerningAdjustment(char c1, char c2) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.awt.Font;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineFontTag extends FontTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontId;
|
||||
|
||||
public List<SHAPE> glyphShapeTable;
|
||||
|
||||
@Internal
|
||||
private DefineFontInfoTag fontInfoTag = null;
|
||||
|
||||
@Internal
|
||||
private DefineFontInfo2Tag fontInfo2Tag = null;
|
||||
|
||||
public static final int ID = 10;
|
||||
|
||||
public static final String NAME = "DefineFont";
|
||||
|
||||
@Override
|
||||
public boolean isSmall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getGlyphAdvance(int glyphIndex) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGlyphWidth(int glyphIndex) {
|
||||
return glyphShapeTable.get(glyphIndex).getBounds().getWidth();
|
||||
}
|
||||
|
||||
private void ensureFontInfo() {
|
||||
if (fontInfoTag == null) {
|
||||
for (Tag t : swf.tags) {
|
||||
if (t instanceof DefineFontInfoTag) {
|
||||
if (((DefineFontInfoTag) t).fontId == fontId) {
|
||||
fontInfoTag = (DefineFontInfoTag) t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t instanceof DefineFontInfo2Tag) {
|
||||
if (((DefineFontInfo2Tag) t).fontID == fontId) {
|
||||
fontInfo2Tag = (DefineFontInfo2Tag) t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public char glyphToChar(int glyphIndex) {
|
||||
ensureFontInfo();
|
||||
if (fontInfo2Tag != null) {
|
||||
return (char) (int) fontInfo2Tag.codeTable.get(glyphIndex);
|
||||
} else if (fontInfoTag != null) {
|
||||
return (char) (int) fontInfoTag.codeTable.get(glyphIndex);
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int charToGlyph(char c) {
|
||||
ensureFontInfo();
|
||||
if (fontInfo2Tag != null) {
|
||||
return fontInfo2Tag.codeTable.indexOf((int) c);
|
||||
} else if (fontInfoTag != null) {
|
||||
return fontInfoTag.codeTable.indexOf((int) c);
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontId);
|
||||
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
|
||||
List<Integer> offsetTable = new ArrayList<>();
|
||||
SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion());
|
||||
for (SHAPE shape : glyphShapeTable) {
|
||||
offsetTable.add(glyphShapeTable.size() * 2 + (int) sos2.getPos());
|
||||
sos2.writeSHAPE(shape, 1);
|
||||
}
|
||||
for (int offset : offsetTable) {
|
||||
sos.writeUI16(offset);
|
||||
}
|
||||
sos.write(baos2.toByteArray());
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineFontTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
fontId = swf.getNextCharacterId();
|
||||
glyphShapeTable = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineFontTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontId = sis.readUI16("fontId");
|
||||
glyphShapeTable = new ArrayList<>();
|
||||
|
||||
if (sis.available() > 0) {
|
||||
long pos = sis.getPos();
|
||||
int firstOffset = sis.readUI16("firstOffset");
|
||||
int nGlyphs = firstOffset / 2;
|
||||
|
||||
long[] offsetTable = new long[nGlyphs];
|
||||
offsetTable[0] = firstOffset;
|
||||
for (int i = 1; i < nGlyphs; i++) {
|
||||
offsetTable[i] = sis.readUI16("offset");
|
||||
}
|
||||
for (int i = 0; i < nGlyphs; i++) {
|
||||
sis.seek(pos + offsetTable[i]);
|
||||
glyphShapeTable.add(sis.readSHAPE(1, false, "shape"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFontId() {
|
||||
return fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SHAPE> getGlyphShapeTable() {
|
||||
return glyphShapeTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFontNameIntag() {
|
||||
ensureFontInfo();
|
||||
if (fontInfo2Tag != null) {
|
||||
return fontInfo2Tag.fontName;
|
||||
}
|
||||
if (fontInfoTag != null) {
|
||||
return fontInfoTag.fontName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBold() {
|
||||
if (fontInfo2Tag != null) {
|
||||
return fontInfo2Tag.fontFlagsBold;
|
||||
}
|
||||
if (fontInfoTag != null) {
|
||||
return fontInfoTag.fontFlagsBold;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItalic() {
|
||||
if (fontInfo2Tag != null) {
|
||||
return fontInfo2Tag.fontFlagsItalic;
|
||||
}
|
||||
if (fontInfoTag != null) {
|
||||
return fontInfoTag.fontFlagsItalic;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSmallEditable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBoldEditable() {
|
||||
return fontInfo2Tag != null || fontInfoTag != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItalicEditable() {
|
||||
return fontInfo2Tag != null || fontInfoTag != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBold(boolean value) {
|
||||
if (fontInfo2Tag != null) {
|
||||
fontInfo2Tag.fontFlagsBold = value;
|
||||
}
|
||||
if (fontInfoTag != null) {
|
||||
fontInfoTag.fontFlagsBold = value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItalic(boolean value) {
|
||||
if (fontInfo2Tag != null) {
|
||||
fontInfo2Tag.fontFlagsItalic = value;
|
||||
}
|
||||
if (fontInfoTag != null) {
|
||||
fontInfoTag.fontFlagsItalic = value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAscent() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDescent() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLeading() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDivider() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCharacter(char character, Font font) {
|
||||
SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(font, (int) Math.round(getDivider() * 1024), character);
|
||||
List<Integer> codeTable = new ArrayList<>();
|
||||
ensureFontInfo();
|
||||
if (fontInfoTag != null) {
|
||||
codeTable = fontInfoTag.codeTable;
|
||||
}
|
||||
if (fontInfo2Tag != null) {
|
||||
codeTable = fontInfo2Tag.codeTable;
|
||||
}
|
||||
int code = (int) character;
|
||||
int pos = -1;
|
||||
boolean exists = false;
|
||||
for (int i = 0; i < codeTable.size(); i++) {
|
||||
if (codeTable.get(i) >= code) {
|
||||
if (codeTable.get(i) == code) {
|
||||
exists = true;
|
||||
}
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos == -1) {
|
||||
pos = codeTable.size();
|
||||
}
|
||||
if (!exists) {
|
||||
shiftGlyphIndices(fontId, pos);
|
||||
glyphShapeTable.add(pos, shp);
|
||||
codeTable.add(pos, (int) character);
|
||||
} else {
|
||||
glyphShapeTable.set(pos, shp);
|
||||
}
|
||||
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdvanceValues(Font font) {
|
||||
throw new UnsupportedOperationException("Setting the advance values for DefineFontTag is not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacters(List<Tag> tags) {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ensureFontInfo();
|
||||
if (fontInfoTag != null) {
|
||||
for (int i : fontInfoTag.codeTable) {
|
||||
ret.append((char) i);
|
||||
}
|
||||
}
|
||||
if (fontInfo2Tag != null) {
|
||||
for (int i : fontInfo2Tag.codeTable) {
|
||||
ret.append((char) i);
|
||||
}
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharKerningAdjustment(char c1, char c2) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,8 @@ public class DefineMorphShape2Tag extends MorphShapeTag {
|
||||
|
||||
public static final int ID = 84;
|
||||
|
||||
public static final String NAME = "DefineMorphShape2";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
@@ -94,7 +96,7 @@ public class DefineMorphShape2Tag extends MorphShapeTag {
|
||||
* @param swf
|
||||
*/
|
||||
public DefineMorphShape2Tag(SWF swf) {
|
||||
super(swf, ID, "DefineMorphShape2", null);
|
||||
super(swf, ID, NAME, null);
|
||||
characterId = swf.getNextCharacterId();
|
||||
startBounds = new RECT();
|
||||
endBounds = new RECT();
|
||||
@@ -116,7 +118,7 @@ public class DefineMorphShape2Tag extends MorphShapeTag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineMorphShape2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineMorphShape2", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ public class DefineMorphShapeTag extends MorphShapeTag {
|
||||
|
||||
public static final int ID = 46;
|
||||
|
||||
public static final String NAME = "DefineMorphShape";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
@@ -74,7 +76,7 @@ public class DefineMorphShapeTag extends MorphShapeTag {
|
||||
* @param swf
|
||||
*/
|
||||
public DefineMorphShapeTag(SWF swf) {
|
||||
super(swf, ID, "DefineMorphShape", null);
|
||||
super(swf, ID, NAME, null);
|
||||
characterId = swf.getNextCharacterId();
|
||||
startBounds = new RECT();
|
||||
endBounds = new RECT();
|
||||
@@ -94,7 +96,7 @@ public class DefineMorphShapeTag extends MorphShapeTag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineMorphShapeTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineMorphShape", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,93 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineScalingGridTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterId;
|
||||
|
||||
public RECT splitter;
|
||||
|
||||
public static final int ID = 78;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineScalingGridTag(SWF swf) {
|
||||
super(swf, ID, "DefineScalingGrid", null);
|
||||
splitter = new RECT();
|
||||
}
|
||||
|
||||
public DefineScalingGridTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineScalingGrid", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterId = sis.readUI16("characterId");
|
||||
splitter = sis.readRECT("splitter");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterId);
|
||||
sos.writeRECT(splitter);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterId = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineScalingGridTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterId;
|
||||
|
||||
public RECT splitter;
|
||||
|
||||
public static final int ID = 78;
|
||||
|
||||
public static final String NAME = "DefineScalingGrid";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineScalingGridTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
splitter = new RECT();
|
||||
}
|
||||
|
||||
public DefineScalingGridTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterId = sis.readUI16("characterId");
|
||||
splitter = sis.readRECT("splitter");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterId);
|
||||
sos.writeRECT(splitter);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterId = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ public class DefineSceneAndFrameLabelDataTag extends Tag {
|
||||
|
||||
public static final int ID = 86;
|
||||
|
||||
public static final String NAME = "DefineSceneAndFrameLabelData";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
@@ -84,7 +86,7 @@ public class DefineSceneAndFrameLabelDataTag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public DefineSceneAndFrameLabelDataTag(SWF swf) {
|
||||
super(swf, ID, "DefineSceneAndFrameLabelData", null);
|
||||
super(swf, ID, NAME, null);
|
||||
sceneOffsets = new long[0];
|
||||
sceneNames = new String[0];
|
||||
frameNums = new long[0];
|
||||
@@ -99,7 +101,7 @@ public class DefineSceneAndFrameLabelDataTag extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineSceneAndFrameLabelDataTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineSceneAndFrameLabelData", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,158 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineShape2Tag extends ShapeTag {
|
||||
|
||||
public static final int ID = 22;
|
||||
|
||||
private ByteArrayRange shapeData;
|
||||
|
||||
@Override
|
||||
public int getShapeNum() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SHAPEWITHSTYLE getShapes() {
|
||||
if (shapes == null && shapeData != null) {
|
||||
try {
|
||||
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
|
||||
sis.seek(shapeData.getPos());
|
||||
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
|
||||
shapeData = null; // not needed anymore, give it to GC
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineShape2Tag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
getShapes().getNeededCharacters(needed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = getShapes().removeCharacter(characterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
return shapeBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineShape2Tag(SWF swf) {
|
||||
super(swf, ID, "DefineShape2", null);
|
||||
shapeId = swf.getNextCharacterId();
|
||||
shapeBounds = new RECT();
|
||||
shapes = SHAPEWITHSTYLE.createEmpty(2);
|
||||
}
|
||||
|
||||
public DefineShape2Tag(SWFInputStream sis, ByteArrayRange data, boolean lazy) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineShape2", data);
|
||||
readData(sis, data, 0, false, false, lazy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
shapeId = sis.readUI16("shapeId");
|
||||
shapeBounds = sis.readRECT("shapeBounds");
|
||||
if (!lazy) {
|
||||
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
|
||||
} else {
|
||||
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, getVersion());
|
||||
try {
|
||||
sos.writeUI16(shapeId);
|
||||
sos.writeRECT(shapeBounds);
|
||||
sos.writeSHAPEWITHSTYLE(getShapes(), getShapeNum());
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.shapeId = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineShape2Tag extends ShapeTag {
|
||||
|
||||
public static final int ID = 22;
|
||||
|
||||
public static final String NAME = "DefineShape2";
|
||||
|
||||
private ByteArrayRange shapeData;
|
||||
|
||||
@Override
|
||||
public int getShapeNum() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SHAPEWITHSTYLE getShapes() {
|
||||
if (shapes == null && shapeData != null) {
|
||||
try {
|
||||
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
|
||||
sis.seek(shapeData.getPos());
|
||||
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
|
||||
shapeData = null; // not needed anymore, give it to GC
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineShape2Tag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
getShapes().getNeededCharacters(needed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = getShapes().removeCharacter(characterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
return shapeBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineShape2Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
shapeId = swf.getNextCharacterId();
|
||||
shapeBounds = new RECT();
|
||||
shapes = SHAPEWITHSTYLE.createEmpty(2);
|
||||
}
|
||||
|
||||
public DefineShape2Tag(SWFInputStream sis, ByteArrayRange data, boolean lazy) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, lazy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
shapeId = sis.readUI16("shapeId");
|
||||
shapeBounds = sis.readRECT("shapeBounds");
|
||||
if (!lazy) {
|
||||
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
|
||||
} else {
|
||||
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, getVersion());
|
||||
try {
|
||||
sos.writeUI16(shapeId);
|
||||
sos.writeRECT(shapeBounds);
|
||||
sos.writeSHAPEWITHSTYLE(getShapes(), getShapeNum());
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.shapeId = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,160 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineShape3Tag extends ShapeTag {
|
||||
|
||||
public static final int ID = 32;
|
||||
|
||||
private ByteArrayRange shapeData;
|
||||
|
||||
@Override
|
||||
public int getShapeNum() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SHAPEWITHSTYLE getShapes() {
|
||||
if (shapes == null && shapeData != null) {
|
||||
try {
|
||||
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
|
||||
sis.seek(shapeData.getPos());
|
||||
shapes = sis.readSHAPEWITHSTYLE(3, false, "shapes");
|
||||
shapeData = null; // not needed anymore, give it to GC
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineShape3Tag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
getShapes().getNeededCharacters(needed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = getShapes().removeCharacter(characterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
return shapeBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineShape3Tag(SWF swf) {
|
||||
super(swf, ID, "DefineShape3", null);
|
||||
shapeId = swf.getNextCharacterId();
|
||||
shapeBounds = new RECT();
|
||||
shapes = SHAPEWITHSTYLE.createEmpty(3);
|
||||
}
|
||||
|
||||
public DefineShape3Tag(SWFInputStream sis, ByteArrayRange data, boolean lazy) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineShape3", data);
|
||||
readData(sis, data, 0, false, false, lazy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
shapeId = sis.readUI16("shapeId");
|
||||
shapeBounds = sis.readRECT("shapeBounds");
|
||||
if (!lazy) {
|
||||
shapes = sis.readSHAPEWITHSTYLE(3, false, "shapes");
|
||||
} else {
|
||||
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(shapeId);
|
||||
sos.writeRECT(shapeBounds);
|
||||
sos.writeSHAPEWITHSTYLE(getShapes(), 3);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.shapeId = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineShape3Tag extends ShapeTag {
|
||||
|
||||
public static final int ID = 32;
|
||||
|
||||
public static final String NAME = "DefineShape3";
|
||||
|
||||
private ByteArrayRange shapeData;
|
||||
|
||||
@Override
|
||||
public int getShapeNum() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SHAPEWITHSTYLE getShapes() {
|
||||
if (shapes == null && shapeData != null) {
|
||||
try {
|
||||
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
|
||||
sis.seek(shapeData.getPos());
|
||||
shapes = sis.readSHAPEWITHSTYLE(3, false, "shapes");
|
||||
shapeData = null; // not needed anymore, give it to GC
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineShape3Tag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
getShapes().getNeededCharacters(needed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = getShapes().removeCharacter(characterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
return shapeBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineShape3Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
shapeId = swf.getNextCharacterId();
|
||||
shapeBounds = new RECT();
|
||||
shapes = SHAPEWITHSTYLE.createEmpty(3);
|
||||
}
|
||||
|
||||
public DefineShape3Tag(SWFInputStream sis, ByteArrayRange data, boolean lazy) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, lazy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
shapeId = sis.readUI16("shapeId");
|
||||
shapeBounds = sis.readRECT("shapeBounds");
|
||||
if (!lazy) {
|
||||
shapes = sis.readSHAPEWITHSTYLE(3, false, "shapes");
|
||||
} else {
|
||||
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(shapeId);
|
||||
sos.writeRECT(shapeBounds);
|
||||
sos.writeSHAPEWITHSTYLE(getShapes(), 3);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.shapeId = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,186 +1,188 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineShape4Tag extends ShapeTag {
|
||||
|
||||
public RECT edgeBounds;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 5)
|
||||
public int reserved;
|
||||
|
||||
public boolean usesFillWindingRule;
|
||||
|
||||
public boolean usesNonScalingStrokes;
|
||||
|
||||
public boolean usesScalingStrokes;
|
||||
|
||||
public static final int ID = 83;
|
||||
|
||||
private ByteArrayRange shapeData;
|
||||
|
||||
@Override
|
||||
public int getShapeNum() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SHAPEWITHSTYLE getShapes() {
|
||||
if (shapes == null && shapeData != null) {
|
||||
try {
|
||||
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
|
||||
sis.seek(shapeData.getPos());
|
||||
shapes = sis.readSHAPEWITHSTYLE(4, false, "shapes");
|
||||
shapeData = null; // not needed anymore, give it to GC
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineShape4Tag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
getShapes().getNeededCharacters(needed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = getShapes().removeCharacter(characterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
return shapeBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineShape4Tag(SWF swf) {
|
||||
super(swf, ID, "DefineShape4", null);
|
||||
shapeId = swf.getNextCharacterId();
|
||||
shapeBounds = new RECT();
|
||||
edgeBounds = new RECT();
|
||||
shapes = SHAPEWITHSTYLE.createEmpty(4);
|
||||
}
|
||||
|
||||
public DefineShape4Tag(SWFInputStream sis, ByteArrayRange data, boolean lazy) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineShape4", data);
|
||||
readData(sis, data, 0, false, false, lazy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
shapeId = sis.readUI16("shapeId");
|
||||
shapeBounds = sis.readRECT("shapeBounds");
|
||||
edgeBounds = sis.readRECT("edgeBounds");
|
||||
reserved = (int) sis.readUB(5, "reserved");
|
||||
usesFillWindingRule = sis.readUB(1, "usesFillWindingRule") == 1;
|
||||
usesNonScalingStrokes = sis.readUB(1, "usesNonScalingStrokes") == 1;
|
||||
usesScalingStrokes = sis.readUB(1, "usesScalingStrokes") == 1;
|
||||
if (!lazy) {
|
||||
shapes = sis.readSHAPEWITHSTYLE(4, false, "shapes");
|
||||
} else {
|
||||
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(shapeId);
|
||||
sos.writeRECT(shapeBounds);
|
||||
sos.writeRECT(edgeBounds);
|
||||
sos.writeUB(5, reserved);
|
||||
sos.writeUB(1, usesFillWindingRule ? 1 : 0);
|
||||
sos.writeUB(1, usesNonScalingStrokes ? 1 : 0);
|
||||
sos.writeUB(1, usesScalingStrokes ? 1 : 0);
|
||||
sos.writeSHAPEWITHSTYLE(getShapes(), 4);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.shapeId = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineShape4Tag extends ShapeTag {
|
||||
|
||||
public RECT edgeBounds;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 5)
|
||||
public int reserved;
|
||||
|
||||
public boolean usesFillWindingRule;
|
||||
|
||||
public boolean usesNonScalingStrokes;
|
||||
|
||||
public boolean usesScalingStrokes;
|
||||
|
||||
public static final int ID = 83;
|
||||
|
||||
public static final String NAME = "DefineShape4";
|
||||
|
||||
private ByteArrayRange shapeData;
|
||||
|
||||
@Override
|
||||
public int getShapeNum() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SHAPEWITHSTYLE getShapes() {
|
||||
if (shapes == null && shapeData != null) {
|
||||
try {
|
||||
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
|
||||
sis.seek(shapeData.getPos());
|
||||
shapes = sis.readSHAPEWITHSTYLE(4, false, "shapes");
|
||||
shapeData = null; // not needed anymore, give it to GC
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineShape4Tag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
getShapes().getNeededCharacters(needed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = getShapes().removeCharacter(characterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
return shapeBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineShape4Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
shapeId = swf.getNextCharacterId();
|
||||
shapeBounds = new RECT();
|
||||
edgeBounds = new RECT();
|
||||
shapes = SHAPEWITHSTYLE.createEmpty(4);
|
||||
}
|
||||
|
||||
public DefineShape4Tag(SWFInputStream sis, ByteArrayRange data, boolean lazy) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, lazy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
shapeId = sis.readUI16("shapeId");
|
||||
shapeBounds = sis.readRECT("shapeBounds");
|
||||
edgeBounds = sis.readRECT("edgeBounds");
|
||||
reserved = (int) sis.readUB(5, "reserved");
|
||||
usesFillWindingRule = sis.readUB(1, "usesFillWindingRule") == 1;
|
||||
usesNonScalingStrokes = sis.readUB(1, "usesNonScalingStrokes") == 1;
|
||||
usesScalingStrokes = sis.readUB(1, "usesScalingStrokes") == 1;
|
||||
if (!lazy) {
|
||||
shapes = sis.readSHAPEWITHSTYLE(4, false, "shapes");
|
||||
} else {
|
||||
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(shapeId);
|
||||
sos.writeRECT(shapeBounds);
|
||||
sos.writeRECT(edgeBounds);
|
||||
sos.writeUB(5, reserved);
|
||||
sos.writeUB(1, usesFillWindingRule ? 1 : 0);
|
||||
sos.writeUB(1, usesNonScalingStrokes ? 1 : 0);
|
||||
sos.writeUB(1, usesScalingStrokes ? 1 : 0);
|
||||
sos.writeSHAPEWITHSTYLE(getShapes(), 4);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.shapeId = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,158 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineShapeTag extends ShapeTag {
|
||||
|
||||
public static final int ID = 2;
|
||||
|
||||
private ByteArrayRange shapeData;
|
||||
|
||||
@Override
|
||||
public int getShapeNum() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SHAPEWITHSTYLE getShapes() {
|
||||
if (shapes == null && shapeData != null) {
|
||||
try {
|
||||
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
|
||||
sis.seek(shapeData.getPos());
|
||||
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
|
||||
shapeData = null; // not needed anymore, give it to GC
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineShapeTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
getShapes().getNeededCharacters(needed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = getShapes().removeCharacter(characterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
return shapeBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineShapeTag(SWF swf) {
|
||||
super(swf, ID, "DefineShape", null);
|
||||
shapeId = swf.getNextCharacterId();
|
||||
shapeBounds = new RECT();
|
||||
shapes = SHAPEWITHSTYLE.createEmpty(1);
|
||||
}
|
||||
|
||||
public DefineShapeTag(SWFInputStream sis, ByteArrayRange data, boolean lazy) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineShape", data);
|
||||
readData(sis, data, 0, false, false, lazy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
shapeId = sis.readUI16("shapeId");
|
||||
shapeBounds = sis.readRECT("shapeBounds");
|
||||
if (!lazy) {
|
||||
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
|
||||
} else {
|
||||
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, getVersion());
|
||||
try {
|
||||
sos.writeUI16(shapeId);
|
||||
sos.writeRECT(shapeBounds);
|
||||
sos.writeSHAPEWITHSTYLE(getShapes(), getShapeNum());
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.shapeId = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineShapeTag extends ShapeTag {
|
||||
|
||||
public static final int ID = 2;
|
||||
|
||||
public static final String NAME = "DefineShape";
|
||||
|
||||
private ByteArrayRange shapeData;
|
||||
|
||||
@Override
|
||||
public int getShapeNum() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SHAPEWITHSTYLE getShapes() {
|
||||
if (shapes == null && shapeData != null) {
|
||||
try {
|
||||
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
|
||||
sis.seek(shapeData.getPos());
|
||||
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
|
||||
shapeData = null; // not needed anymore, give it to GC
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineShapeTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
getShapes().getNeededCharacters(needed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = getShapes().replaceCharacter(oldCharacterId, newCharacterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = getShapes().removeCharacter(characterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
return shapeBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineShapeTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
shapeId = swf.getNextCharacterId();
|
||||
shapeBounds = new RECT();
|
||||
shapes = SHAPEWITHSTYLE.createEmpty(1);
|
||||
}
|
||||
|
||||
public DefineShapeTag(SWFInputStream sis, ByteArrayRange data, boolean lazy) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, lazy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
shapeId = sis.readUI16("shapeId");
|
||||
shapeBounds = sis.readRECT("shapeBounds");
|
||||
if (!lazy) {
|
||||
shapes = sis.readSHAPEWITHSTYLE(getShapeNum(), false, "shapes");
|
||||
} else {
|
||||
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, getVersion());
|
||||
try {
|
||||
sos.writeUI16(shapeId);
|
||||
sos.writeRECT(shapeBounds);
|
||||
sos.writeSHAPEWITHSTYLE(getShapes(), getShapeNum());
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.shapeId = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,362 +1,364 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.sound.MP3FRAME;
|
||||
import com.jpexs.decompiler.flash.types.sound.MP3SOUNDDATA;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineSoundTag extends CharacterTag implements SoundTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int soundId;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int soundFormat;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int soundRate;
|
||||
|
||||
public boolean soundSize;
|
||||
|
||||
public boolean soundType;
|
||||
|
||||
@SWFType(BasicType.UI32)
|
||||
public long soundSampleCount;
|
||||
|
||||
public ByteArrayRange soundData;
|
||||
|
||||
public static final int ID = 14;
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return soundId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.soundId = characterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(soundId);
|
||||
sos.writeUB(4, soundFormat);
|
||||
sos.writeUB(2, soundRate);
|
||||
sos.writeUB(1, soundSize ? 1 : 0);
|
||||
sos.writeUB(1, soundType ? 1 : 0);
|
||||
sos.writeUI32(soundSampleCount);
|
||||
sos.write(soundData);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineSoundTag(SWF swf) {
|
||||
super(swf, ID, "DefineSound", null);
|
||||
soundId = swf.getNextCharacterId();
|
||||
soundData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineSoundTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineSound", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
soundId = sis.readUI16("soundId");
|
||||
soundFormat = (int) sis.readUB(4, "soundFormat");
|
||||
soundRate = (int) sis.readUB(2, "soundRate");
|
||||
soundSize = sis.readUB(1, "soundSize") == 1;
|
||||
soundType = sis.readUB(1, "soundType") == 1;
|
||||
soundSampleCount = sis.readUI32("soundSampleCount");
|
||||
soundData = sis.readByteRangeEx(sis.available(), "soundData");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExportFormat() {
|
||||
if (soundFormat == SoundFormat.FORMAT_MP3) {
|
||||
return "mp3";
|
||||
}
|
||||
if (soundFormat == SoundFormat.FORMAT_ADPCM) {
|
||||
return "wav";
|
||||
}
|
||||
if (soundFormat == SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN) {
|
||||
return "wav";
|
||||
}
|
||||
if (soundFormat == SoundFormat.FORMAT_UNCOMPRESSED_NATIVE_ENDIAN) {
|
||||
return "wav";
|
||||
}
|
||||
if (soundFormat == SoundFormat.FORMAT_NELLYMOSER || soundFormat == SoundFormat.FORMAT_NELLYMOSER16KHZ || soundFormat == SoundFormat.FORMAT_NELLYMOSER8KHZ) {
|
||||
return "wav";
|
||||
}
|
||||
return "flv";
|
||||
}
|
||||
|
||||
private void loadID3v2(InputStream in) {
|
||||
int size = -1;
|
||||
try {
|
||||
// Read ID3v2 header (10 bytes).
|
||||
in.mark(10);
|
||||
size = readID3v2Header(in);
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
try {
|
||||
// Unread ID3v2 header (10 bytes).
|
||||
in.reset();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
// Load ID3v2 tags.
|
||||
try {
|
||||
if (size > 0) {
|
||||
byte[] rawid3v2 = new byte[size];
|
||||
in.read(rawid3v2, 0, rawid3v2.length);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse ID3v2 tag header to find out size of ID3v2 frames.
|
||||
*
|
||||
* @param in MP3 InputStream
|
||||
* @return size of ID3v2 frames + header
|
||||
* @throws IOException
|
||||
* @author JavaZOOM
|
||||
*/
|
||||
private int readID3v2Header(InputStream in) throws IOException {
|
||||
byte[] id3header = new byte[4];
|
||||
int size = -10;
|
||||
in.read(id3header, 0, 3);
|
||||
// Look for ID3v2
|
||||
if ((id3header[0] == 'I') && (id3header[1] == 'D') && (id3header[2] == '3')) {
|
||||
in.read(id3header, 0, 3);
|
||||
int majorVersion = id3header[0];
|
||||
int revision = id3header[1];
|
||||
in.read(id3header, 0, 4);
|
||||
size = (int) (id3header[0] << 21) + (id3header[1] << 14) + (id3header[2] << 7) + (id3header[3]);
|
||||
}
|
||||
return (size + 10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSound(InputStream is, int newSoundFormat) {
|
||||
int newSoundRate = -1;
|
||||
boolean newSoundSize = false;
|
||||
boolean newSoundType = false;
|
||||
long newSoundSampleCount = -1;
|
||||
byte[] newSoundData;
|
||||
switch (newSoundFormat) {
|
||||
case SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN:
|
||||
try (AudioInputStream audioIs = AudioSystem.getAudioInputStream(new BufferedInputStream(is))) {
|
||||
AudioFormat fmt = audioIs.getFormat();
|
||||
newSoundType = fmt.getChannels() == 2;
|
||||
newSoundSize = fmt.getSampleSizeInBits() == 16;
|
||||
newSoundSampleCount = audioIs.getFrameLength();
|
||||
newSoundData = Helper.readStream(audioIs);
|
||||
newSoundRate = (int) Math.round(fmt.getSampleRate());
|
||||
switch (newSoundRate) {
|
||||
case 5512:
|
||||
newSoundRate = 0;
|
||||
break;
|
||||
case 11025:
|
||||
newSoundRate = 1;
|
||||
break;
|
||||
case 22050:
|
||||
newSoundRate = 2;
|
||||
break;
|
||||
case 44100:
|
||||
newSoundRate = 3;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} catch (UnsupportedAudioFileException | IOException ex) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case SoundFormat.FORMAT_MP3:
|
||||
BufferedInputStream bis = new BufferedInputStream(is);
|
||||
loadID3v2(bis);
|
||||
byte[] mp3data = Helper.readStream(bis);
|
||||
|
||||
final int ID3_V1_LENTGH = 128;
|
||||
final int ID3_V1_EXT_LENGTH = 227;
|
||||
|
||||
if (mp3data.length > ID3_V1_LENTGH) {
|
||||
//ID3v1
|
||||
if (mp3data[mp3data.length - ID3_V1_LENTGH] == 'T' && mp3data[mp3data.length - ID3_V1_LENTGH + 1] == 'A' && mp3data[mp3data.length - ID3_V1_LENTGH + 2] == 'G') {
|
||||
mp3data = Arrays.copyOf(mp3data, mp3data.length - ID3_V1_LENTGH);
|
||||
if (mp3data.length > ID3_V1_EXT_LENGTH) {
|
||||
//ID3v1 extended
|
||||
if (mp3data[mp3data.length - ID3_V1_EXT_LENGTH] == 'T' && mp3data[mp3data.length - ID3_V1_EXT_LENGTH + 1] == 'A' && mp3data[mp3data.length - ID3_V1_EXT_LENGTH + 2] == 'G' && mp3data[mp3data.length - ID3_V1_EXT_LENGTH + 3] == '+') {
|
||||
mp3data = Arrays.copyOf(mp3data, mp3data.length - ID3_V1_EXT_LENGTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
MP3SOUNDDATA snd = new MP3SOUNDDATA(new SWFInputStream(swf, mp3data), true);
|
||||
if (!snd.frames.isEmpty()) {
|
||||
MP3FRAME fr = snd.frames.get(0);
|
||||
newSoundRate = fr.getSamplingRate();
|
||||
switch (newSoundRate) {
|
||||
case 11025:
|
||||
newSoundRate = 1;
|
||||
break;
|
||||
case 22050:
|
||||
newSoundRate = 2;
|
||||
break;
|
||||
case 44100:
|
||||
newSoundRate = 3;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
newSoundSize = true;
|
||||
newSoundType = fr.isStereo();
|
||||
int len = snd.sampleCount();
|
||||
if (fr.isStereo()) {
|
||||
len = len / 2;
|
||||
}
|
||||
newSoundSampleCount = len;
|
||||
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, SWF.DEFAULT_VERSION);
|
||||
sos.writeSI16(0); //Latency - how to calculate it?
|
||||
sos.write(mp3data);
|
||||
newSoundData = baos.toByteArray();
|
||||
} catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (newSoundData != null) {
|
||||
this.soundSize = newSoundSize;
|
||||
this.soundRate = newSoundRate;
|
||||
this.soundSampleCount = newSoundSampleCount;
|
||||
this.soundData = new ByteArrayRange(newSoundData);
|
||||
this.soundType = newSoundType;
|
||||
this.soundFormat = newSoundFormat;
|
||||
setModified(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundRate() {
|
||||
return soundRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundType() {
|
||||
return soundType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<byte[]> getRawSoundData() {
|
||||
List<byte[]> ret = new ArrayList<>();
|
||||
if (soundFormat == SoundFormat.FORMAT_MP3) {
|
||||
ret.add(soundData.getRangeData(2, soundData.getLength() - 2));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.add(soundData.getRangeData());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundFormatId() {
|
||||
return soundFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalSoundSampleCount() {
|
||||
return soundSampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundSize() {
|
||||
return soundSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundFormat getSoundFormat() {
|
||||
final int[] rateMap = {5512, 11025, 22050, 44100};
|
||||
return new SoundFormat(getSoundFormatId(), rateMap[getSoundRate()], getSoundType());
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.sound.MP3FRAME;
|
||||
import com.jpexs.decompiler.flash.types.sound.MP3SOUNDDATA;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineSoundTag extends CharacterTag implements SoundTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int soundId;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int soundFormat;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int soundRate;
|
||||
|
||||
public boolean soundSize;
|
||||
|
||||
public boolean soundType;
|
||||
|
||||
@SWFType(BasicType.UI32)
|
||||
public long soundSampleCount;
|
||||
|
||||
public ByteArrayRange soundData;
|
||||
|
||||
public static final int ID = 14;
|
||||
|
||||
public static final String NAME = "DefineSound";
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return soundId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.soundId = characterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(soundId);
|
||||
sos.writeUB(4, soundFormat);
|
||||
sos.writeUB(2, soundRate);
|
||||
sos.writeUB(1, soundSize ? 1 : 0);
|
||||
sos.writeUB(1, soundType ? 1 : 0);
|
||||
sos.writeUI32(soundSampleCount);
|
||||
sos.write(soundData);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineSoundTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
soundId = swf.getNextCharacterId();
|
||||
soundData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineSoundTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
soundId = sis.readUI16("soundId");
|
||||
soundFormat = (int) sis.readUB(4, "soundFormat");
|
||||
soundRate = (int) sis.readUB(2, "soundRate");
|
||||
soundSize = sis.readUB(1, "soundSize") == 1;
|
||||
soundType = sis.readUB(1, "soundType") == 1;
|
||||
soundSampleCount = sis.readUI32("soundSampleCount");
|
||||
soundData = sis.readByteRangeEx(sis.available(), "soundData");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExportFormat() {
|
||||
if (soundFormat == SoundFormat.FORMAT_MP3) {
|
||||
return "mp3";
|
||||
}
|
||||
if (soundFormat == SoundFormat.FORMAT_ADPCM) {
|
||||
return "wav";
|
||||
}
|
||||
if (soundFormat == SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN) {
|
||||
return "wav";
|
||||
}
|
||||
if (soundFormat == SoundFormat.FORMAT_UNCOMPRESSED_NATIVE_ENDIAN) {
|
||||
return "wav";
|
||||
}
|
||||
if (soundFormat == SoundFormat.FORMAT_NELLYMOSER || soundFormat == SoundFormat.FORMAT_NELLYMOSER16KHZ || soundFormat == SoundFormat.FORMAT_NELLYMOSER8KHZ) {
|
||||
return "wav";
|
||||
}
|
||||
return "flv";
|
||||
}
|
||||
|
||||
private void loadID3v2(InputStream in) {
|
||||
int size = -1;
|
||||
try {
|
||||
// Read ID3v2 header (10 bytes).
|
||||
in.mark(10);
|
||||
size = readID3v2Header(in);
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
try {
|
||||
// Unread ID3v2 header (10 bytes).
|
||||
in.reset();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
// Load ID3v2 tags.
|
||||
try {
|
||||
if (size > 0) {
|
||||
byte[] rawid3v2 = new byte[size];
|
||||
in.read(rawid3v2, 0, rawid3v2.length);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse ID3v2 tag header to find out size of ID3v2 frames.
|
||||
*
|
||||
* @param in MP3 InputStream
|
||||
* @return size of ID3v2 frames + header
|
||||
* @throws IOException
|
||||
* @author JavaZOOM
|
||||
*/
|
||||
private int readID3v2Header(InputStream in) throws IOException {
|
||||
byte[] id3header = new byte[4];
|
||||
int size = -10;
|
||||
in.read(id3header, 0, 3);
|
||||
// Look for ID3v2
|
||||
if ((id3header[0] == 'I') && (id3header[1] == 'D') && (id3header[2] == '3')) {
|
||||
in.read(id3header, 0, 3);
|
||||
int majorVersion = id3header[0];
|
||||
int revision = id3header[1];
|
||||
in.read(id3header, 0, 4);
|
||||
size = (int) (id3header[0] << 21) + (id3header[1] << 14) + (id3header[2] << 7) + (id3header[3]);
|
||||
}
|
||||
return (size + 10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSound(InputStream is, int newSoundFormat) {
|
||||
int newSoundRate = -1;
|
||||
boolean newSoundSize = false;
|
||||
boolean newSoundType = false;
|
||||
long newSoundSampleCount = -1;
|
||||
byte[] newSoundData;
|
||||
switch (newSoundFormat) {
|
||||
case SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN:
|
||||
try (AudioInputStream audioIs = AudioSystem.getAudioInputStream(new BufferedInputStream(is))) {
|
||||
AudioFormat fmt = audioIs.getFormat();
|
||||
newSoundType = fmt.getChannels() == 2;
|
||||
newSoundSize = fmt.getSampleSizeInBits() == 16;
|
||||
newSoundSampleCount = audioIs.getFrameLength();
|
||||
newSoundData = Helper.readStream(audioIs);
|
||||
newSoundRate = (int) Math.round(fmt.getSampleRate());
|
||||
switch (newSoundRate) {
|
||||
case 5512:
|
||||
newSoundRate = 0;
|
||||
break;
|
||||
case 11025:
|
||||
newSoundRate = 1;
|
||||
break;
|
||||
case 22050:
|
||||
newSoundRate = 2;
|
||||
break;
|
||||
case 44100:
|
||||
newSoundRate = 3;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} catch (UnsupportedAudioFileException | IOException ex) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case SoundFormat.FORMAT_MP3:
|
||||
BufferedInputStream bis = new BufferedInputStream(is);
|
||||
loadID3v2(bis);
|
||||
byte[] mp3data = Helper.readStream(bis);
|
||||
|
||||
final int ID3_V1_LENTGH = 128;
|
||||
final int ID3_V1_EXT_LENGTH = 227;
|
||||
|
||||
if (mp3data.length > ID3_V1_LENTGH) {
|
||||
//ID3v1
|
||||
if (mp3data[mp3data.length - ID3_V1_LENTGH] == 'T' && mp3data[mp3data.length - ID3_V1_LENTGH + 1] == 'A' && mp3data[mp3data.length - ID3_V1_LENTGH + 2] == 'G') {
|
||||
mp3data = Arrays.copyOf(mp3data, mp3data.length - ID3_V1_LENTGH);
|
||||
if (mp3data.length > ID3_V1_EXT_LENGTH) {
|
||||
//ID3v1 extended
|
||||
if (mp3data[mp3data.length - ID3_V1_EXT_LENGTH] == 'T' && mp3data[mp3data.length - ID3_V1_EXT_LENGTH + 1] == 'A' && mp3data[mp3data.length - ID3_V1_EXT_LENGTH + 2] == 'G' && mp3data[mp3data.length - ID3_V1_EXT_LENGTH + 3] == '+') {
|
||||
mp3data = Arrays.copyOf(mp3data, mp3data.length - ID3_V1_EXT_LENGTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
MP3SOUNDDATA snd = new MP3SOUNDDATA(new SWFInputStream(swf, mp3data), true);
|
||||
if (!snd.frames.isEmpty()) {
|
||||
MP3FRAME fr = snd.frames.get(0);
|
||||
newSoundRate = fr.getSamplingRate();
|
||||
switch (newSoundRate) {
|
||||
case 11025:
|
||||
newSoundRate = 1;
|
||||
break;
|
||||
case 22050:
|
||||
newSoundRate = 2;
|
||||
break;
|
||||
case 44100:
|
||||
newSoundRate = 3;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
newSoundSize = true;
|
||||
newSoundType = fr.isStereo();
|
||||
int len = snd.sampleCount();
|
||||
if (fr.isStereo()) {
|
||||
len = len / 2;
|
||||
}
|
||||
newSoundSampleCount = len;
|
||||
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, SWF.DEFAULT_VERSION);
|
||||
sos.writeSI16(0); //Latency - how to calculate it?
|
||||
sos.write(mp3data);
|
||||
newSoundData = baos.toByteArray();
|
||||
} catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (newSoundData != null) {
|
||||
this.soundSize = newSoundSize;
|
||||
this.soundRate = newSoundRate;
|
||||
this.soundSampleCount = newSoundSampleCount;
|
||||
this.soundData = new ByteArrayRange(newSoundData);
|
||||
this.soundType = newSoundType;
|
||||
this.soundFormat = newSoundFormat;
|
||||
setModified(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundRate() {
|
||||
return soundRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundType() {
|
||||
return soundType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<byte[]> getRawSoundData() {
|
||||
List<byte[]> ret = new ArrayList<>();
|
||||
if (soundFormat == SoundFormat.FORMAT_MP3) {
|
||||
ret.add(soundData.getRangeData(2, soundData.getLength() - 2));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.add(soundData.getRangeData());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundFormatId() {
|
||||
return soundFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalSoundSampleCount() {
|
||||
return soundSampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundSize() {
|
||||
return soundSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundFormat getSoundFormat() {
|
||||
final int[] rateMap = {5512, 11025, 22050, 44100};
|
||||
return new SoundFormat(getSoundFormatId(), rateMap[getSoundRate()], getSoundType());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,394 +1,396 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RenderContext;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Defines a sprite character
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timelined {
|
||||
|
||||
/**
|
||||
* Character ID of sprite
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int spriteId;
|
||||
|
||||
/**
|
||||
* Number of frames in sprite
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int frameCount;
|
||||
|
||||
/**
|
||||
* A series of tags
|
||||
*/
|
||||
public List<Tag> subTags;
|
||||
|
||||
public boolean hasEndTag;
|
||||
|
||||
public static final int ID = 39;
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
private boolean isSingleFrameInitialized;
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
private static final Cache<DefineSpriteTag, RECT> rectCache = Cache.getInstance(true, true, "rect_sprite");
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
if (timeline == null) {
|
||||
timeline = new Timeline(swf, this, subTags, spriteId, getRect());
|
||||
}
|
||||
return timeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTimeline() {
|
||||
if (timeline != null) {
|
||||
timeline.reset(swf, this, subTags, spriteId, getRect());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return spriteId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.spriteId = characterId;
|
||||
}
|
||||
|
||||
private RECT getCharacterBounds(Set<Integer> characters, Set<BoundedTag> added) {
|
||||
RECT ret = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
boolean foundSomething = false;
|
||||
for (int c : characters) {
|
||||
Tag t = swf.getCharacter(c);
|
||||
RECT r = null;
|
||||
if (t instanceof BoundedTag) {
|
||||
BoundedTag bt = (BoundedTag) t;
|
||||
if (!added.contains(bt)) {
|
||||
added.add(bt);
|
||||
r = bt.getRect(added);
|
||||
added.remove(bt);
|
||||
}
|
||||
}
|
||||
if (r != null) {
|
||||
foundSomething = true;
|
||||
ret.Xmin = Math.min(r.Xmin, ret.Xmin);
|
||||
ret.Ymin = Math.min(r.Ymin, ret.Ymin);
|
||||
ret.Xmax = Math.max(r.Xmax, ret.Xmax);
|
||||
ret.Ymax = Math.max(r.Ymax, ret.Ymax);
|
||||
}
|
||||
}
|
||||
if (!foundSomething) {
|
||||
return new RECT();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect() {
|
||||
return getRect(new HashSet<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
if (rectCache.contains(this)) {
|
||||
return rectCache.get(this);
|
||||
}
|
||||
RECT ret = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
HashMap<Integer, Integer> depthMap = new HashMap<>();
|
||||
boolean foundSomething = false;
|
||||
for (Tag t : subTags) {
|
||||
MATRIX m = null;
|
||||
int characterId = -1;
|
||||
if (t instanceof PlaceObjectTypeTag) {
|
||||
PlaceObjectTypeTag pot = (PlaceObjectTypeTag) t;
|
||||
m = pot.getMatrix();
|
||||
int charId = pot.getCharacterId();
|
||||
if (charId > -1) {
|
||||
depthMap.put(pot.getDepth(), charId);
|
||||
characterId = charId;
|
||||
} else {
|
||||
Integer chi = depthMap.get(pot.getDepth());
|
||||
if (chi != null) {
|
||||
characterId = chi;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (characterId == -1) {
|
||||
continue;
|
||||
}
|
||||
Set<Integer> need = new HashSet<>();
|
||||
need.add(characterId);
|
||||
RECT r = getCharacterBounds(need, added);
|
||||
|
||||
if (m != null) {
|
||||
AffineTransform trans = SWF.matrixToTransform(m);
|
||||
|
||||
java.awt.Point topleft = new java.awt.Point();
|
||||
trans.transform(new java.awt.Point(r.Xmin, r.Ymin), topleft);
|
||||
java.awt.Point topright = new java.awt.Point();
|
||||
trans.transform(new java.awt.Point(r.Xmax, r.Ymin), topright);
|
||||
java.awt.Point bottomright = new java.awt.Point();
|
||||
trans.transform(new java.awt.Point(r.Xmax, r.Ymax), bottomright);
|
||||
java.awt.Point bottomleft = new java.awt.Point();
|
||||
trans.transform(new java.awt.Point(r.Xmin, r.Ymax), bottomleft);
|
||||
|
||||
r.Xmin = (int) Math.min(Math.min(Math.min(topleft.x, topright.x), bottomleft.x), bottomright.x);
|
||||
r.Ymin = (int) Math.min(Math.min(Math.min(topleft.y, topright.y), bottomleft.y), bottomright.y);
|
||||
r.Xmax = (int) Math.max(Math.max(Math.max(topleft.x, topright.x), bottomleft.x), bottomright.x);
|
||||
r.Ymax = (int) Math.max(Math.max(Math.max(topleft.y, topright.y), bottomleft.y), bottomright.y);
|
||||
|
||||
}
|
||||
ret.Xmin = Math.min(r.Xmin, ret.Xmin);
|
||||
ret.Ymin = Math.min(r.Ymin, ret.Ymin);
|
||||
ret.Xmax = Math.max(r.Xmax, ret.Xmax);
|
||||
ret.Ymax = Math.max(r.Ymax, ret.Ymax);
|
||||
foundSomething = true;
|
||||
}
|
||||
if (!foundSomething) {
|
||||
ret = new RECT();
|
||||
}
|
||||
rectCache.put(this, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineSpriteTag(SWF swf) {
|
||||
super(swf, ID, "DefineSprite", null);
|
||||
spriteId = swf.getNextCharacterId();
|
||||
subTags = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @param level
|
||||
* @param parallel
|
||||
* @param skipUnusualTags
|
||||
* @throws IOException
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public DefineSpriteTag(SWFInputStream sis, int level, ByteArrayRange data, boolean parallel, boolean skipUnusualTags) throws IOException, InterruptedException {
|
||||
super(sis.getSwf(), ID, "DefineSprite", data);
|
||||
readData(sis, data, level, parallel, skipUnusualTags, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException, InterruptedException {
|
||||
spriteId = sis.readUI16("spriteId");
|
||||
frameCount = sis.readUI16("frameCount");
|
||||
List<Tag> subTags = sis.readTagList(this, level + 1, parallel, skipUnusualTags, true, lazy);
|
||||
if (subTags.size() > 0 && subTags.get(subTags.size() - 1).getId() == EndTag.ID) {
|
||||
hasEndTag = true;
|
||||
subTags.remove(subTags.size() - 1);
|
||||
}
|
||||
this.subTags = subTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
if (Configuration.debugCopy.get()) {
|
||||
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
|
||||
}
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(spriteId);
|
||||
sos.writeUI16(frameCount);
|
||||
sos.writeTags(subTags);
|
||||
if (hasEndTag) {
|
||||
sos.writeUI16(0);
|
||||
}
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public List<Tag> getSubTags() {
|
||||
return subTags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified(boolean value) {
|
||||
if (!value) {
|
||||
for (Tag subTag : subTags) {
|
||||
subTag.setModified(false);
|
||||
}
|
||||
}
|
||||
|
||||
super.setModified(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createOriginalData() {
|
||||
super.createOriginalData();
|
||||
for (Tag subTag : subTags) {
|
||||
subTag.createOriginalData();
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
rectCache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
for (Tag t : subTags) {
|
||||
if (t instanceof CharacterIdTag) {
|
||||
needed.add(((CharacterIdTag) t).getCharacterId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = getTimeline().replaceCharacter(oldCharacterId, newCharacterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = getTimeline().removeCharacter(characterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUsedParameters() {
|
||||
return PARAMETER_FRAME | PARAMETER_TIME | PARAMETER_RATIO; // inner tags can contain morphshapes, too
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
|
||||
return getTimeline().getOutline(frame, time, ratio, renderContext, transformation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
|
||||
SWF.frameToImage(getTimeline(), frame, time, renderContext, image, transformation, colorTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) throws IOException {
|
||||
SWF.frameToSvg(getTimeline(), 0, 0, null, 0, exporter, colorTransform, level + 1, zoom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toHtmlCanvas(double unitDivisor) {
|
||||
return getTimeline().toHtmlCanvas(unitDivisor, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
// flashplayer ignores the count stored in frameCount
|
||||
return getTimeline().getFrameCount(); // frameCount
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
initialiteIsSingleFrame();
|
||||
}
|
||||
return isSingleFrame;
|
||||
}
|
||||
|
||||
private synchronized void initialiteIsSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
if (getTimeline().getRealFrameCount() > 1) {
|
||||
isSingleFrameInitialized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
isSingleFrame = getTimeline().isSingleFrame();
|
||||
isSingleFrameInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
if (super.isModified()) {
|
||||
return true;
|
||||
}
|
||||
for (Tag t : subTags) {
|
||||
if (t.isModified()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RenderContext;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Defines a sprite character
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timelined {
|
||||
|
||||
/**
|
||||
* Character ID of sprite
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int spriteId;
|
||||
|
||||
/**
|
||||
* Number of frames in sprite
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int frameCount;
|
||||
|
||||
/**
|
||||
* A series of tags
|
||||
*/
|
||||
public List<Tag> subTags;
|
||||
|
||||
public boolean hasEndTag;
|
||||
|
||||
public static final int ID = 39;
|
||||
|
||||
public static final String NAME = "DefineSprite";
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
private boolean isSingleFrameInitialized;
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
private static final Cache<DefineSpriteTag, RECT> rectCache = Cache.getInstance(true, true, "rect_sprite");
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
if (timeline == null) {
|
||||
timeline = new Timeline(swf, this, subTags, spriteId, getRect());
|
||||
}
|
||||
return timeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTimeline() {
|
||||
if (timeline != null) {
|
||||
timeline.reset(swf, this, subTags, spriteId, getRect());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return spriteId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.spriteId = characterId;
|
||||
}
|
||||
|
||||
private RECT getCharacterBounds(Set<Integer> characters, Set<BoundedTag> added) {
|
||||
RECT ret = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
boolean foundSomething = false;
|
||||
for (int c : characters) {
|
||||
Tag t = swf.getCharacter(c);
|
||||
RECT r = null;
|
||||
if (t instanceof BoundedTag) {
|
||||
BoundedTag bt = (BoundedTag) t;
|
||||
if (!added.contains(bt)) {
|
||||
added.add(bt);
|
||||
r = bt.getRect(added);
|
||||
added.remove(bt);
|
||||
}
|
||||
}
|
||||
if (r != null) {
|
||||
foundSomething = true;
|
||||
ret.Xmin = Math.min(r.Xmin, ret.Xmin);
|
||||
ret.Ymin = Math.min(r.Ymin, ret.Ymin);
|
||||
ret.Xmax = Math.max(r.Xmax, ret.Xmax);
|
||||
ret.Ymax = Math.max(r.Ymax, ret.Ymax);
|
||||
}
|
||||
}
|
||||
if (!foundSomething) {
|
||||
return new RECT();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect() {
|
||||
return getRect(new HashSet<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
if (rectCache.contains(this)) {
|
||||
return rectCache.get(this);
|
||||
}
|
||||
RECT ret = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
HashMap<Integer, Integer> depthMap = new HashMap<>();
|
||||
boolean foundSomething = false;
|
||||
for (Tag t : subTags) {
|
||||
MATRIX m = null;
|
||||
int characterId = -1;
|
||||
if (t instanceof PlaceObjectTypeTag) {
|
||||
PlaceObjectTypeTag pot = (PlaceObjectTypeTag) t;
|
||||
m = pot.getMatrix();
|
||||
int charId = pot.getCharacterId();
|
||||
if (charId > -1) {
|
||||
depthMap.put(pot.getDepth(), charId);
|
||||
characterId = charId;
|
||||
} else {
|
||||
Integer chi = depthMap.get(pot.getDepth());
|
||||
if (chi != null) {
|
||||
characterId = chi;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (characterId == -1) {
|
||||
continue;
|
||||
}
|
||||
Set<Integer> need = new HashSet<>();
|
||||
need.add(characterId);
|
||||
RECT r = getCharacterBounds(need, added);
|
||||
|
||||
if (m != null) {
|
||||
AffineTransform trans = SWF.matrixToTransform(m);
|
||||
|
||||
java.awt.Point topleft = new java.awt.Point();
|
||||
trans.transform(new java.awt.Point(r.Xmin, r.Ymin), topleft);
|
||||
java.awt.Point topright = new java.awt.Point();
|
||||
trans.transform(new java.awt.Point(r.Xmax, r.Ymin), topright);
|
||||
java.awt.Point bottomright = new java.awt.Point();
|
||||
trans.transform(new java.awt.Point(r.Xmax, r.Ymax), bottomright);
|
||||
java.awt.Point bottomleft = new java.awt.Point();
|
||||
trans.transform(new java.awt.Point(r.Xmin, r.Ymax), bottomleft);
|
||||
|
||||
r.Xmin = (int) Math.min(Math.min(Math.min(topleft.x, topright.x), bottomleft.x), bottomright.x);
|
||||
r.Ymin = (int) Math.min(Math.min(Math.min(topleft.y, topright.y), bottomleft.y), bottomright.y);
|
||||
r.Xmax = (int) Math.max(Math.max(Math.max(topleft.x, topright.x), bottomleft.x), bottomright.x);
|
||||
r.Ymax = (int) Math.max(Math.max(Math.max(topleft.y, topright.y), bottomleft.y), bottomright.y);
|
||||
|
||||
}
|
||||
ret.Xmin = Math.min(r.Xmin, ret.Xmin);
|
||||
ret.Ymin = Math.min(r.Ymin, ret.Ymin);
|
||||
ret.Xmax = Math.max(r.Xmax, ret.Xmax);
|
||||
ret.Ymax = Math.max(r.Ymax, ret.Ymax);
|
||||
foundSomething = true;
|
||||
}
|
||||
if (!foundSomething) {
|
||||
ret = new RECT();
|
||||
}
|
||||
rectCache.put(this, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineSpriteTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
spriteId = swf.getNextCharacterId();
|
||||
subTags = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @param level
|
||||
* @param parallel
|
||||
* @param skipUnusualTags
|
||||
* @throws IOException
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public DefineSpriteTag(SWFInputStream sis, int level, ByteArrayRange data, boolean parallel, boolean skipUnusualTags) throws IOException, InterruptedException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, level, parallel, skipUnusualTags, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException, InterruptedException {
|
||||
spriteId = sis.readUI16("spriteId");
|
||||
frameCount = sis.readUI16("frameCount");
|
||||
List<Tag> subTags = sis.readTagList(this, level + 1, parallel, skipUnusualTags, true, lazy);
|
||||
if (subTags.size() > 0 && subTags.get(subTags.size() - 1).getId() == EndTag.ID) {
|
||||
hasEndTag = true;
|
||||
subTags.remove(subTags.size() - 1);
|
||||
}
|
||||
this.subTags = subTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
if (Configuration.debugCopy.get()) {
|
||||
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
|
||||
}
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(spriteId);
|
||||
sos.writeUI16(frameCount);
|
||||
sos.writeTags(subTags);
|
||||
if (hasEndTag) {
|
||||
sos.writeUI16(0);
|
||||
}
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public List<Tag> getSubTags() {
|
||||
return subTags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified(boolean value) {
|
||||
if (!value) {
|
||||
for (Tag subTag : subTags) {
|
||||
subTag.setModified(false);
|
||||
}
|
||||
}
|
||||
|
||||
super.setModified(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createOriginalData() {
|
||||
super.createOriginalData();
|
||||
for (Tag subTag : subTags) {
|
||||
subTag.createOriginalData();
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
rectCache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
for (Tag t : subTags) {
|
||||
if (t instanceof CharacterIdTag) {
|
||||
needed.add(((CharacterIdTag) t).getCharacterId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = getTimeline().replaceCharacter(oldCharacterId, newCharacterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = getTimeline().removeCharacter(characterId);
|
||||
if (modified) {
|
||||
setModified(true);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUsedParameters() {
|
||||
return PARAMETER_FRAME | PARAMETER_TIME | PARAMETER_RATIO; // inner tags can contain morphshapes, too
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
|
||||
return getTimeline().getOutline(frame, time, ratio, renderContext, transformation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
|
||||
SWF.frameToImage(getTimeline(), frame, time, renderContext, image, transformation, colorTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) throws IOException {
|
||||
SWF.frameToSvg(getTimeline(), 0, 0, null, 0, exporter, colorTransform, level + 1, zoom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toHtmlCanvas(double unitDivisor) {
|
||||
return getTimeline().toHtmlCanvas(unitDivisor, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFrames() {
|
||||
// flashplayer ignores the count stored in frameCount
|
||||
return getTimeline().getFrameCount(); // frameCount
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
initialiteIsSingleFrame();
|
||||
}
|
||||
return isSingleFrame;
|
||||
}
|
||||
|
||||
private synchronized void initialiteIsSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
if (getTimeline().getRealFrameCount() > 1) {
|
||||
isSingleFrameInitialized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
isSingleFrame = getTimeline().isSingleFrame();
|
||||
isSingleFrameInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
if (super.isModified()) {
|
||||
return true;
|
||||
}
|
||||
for (Tag t : subTags) {
|
||||
if (t.isModified()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.StaticTextTag;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineText2Tag extends StaticTextTag {
|
||||
|
||||
public static final int ID = 33;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineText2Tag(SWF swf) {
|
||||
super(swf, ID, "DefineText2", null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
textBounds = new RECT();
|
||||
textMatrix = new MATRIX();
|
||||
textRecords = new ArrayList<>();
|
||||
glyphBits = 0;
|
||||
advanceBits = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineText2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineText2", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextNum() {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.StaticTextTag;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineText2Tag extends StaticTextTag {
|
||||
|
||||
public static final int ID = 33;
|
||||
|
||||
public static final String NAME = "DefineText2";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineText2Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
textBounds = new RECT();
|
||||
textMatrix = new MATRIX();
|
||||
textRecords = new ArrayList<>();
|
||||
glyphBits = 0;
|
||||
advanceBits = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineText2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextNum() {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.StaticTextTag;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.TEXTRECORD;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineTextTag extends StaticTextTag {
|
||||
|
||||
public static final int ID = 11;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineTextTag(SWF swf) {
|
||||
super(swf, ID, "DefineText", null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
textBounds = new RECT();
|
||||
textMatrix = new MATRIX();
|
||||
textRecords = new ArrayList<>();
|
||||
glyphBits = 0;
|
||||
advanceBits = 0;
|
||||
}
|
||||
|
||||
public DefineTextTag(SWF swf, int characterID, RECT textBounds, MATRIX textMatrix, List<TEXTRECORD> textRecords) {
|
||||
super(swf, ID, "DefineText", null);
|
||||
this.characterID = characterID;
|
||||
this.textBounds = textBounds;
|
||||
this.textMatrix = textMatrix;
|
||||
this.textRecords = textRecords;
|
||||
this.glyphBits = 0;
|
||||
this.advanceBits = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineTextTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineText", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextNum() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.StaticTextTag;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.TEXTRECORD;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineTextTag extends StaticTextTag {
|
||||
|
||||
public static final int ID = 11;
|
||||
|
||||
public static final String NAME = "DefineText";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineTextTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
textBounds = new RECT();
|
||||
textMatrix = new MATRIX();
|
||||
textRecords = new ArrayList<>();
|
||||
glyphBits = 0;
|
||||
advanceBits = 0;
|
||||
}
|
||||
|
||||
public DefineTextTag(SWF swf, int characterID, RECT textBounds, MATRIX textMatrix, List<TEXTRECORD> textRecords) {
|
||||
super(swf, ID, NAME, null);
|
||||
this.characterID = characterID;
|
||||
this.textBounds = textBounds;
|
||||
this.textMatrix = textMatrix;
|
||||
this.textRecords = textRecords;
|
||||
this.glyphBits = 0;
|
||||
this.advanceBits = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineTextTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextNum() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,152 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineVideoStreamTag extends CharacterTag implements BoundedTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterID;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int numFrames;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int width;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int height;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int reserved;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 3)
|
||||
public int videoFlagsDeblocking;
|
||||
|
||||
public boolean videoFlagsSmoothing;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public int codecID;
|
||||
|
||||
public static final int CODEC_SORENSON_H263 = 2;
|
||||
|
||||
public static final int CODEC_SCREEN_VIDEO = 3;
|
||||
|
||||
public static final int CODEC_VP6 = 4;
|
||||
|
||||
public static final int CODEC_VP6_ALPHA = 5;
|
||||
|
||||
public static final int ID = 60;
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterID = characterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterID);
|
||||
sos.writeUI16(numFrames);
|
||||
sos.writeUI16(width);
|
||||
sos.writeUI16(height);
|
||||
sos.writeUB(4, reserved);
|
||||
sos.writeUB(3, videoFlagsDeblocking);
|
||||
sos.writeUB(1, videoFlagsSmoothing ? 1 : 0);
|
||||
sos.writeUI8(codecID);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineVideoStreamTag(SWF swf) {
|
||||
super(swf, ID, "DefineVideoStream", null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineVideoStreamTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineVideoStream", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterID = sis.readUI16("characterID");
|
||||
numFrames = sis.readUI16("numFrames");
|
||||
width = sis.readUI16("width");
|
||||
height = sis.readUI16("height");
|
||||
reserved = (int) sis.readUB(4, "reserved");
|
||||
videoFlagsDeblocking = (int) sis.readUB(3, "videoFlagsDeblocking");
|
||||
videoFlagsSmoothing = sis.readUB(1, "videoFlagsSmoothing") == 1;
|
||||
codecID = sis.readUI8("codecID");
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect() {
|
||||
return getRect(null); // parameter not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
return new RECT(0, (int) (SWF.unitDivisor * width), 0, (int) (SWF.unitDivisor * height));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineVideoStreamTag extends CharacterTag implements BoundedTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterID;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int numFrames;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int width;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int height;
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int reserved;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 3)
|
||||
public int videoFlagsDeblocking;
|
||||
|
||||
public boolean videoFlagsSmoothing;
|
||||
|
||||
@SWFType(BasicType.UI8)
|
||||
public int codecID;
|
||||
|
||||
public static final int CODEC_SORENSON_H263 = 2;
|
||||
|
||||
public static final int CODEC_SCREEN_VIDEO = 3;
|
||||
|
||||
public static final int CODEC_VP6 = 4;
|
||||
|
||||
public static final int CODEC_VP6_ALPHA = 5;
|
||||
|
||||
public static final int ID = 60;
|
||||
|
||||
public static final String NAME = "DefineVideoStream";
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterID = characterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterID);
|
||||
sos.writeUI16(numFrames);
|
||||
sos.writeUI16(width);
|
||||
sos.writeUI16(height);
|
||||
sos.writeUB(4, reserved);
|
||||
sos.writeUB(3, videoFlagsDeblocking);
|
||||
sos.writeUB(1, videoFlagsSmoothing ? 1 : 0);
|
||||
sos.writeUI8(codecID);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineVideoStreamTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineVideoStreamTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterID = sis.readUI16("characterID");
|
||||
numFrames = sis.readUI16("numFrames");
|
||||
width = sis.readUI16("width");
|
||||
height = sis.readUI16("height");
|
||||
reserved = (int) sis.readUB(4, "reserved");
|
||||
videoFlagsDeblocking = (int) sis.readUB(3, "videoFlagsDeblocking");
|
||||
videoFlagsSmoothing = sis.readUB(1, "videoFlagsSmoothing") == 1;
|
||||
codecID = sis.readUI8("codecID");
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect() {
|
||||
return getRect(null); // parameter not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
return new RECT(0, (int) (SWF.unitDivisor * width), 0, (int) (SWF.unitDivisor * height));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,156 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
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.ABCInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFField;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Defines a series of ActionScript 3 bytecodes to be executed
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DoABCDefineTag extends Tag implements ABCContainerTag {
|
||||
|
||||
/**
|
||||
* ActionScript 3 bytecodes
|
||||
*/
|
||||
@HideInRawEdit
|
||||
@SWFField
|
||||
private ABC abc;
|
||||
|
||||
/**
|
||||
* A 32-bit flags value, which may contain the following bits set:
|
||||
* kDoAbcLazyInitializeFlag = 1: Indicates that the ABC block should not be
|
||||
* executed immediately, but only parsed. A later finddef may cause its
|
||||
* scripts to execute.
|
||||
*/
|
||||
@SWFType(BasicType.UI32)
|
||||
public long flags;
|
||||
|
||||
/**
|
||||
* The name assigned to the bytecode.
|
||||
*/
|
||||
public String name;
|
||||
|
||||
public static final int ID = 82;
|
||||
|
||||
@Override
|
||||
public ABC getABC() {
|
||||
return abc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "DoABCDefine (" + name + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DoABCDefineTag(SWF swf) {
|
||||
super(swf, ID, "DoABCDefine", null);
|
||||
name = "New DoABC";
|
||||
abc = new ABC(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DoABCDefineTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DoABCDefine", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
flags = sis.readUI32("flags");
|
||||
name = sis.readString("name");
|
||||
|
||||
ABCInputStream ais = new ABCInputStream(sis.getBaseStream());
|
||||
// put it to the dumpview:
|
||||
sis.readByteRangeEx(sis.available(), "abcBytes");
|
||||
abc = new ABC(ais, swf, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
OutputStream os = bos;
|
||||
if (Configuration.debugCopy.get()) {
|
||||
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
|
||||
}
|
||||
try (SWFOutputStream sos = new SWFOutputStream(os, getVersion())) {
|
||||
sos.writeUI32(flags);
|
||||
sos.writeString(name);
|
||||
abc.saveToStream(sos);
|
||||
}
|
||||
return bos.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ABCContainerTag o) {
|
||||
if (o instanceof DoABCDefineTag) {
|
||||
DoABCDefineTag n = (DoABCDefineTag) o;
|
||||
int lastCmp = name.compareTo(n.name);
|
||||
return (lastCmp != 0 ? lastCmp
|
||||
: name.compareTo(n.name));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified(boolean value) {
|
||||
super.setModified(value);
|
||||
if (value == false && !isModified()) {
|
||||
ABC abc = getABC();
|
||||
for (ScriptInfo si : abc.script_info) {
|
||||
si.setModified(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
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.ABCInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFField;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Defines a series of ActionScript 3 bytecodes to be executed
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DoABCDefineTag extends Tag implements ABCContainerTag {
|
||||
|
||||
/**
|
||||
* ActionScript 3 bytecodes
|
||||
*/
|
||||
@HideInRawEdit
|
||||
@SWFField
|
||||
private ABC abc;
|
||||
|
||||
/**
|
||||
* A 32-bit flags value, which may contain the following bits set:
|
||||
* kDoAbcLazyInitializeFlag = 1: Indicates that the ABC block should not be
|
||||
* executed immediately, but only parsed. A later finddef may cause its
|
||||
* scripts to execute.
|
||||
*/
|
||||
@SWFType(BasicType.UI32)
|
||||
public long flags;
|
||||
|
||||
/**
|
||||
* The name assigned to the bytecode.
|
||||
*/
|
||||
public String name;
|
||||
|
||||
public static final int ID = 82;
|
||||
|
||||
public static final String NAME = "DoABCDefine";
|
||||
|
||||
@Override
|
||||
public ABC getABC() {
|
||||
return abc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return super.getName() + " (" + name + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DoABCDefineTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
name = "New DoABC";
|
||||
abc = new ABC(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DoABCDefineTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
flags = sis.readUI32("flags");
|
||||
name = sis.readString("name");
|
||||
|
||||
ABCInputStream ais = new ABCInputStream(sis.getBaseStream());
|
||||
// put it to the dumpview:
|
||||
sis.readByteRangeEx(sis.available(), "abcBytes");
|
||||
abc = new ABC(ais, swf, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
OutputStream os = bos;
|
||||
if (Configuration.debugCopy.get()) {
|
||||
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
|
||||
}
|
||||
try (SWFOutputStream sos = new SWFOutputStream(os, getVersion())) {
|
||||
sos.writeUI32(flags);
|
||||
sos.writeString(name);
|
||||
abc.saveToStream(sos);
|
||||
}
|
||||
return bos.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ABCContainerTag o) {
|
||||
if (o instanceof DoABCDefineTag) {
|
||||
DoABCDefineTag n = (DoABCDefineTag) o;
|
||||
int lastCmp = name.compareTo(n.name);
|
||||
return (lastCmp != 0 ? lastCmp
|
||||
: name.compareTo(n.name));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified(boolean value) {
|
||||
super.setModified(value);
|
||||
if (value == false && !isModified()) {
|
||||
ABC abc = getABC();
|
||||
for (ScriptInfo si : abc.script_info) {
|
||||
si.setModified(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,128 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
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.ABCInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFField;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Defines a series of ActionScript 3 bytecodes to be executed
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DoABCTag extends Tag implements ABCContainerTag {
|
||||
|
||||
/**
|
||||
* ActionScript 3 bytecodes
|
||||
*/
|
||||
@HideInRawEdit
|
||||
@SWFField
|
||||
private ABC abc;
|
||||
|
||||
public static final int ID = 72;
|
||||
|
||||
@Override
|
||||
public ABC getABC() {
|
||||
return abc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "DoABC";
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DoABCTag(SWF swf) {
|
||||
super(swf, ID, "DoABC", null);
|
||||
abc = new ABC(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DoABCTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DoABC", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
ABCInputStream ais = new ABCInputStream(sis.getBaseStream());
|
||||
// put it to the dumpview:
|
||||
sis.readByteRangeEx(sis.available(), "abcBytes");
|
||||
abc = new ABC(ais, swf, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
OutputStream os = bos;
|
||||
if (Configuration.debugCopy.get()) {
|
||||
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
|
||||
}
|
||||
try (SWFOutputStream sos = new SWFOutputStream(os, getVersion())) {
|
||||
abc.saveToStream(sos);
|
||||
}
|
||||
return bos.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ABCContainerTag o) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified(boolean value) {
|
||||
super.setModified(value);
|
||||
if (value == false && !isModified()) {
|
||||
ABC abc = getABC();
|
||||
for (ScriptInfo si : abc.script_info) {
|
||||
si.setModified(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
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.ABCInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFField;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Defines a series of ActionScript 3 bytecodes to be executed
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DoABCTag extends Tag implements ABCContainerTag {
|
||||
|
||||
/**
|
||||
* ActionScript 3 bytecodes
|
||||
*/
|
||||
@HideInRawEdit
|
||||
@SWFField
|
||||
private ABC abc;
|
||||
|
||||
public static final int ID = 72;
|
||||
|
||||
public static final String NAME = "DoABC";
|
||||
|
||||
@Override
|
||||
public ABC getABC() {
|
||||
return abc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DoABCTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
abc = new ABC(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DoABCTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
ABCInputStream ais = new ABCInputStream(sis.getBaseStream());
|
||||
// put it to the dumpview:
|
||||
sis.readByteRangeEx(sis.available(), "abcBytes");
|
||||
abc = new ABC(ais, swf, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
OutputStream os = bos;
|
||||
if (Configuration.debugCopy.get()) {
|
||||
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
|
||||
}
|
||||
try (SWFOutputStream sos = new SWFOutputStream(os, getVersion())) {
|
||||
abc.saveToStream(sos);
|
||||
}
|
||||
return bos.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ABCContainerTag o) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified(boolean value) {
|
||||
super.setModified(value);
|
||||
if (value == false && !isModified()) {
|
||||
ABC abc = getABC();
|
||||
for (ScriptInfo si : abc.script_info) {
|
||||
si.setModified(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,210 +1,212 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.ActionListReader;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Instructs Flash Player to perform a list of actions when the current frame is
|
||||
* complete.
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DoActionTag extends Tag implements ASMSource {
|
||||
|
||||
/**
|
||||
* List of actions to perform
|
||||
*/
|
||||
//public List<Action> actions = new ArrayList<Action>();
|
||||
@HideInRawEdit
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
public static final int ID = 12;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DoActionTag(SWF swf) {
|
||||
super(swf, ID, "DoAction", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public DoActionTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DoAction", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
actionBytes = sis.readByteRangeEx(sis.available(), "actionBytes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
* @param data
|
||||
*/
|
||||
public DoActionTag(SWF swf, ByteArrayRange data) {
|
||||
super(swf, ID, "DoAction", data);
|
||||
actionBytes = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
return getActionBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts actions to ASM source
|
||||
*
|
||||
* @param exportMode PCode or hex?
|
||||
* @param writer
|
||||
* @param actions
|
||||
* @return ASM source
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public GraphTextWriter getASMSource(ScriptExportMode exportMode, GraphTextWriter writer, ActionList actions) throws InterruptedException {
|
||||
if (actions == null) {
|
||||
actions = getActions();
|
||||
}
|
||||
|
||||
return Action.actionsToString(listeners, 0, actions, swf.version, exportMode, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this object contains ASM source
|
||||
*
|
||||
* @return True when contains
|
||||
*/
|
||||
@Override
|
||||
public boolean containsSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionList getActions() throws InterruptedException {
|
||||
try {
|
||||
int prevLength = actionBytes.getPos();
|
||||
SWFInputStream rri = new SWFInputStream(swf, actionBytes.getArray());
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (InterruptedException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DoActionTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ActionList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActions(List<Action> actions) {
|
||||
byte[] bytes = Action.actionsToBytes(actions, true, swf.version);
|
||||
actionBytes = new ByteArrayRange(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getActionBytes() {
|
||||
return actionBytes.getRangeData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = new ByteArrayRange(actionBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified() {
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionBytesAsHex(GraphTextWriter writer) {
|
||||
return Helper.byteArrayToHexWithHeader(writer, actionBytes.getRangeData());
|
||||
}
|
||||
|
||||
List<DisassemblyListener> listeners = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourceSuffix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrefixLineCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String removePrefixAndSuffix(String source) {
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getSourceTag() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.ActionListReader;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Instructs Flash Player to perform a list of actions when the current frame is
|
||||
* complete.
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DoActionTag extends Tag implements ASMSource {
|
||||
|
||||
/**
|
||||
* List of actions to perform
|
||||
*/
|
||||
//public List<Action> actions = new ArrayList<Action>();
|
||||
@HideInRawEdit
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
public static final int ID = 12;
|
||||
|
||||
public static final String NAME = "DoAction";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DoActionTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public DoActionTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
actionBytes = sis.readByteRangeEx(sis.available(), "actionBytes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
* @param data
|
||||
*/
|
||||
public DoActionTag(SWF swf, ByteArrayRange data) {
|
||||
super(swf, ID, NAME, data);
|
||||
actionBytes = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
return getActionBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts actions to ASM source
|
||||
*
|
||||
* @param exportMode PCode or hex?
|
||||
* @param writer
|
||||
* @param actions
|
||||
* @return ASM source
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public GraphTextWriter getASMSource(ScriptExportMode exportMode, GraphTextWriter writer, ActionList actions) throws InterruptedException {
|
||||
if (actions == null) {
|
||||
actions = getActions();
|
||||
}
|
||||
|
||||
return Action.actionsToString(listeners, 0, actions, swf.version, exportMode, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this object contains ASM source
|
||||
*
|
||||
* @return True when contains
|
||||
*/
|
||||
@Override
|
||||
public boolean containsSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionList getActions() throws InterruptedException {
|
||||
try {
|
||||
int prevLength = actionBytes.getPos();
|
||||
SWFInputStream rri = new SWFInputStream(swf, actionBytes.getArray());
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (InterruptedException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DoActionTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ActionList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActions(List<Action> actions) {
|
||||
byte[] bytes = Action.actionsToBytes(actions, true, swf.version);
|
||||
actionBytes = new ByteArrayRange(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getActionBytes() {
|
||||
return actionBytes.getRangeData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = new ByteArrayRange(actionBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified() {
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionBytesAsHex(GraphTextWriter writer) {
|
||||
return Helper.byteArrayToHexWithHeader(writer, actionBytes.getRangeData());
|
||||
}
|
||||
|
||||
List<DisassemblyListener> listeners = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourceSuffix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrefixLineCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String removePrefixAndSuffix(String source) {
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getSourceTag() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,258 +1,260 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.ActionListReader;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DoInitActionTag extends Tag implements CharacterIdTag, ASMSource {
|
||||
|
||||
/**
|
||||
* Identifier of Sprite
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int spriteId = 0;
|
||||
|
||||
/**
|
||||
* List of actions to perform
|
||||
*/
|
||||
//public List<Action> actions = new ArrayList<Action>();
|
||||
@HideInRawEdit
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
public static final int ID = 59;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DoInitActionTag(SWF swf) {
|
||||
super(swf, ID, "DoInitAction", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DoInitActionTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DoInitAction", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
spriteId = sis.readUI16("spriteId");
|
||||
actionBytes = sis.readByteRangeEx(sis.available(), "actionBytes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, getVersion());
|
||||
try {
|
||||
sos.writeUI16(spriteId);
|
||||
sos.write(getActionBytes());
|
||||
//sos.write(Action.actionsToBytes(actions, true, version));
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this object contains ASM source
|
||||
*
|
||||
* @return True when contains
|
||||
*/
|
||||
@Override
|
||||
public boolean containsSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts actions to ASM source
|
||||
*
|
||||
* @param exportMode PCode or hex?
|
||||
* @param writer
|
||||
* @param actions
|
||||
* @return ASM source
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public GraphTextWriter getASMSource(ScriptExportMode exportMode, GraphTextWriter writer, ActionList actions) throws InterruptedException {
|
||||
if (actions == null) {
|
||||
actions = getActions();
|
||||
}
|
||||
return Action.actionsToString(listeners, 0, actions, swf.version, exportMode, writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionList getActions() throws InterruptedException {
|
||||
try {
|
||||
int prevLength = actionBytes.getPos();
|
||||
SWFInputStream rri = new SWFInputStream(swf, actionBytes.getArray());
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (InterruptedException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DoInitActionTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ActionList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActions(List<Action> actions) {
|
||||
byte[] bytes = Action.actionsToBytes(actions, true, swf.version);
|
||||
actionBytes = new ByteArrayRange(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getActionBytes() {
|
||||
return actionBytes.getRangeData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = new ByteArrayRange(actionBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified() {
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionBytesAsHex(GraphTextWriter writer) {
|
||||
return Helper.byteArrayToHexWithHeader(writer, actionBytes.getRangeData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return spriteId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.spriteId = characterId;
|
||||
}
|
||||
|
||||
List<DisassemblyListener> listeners = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExportFileName() {
|
||||
String expName = swf.getExportName(spriteId);
|
||||
if ((expName == null) || expName.isEmpty()) {
|
||||
return super.getExportFileName();
|
||||
}
|
||||
String[] pathParts;
|
||||
if (expName.contains(".")) {
|
||||
pathParts = expName.split("\\.");
|
||||
} else {
|
||||
pathParts = new String[]{expName};
|
||||
}
|
||||
return pathParts[pathParts.length - 1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
String expName = swf == null ? "" : swf.getExportName(spriteId);
|
||||
if ((expName == null) || expName.isEmpty()) {
|
||||
return super.getName();
|
||||
}
|
||||
String[] pathParts;
|
||||
if (expName.contains(".")) {
|
||||
pathParts = expName.split("\\.");
|
||||
} else {
|
||||
pathParts = new String[]{expName};
|
||||
}
|
||||
return pathParts[pathParts.length - 1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourceSuffix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrefixLineCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String removePrefixAndSuffix(String source) {
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getSourceTag() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.ActionListReader;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DoInitActionTag extends Tag implements CharacterIdTag, ASMSource {
|
||||
|
||||
/**
|
||||
* Identifier of Sprite
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int spriteId = 0;
|
||||
|
||||
/**
|
||||
* List of actions to perform
|
||||
*/
|
||||
//public List<Action> actions = new ArrayList<Action>();
|
||||
@HideInRawEdit
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
public static final int ID = 59;
|
||||
|
||||
public static final String NAME = "DoInitAction";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DoInitActionTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DoInitActionTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
spriteId = sis.readUI16("spriteId");
|
||||
actionBytes = sis.readByteRangeEx(sis.available(), "actionBytes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, getVersion());
|
||||
try {
|
||||
sos.writeUI16(spriteId);
|
||||
sos.write(getActionBytes());
|
||||
//sos.write(Action.actionsToBytes(actions, true, version));
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this object contains ASM source
|
||||
*
|
||||
* @return True when contains
|
||||
*/
|
||||
@Override
|
||||
public boolean containsSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts actions to ASM source
|
||||
*
|
||||
* @param exportMode PCode or hex?
|
||||
* @param writer
|
||||
* @param actions
|
||||
* @return ASM source
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public GraphTextWriter getASMSource(ScriptExportMode exportMode, GraphTextWriter writer, ActionList actions) throws InterruptedException {
|
||||
if (actions == null) {
|
||||
actions = getActions();
|
||||
}
|
||||
return Action.actionsToString(listeners, 0, actions, swf.version, exportMode, writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionList getActions() throws InterruptedException {
|
||||
try {
|
||||
int prevLength = actionBytes.getPos();
|
||||
SWFInputStream rri = new SWFInputStream(swf, actionBytes.getArray());
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (InterruptedException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DoInitActionTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ActionList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActions(List<Action> actions) {
|
||||
byte[] bytes = Action.actionsToBytes(actions, true, swf.version);
|
||||
actionBytes = new ByteArrayRange(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getActionBytes() {
|
||||
return actionBytes.getRangeData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = new ByteArrayRange(actionBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified() {
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionBytesAsHex(GraphTextWriter writer) {
|
||||
return Helper.byteArrayToHexWithHeader(writer, actionBytes.getRangeData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return spriteId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.spriteId = characterId;
|
||||
}
|
||||
|
||||
List<DisassemblyListener> listeners = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExportFileName() {
|
||||
String expName = swf.getExportName(spriteId);
|
||||
if ((expName == null) || expName.isEmpty()) {
|
||||
return super.getExportFileName();
|
||||
}
|
||||
String[] pathParts;
|
||||
if (expName.contains(".")) {
|
||||
pathParts = expName.split("\\.");
|
||||
} else {
|
||||
pathParts = new String[]{expName};
|
||||
}
|
||||
return pathParts[pathParts.length - 1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
String expName = swf == null ? "" : swf.getExportName(spriteId);
|
||||
if ((expName == null) || expName.isEmpty()) {
|
||||
return super.getName();
|
||||
}
|
||||
String[] pathParts;
|
||||
if (expName.contains(".")) {
|
||||
pathParts = expName.split("\\.");
|
||||
} else {
|
||||
pathParts = new String[]{expName};
|
||||
}
|
||||
return pathParts[pathParts.length - 1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourceSuffix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrefixLineCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String removePrefixAndSuffix(String source) {
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getSourceTag() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ public class EnableDebugger2Tag extends Tag {
|
||||
|
||||
public static final int ID = 64;
|
||||
|
||||
public static final String NAME = "EnableDebugger2";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
@@ -71,7 +73,7 @@ public class EnableDebugger2Tag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public EnableDebugger2Tag(SWF swf) {
|
||||
super(swf, ID, "EnableDebugger2", null);
|
||||
super(swf, ID, NAME, null);
|
||||
passwordHash = "PasswordHash";
|
||||
}
|
||||
|
||||
@@ -83,7 +85,7 @@ public class EnableDebugger2Tag extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public EnableDebugger2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "EnableDebugger2", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ public class EnableDebuggerTag extends Tag {
|
||||
|
||||
public static final int ID = 58;
|
||||
|
||||
public static final String NAME = "EnableDebugger";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
@@ -64,7 +66,7 @@ public class EnableDebuggerTag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public EnableDebuggerTag(SWF swf) {
|
||||
super(swf, ID, "EnableDebugger", null);
|
||||
super(swf, ID, NAME, null);
|
||||
passwordHash = "PasswordHash";
|
||||
}
|
||||
|
||||
@@ -76,7 +78,7 @@ public class EnableDebuggerTag extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public EnableDebuggerTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "EnableDebugger", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ public class EnableTelemetryTag extends Tag {
|
||||
|
||||
public static final int ID = 93;
|
||||
|
||||
public static final String NAME = "EnableTelemetry";
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 16)
|
||||
@Reserved
|
||||
public int reserved;
|
||||
@@ -72,7 +74,7 @@ public class EnableTelemetryTag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public EnableTelemetryTag(SWF swf) {
|
||||
super(swf, ID, "EnableTelemetry", null);
|
||||
super(swf, ID, NAME, null);
|
||||
passwordHash = new byte[32];
|
||||
}
|
||||
|
||||
@@ -84,7 +86,7 @@ public class EnableTelemetryTag extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public EnableTelemetryTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,13 +40,15 @@ public class EndTag extends Tag {
|
||||
|
||||
public static final int ID = 0;
|
||||
|
||||
public static final String NAME = "End";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public EndTag(SWF swf) {
|
||||
super(swf, ID, "End", null);
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,7 +59,7 @@ public class EndTag extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public EndTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "End", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,13 +49,15 @@ public class ExportAssetsTag extends SymbolClassTypeTag {
|
||||
|
||||
public static final int ID = 56;
|
||||
|
||||
public static final String NAME = "ExportAssets";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public ExportAssetsTag(SWF swf) {
|
||||
super(swf, ID, "ExportAssets", null);
|
||||
super(swf, ID, NAME, null);
|
||||
tags = new ArrayList<>();
|
||||
names = new ArrayList<>();
|
||||
}
|
||||
@@ -68,7 +70,7 @@ public class ExportAssetsTag extends SymbolClassTypeTag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public ExportAssetsTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "ExportAssets", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,17 +53,19 @@ public class FileAttributesTag extends Tag {
|
||||
|
||||
public static final int ID = 69;
|
||||
|
||||
public static final String NAME = "FileAttributes";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public FileAttributesTag(SWF swf) {
|
||||
super(swf, ID, "FileAttributes", null);
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public FileAttributesTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "FileAttributes", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ public class FrameLabelTag extends Tag {
|
||||
|
||||
public static final int ID = 43;
|
||||
|
||||
public static final String NAME = "FrameLabel";
|
||||
|
||||
public String getLabelName() {
|
||||
return name;
|
||||
}
|
||||
@@ -46,12 +48,12 @@ public class FrameLabelTag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public FrameLabelTag(SWF swf) {
|
||||
super(swf, ID, "FrameLabel", null);
|
||||
super(swf, ID, NAME, null);
|
||||
name = "New frame label";
|
||||
}
|
||||
|
||||
public FrameLabelTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "FrameLabel", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,13 +62,15 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
|
||||
|
||||
public static final int ID = 71;
|
||||
|
||||
public static final String NAME = "ImportAssets2";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public ImportAssets2Tag(SWF swf) {
|
||||
super(swf, ID, "ImportAssets2", null);
|
||||
super(swf, ID, NAME, null);
|
||||
url = "";
|
||||
tags = new ArrayList<>();
|
||||
}
|
||||
@@ -81,7 +83,7 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public ImportAssets2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "ImportAssets2", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,13 +53,15 @@ public class ImportAssetsTag extends Tag implements ImportTag {
|
||||
|
||||
public static final int ID = 57;
|
||||
|
||||
public static final String NAME = "ImportAssets";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public ImportAssetsTag(SWF swf) {
|
||||
super(swf, ID, "ImportAssets", null);
|
||||
super(swf, ID, NAME, null);
|
||||
url = "";
|
||||
tags = new ArrayList<>();
|
||||
}
|
||||
@@ -72,7 +74,7 @@ public class ImportAssetsTag extends Tag implements ImportTag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public ImportAssetsTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "ImportAssets", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ public class JPEGTablesTag extends Tag {
|
||||
|
||||
public static final int ID = 8;
|
||||
|
||||
public static final String NAME = "JPEGTables";
|
||||
|
||||
@HideInRawEdit
|
||||
public byte[] jpegData;
|
||||
|
||||
@@ -38,12 +40,12 @@ public class JPEGTablesTag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public JPEGTablesTag(SWF swf) {
|
||||
super(swf, ID, "JPEGTables", null);
|
||||
super(swf, ID, NAME, null);
|
||||
jpegData = new byte[0];
|
||||
}
|
||||
|
||||
public JPEGTablesTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "JPEGTables", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,18 +32,20 @@ public class MetadataTag extends Tag {
|
||||
|
||||
public static final int ID = 77;
|
||||
|
||||
public static final String NAME = "Metadata";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public MetadataTag(SWF swf) {
|
||||
super(swf, ID, "Metadata", null);
|
||||
super(swf, ID, NAME, null);
|
||||
xmlMetadata = "";
|
||||
}
|
||||
|
||||
public MetadataTag(SWFInputStream sis, ByteArrayRange data) {
|
||||
super(sis.getSwf(), ID, "Metadata", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,440 +1,442 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSourceContainer;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.CLIPACTIONRECORD;
|
||||
import com.jpexs.decompiler.flash.types.CLIPACTIONS;
|
||||
import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.filters.FILTER;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Extends the functionality of the PlaceObject2Tag
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceContainer {
|
||||
|
||||
/**
|
||||
* @since SWF 5 Has clip actions (sprite characters only)
|
||||
*/
|
||||
public boolean placeFlagHasClipActions;
|
||||
|
||||
/**
|
||||
* Has clip depth
|
||||
*/
|
||||
public boolean placeFlagHasClipDepth;
|
||||
|
||||
/**
|
||||
* Has name
|
||||
*/
|
||||
public boolean placeFlagHasName;
|
||||
|
||||
/**
|
||||
* Has ratio
|
||||
*/
|
||||
public boolean placeFlagHasRatio;
|
||||
|
||||
/**
|
||||
* Has color transform
|
||||
*/
|
||||
public boolean placeFlagHasColorTransform;
|
||||
|
||||
/**
|
||||
* Has matrix
|
||||
*/
|
||||
public boolean placeFlagHasMatrix;
|
||||
|
||||
/**
|
||||
* Places a character
|
||||
*/
|
||||
public boolean placeFlagHasCharacter;
|
||||
|
||||
/**
|
||||
* Defines a character to be moved
|
||||
*/
|
||||
public boolean placeFlagMove;
|
||||
|
||||
/**
|
||||
* Depth of character
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int depth;
|
||||
|
||||
/**
|
||||
* If PlaceFlagHasCharacter, ID of character to place
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
@Conditional("placeFlagHasCharacter")
|
||||
public int characterId;
|
||||
|
||||
/**
|
||||
* If PlaceFlagHasMatrix, Transform matrix data
|
||||
*/
|
||||
@Conditional("placeFlagHasMatrix")
|
||||
public MATRIX matrix;
|
||||
|
||||
/**
|
||||
* If PlaceFlagHasColorTransform, Color transform data
|
||||
*/
|
||||
@Conditional("placeFlagHasColorTransform")
|
||||
public CXFORMWITHALPHA colorTransform;
|
||||
|
||||
/**
|
||||
* If PlaceFlagHasRatio, ratio
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
@Conditional("placeFlagHasRatio")
|
||||
public int ratio;
|
||||
|
||||
/**
|
||||
* If PlaceFlagHasName, Name of character
|
||||
*/
|
||||
@Conditional("placeFlagHasName")
|
||||
public String name;
|
||||
|
||||
/**
|
||||
* If PlaceFlagHasClipDepth, Clip depth
|
||||
*/
|
||||
@Conditional("placeFlagHasClipDepth")
|
||||
public int clipDepth;
|
||||
|
||||
/**
|
||||
* @since SWF 5 If PlaceFlagHasClipActions, Clip Actions Data
|
||||
*/
|
||||
@Conditional("placeFlagHasClipActions")
|
||||
@HideInRawEdit //TODO: make editable
|
||||
public CLIPACTIONS clipActions;
|
||||
|
||||
public static final int ID = 26;
|
||||
|
||||
@Override
|
||||
public int getClipDepth() {
|
||||
if (placeFlagHasClipDepth) {
|
||||
return clipDepth;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FILTER> getFilters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
if (Configuration.debugCopy.get()) {
|
||||
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
|
||||
}
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUB(1, placeFlagHasClipActions ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasClipDepth ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasName ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasRatio ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasColorTransform ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasMatrix ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasCharacter ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagMove ? 1 : 0);
|
||||
sos.writeUI16(depth);
|
||||
if (placeFlagHasCharacter) {
|
||||
sos.writeUI16(characterId);
|
||||
}
|
||||
if (placeFlagHasMatrix) {
|
||||
sos.writeMatrix(matrix);
|
||||
}
|
||||
if (placeFlagHasColorTransform) {
|
||||
sos.writeCXFORMWITHALPHA(colorTransform);
|
||||
}
|
||||
if (placeFlagHasRatio) {
|
||||
sos.writeUI16(ratio);
|
||||
}
|
||||
if (placeFlagHasName) {
|
||||
sos.writeString(name);
|
||||
}
|
||||
if (placeFlagHasClipDepth) {
|
||||
sos.writeUI16(clipDepth);
|
||||
}
|
||||
if (placeFlagHasClipActions) {
|
||||
sos.writeCLIPACTIONS(clipActions);
|
||||
}
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public PlaceObject2Tag(SWF swf) {
|
||||
super(swf, ID, "PlaceObject2", null);
|
||||
}
|
||||
|
||||
public PlaceObject2Tag(SWF swf, boolean placeFlagHasClipActions, boolean placeFlagHasClipDepth, boolean placeFlagHasName, boolean placeFlagHasRatio, boolean placeFlagHasColorTransform, boolean placeFlagHasMatrix, boolean placeFlagHasCharacter, boolean placeFlagMove, int depth, int characterId, MATRIX matrix, CXFORMWITHALPHA colorTransform, int ratio, String name, int clipDepth, CLIPACTIONS clipActions) {
|
||||
super(swf, ID, "PlaceObject2", null);
|
||||
this.placeFlagHasClipActions = placeFlagHasClipActions;
|
||||
this.placeFlagHasClipDepth = placeFlagHasClipDepth;
|
||||
this.placeFlagHasName = placeFlagHasName;
|
||||
this.placeFlagHasRatio = placeFlagHasRatio;
|
||||
this.placeFlagHasColorTransform = placeFlagHasColorTransform;
|
||||
this.placeFlagHasMatrix = placeFlagHasMatrix;
|
||||
this.placeFlagHasCharacter = placeFlagHasCharacter;
|
||||
this.placeFlagMove = placeFlagMove;
|
||||
this.depth = depth;
|
||||
this.characterId = characterId;
|
||||
this.matrix = matrix;
|
||||
this.colorTransform = colorTransform;
|
||||
this.ratio = ratio;
|
||||
this.name = name;
|
||||
this.clipDepth = clipDepth;
|
||||
this.clipActions = clipActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public PlaceObject2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "PlaceObject2", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
placeFlagHasClipActions = sis.readUB(1, "placeFlagHasClipActions") == 1;
|
||||
placeFlagHasClipDepth = sis.readUB(1, "placeFlagHasClipDepth") == 1;
|
||||
placeFlagHasName = sis.readUB(1, "placeFlagHasName") == 1;
|
||||
placeFlagHasRatio = sis.readUB(1, "placeFlagHasRatio") == 1;
|
||||
placeFlagHasColorTransform = sis.readUB(1, "placeFlagHasColorTransform") == 1;
|
||||
placeFlagHasMatrix = sis.readUB(1, "placeFlagHasMatrix") == 1;
|
||||
placeFlagHasCharacter = sis.readUB(1, "placeFlagHasCharacter") == 1;
|
||||
placeFlagMove = sis.readUB(1, "placeFlagMove") == 1;
|
||||
|
||||
depth = sis.readUI16("depth");
|
||||
if (placeFlagHasCharacter) {
|
||||
characterId = sis.readUI16("characterId");
|
||||
}
|
||||
if (placeFlagHasMatrix) {
|
||||
matrix = sis.readMatrix("matrix");
|
||||
}
|
||||
if (placeFlagHasColorTransform) {
|
||||
colorTransform = sis.readCXFORMWITHALPHA("colorTransform");
|
||||
}
|
||||
if (placeFlagHasRatio) {
|
||||
ratio = sis.readUI16("ratio");
|
||||
}
|
||||
if (placeFlagHasName) {
|
||||
name = sis.readString("name");
|
||||
}
|
||||
if (placeFlagHasClipDepth) {
|
||||
clipDepth = sis.readUI16("clipDepth");
|
||||
}
|
||||
if (placeFlagHasClipActions) {
|
||||
clipActions = sis.readCLIPACTIONS(swf, this, "clipActions");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all sub-items
|
||||
*
|
||||
* @return List of sub-items
|
||||
*/
|
||||
@Override
|
||||
public List<CLIPACTIONRECORD> getSubItems() {
|
||||
if (placeFlagHasClipActions) {
|
||||
return clipActions.clipActionRecords;
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
if (placeFlagHasCharacter) {
|
||||
needed.add(characterId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
// the place object tag will be removed
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
if (placeFlagHasCharacter) {
|
||||
return characterId;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
placeFlagHasCharacter = true;
|
||||
this.characterId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MATRIX getMatrix() {
|
||||
if (placeFlagHasMatrix) {
|
||||
return matrix;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceName() {
|
||||
if (placeFlagHasName) {
|
||||
return name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorTransform getColorTransform() {
|
||||
if (placeFlagHasColorTransform) {
|
||||
return colorTransform;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlendMode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cacheAsBitmap() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RGBA getBackgroundColor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean flagMove() {
|
||||
return placeFlagMove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRatio() {
|
||||
if (!placeFlagHasRatio) {
|
||||
return -1;
|
||||
}
|
||||
return ratio;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInstanceName(String name) {
|
||||
placeFlagHasName = true;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClassName(String className) {
|
||||
//not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
if (placeFlagHasName) {
|
||||
return super.getName() + " (" + name + ")";
|
||||
} else {
|
||||
return super.getName();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CLIPACTIONS getClipActions() {
|
||||
if (placeFlagHasClipActions) {
|
||||
return clipActions;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTagWithMatrix(SWFOutputStream sos, MATRIX m) throws IOException {
|
||||
MATRIX old = matrix;
|
||||
matrix = m;
|
||||
boolean mod = isModified();
|
||||
setModified(true);
|
||||
super.writeTag(sos);
|
||||
setModified(mod);
|
||||
matrix = old;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSourceContainer;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.CLIPACTIONRECORD;
|
||||
import com.jpexs.decompiler.flash.types.CLIPACTIONS;
|
||||
import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.filters.FILTER;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Extends the functionality of the PlaceObject2Tag
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceContainer {
|
||||
|
||||
/**
|
||||
* @since SWF 5 Has clip actions (sprite characters only)
|
||||
*/
|
||||
public boolean placeFlagHasClipActions;
|
||||
|
||||
/**
|
||||
* Has clip depth
|
||||
*/
|
||||
public boolean placeFlagHasClipDepth;
|
||||
|
||||
/**
|
||||
* Has name
|
||||
*/
|
||||
public boolean placeFlagHasName;
|
||||
|
||||
/**
|
||||
* Has ratio
|
||||
*/
|
||||
public boolean placeFlagHasRatio;
|
||||
|
||||
/**
|
||||
* Has color transform
|
||||
*/
|
||||
public boolean placeFlagHasColorTransform;
|
||||
|
||||
/**
|
||||
* Has matrix
|
||||
*/
|
||||
public boolean placeFlagHasMatrix;
|
||||
|
||||
/**
|
||||
* Places a character
|
||||
*/
|
||||
public boolean placeFlagHasCharacter;
|
||||
|
||||
/**
|
||||
* Defines a character to be moved
|
||||
*/
|
||||
public boolean placeFlagMove;
|
||||
|
||||
/**
|
||||
* Depth of character
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int depth;
|
||||
|
||||
/**
|
||||
* If PlaceFlagHasCharacter, ID of character to place
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
@Conditional("placeFlagHasCharacter")
|
||||
public int characterId;
|
||||
|
||||
/**
|
||||
* If PlaceFlagHasMatrix, Transform matrix data
|
||||
*/
|
||||
@Conditional("placeFlagHasMatrix")
|
||||
public MATRIX matrix;
|
||||
|
||||
/**
|
||||
* If PlaceFlagHasColorTransform, Color transform data
|
||||
*/
|
||||
@Conditional("placeFlagHasColorTransform")
|
||||
public CXFORMWITHALPHA colorTransform;
|
||||
|
||||
/**
|
||||
* If PlaceFlagHasRatio, ratio
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
@Conditional("placeFlagHasRatio")
|
||||
public int ratio;
|
||||
|
||||
/**
|
||||
* If PlaceFlagHasName, Name of character
|
||||
*/
|
||||
@Conditional("placeFlagHasName")
|
||||
public String name;
|
||||
|
||||
/**
|
||||
* If PlaceFlagHasClipDepth, Clip depth
|
||||
*/
|
||||
@Conditional("placeFlagHasClipDepth")
|
||||
public int clipDepth;
|
||||
|
||||
/**
|
||||
* @since SWF 5 If PlaceFlagHasClipActions, Clip Actions Data
|
||||
*/
|
||||
@Conditional("placeFlagHasClipActions")
|
||||
@HideInRawEdit //TODO: make editable
|
||||
public CLIPACTIONS clipActions;
|
||||
|
||||
public static final int ID = 26;
|
||||
|
||||
public static final String NAME = "PlaceObject2";
|
||||
|
||||
@Override
|
||||
public int getClipDepth() {
|
||||
if (placeFlagHasClipDepth) {
|
||||
return clipDepth;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FILTER> getFilters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
if (Configuration.debugCopy.get()) {
|
||||
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
|
||||
}
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUB(1, placeFlagHasClipActions ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasClipDepth ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasName ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasRatio ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasColorTransform ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasMatrix ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasCharacter ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagMove ? 1 : 0);
|
||||
sos.writeUI16(depth);
|
||||
if (placeFlagHasCharacter) {
|
||||
sos.writeUI16(characterId);
|
||||
}
|
||||
if (placeFlagHasMatrix) {
|
||||
sos.writeMatrix(matrix);
|
||||
}
|
||||
if (placeFlagHasColorTransform) {
|
||||
sos.writeCXFORMWITHALPHA(colorTransform);
|
||||
}
|
||||
if (placeFlagHasRatio) {
|
||||
sos.writeUI16(ratio);
|
||||
}
|
||||
if (placeFlagHasName) {
|
||||
sos.writeString(name);
|
||||
}
|
||||
if (placeFlagHasClipDepth) {
|
||||
sos.writeUI16(clipDepth);
|
||||
}
|
||||
if (placeFlagHasClipActions) {
|
||||
sos.writeCLIPACTIONS(clipActions);
|
||||
}
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public PlaceObject2Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public PlaceObject2Tag(SWF swf, boolean placeFlagHasClipActions, boolean placeFlagHasClipDepth, boolean placeFlagHasName, boolean placeFlagHasRatio, boolean placeFlagHasColorTransform, boolean placeFlagHasMatrix, boolean placeFlagHasCharacter, boolean placeFlagMove, int depth, int characterId, MATRIX matrix, CXFORMWITHALPHA colorTransform, int ratio, String name, int clipDepth, CLIPACTIONS clipActions) {
|
||||
super(swf, ID, NAME, null);
|
||||
this.placeFlagHasClipActions = placeFlagHasClipActions;
|
||||
this.placeFlagHasClipDepth = placeFlagHasClipDepth;
|
||||
this.placeFlagHasName = placeFlagHasName;
|
||||
this.placeFlagHasRatio = placeFlagHasRatio;
|
||||
this.placeFlagHasColorTransform = placeFlagHasColorTransform;
|
||||
this.placeFlagHasMatrix = placeFlagHasMatrix;
|
||||
this.placeFlagHasCharacter = placeFlagHasCharacter;
|
||||
this.placeFlagMove = placeFlagMove;
|
||||
this.depth = depth;
|
||||
this.characterId = characterId;
|
||||
this.matrix = matrix;
|
||||
this.colorTransform = colorTransform;
|
||||
this.ratio = ratio;
|
||||
this.name = name;
|
||||
this.clipDepth = clipDepth;
|
||||
this.clipActions = clipActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public PlaceObject2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
placeFlagHasClipActions = sis.readUB(1, "placeFlagHasClipActions") == 1;
|
||||
placeFlagHasClipDepth = sis.readUB(1, "placeFlagHasClipDepth") == 1;
|
||||
placeFlagHasName = sis.readUB(1, "placeFlagHasName") == 1;
|
||||
placeFlagHasRatio = sis.readUB(1, "placeFlagHasRatio") == 1;
|
||||
placeFlagHasColorTransform = sis.readUB(1, "placeFlagHasColorTransform") == 1;
|
||||
placeFlagHasMatrix = sis.readUB(1, "placeFlagHasMatrix") == 1;
|
||||
placeFlagHasCharacter = sis.readUB(1, "placeFlagHasCharacter") == 1;
|
||||
placeFlagMove = sis.readUB(1, "placeFlagMove") == 1;
|
||||
|
||||
depth = sis.readUI16("depth");
|
||||
if (placeFlagHasCharacter) {
|
||||
characterId = sis.readUI16("characterId");
|
||||
}
|
||||
if (placeFlagHasMatrix) {
|
||||
matrix = sis.readMatrix("matrix");
|
||||
}
|
||||
if (placeFlagHasColorTransform) {
|
||||
colorTransform = sis.readCXFORMWITHALPHA("colorTransform");
|
||||
}
|
||||
if (placeFlagHasRatio) {
|
||||
ratio = sis.readUI16("ratio");
|
||||
}
|
||||
if (placeFlagHasName) {
|
||||
name = sis.readString("name");
|
||||
}
|
||||
if (placeFlagHasClipDepth) {
|
||||
clipDepth = sis.readUI16("clipDepth");
|
||||
}
|
||||
if (placeFlagHasClipActions) {
|
||||
clipActions = sis.readCLIPACTIONS(swf, this, "clipActions");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all sub-items
|
||||
*
|
||||
* @return List of sub-items
|
||||
*/
|
||||
@Override
|
||||
public List<CLIPACTIONRECORD> getSubItems() {
|
||||
if (placeFlagHasClipActions) {
|
||||
return clipActions.clipActionRecords;
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
if (placeFlagHasCharacter) {
|
||||
needed.add(characterId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
// the place object tag will be removed
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
if (placeFlagHasCharacter) {
|
||||
return characterId;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
placeFlagHasCharacter = true;
|
||||
this.characterId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MATRIX getMatrix() {
|
||||
if (placeFlagHasMatrix) {
|
||||
return matrix;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceName() {
|
||||
if (placeFlagHasName) {
|
||||
return name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorTransform getColorTransform() {
|
||||
if (placeFlagHasColorTransform) {
|
||||
return colorTransform;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlendMode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cacheAsBitmap() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RGBA getBackgroundColor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean flagMove() {
|
||||
return placeFlagMove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRatio() {
|
||||
if (!placeFlagHasRatio) {
|
||||
return -1;
|
||||
}
|
||||
return ratio;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInstanceName(String name) {
|
||||
placeFlagHasName = true;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClassName(String className) {
|
||||
//not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
if (placeFlagHasName) {
|
||||
return super.getName() + " (" + name + ")";
|
||||
} else {
|
||||
return super.getName();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CLIPACTIONS getClipActions() {
|
||||
if (placeFlagHasClipActions) {
|
||||
return clipActions;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTagWithMatrix(SWFOutputStream sos, MATRIX m) throws IOException {
|
||||
MATRIX old = matrix;
|
||||
matrix = m;
|
||||
boolean mod = isModified();
|
||||
setModified(true);
|
||||
super.writeTag(sos);
|
||||
setModified(mod);
|
||||
matrix = old;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,250 +1,252 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.CLIPACTIONS;
|
||||
import com.jpexs.decompiler.flash.types.CXFORM;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Optional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.filters.FILTER;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Adds character to the display list
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class PlaceObjectTag extends PlaceObjectTypeTag {
|
||||
|
||||
/**
|
||||
* ID of character to place
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterId;
|
||||
|
||||
/**
|
||||
* Depth of character
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int depth;
|
||||
|
||||
/**
|
||||
* Transform matrix data
|
||||
*/
|
||||
public MATRIX matrix;
|
||||
|
||||
/**
|
||||
* Color transform data
|
||||
*/
|
||||
@Optional
|
||||
public CXFORM colorTransform;
|
||||
|
||||
public static final int ID = 4;
|
||||
|
||||
@Override
|
||||
public List<FILTER> getFilters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getClipDepth() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterId);
|
||||
sos.writeUI16(depth);
|
||||
sos.writeMatrix(matrix);
|
||||
if (colorTransform != null) {
|
||||
sos.writeCXFORM(colorTransform);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public PlaceObjectTag(SWF swf) {
|
||||
super(swf, ID, "PlaceObject", null);
|
||||
matrix = new MATRIX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public PlaceObjectTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "PlaceObject", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterId = sis.readUI16("characterId");
|
||||
depth = sis.readUI16("depth");
|
||||
matrix = sis.readMatrix("matrix");
|
||||
if (sis.available() > 0) {
|
||||
colorTransform = sis.readCXFORM("colorTransform");
|
||||
}
|
||||
}
|
||||
|
||||
public PlaceObjectTag(SWF swf, int characterId, int depth, MATRIX matrix, CXFORM colorTransform) {
|
||||
super(swf, ID, "PlaceObject", null);
|
||||
this.characterId = characterId;
|
||||
this.depth = depth;
|
||||
this.matrix = matrix;
|
||||
this.colorTransform = colorTransform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
needed.add(characterId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
// the place object tag will be removed
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MATRIX getMatrix() {
|
||||
return matrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorTransform getColorTransform() {
|
||||
return colorTransform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlendMode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cacheAsBitmap() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RGBA getBackgroundColor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean flagMove() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRatio() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInstanceName(String name) {
|
||||
//not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClassName(String className) {
|
||||
//not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public CLIPACTIONS getClipActions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTagWithMatrix(SWFOutputStream sos, MATRIX m) throws IOException {
|
||||
MATRIX old = matrix;
|
||||
matrix = m;
|
||||
boolean mod = isModified();
|
||||
setModified(true);
|
||||
super.writeTag(sos);
|
||||
setModified(mod);
|
||||
matrix = old;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.CLIPACTIONS;
|
||||
import com.jpexs.decompiler.flash.types.CXFORM;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Optional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.filters.FILTER;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Adds character to the display list
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class PlaceObjectTag extends PlaceObjectTypeTag {
|
||||
|
||||
/**
|
||||
* ID of character to place
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterId;
|
||||
|
||||
/**
|
||||
* Depth of character
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int depth;
|
||||
|
||||
/**
|
||||
* Transform matrix data
|
||||
*/
|
||||
public MATRIX matrix;
|
||||
|
||||
/**
|
||||
* Color transform data
|
||||
*/
|
||||
@Optional
|
||||
public CXFORM colorTransform;
|
||||
|
||||
public static final int ID = 4;
|
||||
|
||||
public static final String NAME = "PlaceObject";
|
||||
|
||||
@Override
|
||||
public List<FILTER> getFilters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getClipDepth() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterId);
|
||||
sos.writeUI16(depth);
|
||||
sos.writeMatrix(matrix);
|
||||
if (colorTransform != null) {
|
||||
sos.writeCXFORM(colorTransform);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public PlaceObjectTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
matrix = new MATRIX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public PlaceObjectTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterId = sis.readUI16("characterId");
|
||||
depth = sis.readUI16("depth");
|
||||
matrix = sis.readMatrix("matrix");
|
||||
if (sis.available() > 0) {
|
||||
colorTransform = sis.readCXFORM("colorTransform");
|
||||
}
|
||||
}
|
||||
|
||||
public PlaceObjectTag(SWF swf, int characterId, int depth, MATRIX matrix, CXFORM colorTransform) {
|
||||
super(swf, ID, NAME, null);
|
||||
this.characterId = characterId;
|
||||
this.depth = depth;
|
||||
this.matrix = matrix;
|
||||
this.colorTransform = colorTransform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
needed.add(characterId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(int characterId) {
|
||||
// the place object tag will be removed
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MATRIX getMatrix() {
|
||||
return matrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorTransform getColorTransform() {
|
||||
return colorTransform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlendMode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cacheAsBitmap() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RGBA getBackgroundColor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean flagMove() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRatio() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInstanceName(String name) {
|
||||
//not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClassName(String className) {
|
||||
//not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public CLIPACTIONS getClipActions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTagWithMatrix(SWFOutputStream sos, MATRIX m) throws IOException {
|
||||
MATRIX old = matrix;
|
||||
matrix = m;
|
||||
boolean mod = isModified();
|
||||
setModified(true);
|
||||
super.writeTag(sos);
|
||||
setModified(mod);
|
||||
matrix = old;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,17 +54,19 @@ public class ProductInfoTag extends Tag {
|
||||
|
||||
public static final int ID = 41;
|
||||
|
||||
public static final String NAME = "ProductInfo";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public ProductInfoTag(SWF swf) {
|
||||
super(swf, ID, "ProductInfo", null);
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public ProductInfoTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "ProductInfo", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ public class ProtectTag extends Tag {
|
||||
|
||||
public static final int ID = 24;
|
||||
|
||||
public static final String NAME = "Protect";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
@@ -64,7 +66,7 @@ public class ProtectTag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public ProtectTag(SWF swf) {
|
||||
super(swf, ID, "Protect", null);
|
||||
super(swf, ID, NAME, null);
|
||||
passwordHash = "";
|
||||
}
|
||||
|
||||
@@ -76,7 +78,7 @@ public class ProtectTag extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public ProtectTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "Protect", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,17 +34,19 @@ public class RemoveObject2Tag extends RemoveTag {
|
||||
|
||||
public static final int ID = 28;
|
||||
|
||||
public static final String NAME = "RemoveObject2";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public RemoveObject2Tag(SWF swf) {
|
||||
super(swf, ID, "RemoveObject2", null);
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public RemoveObject2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "RemoveObject2", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,113 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Removes the specified character
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class RemoveObjectTag extends RemoveTag implements CharacterIdTag {
|
||||
|
||||
/**
|
||||
* ID of character to place
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterId;
|
||||
|
||||
/**
|
||||
* Depth of character
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int depth;
|
||||
|
||||
public static final int ID = 5;
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterId);
|
||||
sos.writeUI16(depth);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public RemoveObjectTag(SWF swf) {
|
||||
super(swf, ID, "RemoveObject", null);
|
||||
characterId = swf.getNextCharacterId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public RemoveObjectTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "RemoveObject", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterId = sis.readUI16("characterId");
|
||||
depth = sis.readUI16("depth");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterId = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Removes the specified character
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class RemoveObjectTag extends RemoveTag implements CharacterIdTag {
|
||||
|
||||
/**
|
||||
* ID of character to place
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterId;
|
||||
|
||||
/**
|
||||
* Depth of character
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int depth;
|
||||
|
||||
public static final int ID = 5;
|
||||
|
||||
public static final String NAME = "RemoveObject";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(characterId);
|
||||
sos.writeUI16(depth);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public RemoveObjectTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
characterId = swf.getNextCharacterId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public RemoveObjectTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterId = sis.readUI16("characterId");
|
||||
depth = sis.readUI16("depth");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterId = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,17 +36,19 @@ public class ScriptLimitsTag extends Tag {
|
||||
|
||||
public static final int ID = 65;
|
||||
|
||||
public static final String NAME = "ScriptLimits";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public ScriptLimitsTag(SWF swf) {
|
||||
super(swf, ID, "ScriptLimits", null);
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public ScriptLimitsTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "ScriptLimits", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,23 +30,25 @@ public class SetBackgroundColorTag extends Tag {
|
||||
|
||||
public static final int ID = 9;
|
||||
|
||||
public static final String NAME = "SetBackgroundColor";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public SetBackgroundColorTag(SWF swf) {
|
||||
super(swf, ID, "SetBackgroundColor", null);
|
||||
super(swf, ID, NAME, null);
|
||||
backgroundColor = new RGB();
|
||||
}
|
||||
|
||||
public SetBackgroundColorTag(SWF swf, RGB backgroundColor) {
|
||||
super(swf, ID, "SetBackgroundColor", null);
|
||||
super(swf, ID, NAME, null);
|
||||
this.backgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
public SetBackgroundColorTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "SetBackgroundColor", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ public class SetTabIndexTag extends Tag {
|
||||
|
||||
public static final int ID = 66;
|
||||
|
||||
public static final String NAME = "SetTabIndex";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
@@ -72,7 +74,7 @@ public class SetTabIndexTag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public SetTabIndexTag(SWF swf) {
|
||||
super(swf, ID, "SetTabIndex", null);
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,7 +85,7 @@ public class SetTabIndexTag extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public SetTabIndexTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "SetTabIndex", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ public class ShowFrameTag extends Tag {
|
||||
|
||||
public static final int ID = 1;
|
||||
|
||||
public static final String NAME = "ShowFrame";
|
||||
|
||||
private static List<Integer> nestedTagTypeIds = new ArrayList<Integer>() {
|
||||
{
|
||||
add(PlaceObjectTag.ID);
|
||||
@@ -55,7 +57,7 @@ public class ShowFrameTag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public ShowFrameTag(SWF swf) {
|
||||
super(swf, ID, "ShowFrame", null);
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +67,7 @@ public class ShowFrameTag extends Tag {
|
||||
* @param data
|
||||
*/
|
||||
public ShowFrameTag(SWFInputStream sis, ByteArrayRange data) {
|
||||
super(sis.getSwf(), ID, "ShowFrame", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ public class SoundStreamBlockTag extends Tag {
|
||||
|
||||
public static final int ID = 19;
|
||||
|
||||
public static final String NAME = "SoundStreamBlock";
|
||||
|
||||
@HideInRawEdit
|
||||
public ByteArrayRange streamSoundData;
|
||||
|
||||
@@ -43,7 +45,7 @@ public class SoundStreamBlockTag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public SoundStreamBlockTag(SWF swf) {
|
||||
super(swf, ID, "SoundStreamBlock", null);
|
||||
super(swf, ID, NAME, null);
|
||||
streamSoundData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
@@ -55,7 +57,7 @@ public class SoundStreamBlockTag extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public SoundStreamBlockTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "SoundStreamBlock", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,251 +1,253 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SoundStreamHead2Tag extends Tag implements SoundStreamHeadTypeTag {
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int reserved;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int playBackSoundRate;
|
||||
|
||||
public boolean playBackSoundSize;
|
||||
|
||||
public boolean playBackSoundType;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int streamSoundCompression;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int streamSoundRate;
|
||||
|
||||
public boolean streamSoundSize;
|
||||
|
||||
public boolean streamSoundType;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int streamSoundSampleCount;
|
||||
|
||||
@SWFType(BasicType.SI16)
|
||||
@Conditional(value = "streamSoundCompression", options = {2})
|
||||
public int latencySeek;
|
||||
|
||||
@Internal
|
||||
private int virtualCharacterId = 0;
|
||||
|
||||
public static final int ID = 45;
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return virtualCharacterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
virtualCharacterId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExportFormat() {
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_MP3) {
|
||||
return "mp3";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_ADPCM) {
|
||||
return "wav";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN) {
|
||||
return "wav";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_UNCOMPRESSED_NATIVE_ENDIAN) {
|
||||
return "wav";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_NELLYMOSER || streamSoundCompression == SoundFormat.FORMAT_NELLYMOSER16KHZ || streamSoundCompression == SoundFormat.FORMAT_NELLYMOSER8KHZ) {
|
||||
return "wav";
|
||||
}
|
||||
return "flv";
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSoundSampleCount() {
|
||||
return streamSoundSampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVirtualCharacterId(int ch) {
|
||||
virtualCharacterId = ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUB(4, reserved);
|
||||
sos.writeUB(2, playBackSoundRate);
|
||||
sos.writeUB(1, playBackSoundSize ? 1 : 0);
|
||||
sos.writeUB(1, playBackSoundType ? 1 : 0);
|
||||
sos.writeUB(4, streamSoundCompression);
|
||||
sos.writeUB(2, streamSoundRate);
|
||||
sos.writeUB(1, streamSoundSize ? 1 : 0);
|
||||
sos.writeUB(1, streamSoundType ? 1 : 0);
|
||||
sos.writeUI16(streamSoundSampleCount);
|
||||
if (streamSoundCompression == 2) {
|
||||
sos.writeSI16(latencySeek);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public SoundStreamHead2Tag(SWF swf) {
|
||||
super(swf, ID, "SoundStreamHead2", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public SoundStreamHead2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "SoundStreamHead2", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
reserved = (int) sis.readUB(4, "reserved");
|
||||
playBackSoundRate = (int) sis.readUB(2, "playBackSoundRate");
|
||||
playBackSoundSize = sis.readUB(1, "playBackSoundSize") == 1;
|
||||
playBackSoundType = sis.readUB(1, "playBackSoundType") == 1;
|
||||
streamSoundCompression = (int) sis.readUB(4, "streamSoundCompression");
|
||||
streamSoundRate = (int) sis.readUB(2, "streamSoundRate");
|
||||
streamSoundSize = sis.readUB(1, "streamSoundSize") == 1;
|
||||
streamSoundType = sis.readUB(1, "streamSoundType") == 1;
|
||||
streamSoundSampleCount = sis.readUI16("streamSoundSampleCount");
|
||||
if (streamSoundCompression == 2) {
|
||||
latencySeek = sis.readSI16("latencySeek");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundFormatId() {
|
||||
return streamSoundCompression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundRate() {
|
||||
return streamSoundRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundSize() {
|
||||
return streamSoundSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundType() {
|
||||
return streamSoundType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SoundStreamBlockTag> getBlocks() {
|
||||
List<SoundStreamBlockTag> ret = new ArrayList<>();
|
||||
SoundStreamHeadTag.populateSoundStreamBlocks(0, swf.tags, this, ret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSound(InputStream is, int newSoundFormat) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<byte[]> getRawSoundData() {
|
||||
List<byte[]> ret = new ArrayList<>();
|
||||
List<SoundStreamBlockTag> blocks = getBlocks();
|
||||
for (SoundStreamBlockTag block : blocks) {
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_MP3) {
|
||||
ret.add(block.streamSoundData.getRangeData(4, block.streamSoundData.getLength() - 4));
|
||||
} else {
|
||||
ret.add(block.streamSoundData.getRangeData());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalSoundSampleCount() {
|
||||
return getBlocks().size() * streamSoundSampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundFormat getSoundFormat() {
|
||||
final int[] rateMap = {5512, 11025, 22050, 44100};
|
||||
return new SoundFormat(getSoundFormatId(), rateMap[getSoundRate()], getSoundType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacterExportFileName() {
|
||||
String exportName = swf.getExportName(getCharacterId());
|
||||
return getCharacterId() + (exportName != null ? "_" + exportName : "");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SoundStreamHead2Tag extends Tag implements SoundStreamHeadTypeTag {
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int reserved;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int playBackSoundRate;
|
||||
|
||||
public boolean playBackSoundSize;
|
||||
|
||||
public boolean playBackSoundType;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int streamSoundCompression;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int streamSoundRate;
|
||||
|
||||
public boolean streamSoundSize;
|
||||
|
||||
public boolean streamSoundType;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int streamSoundSampleCount;
|
||||
|
||||
@SWFType(BasicType.SI16)
|
||||
@Conditional(value = "streamSoundCompression", options = {2})
|
||||
public int latencySeek;
|
||||
|
||||
@Internal
|
||||
private int virtualCharacterId = 0;
|
||||
|
||||
public static final int ID = 45;
|
||||
|
||||
public static final String NAME = "SoundStreamHead2";
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return virtualCharacterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
virtualCharacterId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExportFormat() {
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_MP3) {
|
||||
return "mp3";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_ADPCM) {
|
||||
return "wav";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN) {
|
||||
return "wav";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_UNCOMPRESSED_NATIVE_ENDIAN) {
|
||||
return "wav";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_NELLYMOSER || streamSoundCompression == SoundFormat.FORMAT_NELLYMOSER16KHZ || streamSoundCompression == SoundFormat.FORMAT_NELLYMOSER8KHZ) {
|
||||
return "wav";
|
||||
}
|
||||
return "flv";
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSoundSampleCount() {
|
||||
return streamSoundSampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVirtualCharacterId(int ch) {
|
||||
virtualCharacterId = ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUB(4, reserved);
|
||||
sos.writeUB(2, playBackSoundRate);
|
||||
sos.writeUB(1, playBackSoundSize ? 1 : 0);
|
||||
sos.writeUB(1, playBackSoundType ? 1 : 0);
|
||||
sos.writeUB(4, streamSoundCompression);
|
||||
sos.writeUB(2, streamSoundRate);
|
||||
sos.writeUB(1, streamSoundSize ? 1 : 0);
|
||||
sos.writeUB(1, streamSoundType ? 1 : 0);
|
||||
sos.writeUI16(streamSoundSampleCount);
|
||||
if (streamSoundCompression == 2) {
|
||||
sos.writeSI16(latencySeek);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public SoundStreamHead2Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public SoundStreamHead2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
reserved = (int) sis.readUB(4, "reserved");
|
||||
playBackSoundRate = (int) sis.readUB(2, "playBackSoundRate");
|
||||
playBackSoundSize = sis.readUB(1, "playBackSoundSize") == 1;
|
||||
playBackSoundType = sis.readUB(1, "playBackSoundType") == 1;
|
||||
streamSoundCompression = (int) sis.readUB(4, "streamSoundCompression");
|
||||
streamSoundRate = (int) sis.readUB(2, "streamSoundRate");
|
||||
streamSoundSize = sis.readUB(1, "streamSoundSize") == 1;
|
||||
streamSoundType = sis.readUB(1, "streamSoundType") == 1;
|
||||
streamSoundSampleCount = sis.readUI16("streamSoundSampleCount");
|
||||
if (streamSoundCompression == 2) {
|
||||
latencySeek = sis.readSI16("latencySeek");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundFormatId() {
|
||||
return streamSoundCompression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundRate() {
|
||||
return streamSoundRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundSize() {
|
||||
return streamSoundSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundType() {
|
||||
return streamSoundType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SoundStreamBlockTag> getBlocks() {
|
||||
List<SoundStreamBlockTag> ret = new ArrayList<>();
|
||||
SoundStreamHeadTag.populateSoundStreamBlocks(0, swf.tags, this, ret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSound(InputStream is, int newSoundFormat) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<byte[]> getRawSoundData() {
|
||||
List<byte[]> ret = new ArrayList<>();
|
||||
List<SoundStreamBlockTag> blocks = getBlocks();
|
||||
for (SoundStreamBlockTag block : blocks) {
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_MP3) {
|
||||
ret.add(block.streamSoundData.getRangeData(4, block.streamSoundData.getLength() - 4));
|
||||
} else {
|
||||
ret.add(block.streamSoundData.getRangeData());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalSoundSampleCount() {
|
||||
return getBlocks().size() * streamSoundSampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundFormat getSoundFormat() {
|
||||
final int[] rateMap = {5512, 11025, 22050, 44100};
|
||||
return new SoundFormat(getSoundFormatId(), rateMap[getSoundRate()], getSoundType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacterExportFileName() {
|
||||
String exportName = swf.getExportName(getCharacterId());
|
||||
return getCharacterId() + (exportName != null ? "_" + exportName : "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,274 +1,276 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SoundStreamHeadTag extends Tag implements SoundStreamHeadTypeTag {
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int reserved;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int playBackSoundRate;
|
||||
|
||||
public boolean playBackSoundSize;
|
||||
|
||||
public boolean playBackSoundType;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int streamSoundCompression;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int streamSoundRate;
|
||||
|
||||
public boolean streamSoundSize;
|
||||
|
||||
public boolean streamSoundType;
|
||||
|
||||
@SWFType(value = BasicType.UI16)
|
||||
public int streamSoundSampleCount;
|
||||
|
||||
@Conditional(value = "streamSoundCompression", options = {2})
|
||||
public int latencySeek;
|
||||
|
||||
@Internal
|
||||
private int virtualCharacterId = 0;
|
||||
|
||||
public static final int ID = 18;
|
||||
|
||||
@Override
|
||||
public String getExportFormat() {
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_MP3) {
|
||||
return "mp3";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_ADPCM) {
|
||||
return "wav";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN) {
|
||||
return "wav";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_UNCOMPRESSED_NATIVE_ENDIAN) {
|
||||
return "wav";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_NELLYMOSER || streamSoundCompression == SoundFormat.FORMAT_NELLYMOSER16KHZ || streamSoundCompression == SoundFormat.FORMAT_NELLYMOSER8KHZ) {
|
||||
return "wav";
|
||||
}
|
||||
return "flv";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return virtualCharacterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
virtualCharacterId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVirtualCharacterId(int ch) {
|
||||
virtualCharacterId = ch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSoundSampleCount() {
|
||||
return streamSoundSampleCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUB(4, reserved);
|
||||
sos.writeUB(2, playBackSoundRate);
|
||||
sos.writeUB(1, playBackSoundSize ? 1 : 0);
|
||||
sos.writeUB(1, playBackSoundType ? 1 : 0);
|
||||
sos.writeUB(4, streamSoundCompression);
|
||||
sos.writeUB(2, streamSoundRate);
|
||||
sos.writeUB(1, streamSoundSize ? 1 : 0);
|
||||
sos.writeUB(1, streamSoundType ? 1 : 0);
|
||||
sos.writeUI16(streamSoundSampleCount);
|
||||
if (streamSoundCompression == 2) {
|
||||
sos.writeSI16(latencySeek);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public SoundStreamHeadTag(SWF swf) {
|
||||
super(swf, ID, "SoundStreamHead", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public SoundStreamHeadTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "SoundStreamHead", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
reserved = (int) sis.readUB(4, "reserved");
|
||||
playBackSoundRate = (int) sis.readUB(2, "playBackSoundRate");
|
||||
playBackSoundSize = sis.readUB(1, "playBackSoundSize") == 1;
|
||||
playBackSoundType = sis.readUB(1, "playBackSoundType") == 1;
|
||||
streamSoundCompression = (int) sis.readUB(4, "streamSoundCompression");
|
||||
streamSoundRate = (int) sis.readUB(2, "streamSoundRate");
|
||||
streamSoundSize = sis.readUB(1, "streamSoundSize") == 1;
|
||||
streamSoundType = sis.readUB(1, "streamSoundType") == 1;
|
||||
streamSoundSampleCount = sis.readUI16("streamSoundSampleCount");
|
||||
if (streamSoundCompression == 2) {
|
||||
latencySeek = sis.readSI16("latencySeek");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundFormatId() {
|
||||
return streamSoundCompression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundRate() {
|
||||
return streamSoundRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundSize() {
|
||||
return streamSoundSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundType() {
|
||||
return streamSoundType;
|
||||
}
|
||||
|
||||
public static void populateSoundStreamBlocks(int containerId, List<Tag> tags, SoundStreamHeadTypeTag head, List<SoundStreamBlockTag> output) {
|
||||
boolean found = false;
|
||||
for (Tag t : tags) {
|
||||
if (t == head) {
|
||||
found = true;
|
||||
head.setVirtualCharacterId(containerId);
|
||||
continue;
|
||||
}
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) t;
|
||||
populateSoundStreamBlocks(sprite.getCharacterId(), sprite.getSubTags(), head, output);
|
||||
}
|
||||
if (!found) {
|
||||
continue;
|
||||
}
|
||||
if (t instanceof SoundStreamBlockTag) {
|
||||
output.add((SoundStreamBlockTag) t);
|
||||
}
|
||||
if (t instanceof SoundStreamHeadTypeTag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SoundStreamBlockTag> getBlocks() {
|
||||
List<SoundStreamBlockTag> ret = new ArrayList<>();
|
||||
populateSoundStreamBlocks(0, swf.tags, this, ret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSound(InputStream is, int newSoundFormat) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<byte[]> getRawSoundData() {
|
||||
List<byte[]> ret = new ArrayList<>();
|
||||
List<SoundStreamBlockTag> blocks = getBlocks();
|
||||
for (SoundStreamBlockTag block : blocks) {
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_MP3) {
|
||||
ret.add(block.streamSoundData.getRangeData(4, block.streamSoundData.getLength() - 4));
|
||||
} else {
|
||||
ret.add(block.streamSoundData.getRangeData());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalSoundSampleCount() {
|
||||
return getBlocks().size() * streamSoundSampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundFormat getSoundFormat() {
|
||||
final int[] rateMap = {5512, 11025, 22050, 44100};
|
||||
return new SoundFormat(getSoundFormatId(), rateMap[getSoundRate()], getSoundType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacterExportFileName() {
|
||||
String exportName = swf.getExportName(getCharacterId());
|
||||
return getCharacterId() + (exportName != null ? "_" + exportName : "");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SoundStreamHeadTag extends Tag implements SoundStreamHeadTypeTag {
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int reserved;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int playBackSoundRate;
|
||||
|
||||
public boolean playBackSoundSize;
|
||||
|
||||
public boolean playBackSoundType;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int streamSoundCompression;
|
||||
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int streamSoundRate;
|
||||
|
||||
public boolean streamSoundSize;
|
||||
|
||||
public boolean streamSoundType;
|
||||
|
||||
@SWFType(value = BasicType.UI16)
|
||||
public int streamSoundSampleCount;
|
||||
|
||||
@Conditional(value = "streamSoundCompression", options = {2})
|
||||
public int latencySeek;
|
||||
|
||||
@Internal
|
||||
private int virtualCharacterId = 0;
|
||||
|
||||
public static final int ID = 18;
|
||||
|
||||
public static final String NAME = "SoundStreamHead";
|
||||
|
||||
@Override
|
||||
public String getExportFormat() {
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_MP3) {
|
||||
return "mp3";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_ADPCM) {
|
||||
return "wav";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN) {
|
||||
return "wav";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_UNCOMPRESSED_NATIVE_ENDIAN) {
|
||||
return "wav";
|
||||
}
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_NELLYMOSER || streamSoundCompression == SoundFormat.FORMAT_NELLYMOSER16KHZ || streamSoundCompression == SoundFormat.FORMAT_NELLYMOSER8KHZ) {
|
||||
return "wav";
|
||||
}
|
||||
return "flv";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return virtualCharacterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
virtualCharacterId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVirtualCharacterId(int ch) {
|
||||
virtualCharacterId = ch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSoundSampleCount() {
|
||||
return streamSoundSampleCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUB(4, reserved);
|
||||
sos.writeUB(2, playBackSoundRate);
|
||||
sos.writeUB(1, playBackSoundSize ? 1 : 0);
|
||||
sos.writeUB(1, playBackSoundType ? 1 : 0);
|
||||
sos.writeUB(4, streamSoundCompression);
|
||||
sos.writeUB(2, streamSoundRate);
|
||||
sos.writeUB(1, streamSoundSize ? 1 : 0);
|
||||
sos.writeUB(1, streamSoundType ? 1 : 0);
|
||||
sos.writeUI16(streamSoundSampleCount);
|
||||
if (streamSoundCompression == 2) {
|
||||
sos.writeSI16(latencySeek);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public SoundStreamHeadTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public SoundStreamHeadTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
reserved = (int) sis.readUB(4, "reserved");
|
||||
playBackSoundRate = (int) sis.readUB(2, "playBackSoundRate");
|
||||
playBackSoundSize = sis.readUB(1, "playBackSoundSize") == 1;
|
||||
playBackSoundType = sis.readUB(1, "playBackSoundType") == 1;
|
||||
streamSoundCompression = (int) sis.readUB(4, "streamSoundCompression");
|
||||
streamSoundRate = (int) sis.readUB(2, "streamSoundRate");
|
||||
streamSoundSize = sis.readUB(1, "streamSoundSize") == 1;
|
||||
streamSoundType = sis.readUB(1, "streamSoundType") == 1;
|
||||
streamSoundSampleCount = sis.readUI16("streamSoundSampleCount");
|
||||
if (streamSoundCompression == 2) {
|
||||
latencySeek = sis.readSI16("latencySeek");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundFormatId() {
|
||||
return streamSoundCompression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundRate() {
|
||||
return streamSoundRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundSize() {
|
||||
return streamSoundSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundType() {
|
||||
return streamSoundType;
|
||||
}
|
||||
|
||||
public static void populateSoundStreamBlocks(int containerId, List<Tag> tags, SoundStreamHeadTypeTag head, List<SoundStreamBlockTag> output) {
|
||||
boolean found = false;
|
||||
for (Tag t : tags) {
|
||||
if (t == head) {
|
||||
found = true;
|
||||
head.setVirtualCharacterId(containerId);
|
||||
continue;
|
||||
}
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) t;
|
||||
populateSoundStreamBlocks(sprite.getCharacterId(), sprite.getSubTags(), head, output);
|
||||
}
|
||||
if (!found) {
|
||||
continue;
|
||||
}
|
||||
if (t instanceof SoundStreamBlockTag) {
|
||||
output.add((SoundStreamBlockTag) t);
|
||||
}
|
||||
if (t instanceof SoundStreamHeadTypeTag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SoundStreamBlockTag> getBlocks() {
|
||||
List<SoundStreamBlockTag> ret = new ArrayList<>();
|
||||
populateSoundStreamBlocks(0, swf.tags, this, ret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSound(InputStream is, int newSoundFormat) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<byte[]> getRawSoundData() {
|
||||
List<byte[]> ret = new ArrayList<>();
|
||||
List<SoundStreamBlockTag> blocks = getBlocks();
|
||||
for (SoundStreamBlockTag block : blocks) {
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_MP3) {
|
||||
ret.add(block.streamSoundData.getRangeData(4, block.streamSoundData.getLength() - 4));
|
||||
} else {
|
||||
ret.add(block.streamSoundData.getRangeData());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalSoundSampleCount() {
|
||||
return getBlocks().size() * streamSoundSampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundFormat getSoundFormat() {
|
||||
final int[] rateMap = {5512, 11025, 22050, 44100};
|
||||
return new SoundFormat(getSoundFormatId(), rateMap[getSoundRate()], getSoundType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacterExportFileName() {
|
||||
String exportName = swf.getExportName(getCharacterId());
|
||||
return getCharacterId() + (exportName != null ? "_" + exportName : "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
@@ -38,6 +37,8 @@ public class StartSound2Tag extends Tag {
|
||||
|
||||
public static final int ID = 89;
|
||||
|
||||
public static final String NAME = "StartSound2";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
@@ -63,7 +64,7 @@ public class StartSound2Tag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public StartSound2Tag(SWF swf) {
|
||||
super(swf, ID, "StartSound2", null);
|
||||
super(swf, ID, NAME, null);
|
||||
soundClassName = "NewSoundClass";
|
||||
soundInfo = new SOUNDINFO();
|
||||
}
|
||||
@@ -76,7 +77,7 @@ public class StartSound2Tag extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public StartSound2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "StartSound2", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ public class StartSoundTag extends Tag {
|
||||
|
||||
public static final int ID = 15;
|
||||
|
||||
public static final String NAME = "StartSound";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
@@ -66,7 +68,7 @@ public class StartSoundTag extends Tag {
|
||||
* @param swf
|
||||
*/
|
||||
public StartSoundTag(SWF swf) {
|
||||
super(swf, ID, "StartSound", null);
|
||||
super(swf, ID, NAME, null);
|
||||
soundInfo = new SOUNDINFO();
|
||||
}
|
||||
|
||||
@@ -78,7 +80,7 @@ public class StartSoundTag extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public StartSoundTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "StartSound", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,19 +41,21 @@ public class SymbolClassTag extends SymbolClassTypeTag {
|
||||
|
||||
public static final int ID = 76;
|
||||
|
||||
public static final String NAME = "SymbolClass";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public SymbolClassTag(SWF swf) {
|
||||
super(swf, ID, "SymbolClass", null);
|
||||
super(swf, ID, NAME, null);
|
||||
tags = new ArrayList<>();
|
||||
names = new ArrayList<>();
|
||||
}
|
||||
|
||||
public SymbolClassTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "SymbolClass", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TagInfo {
|
||||
|
||||
public int id;
|
||||
|
||||
public Class cls;
|
||||
|
||||
public String name;
|
||||
|
||||
public TagInfo(int id, Class cls, String name) {
|
||||
this.id = id;
|
||||
this.cls = cls;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -1,105 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class VideoFrameTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int streamID;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int frameNum;
|
||||
|
||||
public ByteArrayRange videoData;
|
||||
|
||||
public static final int ID = 61;
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(streamID);
|
||||
sos.writeUI16(frameNum);
|
||||
sos.write(videoData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public VideoFrameTag(SWF swf) {
|
||||
super(swf, ID, "VideoFrame", null);
|
||||
videoData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public VideoFrameTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "VideoFrame", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
streamID = sis.readUI16("streamID");
|
||||
frameNum = sis.readUI16("frameNum");
|
||||
videoData = sis.readByteRangeEx(sis.available(), "videoData"); //TODO: Parse video packets
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return streamID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.streamID = characterId;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class VideoFrameTag extends Tag implements CharacterIdTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int streamID;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int frameNum;
|
||||
|
||||
public ByteArrayRange videoData;
|
||||
|
||||
public static final int ID = 61;
|
||||
|
||||
public static final String NAME = "VideoFrame";
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(streamID);
|
||||
sos.writeUI16(frameNum);
|
||||
sos.write(videoData);
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public VideoFrameTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
videoData = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public VideoFrameTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
streamID = sis.readUI16("streamID");
|
||||
frameNum = sis.readUI16("frameNum");
|
||||
videoData = sis.readByteRangeEx(sis.available(), "videoData"); //TODO: Parse video packets
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return streamID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.streamID = characterId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,430 +1,432 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags.gfx;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.helpers.FontHelper;
|
||||
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
|
||||
import com.jpexs.decompiler.flash.types.LANGCODE;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.gfx.FontType;
|
||||
import com.jpexs.decompiler.flash.types.gfx.GFxInputStream;
|
||||
import com.jpexs.decompiler.flash.types.gfx.GFxOutputStream;
|
||||
import com.jpexs.decompiler.flash.types.gfx.GlyphInfoType;
|
||||
import com.jpexs.decompiler.flash.types.gfx.GlyphType;
|
||||
import com.jpexs.decompiler.flash.types.gfx.KerningPairType;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import java.awt.Font;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public final class DefineCompactedFont extends FontTag {
|
||||
|
||||
public static final int ID = 1005;
|
||||
|
||||
public int fontId;
|
||||
|
||||
public List<FontType> fonts;
|
||||
|
||||
private List<SHAPE> shapeCache;
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontId);
|
||||
for (FontType ft : fonts) {
|
||||
ft.write(new GFxOutputStream(sos));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineCompactedFont(SWF swf) {
|
||||
super(swf, ID, "DefineCompactedFont", null);
|
||||
fontId = swf.getNextCharacterId();
|
||||
|
||||
fonts = new ArrayList<>();
|
||||
FontType ft = new FontType();
|
||||
fonts.add(ft);
|
||||
|
||||
rebuildShapeCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineCompactedFont(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineCompactedFont", data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontId = sis.readUI16("fontId");
|
||||
fonts = new ArrayList<>();
|
||||
|
||||
MemoryInputStream mis = sis.getBaseStream();
|
||||
while (mis.available() > 0) {
|
||||
GFxInputStream gis = new GFxInputStream(mis);
|
||||
gis.dumpInfo = sis.dumpInfo;
|
||||
gis.newDumpLevel("fontType", "FontType");
|
||||
fonts.add(new FontType(gis));
|
||||
gis.endDumpLevel();
|
||||
}
|
||||
rebuildShapeCache();
|
||||
}
|
||||
|
||||
public void rebuildShapeCache() {
|
||||
shapeCache = fonts.get(0).getGlyphShapes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFontNameIntag() {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i = 0; i < fonts.size(); i++) {
|
||||
if (i > 0) {
|
||||
ret.append(", ");
|
||||
}
|
||||
ret.append(fonts.get(i).fontName);
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFontId() {
|
||||
return fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SHAPE> getGlyphShapeTable() {
|
||||
return shapeCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCharacter(char character, Font cfont) {
|
||||
int fontStyle = getFontStyle();
|
||||
FontType font = fonts.get(0);
|
||||
|
||||
double d = 1;
|
||||
SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(cfont, (int) (font.nominalSize * d), character);
|
||||
|
||||
int code = (int) character;
|
||||
int pos = -1;
|
||||
boolean exists = false;
|
||||
for (int i = 0; i < font.glyphInfo.size(); i++) {
|
||||
if (font.glyphInfo.get(i).glyphCode >= code) {
|
||||
if (font.glyphInfo.get(i).glyphCode == code) {
|
||||
exists = true;
|
||||
}
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos == -1) {
|
||||
pos = font.glyphInfo.size();
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
shiftGlyphIndices(fontId, pos);
|
||||
}
|
||||
|
||||
Font fnt = cfont.deriveFont(fontStyle, Math.round(font.nominalSize * d));
|
||||
int advance = (int) Math.round(FontHelper.getFontAdvance(fnt, character));
|
||||
if (!exists) {
|
||||
font.glyphInfo.add(pos, new GlyphInfoType(code, advance, 0));
|
||||
font.glyphs.add(pos, new GlyphType(shp.shapeRecords));
|
||||
shapeCache.add(pos, font.glyphs.get(pos).toSHAPE());
|
||||
} else {
|
||||
font.glyphInfo.set(pos, new GlyphInfoType(code, advance, 0));
|
||||
font.glyphs.set(pos, new GlyphType(shp.shapeRecords));
|
||||
shapeCache.set(pos, font.glyphs.get(pos).toSHAPE());
|
||||
}
|
||||
|
||||
setModified(true);
|
||||
getSwf().clearImageCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdvanceValues(Font font) {
|
||||
throw new UnsupportedOperationException("Setting the advance values for DefineCompactedFont is not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public char glyphToChar(int glyphIndex) {
|
||||
return (char) fonts.get(0).glyphInfo.get(glyphIndex).glyphCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int charToGlyph(char c) {
|
||||
FontType ft = fonts.get(0);
|
||||
for (int i = 0; i < ft.glyphInfo.size(); i++) {
|
||||
if (ft.glyphInfo.get(i).glyphCode == c) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getGlyphAdvance(int glyphIndex) {
|
||||
return resize(fonts.get(0).glyphInfo.get(glyphIndex).advanceX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
|
||||
char c1 = glyphToChar(glyphIndex);
|
||||
char c2 = glyphToChar(nextGlyphIndex);
|
||||
return getCharKerningAdjustment(c1, c2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharKerningAdjustment(char c1, char c2) {
|
||||
for (KerningPairType kp : fonts.get(0).kerning) {
|
||||
if (kp.char1 == c1 && kp.char2 == c2) {
|
||||
return resize(kp.advance);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGlyphWidth(int glyphIndex) {
|
||||
return resize(getGlyphShapeTable().get(glyphIndex).getBounds().getWidth());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSmall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBold() {
|
||||
return (fonts.get(0).flags & FontType.FF_Bold) == FontType.FF_Bold;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItalic() {
|
||||
return (fonts.get(0).flags & FontType.FF_Italic) == FontType.FF_Italic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSmallEditable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBoldEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItalicEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBold(boolean value) {
|
||||
for (FontType font : fonts) {
|
||||
font.flags &= FontType.FF_Bold;
|
||||
if (!value) {
|
||||
font.flags ^= FontType.FF_Bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItalic(boolean value) {
|
||||
for (FontType font : fonts) {
|
||||
font.flags &= FontType.FF_Italic;
|
||||
if (!value) {
|
||||
font.flags ^= FontType.FF_Italic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDivider() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAscent() {
|
||||
return fonts.get(0).ascent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDescent() {
|
||||
return fonts.get(0).descent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLeading() {
|
||||
return fonts.get(0).leading;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacters(List<Tag> tags) {
|
||||
FontType ft = fonts.get(0);
|
||||
StringBuilder ret = new StringBuilder(ft.glyphInfo.size());
|
||||
for (GlyphInfoType gi : ft.glyphInfo) {
|
||||
ret.append((char) gi.glyphCode);
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getGlyphBounds(int glyphIndex) {
|
||||
GlyphType gt = fonts.get(0).glyphs.get(glyphIndex);
|
||||
return new RECT(resize(gt.boundingBox[0]), resize(gt.boundingBox[1]), resize(gt.boundingBox[2]), resize(gt.boundingBox[3]));
|
||||
}
|
||||
|
||||
public SHAPE resizeShape(SHAPE shp) {
|
||||
SHAPE ret = new SHAPE();
|
||||
ret.numFillBits = 1;
|
||||
ret.numLineBits = 0;
|
||||
List<SHAPERECORD> recs = new ArrayList<>();
|
||||
for (SHAPERECORD r : shp.shapeRecords) {
|
||||
SHAPERECORD c = r.clone();
|
||||
if (c instanceof StyleChangeRecord) {
|
||||
StyleChangeRecord scr = (StyleChangeRecord) c;
|
||||
scr.moveDeltaX = resize(scr.moveDeltaX);
|
||||
scr.moveDeltaY = resize(scr.moveDeltaY);
|
||||
scr.calculateBits();
|
||||
}
|
||||
if (c instanceof CurvedEdgeRecord) {
|
||||
CurvedEdgeRecord cer = (CurvedEdgeRecord) c;
|
||||
cer.controlDeltaX = resize(cer.controlDeltaX);
|
||||
cer.controlDeltaY = resize(cer.controlDeltaY);
|
||||
cer.anchorDeltaX = resize(cer.anchorDeltaX);
|
||||
cer.anchorDeltaY = resize(cer.anchorDeltaY);
|
||||
cer.calculateBits();
|
||||
}
|
||||
if (c instanceof StraightEdgeRecord) {
|
||||
StraightEdgeRecord ser = (StraightEdgeRecord) c;
|
||||
ser.deltaX = resize(ser.deltaX);
|
||||
ser.deltaY = resize(ser.deltaY);
|
||||
ser.calculateBits();
|
||||
}
|
||||
recs.add(c);
|
||||
}
|
||||
ret.shapeRecords = recs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected int resize(double val) {
|
||||
FontType ft = fonts.get(0);
|
||||
return (int) Math.round(val * 1024.0 / ft.nominalSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontTag toClassicFont() {
|
||||
DefineFont2Tag ret = new DefineFont2Tag(swf);
|
||||
ret.fontId = getFontId();
|
||||
ret.fontFlagsBold = isBold();
|
||||
ret.fontFlagsItalic = isItalic();
|
||||
ret.fontFlagsWideOffsets = true;
|
||||
ret.fontFlagsWideCodes = true;
|
||||
ret.fontFlagsHasLayout = true;
|
||||
ret.fontAscent = (getAscent());
|
||||
ret.fontDescent = (getDescent());
|
||||
ret.fontLeading = (getLeading());
|
||||
ret.fontAdvanceTable = new ArrayList<>();
|
||||
ret.fontBoundsTable = new ArrayList<>();
|
||||
ret.codeTable = new ArrayList<>();
|
||||
ret.glyphShapeTable = new ArrayList<>();
|
||||
List<SHAPE> shp = getGlyphShapeTable();
|
||||
for (int g = 0; g < shp.size(); g++) {
|
||||
ret.fontAdvanceTable.add(resize(getGlyphAdvance(g)));
|
||||
ret.codeTable.add((int) glyphToChar(g));
|
||||
|
||||
SHAPE shpX = resizeShape(shp.get(g));
|
||||
ret.glyphShapeTable.add(shpX);
|
||||
ret.fontBoundsTable.add(getGlyphBounds(g));
|
||||
}
|
||||
ret.fontName = getFontNameIntag();
|
||||
ret.languageCode = new LANGCODE(1);
|
||||
ret.fontKerningTable = new ArrayList<>();
|
||||
|
||||
FontType ft = fonts.get(0);
|
||||
for (int i = 0; i < ft.kerning.size(); i++) {
|
||||
KERNINGRECORD kr = new KERNINGRECORD();
|
||||
kr.fontKerningAdjustment = resize(ft.kerning.get(i).advance);
|
||||
kr.fontKerningCode1 = ft.kerning.get(i).char1;
|
||||
kr.fontKerningCode2 = ft.kerning.get(i).char2;
|
||||
ret.fontKerningTable.add(kr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLayout() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags.gfx;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.helpers.FontHelper;
|
||||
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
|
||||
import com.jpexs.decompiler.flash.types.LANGCODE;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.gfx.FontType;
|
||||
import com.jpexs.decompiler.flash.types.gfx.GFxInputStream;
|
||||
import com.jpexs.decompiler.flash.types.gfx.GFxOutputStream;
|
||||
import com.jpexs.decompiler.flash.types.gfx.GlyphInfoType;
|
||||
import com.jpexs.decompiler.flash.types.gfx.GlyphType;
|
||||
import com.jpexs.decompiler.flash.types.gfx.KerningPairType;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import java.awt.Font;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public final class DefineCompactedFont extends FontTag {
|
||||
|
||||
public static final int ID = 1005;
|
||||
|
||||
public static final String NAME = "DefineCompactedFont";
|
||||
|
||||
public int fontId;
|
||||
|
||||
public List<FontType> fonts;
|
||||
|
||||
private List<SHAPE> shapeCache;
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @return Bytes of data
|
||||
*/
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
|
||||
try {
|
||||
sos.writeUI16(fontId);
|
||||
for (FontType ft : fonts) {
|
||||
ft.write(new GFxOutputStream(sos));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
*/
|
||||
public DefineCompactedFont(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
fontId = swf.getNextCharacterId();
|
||||
|
||||
fonts = new ArrayList<>();
|
||||
FontType ft = new FontType();
|
||||
fonts.add(ft);
|
||||
|
||||
rebuildShapeCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineCompactedFont(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontId = sis.readUI16("fontId");
|
||||
fonts = new ArrayList<>();
|
||||
|
||||
MemoryInputStream mis = sis.getBaseStream();
|
||||
while (mis.available() > 0) {
|
||||
GFxInputStream gis = new GFxInputStream(mis);
|
||||
gis.dumpInfo = sis.dumpInfo;
|
||||
gis.newDumpLevel("fontType", "FontType");
|
||||
fonts.add(new FontType(gis));
|
||||
gis.endDumpLevel();
|
||||
}
|
||||
rebuildShapeCache();
|
||||
}
|
||||
|
||||
public void rebuildShapeCache() {
|
||||
shapeCache = fonts.get(0).getGlyphShapes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFontNameIntag() {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i = 0; i < fonts.size(); i++) {
|
||||
if (i > 0) {
|
||||
ret.append(", ");
|
||||
}
|
||||
ret.append(fonts.get(i).fontName);
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.fontId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFontId() {
|
||||
return fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SHAPE> getGlyphShapeTable() {
|
||||
return shapeCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCharacter(char character, Font cfont) {
|
||||
int fontStyle = getFontStyle();
|
||||
FontType font = fonts.get(0);
|
||||
|
||||
double d = 1;
|
||||
SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(cfont, (int) (font.nominalSize * d), character);
|
||||
|
||||
int code = (int) character;
|
||||
int pos = -1;
|
||||
boolean exists = false;
|
||||
for (int i = 0; i < font.glyphInfo.size(); i++) {
|
||||
if (font.glyphInfo.get(i).glyphCode >= code) {
|
||||
if (font.glyphInfo.get(i).glyphCode == code) {
|
||||
exists = true;
|
||||
}
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos == -1) {
|
||||
pos = font.glyphInfo.size();
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
shiftGlyphIndices(fontId, pos);
|
||||
}
|
||||
|
||||
Font fnt = cfont.deriveFont(fontStyle, Math.round(font.nominalSize * d));
|
||||
int advance = (int) Math.round(FontHelper.getFontAdvance(fnt, character));
|
||||
if (!exists) {
|
||||
font.glyphInfo.add(pos, new GlyphInfoType(code, advance, 0));
|
||||
font.glyphs.add(pos, new GlyphType(shp.shapeRecords));
|
||||
shapeCache.add(pos, font.glyphs.get(pos).toSHAPE());
|
||||
} else {
|
||||
font.glyphInfo.set(pos, new GlyphInfoType(code, advance, 0));
|
||||
font.glyphs.set(pos, new GlyphType(shp.shapeRecords));
|
||||
shapeCache.set(pos, font.glyphs.get(pos).toSHAPE());
|
||||
}
|
||||
|
||||
setModified(true);
|
||||
getSwf().clearImageCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdvanceValues(Font font) {
|
||||
throw new UnsupportedOperationException("Setting the advance values for DefineCompactedFont is not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public char glyphToChar(int glyphIndex) {
|
||||
return (char) fonts.get(0).glyphInfo.get(glyphIndex).glyphCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int charToGlyph(char c) {
|
||||
FontType ft = fonts.get(0);
|
||||
for (int i = 0; i < ft.glyphInfo.size(); i++) {
|
||||
if (ft.glyphInfo.get(i).glyphCode == c) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getGlyphAdvance(int glyphIndex) {
|
||||
return resize(fonts.get(0).glyphInfo.get(glyphIndex).advanceX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
|
||||
char c1 = glyphToChar(glyphIndex);
|
||||
char c2 = glyphToChar(nextGlyphIndex);
|
||||
return getCharKerningAdjustment(c1, c2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharKerningAdjustment(char c1, char c2) {
|
||||
for (KerningPairType kp : fonts.get(0).kerning) {
|
||||
if (kp.char1 == c1 && kp.char2 == c2) {
|
||||
return resize(kp.advance);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGlyphWidth(int glyphIndex) {
|
||||
return resize(getGlyphShapeTable().get(glyphIndex).getBounds().getWidth());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSmall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBold() {
|
||||
return (fonts.get(0).flags & FontType.FF_Bold) == FontType.FF_Bold;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItalic() {
|
||||
return (fonts.get(0).flags & FontType.FF_Italic) == FontType.FF_Italic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSmallEditable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBoldEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItalicEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBold(boolean value) {
|
||||
for (FontType font : fonts) {
|
||||
font.flags &= FontType.FF_Bold;
|
||||
if (!value) {
|
||||
font.flags ^= FontType.FF_Bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItalic(boolean value) {
|
||||
for (FontType font : fonts) {
|
||||
font.flags &= FontType.FF_Italic;
|
||||
if (!value) {
|
||||
font.flags ^= FontType.FF_Italic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDivider() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAscent() {
|
||||
return fonts.get(0).ascent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDescent() {
|
||||
return fonts.get(0).descent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLeading() {
|
||||
return fonts.get(0).leading;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacters(List<Tag> tags) {
|
||||
FontType ft = fonts.get(0);
|
||||
StringBuilder ret = new StringBuilder(ft.glyphInfo.size());
|
||||
for (GlyphInfoType gi : ft.glyphInfo) {
|
||||
ret.append((char) gi.glyphCode);
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RECT getGlyphBounds(int glyphIndex) {
|
||||
GlyphType gt = fonts.get(0).glyphs.get(glyphIndex);
|
||||
return new RECT(resize(gt.boundingBox[0]), resize(gt.boundingBox[1]), resize(gt.boundingBox[2]), resize(gt.boundingBox[3]));
|
||||
}
|
||||
|
||||
public SHAPE resizeShape(SHAPE shp) {
|
||||
SHAPE ret = new SHAPE();
|
||||
ret.numFillBits = 1;
|
||||
ret.numLineBits = 0;
|
||||
List<SHAPERECORD> recs = new ArrayList<>();
|
||||
for (SHAPERECORD r : shp.shapeRecords) {
|
||||
SHAPERECORD c = r.clone();
|
||||
if (c instanceof StyleChangeRecord) {
|
||||
StyleChangeRecord scr = (StyleChangeRecord) c;
|
||||
scr.moveDeltaX = resize(scr.moveDeltaX);
|
||||
scr.moveDeltaY = resize(scr.moveDeltaY);
|
||||
scr.calculateBits();
|
||||
}
|
||||
if (c instanceof CurvedEdgeRecord) {
|
||||
CurvedEdgeRecord cer = (CurvedEdgeRecord) c;
|
||||
cer.controlDeltaX = resize(cer.controlDeltaX);
|
||||
cer.controlDeltaY = resize(cer.controlDeltaY);
|
||||
cer.anchorDeltaX = resize(cer.anchorDeltaX);
|
||||
cer.anchorDeltaY = resize(cer.anchorDeltaY);
|
||||
cer.calculateBits();
|
||||
}
|
||||
if (c instanceof StraightEdgeRecord) {
|
||||
StraightEdgeRecord ser = (StraightEdgeRecord) c;
|
||||
ser.deltaX = resize(ser.deltaX);
|
||||
ser.deltaY = resize(ser.deltaY);
|
||||
ser.calculateBits();
|
||||
}
|
||||
recs.add(c);
|
||||
}
|
||||
ret.shapeRecords = recs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected int resize(double val) {
|
||||
FontType ft = fonts.get(0);
|
||||
return (int) Math.round(val * 1024.0 / ft.nominalSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontTag toClassicFont() {
|
||||
DefineFont2Tag ret = new DefineFont2Tag(swf);
|
||||
ret.fontId = getFontId();
|
||||
ret.fontFlagsBold = isBold();
|
||||
ret.fontFlagsItalic = isItalic();
|
||||
ret.fontFlagsWideOffsets = true;
|
||||
ret.fontFlagsWideCodes = true;
|
||||
ret.fontFlagsHasLayout = true;
|
||||
ret.fontAscent = (getAscent());
|
||||
ret.fontDescent = (getDescent());
|
||||
ret.fontLeading = (getLeading());
|
||||
ret.fontAdvanceTable = new ArrayList<>();
|
||||
ret.fontBoundsTable = new ArrayList<>();
|
||||
ret.codeTable = new ArrayList<>();
|
||||
ret.glyphShapeTable = new ArrayList<>();
|
||||
List<SHAPE> shp = getGlyphShapeTable();
|
||||
for (int g = 0; g < shp.size(); g++) {
|
||||
ret.fontAdvanceTable.add(resize(getGlyphAdvance(g)));
|
||||
ret.codeTable.add((int) glyphToChar(g));
|
||||
|
||||
SHAPE shpX = resizeShape(shp.get(g));
|
||||
ret.glyphShapeTable.add(shpX);
|
||||
ret.fontBoundsTable.add(getGlyphBounds(g));
|
||||
}
|
||||
ret.fontName = getFontNameIntag();
|
||||
ret.languageCode = new LANGCODE(1);
|
||||
ret.fontKerningTable = new ArrayList<>();
|
||||
|
||||
FontType ft = fonts.get(0);
|
||||
for (int i = 0; i < ft.kerning.size(); i++) {
|
||||
KERNINGRECORD kr = new KERNINGRECORD();
|
||||
kr.fontKerningAdjustment = resize(ft.kerning.get(i).advance);
|
||||
kr.fontKerningCode1 = ft.kerning.get(i).char1;
|
||||
kr.fontKerningCode2 = ft.kerning.get(i).char2;
|
||||
ret.fontKerningTable.add(kr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLayout() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ public class DefineExternalGradient extends Tag {
|
||||
|
||||
public static final int ID = 1003;
|
||||
|
||||
public static final String NAME = "DefineExternalGradient";
|
||||
|
||||
public static final int BITMAP_FORMAT_DEFAULT = 0;
|
||||
|
||||
public static final int BITMAP_FORMAT_TGA = 1;
|
||||
@@ -78,7 +80,7 @@ public class DefineExternalGradient extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineExternalGradient(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineExternalGradient", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ public class DefineExternalImage extends Tag {
|
||||
|
||||
public static final int ID = 1001;
|
||||
|
||||
public static final String NAME = "DefineExternalImage";
|
||||
|
||||
public int characterId;
|
||||
|
||||
public int bitmapFormat;
|
||||
@@ -81,7 +83,7 @@ public class DefineExternalImage extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineExternalImage(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineExternalImage", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ public class DefineExternalImage2 extends Tag {
|
||||
|
||||
public static final int ID = 1009;
|
||||
|
||||
public static final String NAME = "DefineExternalImage2";
|
||||
|
||||
public long characterId;
|
||||
|
||||
public int bitmapFormat;
|
||||
@@ -91,7 +93,7 @@ public class DefineExternalImage2 extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineExternalImage2(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineExternalImage2", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ public class DefineExternalSound extends Tag {
|
||||
|
||||
public static final int ID = 1006;
|
||||
|
||||
public static final String NAME = "DefineExternalSound";
|
||||
|
||||
public int characterId;
|
||||
|
||||
public int soundFormat;
|
||||
@@ -91,7 +93,7 @@ public class DefineExternalSound extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineExternalSound(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineExternalSound", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ public class DefineExternalStreamSound extends Tag {
|
||||
|
||||
public static final int ID = 1007;
|
||||
|
||||
public static final String NAME = "DefineExternalStreamSound";
|
||||
|
||||
public int soundFormat;
|
||||
|
||||
public int bits;
|
||||
@@ -89,7 +91,7 @@ public class DefineExternalStreamSound extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineExternalStreamSound(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineExternalStreamSound", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ public class DefineGradientMap extends Tag {
|
||||
|
||||
public static final int ID = 1004;
|
||||
|
||||
public static final String NAME = "DefineGradientMap";
|
||||
|
||||
public int[] indices;
|
||||
|
||||
/**
|
||||
@@ -64,7 +66,7 @@ public class DefineGradientMap extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineGradientMap(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineGradientMap", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ public class DefineSubImage extends Tag {
|
||||
|
||||
public static final int ID = 1008;
|
||||
|
||||
public static final String NAME = "DefineSubImage";
|
||||
|
||||
public int characterId;
|
||||
|
||||
public int imageCharacterId;
|
||||
@@ -76,7 +78,7 @@ public class DefineSubImage extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineSubImage(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DefineSubImage", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ public class ExporterInfo extends Tag {
|
||||
|
||||
public static final int ID = 1000;
|
||||
|
||||
public static final String NAME = "ExporterInfo";
|
||||
|
||||
//Version (1.10 will be encoded as 0x10A)
|
||||
public int version;
|
||||
|
||||
@@ -100,7 +102,7 @@ public class ExporterInfo extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public ExporterInfo(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "ExporterInfo", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ public class FontTextureInfo extends Tag {
|
||||
|
||||
public static final int ID = 1002;
|
||||
|
||||
public static final String NAME = "FontTextureInfo";
|
||||
|
||||
public long textureID;
|
||||
|
||||
public int textureFormat;
|
||||
@@ -104,7 +106,7 @@ public class FontTextureInfo extends Tag {
|
||||
* @throws IOException
|
||||
*/
|
||||
public FontTextureInfo(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "FontTextureInfo", data);
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user