mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-18 21:08:08 +00:00
Iggy to SWF export class, refactorings
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
@@ -22,9 +22,9 @@ import java.util.logging.Logger;
|
||||
* Based of works of somebody called eternity.
|
||||
*
|
||||
*/
|
||||
public class IggyExtractor extends AbstractDataStream implements AutoCloseable {
|
||||
public class IggyFile extends AbstractDataStream implements AutoCloseable {
|
||||
|
||||
final static Logger LOGGER = Logger.getLogger(IggyExtractor.class.getName());
|
||||
final static Logger LOGGER = Logger.getLogger(IggyFile.class.getName());
|
||||
|
||||
private RandomAccessFile raf;
|
||||
private IggyHeader header;
|
||||
@@ -37,7 +37,7 @@ public class IggyExtractor extends AbstractDataStream implements AutoCloseable {
|
||||
private List<IggyNameAndTagList> namesAndTagLists = new ArrayList<>();
|
||||
private List<List<ByteArrayDataStream>> tagDataTables = new ArrayList<>();
|
||||
|
||||
public IggyExtractor(File file) throws IOException {
|
||||
public IggyFile(File file) throws IOException {
|
||||
raf = new RandomAccessFile(file, "r");
|
||||
header = new IggyHeader(this);
|
||||
for (int i = 0; i < header.getNumSubfiles(); i++) {
|
||||
@@ -71,7 +71,7 @@ public class IggyExtractor extends AbstractDataStream implements AutoCloseable {
|
||||
ByteArrayDataStream flashStream = flashStreams.get(i);
|
||||
List<Long> offsets = offsetTables.get(i);
|
||||
List<Integer> tagIds = namesAndTagLists.get(i).getTagIds();
|
||||
List<Long> tagExtended = namesAndTagLists.get(i).getTagIdsExtendedInfo();
|
||||
List<Long> tagExtended = namesAndTagLists.get(i).getTagIdsExtraInfo();
|
||||
int offsetIndex = 3; //0 = SWF name, 1 = UI16 zero, 2 = tag list
|
||||
|
||||
List<ByteArrayDataStream> tagDataStreams = new ArrayList<>();
|
||||
@@ -183,7 +183,7 @@ public class IggyExtractor extends AbstractDataStream implements AutoCloseable {
|
||||
|
||||
public static void extractIggyFile(File iggyFile, File extractDir) throws IOException {
|
||||
final String FILENAME_FORMAT = "index%d_type%d.bin";
|
||||
try (IggyExtractor ir = new IggyExtractor(iggyFile)) {
|
||||
try (IggyFile ir = new IggyFile(iggyFile)) {
|
||||
for (int i = 0; i < ir.getNumEntries(); i++) {
|
||||
IggySubFileEntry entry = ir.getSubFileEntry(i);
|
||||
try (FileOutputStream fos = new FileOutputStream(new File(extractDir, String.format(FILENAME_FORMAT, i, entry.type)))) {
|
||||
@@ -695,12 +695,67 @@ public class IggyExtractor extends AbstractDataStream implements AutoCloseable {
|
||||
return namesAndTagLists.get(swfIndex).getTagIds();
|
||||
}
|
||||
|
||||
public List<Long> getSwfTagExtraInfos(int swfIndex) {
|
||||
return namesAndTagLists.get(swfIndex).getTagIdsExtendedInfo();
|
||||
public Integer getSwfTagId(int swfIndex, int tagIndex) {
|
||||
return namesAndTagLists.get(swfIndex).getTagIds().get(tagIndex);
|
||||
}
|
||||
|
||||
public SWF extractSwf(int swfIndex) {
|
||||
return null; //TODO
|
||||
public List<Long> getSwfTagExtraInfos(int swfIndex) {
|
||||
return namesAndTagLists.get(swfIndex).getTagIdsExtraInfo();
|
||||
}
|
||||
|
||||
public Long getSwfTagExtraInfo(int swfIndex, int tagIndex) {
|
||||
return namesAndTagLists.get(swfIndex).getTagIdsExtraInfo().get(tagIndex);
|
||||
}
|
||||
|
||||
public long getSwfXMin(int swfIndex) {
|
||||
return headers.get(swfIndex).getXMin();
|
||||
}
|
||||
|
||||
public long getSwfYMin(int swfIndex) {
|
||||
return headers.get(swfIndex).getYMin();
|
||||
}
|
||||
|
||||
public long getSwfXMax(int swfIndex) {
|
||||
return headers.get(swfIndex).getXMax();
|
||||
}
|
||||
|
||||
public long getSwfYMax(int swfIndex) {
|
||||
return headers.get(swfIndex).getYMax();
|
||||
}
|
||||
|
||||
public float getSwfFrameRate(int swfIndex) {
|
||||
return headers.get(swfIndex).getFrameRate();
|
||||
}
|
||||
|
||||
public int getSwfTagCount(int swfIndex) {
|
||||
return getSwfTagIds(swfIndex).size();
|
||||
}
|
||||
|
||||
public AbstractDataStream gettSwfTagDataStream(int swfIndex, int tagIndex) {
|
||||
return tagDataTables.get(swfIndex).get(tagIndex);
|
||||
}
|
||||
|
||||
public InputStream getSwfTagInputStream(int swfIndex, int tagIndex) {
|
||||
return new ByteArrayInputStream(getSwfTagData(swfIndex, tagIndex));
|
||||
}
|
||||
|
||||
public byte[] getSwfTagData(int swfIndex, int tagIndex) {
|
||||
AbstractDataStream stream = gettSwfTagDataStream(swfIndex, tagIndex);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
int bufSize = 4096;
|
||||
//Assuming available() result is always known (= not returning null)
|
||||
while (stream.available() > 0) {
|
||||
if (stream.available() < bufSize) {
|
||||
bufSize = (int) (long) stream.available();
|
||||
}
|
||||
try {
|
||||
byte[] buffer = stream.readBytes(bufSize);
|
||||
baos.write(buffer);
|
||||
} catch (IOException iex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -51,7 +51,7 @@ public class IggyFlashHeader32 implements IggyFlashHeaderInterface {
|
||||
long unk_38;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_3C;
|
||||
float frame_rate;
|
||||
float frameRate;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_44;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
@@ -80,11 +80,6 @@ public class IggyFlashHeader32 implements IggyFlashHeaderInterface {
|
||||
long unk_78; // Maybe number of classes / as3 names
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_7C;
|
||||
@IggyFieldType(value = DataType.uint16_t, count = 20)
|
||||
String name;
|
||||
|
||||
List<Integer> tagIds = new ArrayList<>();
|
||||
List<Long> tagIdsExtendedInfo = new ArrayList<>();
|
||||
|
||||
// Offset 0x80 (outside header): there are *unk_28* relative offsets that point to flash objects.
|
||||
// The flash objects are in a format different to swf but there is probably a way to convert between them.
|
||||
@@ -114,7 +109,7 @@ public class IggyFlashHeader32 implements IggyFlashHeaderInterface {
|
||||
unk_34 = stream.readUI32();
|
||||
unk_38 = stream.readUI32();
|
||||
unk_3C = stream.readUI32();
|
||||
frame_rate = stream.readFloat();
|
||||
frameRate = stream.readFloat();
|
||||
unk_44 = stream.readUI32();
|
||||
unk_48 = stream.readUI32();
|
||||
unk_4C = stream.readUI32();
|
||||
@@ -130,26 +125,6 @@ public class IggyFlashHeader32 implements IggyFlashHeaderInterface {
|
||||
unk_74 = stream.readUI32();
|
||||
unk_78 = stream.readUI32();
|
||||
unk_7C = stream.readUI32();
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
do {
|
||||
char c = (char) stream.readUI16();
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
nameBuilder.append(c);
|
||||
} while (true);
|
||||
name = nameBuilder.toString();
|
||||
|
||||
while (true) {
|
||||
long typeLen = stream.readUI16(); //TODO: check whether it's really UI16 - 64bit works with UI32
|
||||
if (typeLen == 0) {
|
||||
break;
|
||||
}
|
||||
long tagLength = stream.readUI16();
|
||||
int tagType = (int) ((typeLen >>> 6) + 10) & 0x3FF;
|
||||
tagIds.add(tagType);
|
||||
tagIdsExtendedInfo.add(tagLength);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,7 +153,7 @@ public class IggyFlashHeader32 implements IggyFlashHeaderInterface {
|
||||
sb.append("unk_34 ").append(unk_34).append("\r\n");
|
||||
sb.append("unk_38 ").append(unk_38).append("\r\n");
|
||||
sb.append("unk_3C ").append(unk_3C).append("\r\n");
|
||||
sb.append("frame_rate ").append(frame_rate).append("\r\n");
|
||||
sb.append("frameRate ").append(frameRate).append("\r\n");
|
||||
sb.append("unk_44 ").append(unk_44).append("\r\n");
|
||||
sb.append("unk_48 ").append(unk_48).append("\r\n");
|
||||
sb.append("unk_4C ").append(unk_4C).append("\r\n");
|
||||
@@ -193,19 +168,32 @@ public class IggyFlashHeader32 implements IggyFlashHeaderInterface {
|
||||
sb.append("unk_74 ").append(unk_74).append("\r\n");
|
||||
sb.append("unk_78 ").append(unk_78).append("\r\n");
|
||||
sb.append("unk_7C ").append(unk_7C).append("\r\n");
|
||||
sb.append("name ").append(name).append("\r\n");
|
||||
Map<Integer, TagTypeInfo> map = Tag.getKnownClasses();
|
||||
sb.append("tags:").append("\r\n");
|
||||
for (int i = 0; i < tagIds.size(); i++) {
|
||||
TagTypeInfo tti = map.get(tagIds.get(i));
|
||||
sb.append(" tag ").append(tagIds.get(i)).append(":").append(tti == null ? "?" : tti.getName());
|
||||
if (tagIdsExtendedInfo.get(i) > 0) {
|
||||
sb.append(" (special: ").append(tagIdsExtendedInfo.get(i)).append(")");
|
||||
}
|
||||
sb.append("\r\n");
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMin() {
|
||||
return xmin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMin() {
|
||||
return ymin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMax() {
|
||||
return xmax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMax() {
|
||||
return ymax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFrameRate() {
|
||||
return frameRate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
|
||||
long unk_50;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_54;
|
||||
float frame_rate;
|
||||
float frameRate;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_5C;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
@@ -127,7 +127,7 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
|
||||
unk_4C = stream.readUI32();
|
||||
unk_50 = stream.readUI32();
|
||||
unk_54 = stream.readUI32();
|
||||
frame_rate = stream.readFloat();
|
||||
frameRate = stream.readFloat();
|
||||
unk_5C = stream.readUI32();
|
||||
unk_60 = stream.readUI64();
|
||||
unk_68 = stream.readUI64();
|
||||
@@ -169,7 +169,7 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
|
||||
sb.append("unk_4C ").append(unk_4C).append("\r\n");
|
||||
sb.append("unk_50 ").append(unk_50).append("\r\n");
|
||||
sb.append("unk_54 ").append(unk_54).append("\r\n");
|
||||
sb.append("frame_rate ").append(frame_rate).append("\r\n");
|
||||
sb.append("frameRate ").append(frameRate).append("\r\n");
|
||||
sb.append("unk_5C ").append(unk_5C).append("\r\n");
|
||||
sb.append("unk_60 ").append(unk_60).append("\r\n");
|
||||
sb.append("unk_68 ").append(unk_68).append("\r\n");
|
||||
@@ -189,4 +189,29 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMin() {
|
||||
return xmin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMin() {
|
||||
return ymin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMax() {
|
||||
return xmax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMax() {
|
||||
return ymax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFrameRate() {
|
||||
return frameRate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,4 +6,13 @@ package com.jpexs.decompiler.flash.iggy;
|
||||
*/
|
||||
public interface IggyFlashHeaderInterface extends StructureInterface {
|
||||
|
||||
public long getXMin();
|
||||
|
||||
public long getYMin();
|
||||
|
||||
public long getXMax();
|
||||
|
||||
public long getYMax();
|
||||
|
||||
public float getFrameRate();
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@ public class IggyNameAndTagList implements StructureInterface {
|
||||
private List<Integer> tagIds;
|
||||
|
||||
@IggyArrayFieldType(value = DataType.uint16_t)
|
||||
private List<Long> tagIdsExtendedInfo;
|
||||
private List<Long> tagIdsExtraInfo;
|
||||
|
||||
public IggyNameAndTagList(String name, List<Integer> tagIds, List<Long> tagIdsExtendedInfo) {
|
||||
this.name = name;
|
||||
this.tagIds = tagIds;
|
||||
this.tagIdsExtendedInfo = tagIdsExtendedInfo;
|
||||
this.tagIdsExtraInfo = tagIdsExtendedInfo;
|
||||
}
|
||||
|
||||
public IggyNameAndTagList(AbstractDataStream stream) throws IOException {
|
||||
@@ -44,7 +44,7 @@ public class IggyNameAndTagList implements StructureInterface {
|
||||
name = nameBuilder.toString();
|
||||
|
||||
tagIds = new ArrayList<>();
|
||||
tagIdsExtendedInfo = new ArrayList<>();
|
||||
tagIdsExtraInfo = new ArrayList<>();
|
||||
while (true) {
|
||||
long typeLen = stream.readUI32();
|
||||
if (typeLen == 0) {
|
||||
@@ -53,7 +53,7 @@ public class IggyNameAndTagList implements StructureInterface {
|
||||
long tagLength = stream.readUI32();
|
||||
int tagType = (int) ((typeLen >>> 6) + 10) & 0x3FF;
|
||||
tagIds.add(tagType);
|
||||
tagIdsExtendedInfo.add(tagLength);
|
||||
tagIdsExtraInfo.add(tagLength);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,8 +65,8 @@ public class IggyNameAndTagList implements StructureInterface {
|
||||
return tagIds;
|
||||
}
|
||||
|
||||
public List<Long> getTagIdsExtendedInfo() {
|
||||
return tagIdsExtendedInfo;
|
||||
public List<Long> getTagIdsExtraInfo() {
|
||||
return tagIdsExtraInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.jpexs.decompiler.flash.iggy.conversion;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFCompression;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFile;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFlashHeaderInterface;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.UnknownTag;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO: TEST!!!
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyToSwfConvertor {
|
||||
|
||||
public SWF[] getAllSwfs(IggyFile file) {
|
||||
SWF[] ret = new SWF[file.getSwfCount()];
|
||||
for (int i = 0; i < ret.length; i++) {
|
||||
ret[i] = getSwf(file, i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void exportAllSwfsToDir(IggyFile file, File outputDir) throws IOException {
|
||||
for (int swfIndex = 0; swfIndex < file.getSwfCount(); swfIndex++) {
|
||||
exportSwfToDir(file, swfIndex, outputDir);
|
||||
}
|
||||
}
|
||||
|
||||
public void exportSwfToDir(IggyFile file, int swfIndex, File outputDir) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(new File(outputDir, file.getSwfName(swfIndex)))) {
|
||||
exportSwf(file, swfIndex, fos);
|
||||
}
|
||||
}
|
||||
|
||||
public void exportSwfToFile(IggyFile file, int swfIndex, File outputFile) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
|
||||
exportSwf(file, swfIndex, fos);
|
||||
}
|
||||
}
|
||||
|
||||
public void exportSwf(IggyFile file, int swfIndex, OutputStream output) throws IOException {
|
||||
SWF swf = getSwf(file, swfIndex);
|
||||
swf.saveTo(output);
|
||||
}
|
||||
|
||||
public SWF getSwf(IggyFile file, int swfIndex) {
|
||||
SWF swf = new SWF();
|
||||
swf.compression = SWFCompression.NONE;
|
||||
swf.frameCount = 1; //FIXME!!
|
||||
swf.gfx = false;
|
||||
swf.displayRect = new RECT(
|
||||
(int) (file.getSwfXMin(swfIndex) * SWF.unitDivisor),
|
||||
(int) (file.getSwfXMax(swfIndex) * SWF.unitDivisor),
|
||||
(int) (file.getSwfYMin(swfIndex) * SWF.unitDivisor),
|
||||
(int) (file.getSwfYMax(swfIndex) * SWF.unitDivisor));
|
||||
swf.version = 9; //FIXME
|
||||
for (int tagIndex = 0; tagIndex < file.getSwfTagCount(swfIndex); tagIndex++) {
|
||||
byte[] data = file.getSwfTagData(swfIndex, tagIndex);
|
||||
int dataLength = data.length;
|
||||
int tagLength = dataLength;
|
||||
int tagID = file.getSwfTagId(swfIndex, tagIndex);
|
||||
long tagExtra = file.getSwfTagExtraInfo(swfIndex, tagIndex);
|
||||
try {
|
||||
swf.addTag(new UnknownTag(new SWFInputStream(swf, data), tagID, new ByteArrayRange(data)));
|
||||
} catch (IOException ex) {
|
||||
//ignored
|
||||
}
|
||||
}
|
||||
return swf;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user