Normalize line endings

This commit is contained in:
Gauthier Billot
2017-05-05 15:35:09 +02:00
parent 40e31a5f99
commit f49ee84fc9
10 changed files with 5245 additions and 5245 deletions

View File

@@ -1,79 +1,79 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class IggyDeclStrings implements StructureInterface {
@IggyFieldType(DataType.uint64_t)
long one;
//@IggyFieldType(DataType.uint32_t)
//long size;
@IggyArrayFieldType(value = DataType.uint8_t, count = 3)
byte xxx[];
@IggyArrayFieldType(value = DataType.uint8_t, countField = "size")
byte data[];
byte padd[];
@IggyFieldType(DataType.uint64_t)
long one2;
@IggyFieldType(DataType.uint64_t)
long zero;
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public IggyDeclStrings(ReadDataStreamInterface stream) throws IOException {
readFromDataStream(stream);
}
@Override
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
one = s.readUI64();
long size = s.readUI32();
xxx = s.readBytes(3);
data = s.readBytes((int) size);
if ((15 + size) % 8 != 0) {
padd = s.readBytes((int) (((15 + size) / 8 + 1) * 8 - 15 - size));
} else {
padd = new byte[0];
}
one = s.readUI64();
if (one != 1) {
throw new IOException("Wrong iggy font format (declend)!");
}
zero = s.readUI64();
}
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
IggyIndexBuilder ib = s.getIndexing();
s.writeUI64(one);
s.writeUI32(data.length);
ib.writeLengthCustom(15, new int[]{0x00, 0x08}, new int[]{2, 5});
s.writeBytes(xxx);
s.writeBytes(data);
ib.writeLengthUI32(data.length);
if ((15 + data.length) % 8 != 0) {
byte[] padd = new byte[((int) (((15 + data.length) / 8 + 1) * 8 - 15 - data.length))];
s.writeBytes(padd);
}
ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE);
s.writeUI64(one);
s.writeUI64(zero);
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class IggyDeclStrings implements StructureInterface {
@IggyFieldType(DataType.uint64_t)
long one;
//@IggyFieldType(DataType.uint32_t)
//long size;
@IggyArrayFieldType(value = DataType.uint8_t, count = 3)
byte xxx[];
@IggyArrayFieldType(value = DataType.uint8_t, countField = "size")
byte data[];
byte padd[];
@IggyFieldType(DataType.uint64_t)
long one2;
@IggyFieldType(DataType.uint64_t)
long zero;
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public IggyDeclStrings(ReadDataStreamInterface stream) throws IOException {
readFromDataStream(stream);
}
@Override
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
one = s.readUI64();
long size = s.readUI32();
xxx = s.readBytes(3);
data = s.readBytes((int) size);
if ((15 + size) % 8 != 0) {
padd = s.readBytes((int) (((15 + size) / 8 + 1) * 8 - 15 - size));
} else {
padd = new byte[0];
}
one = s.readUI64();
if (one != 1) {
throw new IOException("Wrong iggy font format (declend)!");
}
zero = s.readUI64();
}
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
IggyIndexBuilder ib = s.getIndexing();
s.writeUI64(one);
s.writeUI32(data.length);
ib.writeLengthCustom(15, new int[]{0x00, 0x08}, new int[]{2, 5});
s.writeBytes(xxx);
s.writeBytes(data);
ib.writeLengthUI32(data.length);
if ((15 + data.length) % 8 != 0) {
byte[] padd = new byte[((int) (((15 + data.length) / 8 + 1) * 8 - 15 - data.length))];
s.writeBytes(padd);
}
ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE);
s.writeUI64(one);
s.writeUI64(zero);
}
}

View File

@@ -1,244 +1,244 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.DataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.RandomAccessFileDataStream;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.TemporaryDataStream;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*
* Based of works of somebody called eternity.
*
*/
public class IggyFile implements StructureInterface {
final static Logger LOGGER = Logger.getLogger(IggyFile.class.getName());
private File originalFile;
private IggyHeader header;
private List<IggySubFileEntry> subFileEntries = new ArrayList<>();
private List<byte[]> subFileEntriesData = new ArrayList<>();
private IggySwf iggySwf;
public static final int FIRST_TAG_POSITION = 3;
public IggySwf getSwf() {
return iggySwf;
}
public IggyFile(String filePath) throws IOException {
this(new File(filePath));
}
public IggyFile(File file) throws IOException {
this.originalFile = file;
try (ReadDataStreamInterface stream = new RandomAccessFileDataStream(file)) {
readFromDataStream(stream);
}
}
public File getOriginalFile() {
return originalFile;
}
public IggyHeader getHeader() {
return header;
}
public IggySubFileEntry getSubFileEntry(int entryIndex) {
if (entryIndex < 0 || entryIndex >= subFileEntries.size()) {
throw new ArrayIndexOutOfBoundsException("No entry with index " + entryIndex + " exists");
}
return subFileEntries.get(entryIndex);
}
public int getNumEntries() {
return subFileEntries.size();
}
public byte[] getEntryData(int entryIndex) {
if (entryIndex < 0 || entryIndex >= subFileEntries.size()) {
throw new ArrayIndexOutOfBoundsException("No entry with index " + entryIndex + " exists");
}
return subFileEntriesData.get(entryIndex);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[IggyFile:").append("\r\n");
sb.append(header).append("\r\n");
sb.append("Entries:").append("\r\n");
for (IggySubFileEntry entry : subFileEntries) {
sb.append(entry).append("\r\n");
}
sb.append("]");
return sb.toString();
}
public static void extractIggyFile(File iggyFile, File extractDir) throws IOException {
final String FILENAME_FORMAT = "index%d_type%d.bin";
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)))) {
fos.write(ir.getEntryData(i));
}
}
}
public String getSwfName() {
return iggySwf.getName();
}
public long getSwfXMin() {
return iggySwf.getHdr().getXMin();
}
public long getSwfYMin() {
return iggySwf.getHdr().getYMin();
}
public long getSwfXMax() {
return iggySwf.getHdr().getXMax();
}
public long getSwfYMax() {
return iggySwf.getHdr().getYMax();
}
public float getSwfFrameRate() {
return iggySwf.getHdr().getFrameRate();
}
/**
* Removes entries of type INDEX.There can be more than one INDEX,
* continuous. This removes all ot them.
*/
public void removeIndexEntries() {
long offsetsChange = 0;
final int ENTRY_SIZE = 16;
for (int i = 0; i < subFileEntries.size(); i++) {
IggySubFileEntry entry = subFileEntries.get(i);
entry.offset += offsetsChange;
if (entry.type == IggySubFileEntry.TYPE_INDEX) {
offsetsChange = offsetsChange - entry.size - ENTRY_SIZE;
subFileEntriesData.remove(i);
subFileEntries.remove(i);
i--;
}
}
}
public boolean updateFlashEntry() throws IOException {
byte replacementData[];
byte replacementIndexData[];
IggyIndexBuilder ib = new IggyIndexBuilder();
try (DataStreamInterface stream = new TemporaryDataStream()) {
stream.setIndexing(ib);
iggySwf.writeToDataStream(stream);
replacementData = stream.getAllBytes();
replacementIndexData = ib.getIndexBytes();
} catch (IOException ex) {
Logger.getLogger(IggyFile.class.getName()).log(Level.SEVERE, "Error during updating SWF", ex);
return false;
}
long offsetsChange = 0;
for (int i = 0; i < subFileEntries.size(); i++) {
IggySubFileEntry entry = subFileEntries.get(i);
entry.offset += offsetsChange;
if (entry.type == IggySubFileEntry.TYPE_FLASH) {
long oldSize = entry.size;
long newSize = replacementData.length;
entry.size = newSize;
entry.size2 = newSize;
offsetsChange = offsetsChange + (newSize - oldSize); //entries after this one will have modified offsets
subFileEntriesData.set(i, replacementData);
}
}
removeIndexEntries();
IggySubFileEntry indexEntry = new IggySubFileEntry(IggySubFileEntry.TYPE_INDEX, replacementIndexData.length, replacementIndexData.length, 0 /*offset will be set automatically*/);
subFileEntries.add(indexEntry);
subFileEntriesData.add(replacementIndexData);
return true;
}
private void parseEntries() throws IOException {
for (int i = 0; i < subFileEntries.size(); i++) {
IggySubFileEntry entry = subFileEntries.get(i);
if (entry.type == IggySubFileEntry.TYPE_FLASH) {
iggySwf = new IggySwf(new TemporaryDataStream(getEntryData(i)));
break;
}
/*if (entry.type == IggySubFileEntry.TYPE_INDEX) {
IggyIndexParser.parseIndex(true, new TemporaryDataStream(getEntryData(i)), new ArrayList<>(), new ArrayList<>());
}*/
}
}
@Override
public void readFromDataStream(ReadDataStreamInterface stream) throws IOException {
header = new IggyHeader(stream);
if (!header.is64()) {
throw new IOException("32 bit iggy files are not (yet) supported, sorry");
}
for (int i = 0; i < header.getNumSubfiles(); i++) {
subFileEntries.add(new IggySubFileEntry(stream));
}
for (IggySubFileEntry entry : subFileEntries) {
stream.seek(entry.offset, SeekMode.SET);
byte[] entryData = stream.readBytes((int) entry.size);
subFileEntriesData.add(entryData);
}
parseEntries();
}
public void saveChanges() throws IOException {
updateFlashEntry();
try (RandomAccessFileDataStream raf = new RandomAccessFileDataStream(originalFile)) {
writeToDataStream(raf);
}
}
@Override
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
header.writeToDataStream(stream);
long startOffset = IggyHeader.STRUCT_SIZE + IggySubFileEntry.STRUCTURE_SIZE * subFileEntries.size();
long currentOffset = startOffset;
for (int i = 0; i < subFileEntries.size(); i++) {
IggySubFileEntry entry = subFileEntries.get(i);
entry.offset = currentOffset;
currentOffset += entry.size;
entry.writeToDataStream(stream);
}
for (int i = 0; i < subFileEntries.size(); i++) {
byte[] entryData = subFileEntriesData.get(i);
stream.writeBytes(entryData);
}
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.DataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.RandomAccessFileDataStream;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.TemporaryDataStream;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*
* Based of works of somebody called eternity.
*
*/
public class IggyFile implements StructureInterface {
final static Logger LOGGER = Logger.getLogger(IggyFile.class.getName());
private File originalFile;
private IggyHeader header;
private List<IggySubFileEntry> subFileEntries = new ArrayList<>();
private List<byte[]> subFileEntriesData = new ArrayList<>();
private IggySwf iggySwf;
public static final int FIRST_TAG_POSITION = 3;
public IggySwf getSwf() {
return iggySwf;
}
public IggyFile(String filePath) throws IOException {
this(new File(filePath));
}
public IggyFile(File file) throws IOException {
this.originalFile = file;
try (ReadDataStreamInterface stream = new RandomAccessFileDataStream(file)) {
readFromDataStream(stream);
}
}
public File getOriginalFile() {
return originalFile;
}
public IggyHeader getHeader() {
return header;
}
public IggySubFileEntry getSubFileEntry(int entryIndex) {
if (entryIndex < 0 || entryIndex >= subFileEntries.size()) {
throw new ArrayIndexOutOfBoundsException("No entry with index " + entryIndex + " exists");
}
return subFileEntries.get(entryIndex);
}
public int getNumEntries() {
return subFileEntries.size();
}
public byte[] getEntryData(int entryIndex) {
if (entryIndex < 0 || entryIndex >= subFileEntries.size()) {
throw new ArrayIndexOutOfBoundsException("No entry with index " + entryIndex + " exists");
}
return subFileEntriesData.get(entryIndex);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[IggyFile:").append("\r\n");
sb.append(header).append("\r\n");
sb.append("Entries:").append("\r\n");
for (IggySubFileEntry entry : subFileEntries) {
sb.append(entry).append("\r\n");
}
sb.append("]");
return sb.toString();
}
public static void extractIggyFile(File iggyFile, File extractDir) throws IOException {
final String FILENAME_FORMAT = "index%d_type%d.bin";
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)))) {
fos.write(ir.getEntryData(i));
}
}
}
public String getSwfName() {
return iggySwf.getName();
}
public long getSwfXMin() {
return iggySwf.getHdr().getXMin();
}
public long getSwfYMin() {
return iggySwf.getHdr().getYMin();
}
public long getSwfXMax() {
return iggySwf.getHdr().getXMax();
}
public long getSwfYMax() {
return iggySwf.getHdr().getYMax();
}
public float getSwfFrameRate() {
return iggySwf.getHdr().getFrameRate();
}
/**
* Removes entries of type INDEX.There can be more than one INDEX,
* continuous. This removes all ot them.
*/
public void removeIndexEntries() {
long offsetsChange = 0;
final int ENTRY_SIZE = 16;
for (int i = 0; i < subFileEntries.size(); i++) {
IggySubFileEntry entry = subFileEntries.get(i);
entry.offset += offsetsChange;
if (entry.type == IggySubFileEntry.TYPE_INDEX) {
offsetsChange = offsetsChange - entry.size - ENTRY_SIZE;
subFileEntriesData.remove(i);
subFileEntries.remove(i);
i--;
}
}
}
public boolean updateFlashEntry() throws IOException {
byte replacementData[];
byte replacementIndexData[];
IggyIndexBuilder ib = new IggyIndexBuilder();
try (DataStreamInterface stream = new TemporaryDataStream()) {
stream.setIndexing(ib);
iggySwf.writeToDataStream(stream);
replacementData = stream.getAllBytes();
replacementIndexData = ib.getIndexBytes();
} catch (IOException ex) {
Logger.getLogger(IggyFile.class.getName()).log(Level.SEVERE, "Error during updating SWF", ex);
return false;
}
long offsetsChange = 0;
for (int i = 0; i < subFileEntries.size(); i++) {
IggySubFileEntry entry = subFileEntries.get(i);
entry.offset += offsetsChange;
if (entry.type == IggySubFileEntry.TYPE_FLASH) {
long oldSize = entry.size;
long newSize = replacementData.length;
entry.size = newSize;
entry.size2 = newSize;
offsetsChange = offsetsChange + (newSize - oldSize); //entries after this one will have modified offsets
subFileEntriesData.set(i, replacementData);
}
}
removeIndexEntries();
IggySubFileEntry indexEntry = new IggySubFileEntry(IggySubFileEntry.TYPE_INDEX, replacementIndexData.length, replacementIndexData.length, 0 /*offset will be set automatically*/);
subFileEntries.add(indexEntry);
subFileEntriesData.add(replacementIndexData);
return true;
}
private void parseEntries() throws IOException {
for (int i = 0; i < subFileEntries.size(); i++) {
IggySubFileEntry entry = subFileEntries.get(i);
if (entry.type == IggySubFileEntry.TYPE_FLASH) {
iggySwf = new IggySwf(new TemporaryDataStream(getEntryData(i)));
break;
}
/*if (entry.type == IggySubFileEntry.TYPE_INDEX) {
IggyIndexParser.parseIndex(true, new TemporaryDataStream(getEntryData(i)), new ArrayList<>(), new ArrayList<>());
}*/
}
}
@Override
public void readFromDataStream(ReadDataStreamInterface stream) throws IOException {
header = new IggyHeader(stream);
if (!header.is64()) {
throw new IOException("32 bit iggy files are not (yet) supported, sorry");
}
for (int i = 0; i < header.getNumSubfiles(); i++) {
subFileEntries.add(new IggySubFileEntry(stream));
}
for (IggySubFileEntry entry : subFileEntries) {
stream.seek(entry.offset, SeekMode.SET);
byte[] entryData = stream.readBytes((int) entry.size);
subFileEntriesData.add(entryData);
}
parseEntries();
}
public void saveChanges() throws IOException {
updateFlashEntry();
try (RandomAccessFileDataStream raf = new RandomAccessFileDataStream(originalFile)) {
writeToDataStream(raf);
}
}
@Override
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
header.writeToDataStream(stream);
long startOffset = IggyHeader.STRUCT_SIZE + IggySubFileEntry.STRUCTURE_SIZE * subFileEntries.size();
long currentOffset = startOffset;
for (int i = 0; i < subFileEntries.size(); i++) {
IggySubFileEntry entry = subFileEntries.get(i);
entry.offset = currentOffset;
currentOffset += entry.size;
entry.writeToDataStream(stream);
}
for (int i = 0; i < subFileEntries.size(); i++) {
byte[] entryData = subFileEntriesData.get(i);
stream.writeBytes(entryData);
}
}
}

View File

@@ -1,339 +1,339 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class IggySwf implements StructureInterface {
final static int NO_OFFSET = 1;
@IggyFieldType(value = DataType.wchar_t, count = 48)
String name;
private List<IggyFont> fonts = new ArrayList<>();
// private List<Long> font_data_addresses = new ArrayList<>();
private List<IggyFont> add_fonts = new ArrayList<>();
// private List<Long> add_font_data_addresses = new ArrayList<>();
private IggyFlashHeader64 hdr;
public IggySwf(ReadDataStreamInterface stream) throws IOException {
readFromDataStream(stream);
}
private List<IggyText> texts = new ArrayList<>();
//private List<Long> text_data_addresses = new ArrayList<>();
private List<IggyText> add_texts = new ArrayList<>();
//private List<Long> add_text_data_addresses = new ArrayList<>();
//private byte font_add_data[];
//private List<Long> font_additional_size = new ArrayList<>();
private IggyFontBinInfo font_bin_info[];
private List<String> sequenceNames = new ArrayList<>();
//private List<Long> sequenceValues = new ArrayList<>();
private IggyFontTypeInfo type_info[];
private String type_info_name[];
private IggyDeclStrings decl_strings;
private long ofs_additional;
private long additional_address;
public IggyFlashHeader64 getHdr() {
return hdr;
}
public List<IggyFont> getFonts() {
return fonts;
}
public List<IggyFont> getAddFonts() {
return add_fonts;
}
public List<IggyText> getTexts() {
return texts;
}
public List<IggyText> getAddTexts() {
return add_texts;
}
@Override
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
this.hdr = new IggyFlashHeader64(s);
//Save all font bytes to buffer for later easy modification
//here is offset[0] - 184
name = s.readWChar();
//here is offset[1] - 230
int pad8 = 8 - (int) (s.position() % 8);
if (pad8 > 8) {
s.seek(pad8, SeekMode.CUR);
}
//here is offset [2] - 232
s.seek(hdr.getBaseAddress(), SeekMode.SET);
s.readUI64(); //pad 1
List<Long> itemsAddresses = new ArrayList<>();
while (true) {
long offset = s.readUI64();
if (offset == 1) {
break;
}
itemsAddresses.add(offset + s.position() - 8);
}
if (hdr.getImported_guid() != 0) {
ofs_additional = s.readUI64();
additional_address = ofs_additional == 1 ? 0 : ofs_additional + s.position() - 8;
}
for (Long addr : itemsAddresses) {
s.seek(addr, SeekMode.SET);
int kind = s.readUI8();
s.seek(-1, SeekMode.CUR);
switch (kind) {
case 22 /*FONT*/:
IggyFont font = new IggyFont(s);
//font_data_addresses.add(addr);
fonts.add(font);
break;
case 6 /*TEXT*/:
IggyText text = new IggyText(s);
//text_data_addresses.add(addr);
texts.add(text);
break;
default:
throw new RuntimeException("Unknown item kind: " + kind);
}
}
if (additional_address != 0) {
s.seek(additional_address, SeekMode.SET);
List<Long> additionalItemsAddresses = new ArrayList<>();
while (true) {
long offset = s.readUI64();
if (offset == 1) {
break;
}
additionalItemsAddresses.add(offset + s.position() - 8);
}
for (Long addr : additionalItemsAddresses) {
s.seek(addr, SeekMode.SET);
int kind = s.readUI8();
s.seek(-1, SeekMode.CUR);
switch (kind) {
case 22 /*FONT*/:
IggyFont font = new IggyFont(s);
//add_font_data_addresses.add(addr);
add_fonts.add(font);
break;
case 6 /*TEXT*/:
IggyText text = new IggyText(s);
//add_text_data_addresses.add(addr);
add_texts.add(text);
break;
default:
throw new RuntimeException("Unknown imported item kind: " + kind);
}
}
}
s.seek(hdr.getFontEndAddress(), SeekMode.SET);
//here is offset [4] - 856 ?
font_bin_info = new IggyFontBinInfo[(int) hdr.font_count];
for (int i = 0; i < hdr.font_count; i++) {
font_bin_info[i] = new IggyFontBinInfo(s);
}
sequenceNames = new ArrayList<>();
long seq_addresses[] = new long[]{hdr.getSequenceStartAddress1(), hdr.getSequenceStartAddress2(), hdr.getSequenceStartAddress3()};
long seq_name_addresses[] = new long[3];
for (int i = 0; i < 3; i++) {
if (seq_addresses[i] == 0) {
seq_name_addresses[i] = 0;
//0
} else {
s.seek(seq_addresses[i], SeekMode.SET);
long ofs_seq_name = s.readUI64();
seq_name_addresses[i] = ofs_seq_name == 1 ? 0 : ofs_seq_name + s.position() - 8;
s.readUI64(); //is this crucial?
}
}
for (int i = 0; i < 3; i++) {
if (seq_name_addresses[i] > 0) {
s.seek(seq_name_addresses[i], SeekMode.SET);
sequenceNames.add(s.readWChar());
} else {
sequenceNames.add(null);
}
}
s.pad8bytes();
//sequence = new IggySequence(s);
s.seek(hdr.getTypeFontsAddress(), SeekMode.SET);
type_info = new IggyFontTypeInfo[(int) hdr.font_count];
type_info_name = new String[(int) hdr.font_count];
for (int i = 0; i < hdr.font_count; i++) {
type_info[i] = new IggyFontTypeInfo(s);
}
for (int i = 0; i < hdr.font_count; i++) {
s.seek(type_info[i].getLocal_name_ofs_pos() + type_info[i].ofs_local_name, SeekMode.SET);
type_info_name[i] = s.readWChar();
}
s.seek(hdr.getDeclStringsAddress(), SeekMode.SET);
decl_strings = new IggyDeclStrings(s);
/*WriteDataStreamInterface outs = new TemporaryDataStream();
writeToDataStream(outs);
Helper.writeFile("d:\\Dropbox\\jpexs-laptop\\iggi\\parts\\swf_out.bin", outs.getAllBytes());*/
}
public String getName() {
return name;
}
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
IggyIndexBuilder ib = s.getIndexing();
hdr.writeToDataStream(s);
s.writeWChar(name);
s.pad8bytes();
s.writeUI64(1);
ib.write16bitArray(name.length() + 1);
ib.writeTwoPaddingBytes();
ib.write64bitPointerArray(64);
long posBeforeOffsets = s.position();
final int FILL_LATER = 1;
List<Long> fontPosFillLater = new ArrayList<>();
for (int i = 0; i < fonts.size(); i++) {
fontPosFillLater.add(s.position());
s.writeUI64(FILL_LATER);
}
List<Long> textPosFillLater = new ArrayList<>();
for (int i = 0; i < texts.size(); i++) {
textPosFillLater.add(s.position());
s.writeUI64(FILL_LATER);
}
s.writeUI64(1);
long addPosFillLater = s.position();
s.writeUI64(FILL_LATER);
long posAfter = posBeforeOffsets + 64 * 8;
long curPos = s.position();
long numLeft = posAfter - curPos;
long ofsLeft = numLeft / 8;
for (int i = 0; i < ofsLeft - 1; i++) {
s.writeUI64(FILL_LATER);
}
for (int i = 0; i < fonts.size(); i++) {
s.setOlderOffsetToThisPos(fontPosFillLater.get(i));
fonts.get(i).writeToDataStream(s);
}
for (int i = 0; i < texts.size(); i++) {
s.setOlderOffsetToThisPos(textPosFillLater.get(i));
texts.get(i).writeToDataStream(s);
}
if (!add_fonts.isEmpty() || !add_texts.isEmpty()) {
s.setOlderOffsetToThisPos(addPosFillLater);
List<Long> addFontPosFillLater = new ArrayList<>();
for (int i = 0; i < add_fonts.size(); i++) {
addFontPosFillLater.add(s.position());
s.writeUI64(FILL_LATER);
}
List<Long> addTextPosFillLater = new ArrayList<>();
for (int i = 0; i < add_texts.size(); i++) {
addTextPosFillLater.add(s.position());
s.writeUI64(FILL_LATER);
}
s.writeUI64(FILL_LATER);
for (int i = 0; i < add_fonts.size(); i++) {
s.setOlderOffsetToThisPos(addFontPosFillLater.get(i));
add_fonts.get(i).writeToDataStream(s);
}
for (int i = 0; i < add_texts.size(); i++) {
s.setOlderOffsetToThisPos(addTextPosFillLater.get(i));
add_texts.get(i).writeToDataStream(s);
}
}
s.setOlderOffsetToThisPos(hdr.getFont_end_ofs_pos());
ib.writeConstLengthArray(IggyIndexBuilder.CONST_BIN_INFO_SIZE, hdr.font_count);
for (int i = 0; i < hdr.font_count; i++) {
font_bin_info[i].writeToDataStream(s);
}
long seq_ofs_pos[] = new long[]{hdr.getSequence_start1_ofs_pos(), hdr.getSequence_start2_ofs_pos(), hdr.getSequence_start3_ofs_pos()};
long off_seq_expected[] = new long[]{hdr.off_sequence_start1, hdr.off_sequence_start2, hdr.off_sequence_start3};
long seq_name_fill_later[] = new long[3];
s.setOlderOffsetToThisPos(seq_ofs_pos[0]);
s.writeUI64(1);
s.writeUI64(1);
ib.writeLengthCustom(16, new int[]{0}, new int[]{2});
seq_name_fill_later[2] = s.position();
s.setOlderOffsetToThisPos(seq_ofs_pos[2]);
s.writeUI64(FILL_LATER);
s.writeUI64(0);
ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE);
for (int i = 0; i < 3; i++) {
if (sequenceNames.get(i) != null) {
s.setOlderOffsetToThisPos(seq_name_fill_later[i]);
ib.write16bitArray(sequenceNames.get(i).length() + 1);
s.writeWChar(sequenceNames.get(i));
}
}
s.setOlderOffsetToThisPos(hdr.getSequence_end_ofs_pos());
s.pad8bytes();
ib.pad8bytes();
ib.writeConstLengthArray(IggyIndexBuilder.CONST_TYPE_INFO_SIZE, hdr.font_count);
s.setOlderOffsetToThisPos(hdr.getType_fonts_ofs_pos());
//s.seek(hdr.getTypeFontsAddress(), SeekMode.SET);
for (int i = 0; i < hdr.font_count; i++) {
type_info[i].writeToDataStream(s);
}
for (int i = 0; i < hdr.font_count; i++) {
ib.write16bitArray(type_info_name[i].length() + 1);
s.setOlderOffsetToThisPos(type_info[i].getLocal_name_ofs_pos());
s.writeWChar(type_info_name[i]);
}
s.pad8bytes();
ib.pad8bytes();
s.setOlderOffsetToThisPos(hdr.getDecl_strings_ofs_pos());
//s.seek(hdr.getDeclStringsAddress(), SeekMode.SET);
decl_strings.writeToDataStream(s);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[\r\n");
sb.append("name ").append(name).append("\r\n");
return sb.toString();
}
public IggyDeclStrings getDeclStrings() {
return decl_strings;
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class IggySwf implements StructureInterface {
final static int NO_OFFSET = 1;
@IggyFieldType(value = DataType.wchar_t, count = 48)
String name;
private List<IggyFont> fonts = new ArrayList<>();
// private List<Long> font_data_addresses = new ArrayList<>();
private List<IggyFont> add_fonts = new ArrayList<>();
// private List<Long> add_font_data_addresses = new ArrayList<>();
private IggyFlashHeader64 hdr;
public IggySwf(ReadDataStreamInterface stream) throws IOException {
readFromDataStream(stream);
}
private List<IggyText> texts = new ArrayList<>();
//private List<Long> text_data_addresses = new ArrayList<>();
private List<IggyText> add_texts = new ArrayList<>();
//private List<Long> add_text_data_addresses = new ArrayList<>();
//private byte font_add_data[];
//private List<Long> font_additional_size = new ArrayList<>();
private IggyFontBinInfo font_bin_info[];
private List<String> sequenceNames = new ArrayList<>();
//private List<Long> sequenceValues = new ArrayList<>();
private IggyFontTypeInfo type_info[];
private String type_info_name[];
private IggyDeclStrings decl_strings;
private long ofs_additional;
private long additional_address;
public IggyFlashHeader64 getHdr() {
return hdr;
}
public List<IggyFont> getFonts() {
return fonts;
}
public List<IggyFont> getAddFonts() {
return add_fonts;
}
public List<IggyText> getTexts() {
return texts;
}
public List<IggyText> getAddTexts() {
return add_texts;
}
@Override
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
this.hdr = new IggyFlashHeader64(s);
//Save all font bytes to buffer for later easy modification
//here is offset[0] - 184
name = s.readWChar();
//here is offset[1] - 230
int pad8 = 8 - (int) (s.position() % 8);
if (pad8 > 8) {
s.seek(pad8, SeekMode.CUR);
}
//here is offset [2] - 232
s.seek(hdr.getBaseAddress(), SeekMode.SET);
s.readUI64(); //pad 1
List<Long> itemsAddresses = new ArrayList<>();
while (true) {
long offset = s.readUI64();
if (offset == 1) {
break;
}
itemsAddresses.add(offset + s.position() - 8);
}
if (hdr.getImported_guid() != 0) {
ofs_additional = s.readUI64();
additional_address = ofs_additional == 1 ? 0 : ofs_additional + s.position() - 8;
}
for (Long addr : itemsAddresses) {
s.seek(addr, SeekMode.SET);
int kind = s.readUI8();
s.seek(-1, SeekMode.CUR);
switch (kind) {
case 22 /*FONT*/:
IggyFont font = new IggyFont(s);
//font_data_addresses.add(addr);
fonts.add(font);
break;
case 6 /*TEXT*/:
IggyText text = new IggyText(s);
//text_data_addresses.add(addr);
texts.add(text);
break;
default:
throw new RuntimeException("Unknown item kind: " + kind);
}
}
if (additional_address != 0) {
s.seek(additional_address, SeekMode.SET);
List<Long> additionalItemsAddresses = new ArrayList<>();
while (true) {
long offset = s.readUI64();
if (offset == 1) {
break;
}
additionalItemsAddresses.add(offset + s.position() - 8);
}
for (Long addr : additionalItemsAddresses) {
s.seek(addr, SeekMode.SET);
int kind = s.readUI8();
s.seek(-1, SeekMode.CUR);
switch (kind) {
case 22 /*FONT*/:
IggyFont font = new IggyFont(s);
//add_font_data_addresses.add(addr);
add_fonts.add(font);
break;
case 6 /*TEXT*/:
IggyText text = new IggyText(s);
//add_text_data_addresses.add(addr);
add_texts.add(text);
break;
default:
throw new RuntimeException("Unknown imported item kind: " + kind);
}
}
}
s.seek(hdr.getFontEndAddress(), SeekMode.SET);
//here is offset [4] - 856 ?
font_bin_info = new IggyFontBinInfo[(int) hdr.font_count];
for (int i = 0; i < hdr.font_count; i++) {
font_bin_info[i] = new IggyFontBinInfo(s);
}
sequenceNames = new ArrayList<>();
long seq_addresses[] = new long[]{hdr.getSequenceStartAddress1(), hdr.getSequenceStartAddress2(), hdr.getSequenceStartAddress3()};
long seq_name_addresses[] = new long[3];
for (int i = 0; i < 3; i++) {
if (seq_addresses[i] == 0) {
seq_name_addresses[i] = 0;
//0
} else {
s.seek(seq_addresses[i], SeekMode.SET);
long ofs_seq_name = s.readUI64();
seq_name_addresses[i] = ofs_seq_name == 1 ? 0 : ofs_seq_name + s.position() - 8;
s.readUI64(); //is this crucial?
}
}
for (int i = 0; i < 3; i++) {
if (seq_name_addresses[i] > 0) {
s.seek(seq_name_addresses[i], SeekMode.SET);
sequenceNames.add(s.readWChar());
} else {
sequenceNames.add(null);
}
}
s.pad8bytes();
//sequence = new IggySequence(s);
s.seek(hdr.getTypeFontsAddress(), SeekMode.SET);
type_info = new IggyFontTypeInfo[(int) hdr.font_count];
type_info_name = new String[(int) hdr.font_count];
for (int i = 0; i < hdr.font_count; i++) {
type_info[i] = new IggyFontTypeInfo(s);
}
for (int i = 0; i < hdr.font_count; i++) {
s.seek(type_info[i].getLocal_name_ofs_pos() + type_info[i].ofs_local_name, SeekMode.SET);
type_info_name[i] = s.readWChar();
}
s.seek(hdr.getDeclStringsAddress(), SeekMode.SET);
decl_strings = new IggyDeclStrings(s);
/*WriteDataStreamInterface outs = new TemporaryDataStream();
writeToDataStream(outs);
Helper.writeFile("d:\\Dropbox\\jpexs-laptop\\iggi\\parts\\swf_out.bin", outs.getAllBytes());*/
}
public String getName() {
return name;
}
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
IggyIndexBuilder ib = s.getIndexing();
hdr.writeToDataStream(s);
s.writeWChar(name);
s.pad8bytes();
s.writeUI64(1);
ib.write16bitArray(name.length() + 1);
ib.writeTwoPaddingBytes();
ib.write64bitPointerArray(64);
long posBeforeOffsets = s.position();
final int FILL_LATER = 1;
List<Long> fontPosFillLater = new ArrayList<>();
for (int i = 0; i < fonts.size(); i++) {
fontPosFillLater.add(s.position());
s.writeUI64(FILL_LATER);
}
List<Long> textPosFillLater = new ArrayList<>();
for (int i = 0; i < texts.size(); i++) {
textPosFillLater.add(s.position());
s.writeUI64(FILL_LATER);
}
s.writeUI64(1);
long addPosFillLater = s.position();
s.writeUI64(FILL_LATER);
long posAfter = posBeforeOffsets + 64 * 8;
long curPos = s.position();
long numLeft = posAfter - curPos;
long ofsLeft = numLeft / 8;
for (int i = 0; i < ofsLeft - 1; i++) {
s.writeUI64(FILL_LATER);
}
for (int i = 0; i < fonts.size(); i++) {
s.setOlderOffsetToThisPos(fontPosFillLater.get(i));
fonts.get(i).writeToDataStream(s);
}
for (int i = 0; i < texts.size(); i++) {
s.setOlderOffsetToThisPos(textPosFillLater.get(i));
texts.get(i).writeToDataStream(s);
}
if (!add_fonts.isEmpty() || !add_texts.isEmpty()) {
s.setOlderOffsetToThisPos(addPosFillLater);
List<Long> addFontPosFillLater = new ArrayList<>();
for (int i = 0; i < add_fonts.size(); i++) {
addFontPosFillLater.add(s.position());
s.writeUI64(FILL_LATER);
}
List<Long> addTextPosFillLater = new ArrayList<>();
for (int i = 0; i < add_texts.size(); i++) {
addTextPosFillLater.add(s.position());
s.writeUI64(FILL_LATER);
}
s.writeUI64(FILL_LATER);
for (int i = 0; i < add_fonts.size(); i++) {
s.setOlderOffsetToThisPos(addFontPosFillLater.get(i));
add_fonts.get(i).writeToDataStream(s);
}
for (int i = 0; i < add_texts.size(); i++) {
s.setOlderOffsetToThisPos(addTextPosFillLater.get(i));
add_texts.get(i).writeToDataStream(s);
}
}
s.setOlderOffsetToThisPos(hdr.getFont_end_ofs_pos());
ib.writeConstLengthArray(IggyIndexBuilder.CONST_BIN_INFO_SIZE, hdr.font_count);
for (int i = 0; i < hdr.font_count; i++) {
font_bin_info[i].writeToDataStream(s);
}
long seq_ofs_pos[] = new long[]{hdr.getSequence_start1_ofs_pos(), hdr.getSequence_start2_ofs_pos(), hdr.getSequence_start3_ofs_pos()};
long off_seq_expected[] = new long[]{hdr.off_sequence_start1, hdr.off_sequence_start2, hdr.off_sequence_start3};
long seq_name_fill_later[] = new long[3];
s.setOlderOffsetToThisPos(seq_ofs_pos[0]);
s.writeUI64(1);
s.writeUI64(1);
ib.writeLengthCustom(16, new int[]{0}, new int[]{2});
seq_name_fill_later[2] = s.position();
s.setOlderOffsetToThisPos(seq_ofs_pos[2]);
s.writeUI64(FILL_LATER);
s.writeUI64(0);
ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE);
for (int i = 0; i < 3; i++) {
if (sequenceNames.get(i) != null) {
s.setOlderOffsetToThisPos(seq_name_fill_later[i]);
ib.write16bitArray(sequenceNames.get(i).length() + 1);
s.writeWChar(sequenceNames.get(i));
}
}
s.setOlderOffsetToThisPos(hdr.getSequence_end_ofs_pos());
s.pad8bytes();
ib.pad8bytes();
ib.writeConstLengthArray(IggyIndexBuilder.CONST_TYPE_INFO_SIZE, hdr.font_count);
s.setOlderOffsetToThisPos(hdr.getType_fonts_ofs_pos());
//s.seek(hdr.getTypeFontsAddress(), SeekMode.SET);
for (int i = 0; i < hdr.font_count; i++) {
type_info[i].writeToDataStream(s);
}
for (int i = 0; i < hdr.font_count; i++) {
ib.write16bitArray(type_info_name[i].length() + 1);
s.setOlderOffsetToThisPos(type_info[i].getLocal_name_ofs_pos());
s.writeWChar(type_info_name[i]);
}
s.pad8bytes();
ib.pad8bytes();
s.setOlderOffsetToThisPos(hdr.getDecl_strings_ofs_pos());
//s.seek(hdr.getDeclStringsAddress(), SeekMode.SET);
decl_strings.writeToDataStream(s);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[\r\n");
sb.append("name ").append(name).append("\r\n");
return sb.toString();
}
public IggyDeclStrings getDeclStrings() {
return decl_strings;
}
}

View File

@@ -1,198 +1,198 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class IggyText implements StructureInterface {
public static final int STRUCT_SIZE = 104;
public static final int ID = 0xFF06;
@IggyFieldType(DataType.uint16_t)
int type; // Tag type
@IggyFieldType(DataType.uint16_t)
int textIndex;
@IggyArrayFieldType(value = DataType.uint8_t, count = 28)
byte zeroone[];
@IggyFieldType(DataType.float_t)
float par1;
@IggyFieldType(DataType.float_t)
float par2;
@IggyFieldType(DataType.float_t)
float par3;
@IggyFieldType(DataType.float_t)
float par4;
@IggyFieldType(DataType.uint16_t)
int enum_hex;
//Guessed
boolean hasText;
boolean wordWrap;
boolean multiline;
boolean password;
boolean readOnly;
boolean hasTextColor;
boolean hasMaxLength;
boolean hasFont;
boolean hasFontClass;
boolean autosize;
boolean hasLayout;
boolean noSelect;
boolean border;
boolean wasStatic;
boolean html;
boolean useOutlines;
@IggyFieldType(DataType.uint16_t)
int fontIndex;
@IggyFieldType(DataType.uint32_t)
long zero;
@IggyFieldType(DataType.uint64_t)
long one;
@IggyArrayFieldType(value = DataType.uint8_t, count = 32)
byte[] some; // same for different fonts
long ofs_name;
@IggyArrayFieldType(value = DataType.wchar_t)
String initialText; //till end of info file?
public IggyText(int type, int order_in_iggy_file, byte[] zeroone, float par1, float par2, float par3, float par4, int enum_hex, int for_which_font_order_in_iggyfile, long zero, long one, byte[] some, long offset_of_name, String name) {
this.type = type;
this.textIndex = order_in_iggy_file;
this.zeroone = zeroone;
this.par1 = par1;
this.par2 = par2;
this.par3 = par3;
this.par4 = par4;
this.enum_hex = enum_hex;
this.fontIndex = for_which_font_order_in_iggyfile;
this.zero = zero;
this.one = one;
this.some = some;
this.initialText = name;
}
public IggyText(ReadDataStreamInterface stream) throws IOException {
this.readFromDataStream(stream);
}
@Override
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
type = s.readUI16();
//characterId - iggy Id
textIndex = s.readUI16();
zeroone = s.readBytes(28);
//bounds?:
par1 = s.readFloat();
par2 = s.readFloat();
par3 = s.readFloat();
par4 = s.readFloat();
enum_hex = s.readUI16();
fontIndex = s.readUI16(); //fontId
zero = s.readUI32();
one = s.readUI64(); //01CB FF33 3333
some = s.readBytes(32); // [6] => 40, [24] => 8
ofs_name = s.readUI64();
long name_address = ofs_name + s.position() - 8;
s.seek(name_address, SeekMode.SET);
initialText = s.readWChar();
s.pad8bytes();
}
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
s.getIndexing().writeConstLength(IggyIndexBuilder.CONST_TEXT_DATA_SIZE);
s.writeUI16(type);
s.writeUI16(textIndex);
s.writeBytes(zeroone);
s.writeFloat(par1);
s.writeFloat(par2);
s.writeFloat(par3);
s.writeFloat(par4);
s.writeUI16(enum_hex);
s.writeUI16(fontIndex);
s.writeUI32(zero);
s.writeUI64(one);
s.writeBytes(some);
s.writeUI64(ofs_name);
long name_address = ofs_name + s.position() - 8;
s.seek(name_address, SeekMode.SET);
s.writeWChar(initialText);
s.pad8bytes();
s.getIndexing().write16bitArray(initialText.length() + 1);
s.getIndexing().pad8bytes();
}
public int getType() {
return type;
}
public int getTextIndex() {
return textIndex;
}
public byte[] getZeroone() {
return zeroone;
}
public float getPar1() {
return par1;
}
public float getPar2() {
return par2;
}
public float getPar3() {
return par3;
}
public float getPar4() {
return par4;
}
public int getEnum_hex() {
return enum_hex;
}
public int getFontIndex() {
return fontIndex;
}
public long getZero() {
return zero;
}
public long getOne() {
return one;
}
public byte[] getSome() {
return some;
}
public String getInitialText() {
return initialText;
}
public void setInitialText(String initialText) {
this.initialText = initialText;
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class IggyText implements StructureInterface {
public static final int STRUCT_SIZE = 104;
public static final int ID = 0xFF06;
@IggyFieldType(DataType.uint16_t)
int type; // Tag type
@IggyFieldType(DataType.uint16_t)
int textIndex;
@IggyArrayFieldType(value = DataType.uint8_t, count = 28)
byte zeroone[];
@IggyFieldType(DataType.float_t)
float par1;
@IggyFieldType(DataType.float_t)
float par2;
@IggyFieldType(DataType.float_t)
float par3;
@IggyFieldType(DataType.float_t)
float par4;
@IggyFieldType(DataType.uint16_t)
int enum_hex;
//Guessed
boolean hasText;
boolean wordWrap;
boolean multiline;
boolean password;
boolean readOnly;
boolean hasTextColor;
boolean hasMaxLength;
boolean hasFont;
boolean hasFontClass;
boolean autosize;
boolean hasLayout;
boolean noSelect;
boolean border;
boolean wasStatic;
boolean html;
boolean useOutlines;
@IggyFieldType(DataType.uint16_t)
int fontIndex;
@IggyFieldType(DataType.uint32_t)
long zero;
@IggyFieldType(DataType.uint64_t)
long one;
@IggyArrayFieldType(value = DataType.uint8_t, count = 32)
byte[] some; // same for different fonts
long ofs_name;
@IggyArrayFieldType(value = DataType.wchar_t)
String initialText; //till end of info file?
public IggyText(int type, int order_in_iggy_file, byte[] zeroone, float par1, float par2, float par3, float par4, int enum_hex, int for_which_font_order_in_iggyfile, long zero, long one, byte[] some, long offset_of_name, String name) {
this.type = type;
this.textIndex = order_in_iggy_file;
this.zeroone = zeroone;
this.par1 = par1;
this.par2 = par2;
this.par3 = par3;
this.par4 = par4;
this.enum_hex = enum_hex;
this.fontIndex = for_which_font_order_in_iggyfile;
this.zero = zero;
this.one = one;
this.some = some;
this.initialText = name;
}
public IggyText(ReadDataStreamInterface stream) throws IOException {
this.readFromDataStream(stream);
}
@Override
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
type = s.readUI16();
//characterId - iggy Id
textIndex = s.readUI16();
zeroone = s.readBytes(28);
//bounds?:
par1 = s.readFloat();
par2 = s.readFloat();
par3 = s.readFloat();
par4 = s.readFloat();
enum_hex = s.readUI16();
fontIndex = s.readUI16(); //fontId
zero = s.readUI32();
one = s.readUI64(); //01CB FF33 3333
some = s.readBytes(32); // [6] => 40, [24] => 8
ofs_name = s.readUI64();
long name_address = ofs_name + s.position() - 8;
s.seek(name_address, SeekMode.SET);
initialText = s.readWChar();
s.pad8bytes();
}
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
s.getIndexing().writeConstLength(IggyIndexBuilder.CONST_TEXT_DATA_SIZE);
s.writeUI16(type);
s.writeUI16(textIndex);
s.writeBytes(zeroone);
s.writeFloat(par1);
s.writeFloat(par2);
s.writeFloat(par3);
s.writeFloat(par4);
s.writeUI16(enum_hex);
s.writeUI16(fontIndex);
s.writeUI32(zero);
s.writeUI64(one);
s.writeBytes(some);
s.writeUI64(ofs_name);
long name_address = ofs_name + s.position() - 8;
s.seek(name_address, SeekMode.SET);
s.writeWChar(initialText);
s.pad8bytes();
s.getIndexing().write16bitArray(initialText.length() + 1);
s.getIndexing().pad8bytes();
}
public int getType() {
return type;
}
public int getTextIndex() {
return textIndex;
}
public byte[] getZeroone() {
return zeroone;
}
public float getPar1() {
return par1;
}
public float getPar2() {
return par2;
}
public float getPar3() {
return par3;
}
public float getPar4() {
return par4;
}
public int getEnum_hex() {
return enum_hex;
}
public int getFontIndex() {
return fontIndex;
}
public long getZero() {
return zero;
}
public long getOne() {
return one;
}
public byte[] getSome() {
return some;
}
public String getInitialText() {
return initialText;
}
public void setInitialText(String initialText) {
this.initialText = initialText;
}
}

View File

@@ -1,120 +1,120 @@
package com.jpexs.decompiler.flash.iggy.conversion;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFBundle;
import com.jpexs.decompiler.flash.iggy.IggyFile;
import com.jpexs.decompiler.flash.iggy.IggyFont;
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.MemoryInputStream;
import com.jpexs.helpers.ReReadableInputStream;
import com.jpexs.helpers.streams.SeekableInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class IggySwfBundle implements SWFBundle {
private IggyFile iggyFile;
public IggySwfBundle(InputStream is) throws IOException {
this(is, null);
}
public IggySwfBundle(File filename) throws IOException {
this(null, filename);
}
protected IggySwfBundle(InputStream is, File filename) throws IOException {
initBundle(is, filename);
}
protected void initBundle(InputStream is, File filename) throws IOException {
if (filename == null) {
filename = File.createTempFile("bundle", ".iggy");
Helper.saveStream(is, filename);
}
iggyFile = new IggyFile(filename);
}
@Override
public int length() {
return 1;
}
@Override
public Set<String> getKeys() {
Set<String> ret = new TreeSet<>();
for (int i = 0; i < length(); i++) {
ret.add(iggyFile.getSwfName());
}
return ret;
}
private int keyToSwfIndex(String key) {
for (int i = 0; i < length(); i++) {
if (key.equals(iggyFile.getSwfName())) {
return i;
}
}
throw new IllegalArgumentException("Key " + key + " does not exist!");
}
@Override
public SeekableInputStream getSWF(String key) throws IOException {
SWF swf = IggyToSwfConvertor.getSwf(iggyFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
swf.saveTo(baos);
MemoryInputStream mis = new MemoryInputStream(baos.toByteArray());
return mis;
}
@Override
public Map<String, SeekableInputStream> getAll() throws IOException {
Map<String, SeekableInputStream> ret = new HashMap<>();
for (String key : getKeys()) {
ret.put(key, getSWF(key));
}
return ret;
}
@Override
public String getExtension() {
return "iggy";
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public boolean putSWF(String key, InputStream is) throws IOException {
try {
SWF swf = new SWF(is, false, false);
SwfToIggyConvertor.updateIggy(iggyFile.getSwf(), swf);
iggyFile.saveChanges();
return true;
} catch (InterruptedException ex) {
return false;
}
}
}
package com.jpexs.decompiler.flash.iggy.conversion;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFBundle;
import com.jpexs.decompiler.flash.iggy.IggyFile;
import com.jpexs.decompiler.flash.iggy.IggyFont;
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.MemoryInputStream;
import com.jpexs.helpers.ReReadableInputStream;
import com.jpexs.helpers.streams.SeekableInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class IggySwfBundle implements SWFBundle {
private IggyFile iggyFile;
public IggySwfBundle(InputStream is) throws IOException {
this(is, null);
}
public IggySwfBundle(File filename) throws IOException {
this(null, filename);
}
protected IggySwfBundle(InputStream is, File filename) throws IOException {
initBundle(is, filename);
}
protected void initBundle(InputStream is, File filename) throws IOException {
if (filename == null) {
filename = File.createTempFile("bundle", ".iggy");
Helper.saveStream(is, filename);
}
iggyFile = new IggyFile(filename);
}
@Override
public int length() {
return 1;
}
@Override
public Set<String> getKeys() {
Set<String> ret = new TreeSet<>();
for (int i = 0; i < length(); i++) {
ret.add(iggyFile.getSwfName());
}
return ret;
}
private int keyToSwfIndex(String key) {
for (int i = 0; i < length(); i++) {
if (key.equals(iggyFile.getSwfName())) {
return i;
}
}
throw new IllegalArgumentException("Key " + key + " does not exist!");
}
@Override
public SeekableInputStream getSWF(String key) throws IOException {
SWF swf = IggyToSwfConvertor.getSwf(iggyFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
swf.saveTo(baos);
MemoryInputStream mis = new MemoryInputStream(baos.toByteArray());
return mis;
}
@Override
public Map<String, SeekableInputStream> getAll() throws IOException {
Map<String, SeekableInputStream> ret = new HashMap<>();
for (String key : getKeys()) {
ret.put(key, getSWF(key));
}
return ret;
}
@Override
public String getExtension() {
return "iggy";
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public boolean putSWF(String key, InputStream is) throws IOException {
try {
SWF swf = new SWF(is, false, false);
SwfToIggyConvertor.updateIggy(iggyFile.getSwf(), swf);
iggyFile.saveChanges();
return true;
} catch (InterruptedException ex) {
return false;
}
}
}

View File

@@ -1,271 +1,271 @@
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.iggy.IggyShape;
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
import com.jpexs.decompiler.flash.iggy.IggyCharAdvances;
import com.jpexs.decompiler.flash.iggy.IggyDeclStrings;
import com.jpexs.decompiler.flash.iggy.IggyFile;
import com.jpexs.decompiler.flash.iggy.IggyFont;
import com.jpexs.decompiler.flash.iggy.IggySwf;
import com.jpexs.decompiler.flash.iggy.IggyText;
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
import com.jpexs.decompiler.flash.tags.EndTag;
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
import com.jpexs.decompiler.flash.types.LINESTYLEARRAY;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.RGBA;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord;
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 java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* WIP
*
* @author JPEXS
*/
public class IggyToSwfConvertor {
public static void exportAllSwfsToDir(IggyFile file, File outputDir) throws IOException {
exportSwfToDir(file, outputDir);
}
public static void exportSwfToDir(IggyFile file, File outputDir) throws IOException {
try (FileOutputStream fos = new FileOutputStream(new File(outputDir, file.getSwfName()))) {
exportSwf(file, fos);
}
}
public static void exportSwfToFile(IggyFile file, File outputFile) throws IOException {
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
exportSwf(file, fos);
}
}
public static void exportSwf(IggyFile file, OutputStream output) throws IOException {
SWF swf = getSwf(file);
swf.saveTo(output);
}
private static int makeLengthsEm(double val) {
return (int) (val * 1024.0);
}
private static int makeLengthsTwip(double val) {
return (int) (val * SWF.unitDivisor);
}
public static SWF getSwf(IggyFile file) {
SWF swf = new SWF();
swf.compression = SWFCompression.NONE;
swf.frameCount = 1; //FIXME!!
swf.frameRate = file.getSwfFrameRate();
swf.gfx = false;
swf.displayRect = new RECT(
makeLengthsTwip(file.getSwfXMin()),
makeLengthsTwip(file.getSwfXMax()),
makeLengthsTwip(file.getSwfYMin()),
makeLengthsTwip(file.getSwfYMax()));
swf.version = 10; //FIXME
FileAttributesTag fat = new FileAttributesTag(swf);
fat.actionScript3 = true;
fat.hasMetadata = false;
fat.useNetwork = false;
swf.addTag(fat);
IggySwf iggySwf = file.getSwf();
int currentCharId = 0;
Map<Integer, Integer> fontIndex2CharId = new HashMap<>();
for (int fontIndex = 0; fontIndex < iggySwf.getFonts().size(); fontIndex++) {
IggyFont iggyFont = iggySwf.getFonts().get(fontIndex);
DefineFont2Tag fontTag = new DefineFont2Tag(swf);
currentCharId++;
fontIndex2CharId.put(fontIndex, currentCharId);
fontTag.fontID = currentCharId;
/*System.out.println("===================");
System.out.println("xscale: " + iggyFont.getXscale()); //80
System.out.println("yscale: " + iggyFont.getYscale()); //19
System.out.println("unk_float1: " + iggyFont.getUnk_float()[0]);
System.out.println("unk_float2: " + iggyFont.getUnk_float()[1]);
System.out.println("unk_float3: " + iggyFont.getUnk_float()[2]);
System.out.println("unk_float4: " + iggyFont.getUnk_float()[3]);
System.out.println("unk_float5: " + iggyFont.getUnk_float()[4]);
System.out.println("what_2: " + iggyFont.getWhat_2());
System.out.println("what_3: " + iggyFont.getWhat_3());*/
fontTag.fontKerningTable = new ArrayList<>();
IggyCharKerning ker = iggyFont.getCharKernings();
if (ker != null) {
for (int i = 0; i < ker.getKernCount(); i++) {
int kerningCode1 = ker.getCharsA().get(i);
int kerningCode2 = ker.getCharsA().get(i);
int kerningOffset = ker.getKerningOffsets().get(i);
fontTag.fontKerningTable.add(new KERNINGRECORD(kerningCode1, kerningCode2, kerningOffset));
}
}
fontTag.fontFlagsWideCodes = true;
fontTag.fontFlagsWideOffsets = true;
fontTag.fontAscent = iggyFont.getAscent();
fontTag.fontDescent = iggyFont.getDescent();
fontTag.fontLeading = iggyFont.getLeading();
fontTag.codeTable = new ArrayList<>();
fontTag.fontName = iggyFont.getName();
fontTag.glyphShapeTable = new ArrayList<>();
fontTag.fontBoundsTable = new ArrayList<>();
fontTag.fontAdvanceTable = new ArrayList<>();
fontTag.fontFlagsHasLayout = true;
IggyCharAdvances advanceValues = iggyFont.getCharAdvances();
for (int i = 0; i < iggyFont.getCharacterCount(); i++) {
int code = iggyFont.getCharIndices().getChars().get(i);
fontTag.codeTable.add(code);
IggyShape glyph = iggyFont.getChars().get(i);
SHAPE shp;
if (glyph != null) {
shp = IggyShapeToSwfConvertor.convertCharToShape(glyph);
fontTag.fontBoundsTable.add(shp.getBounds());
} else {
shp = new SHAPE();
shp.shapeRecords = new ArrayList<>();
shp.shapeRecords.add(new EndShapeRecord());
fontTag.fontBoundsTable.add(new RECT()); //??
}
fontTag.glyphShapeTable.add(shp);
fontTag.fontAdvanceTable.add(makeLengthsEm(advanceValues.getScales().get(i)));
}
fontTag.setModified(true);
swf.addTag(fontTag);
}
Map<Integer, Integer> textIndex2CharId = new HashMap<>();
for (int textIndex = 0; textIndex < iggySwf.getTexts().size(); textIndex++) {
IggyText iggyText = iggySwf.getTexts().get(textIndex);
DefineEditTextTag textTag = new DefineEditTextTag(swf);
currentCharId++;
textIndex2CharId.put(textIndex, currentCharId);
textTag.characterID = currentCharId;
textTag.hasText = true;
textTag.initialText = iggyText.getInitialText();
textTag.html = true;
textTag.noSelect = true;
textTag.wasStatic = true;
textTag.hasFont = false;
textTag.hasFontClass = false;
textTag.hasMaxLength = false;
//textTag.multiline = true;
//textTag.wordWrap = true;
//textTag.hasTextColor = true;
//textTag.textColor = new RGBA(Color.black);
//textTag.fontHeight = 40; //??
textTag.readOnly = true;
textTag.bounds = new RECT(
makeLengthsTwip(iggyText.getPar1()),
makeLengthsTwip(iggyText.getPar3()),
makeLengthsTwip(iggyText.getPar2()),
makeLengthsTwip(iggyText.getPar4())
);
//textTag.hasFont = true;
//textTag.fontId = fontIndex2CharId.get(iggyText.getFontIndex());
textTag.setModified(true);
swf.addTag(textTag);
}
IggyDeclStrings declStrings = iggySwf.getDeclStrings();
if (declStrings != null) {
byte[] abcData = declStrings.getData();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(new byte[]{1, 0, 0, 0, 0, 0x10, 0, 0x2E});
baos.write(abcData);
} catch (IOException ex) {
//should not happen
}
byte[] fullAbcTagData = baos.toByteArray();
try {
DoABC2Tag nabc = new DoABC2Tag(new SWFInputStream(swf, fullAbcTagData), new ByteArrayRange(fullAbcTagData));
nabc.setModified(true);
swf.addTag(nabc);
} catch (IOException ex) {
//ignore
}
}
swf.addTag(
new EndTag(swf));
swf.setModified(
true);
return swf;
}
public static void main(String[] args) {
if (args.length < 2 || (args[0].isEmpty() || args[1].isEmpty())) {
System.err.println("Invalid arguments");
System.err.println("Usage: iggy-extract.bat file.iggy d:/outdir/");
System.exit(1);
}
File file = new File(args[0]);
if (!file.exists()) {
System.err.println("FAIL: Input file: " + file.getAbsolutePath() + " does not exist.");
System.exit(1);
}
File outDir = new File(args[1]);
if (!outDir.exists()) {
if (!outDir.mkdirs()) {
System.err.println("FAIL: Cannot create output directory");
System.exit(1);
}
}
try {
System.out.print("(1/2) Loading file " + args[0] + "...");
IggyFile iggyFile = new IggyFile(new File(args[0]));
System.out.println("OK");
System.out.print("(2/2) Exporting SWF files to " + args[1] + "...");
exportAllSwfsToDir(iggyFile, new File(args[1]));
System.out.println("OK");
System.out.println("All finished sucessfully.");
System.exit(0);
} catch (IOException ex) {
System.out.println("FAIL");
System.err.println("Error while converting: " + ex.getMessage());
System.exit(1);
}
}
}
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.iggy.IggyShape;
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
import com.jpexs.decompiler.flash.iggy.IggyCharAdvances;
import com.jpexs.decompiler.flash.iggy.IggyDeclStrings;
import com.jpexs.decompiler.flash.iggy.IggyFile;
import com.jpexs.decompiler.flash.iggy.IggyFont;
import com.jpexs.decompiler.flash.iggy.IggySwf;
import com.jpexs.decompiler.flash.iggy.IggyText;
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
import com.jpexs.decompiler.flash.tags.EndTag;
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
import com.jpexs.decompiler.flash.types.LINESTYLEARRAY;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.RGBA;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord;
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 java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* WIP
*
* @author JPEXS
*/
public class IggyToSwfConvertor {
public static void exportAllSwfsToDir(IggyFile file, File outputDir) throws IOException {
exportSwfToDir(file, outputDir);
}
public static void exportSwfToDir(IggyFile file, File outputDir) throws IOException {
try (FileOutputStream fos = new FileOutputStream(new File(outputDir, file.getSwfName()))) {
exportSwf(file, fos);
}
}
public static void exportSwfToFile(IggyFile file, File outputFile) throws IOException {
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
exportSwf(file, fos);
}
}
public static void exportSwf(IggyFile file, OutputStream output) throws IOException {
SWF swf = getSwf(file);
swf.saveTo(output);
}
private static int makeLengthsEm(double val) {
return (int) (val * 1024.0);
}
private static int makeLengthsTwip(double val) {
return (int) (val * SWF.unitDivisor);
}
public static SWF getSwf(IggyFile file) {
SWF swf = new SWF();
swf.compression = SWFCompression.NONE;
swf.frameCount = 1; //FIXME!!
swf.frameRate = file.getSwfFrameRate();
swf.gfx = false;
swf.displayRect = new RECT(
makeLengthsTwip(file.getSwfXMin()),
makeLengthsTwip(file.getSwfXMax()),
makeLengthsTwip(file.getSwfYMin()),
makeLengthsTwip(file.getSwfYMax()));
swf.version = 10; //FIXME
FileAttributesTag fat = new FileAttributesTag(swf);
fat.actionScript3 = true;
fat.hasMetadata = false;
fat.useNetwork = false;
swf.addTag(fat);
IggySwf iggySwf = file.getSwf();
int currentCharId = 0;
Map<Integer, Integer> fontIndex2CharId = new HashMap<>();
for (int fontIndex = 0; fontIndex < iggySwf.getFonts().size(); fontIndex++) {
IggyFont iggyFont = iggySwf.getFonts().get(fontIndex);
DefineFont2Tag fontTag = new DefineFont2Tag(swf);
currentCharId++;
fontIndex2CharId.put(fontIndex, currentCharId);
fontTag.fontID = currentCharId;
/*System.out.println("===================");
System.out.println("xscale: " + iggyFont.getXscale()); //80
System.out.println("yscale: " + iggyFont.getYscale()); //19
System.out.println("unk_float1: " + iggyFont.getUnk_float()[0]);
System.out.println("unk_float2: " + iggyFont.getUnk_float()[1]);
System.out.println("unk_float3: " + iggyFont.getUnk_float()[2]);
System.out.println("unk_float4: " + iggyFont.getUnk_float()[3]);
System.out.println("unk_float5: " + iggyFont.getUnk_float()[4]);
System.out.println("what_2: " + iggyFont.getWhat_2());
System.out.println("what_3: " + iggyFont.getWhat_3());*/
fontTag.fontKerningTable = new ArrayList<>();
IggyCharKerning ker = iggyFont.getCharKernings();
if (ker != null) {
for (int i = 0; i < ker.getKernCount(); i++) {
int kerningCode1 = ker.getCharsA().get(i);
int kerningCode2 = ker.getCharsA().get(i);
int kerningOffset = ker.getKerningOffsets().get(i);
fontTag.fontKerningTable.add(new KERNINGRECORD(kerningCode1, kerningCode2, kerningOffset));
}
}
fontTag.fontFlagsWideCodes = true;
fontTag.fontFlagsWideOffsets = true;
fontTag.fontAscent = iggyFont.getAscent();
fontTag.fontDescent = iggyFont.getDescent();
fontTag.fontLeading = iggyFont.getLeading();
fontTag.codeTable = new ArrayList<>();
fontTag.fontName = iggyFont.getName();
fontTag.glyphShapeTable = new ArrayList<>();
fontTag.fontBoundsTable = new ArrayList<>();
fontTag.fontAdvanceTable = new ArrayList<>();
fontTag.fontFlagsHasLayout = true;
IggyCharAdvances advanceValues = iggyFont.getCharAdvances();
for (int i = 0; i < iggyFont.getCharacterCount(); i++) {
int code = iggyFont.getCharIndices().getChars().get(i);
fontTag.codeTable.add(code);
IggyShape glyph = iggyFont.getChars().get(i);
SHAPE shp;
if (glyph != null) {
shp = IggyShapeToSwfConvertor.convertCharToShape(glyph);
fontTag.fontBoundsTable.add(shp.getBounds());
} else {
shp = new SHAPE();
shp.shapeRecords = new ArrayList<>();
shp.shapeRecords.add(new EndShapeRecord());
fontTag.fontBoundsTable.add(new RECT()); //??
}
fontTag.glyphShapeTable.add(shp);
fontTag.fontAdvanceTable.add(makeLengthsEm(advanceValues.getScales().get(i)));
}
fontTag.setModified(true);
swf.addTag(fontTag);
}
Map<Integer, Integer> textIndex2CharId = new HashMap<>();
for (int textIndex = 0; textIndex < iggySwf.getTexts().size(); textIndex++) {
IggyText iggyText = iggySwf.getTexts().get(textIndex);
DefineEditTextTag textTag = new DefineEditTextTag(swf);
currentCharId++;
textIndex2CharId.put(textIndex, currentCharId);
textTag.characterID = currentCharId;
textTag.hasText = true;
textTag.initialText = iggyText.getInitialText();
textTag.html = true;
textTag.noSelect = true;
textTag.wasStatic = true;
textTag.hasFont = false;
textTag.hasFontClass = false;
textTag.hasMaxLength = false;
//textTag.multiline = true;
//textTag.wordWrap = true;
//textTag.hasTextColor = true;
//textTag.textColor = new RGBA(Color.black);
//textTag.fontHeight = 40; //??
textTag.readOnly = true;
textTag.bounds = new RECT(
makeLengthsTwip(iggyText.getPar1()),
makeLengthsTwip(iggyText.getPar3()),
makeLengthsTwip(iggyText.getPar2()),
makeLengthsTwip(iggyText.getPar4())
);
//textTag.hasFont = true;
//textTag.fontId = fontIndex2CharId.get(iggyText.getFontIndex());
textTag.setModified(true);
swf.addTag(textTag);
}
IggyDeclStrings declStrings = iggySwf.getDeclStrings();
if (declStrings != null) {
byte[] abcData = declStrings.getData();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(new byte[]{1, 0, 0, 0, 0, 0x10, 0, 0x2E});
baos.write(abcData);
} catch (IOException ex) {
//should not happen
}
byte[] fullAbcTagData = baos.toByteArray();
try {
DoABC2Tag nabc = new DoABC2Tag(new SWFInputStream(swf, fullAbcTagData), new ByteArrayRange(fullAbcTagData));
nabc.setModified(true);
swf.addTag(nabc);
} catch (IOException ex) {
//ignore
}
}
swf.addTag(
new EndTag(swf));
swf.setModified(
true);
return swf;
}
public static void main(String[] args) {
if (args.length < 2 || (args[0].isEmpty() || args[1].isEmpty())) {
System.err.println("Invalid arguments");
System.err.println("Usage: iggy-extract.bat file.iggy d:/outdir/");
System.exit(1);
}
File file = new File(args[0]);
if (!file.exists()) {
System.err.println("FAIL: Input file: " + file.getAbsolutePath() + " does not exist.");
System.exit(1);
}
File outDir = new File(args[1]);
if (!outDir.exists()) {
if (!outDir.mkdirs()) {
System.err.println("FAIL: Cannot create output directory");
System.exit(1);
}
}
try {
System.out.print("(1/2) Loading file " + args[0] + "...");
IggyFile iggyFile = new IggyFile(new File(args[0]));
System.out.println("OK");
System.out.print("(2/2) Exporting SWF files to " + args[1] + "...");
exportAllSwfsToDir(iggyFile, new File(args[1]));
System.out.println("OK");
System.out.println("All finished sucessfully.");
System.exit(0);
} catch (IOException ex) {
System.out.println("FAIL");
System.err.println("Error while converting: " + ex.getMessage());
System.exit(1);
}
}
}

View File

@@ -1,210 +1,210 @@
package com.jpexs.decompiler.flash.iggy.conversion;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.iggy.IggyCharAdvances;
import com.jpexs.decompiler.flash.iggy.IggyCharIndices;
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
import com.jpexs.decompiler.flash.iggy.IggyFont;
import com.jpexs.decompiler.flash.iggy.IggyShape;
import com.jpexs.decompiler.flash.iggy.IggySwf;
import com.jpexs.decompiler.flash.iggy.IggyText;
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
import com.jpexs.decompiler.flash.types.SHAPE;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
*
* @author JPEXS
*/
public class SwfToIggyConvertor {
private static float normalizeLengths(int val) {
return (val / 1024f);
}
public static void updateIggy(IggySwf iggySwf, SWF swf) throws IOException {
List<DefineFont2Tag> fontTags = new ArrayList<>();
List<DefineEditTextTag> textTags = new ArrayList<>();
List<DoABC2Tag> abcTags = new ArrayList<>();
for (Tag t : swf.getTags()) {
if (t instanceof DefineFont2Tag) {
fontTags.add((DefineFont2Tag) t);
}
if (t instanceof DefineEditTextTag) {
textTags.add((DefineEditTextTag) t);
}
if (t instanceof DoABC2Tag) {
abcTags.add((DoABC2Tag) t);
}
}
if (abcTags.size() > 1) {
throw new IOException("Cannot save more than one ABC tag");
}
int fontCount = iggySwf.getFonts().size();
if (fontCount != fontTags.size()) {
throw new IOException("Font count is different from original iggy file");
}
for (int i = 0; i < fontCount; i++) {
IggyFont iggyFont = iggySwf.getFonts().get(i);
DefineFont2Tag fontTag = fontTags.get(i);
SwfToIggyConvertor.updateIggyFont(iggyFont, fontTag);
}
int textCount = iggySwf.getTexts().size();
if (textCount != textTags.size()) {
throw new IOException("Text count is different from original iggy file");
}
for (int i = 0; i < textCount; i++) {
IggyText iggyText = iggySwf.getTexts().get(i);
DefineEditTextTag textTag = textTags.get(i);
SwfToIggyConvertor.updateIggyText(iggyText, textTag);
}
if (!abcTags.isEmpty()) {
DoABC2Tag abcTag = abcTags.get(0);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte abcTagData[] = abcTag.getData();
byte declData[] = Arrays.copyOfRange(abcTagData, 4/*UI32 flags*/ + 1 /*empty string as name*/ + 3 /*versions, leaving one zero intact*/, abcTagData.length);
iggySwf.getDeclStrings().setData(declData);
}
}
public static void updateIggyText(IggyText iggyText, DefineEditTextTag textTag) {
iggyText.setInitialText(textTag.initialText);
}
public static void updateIggyFont(IggyFont iggyFont, DefineFont2Tag fontTag) {
/*byte zeroone[] = new byte[28];
zeroone[12] = 1;
long flags = 65795;
float unk_float[] = new float[]{
-0.6484375f,
-1.116211f,
1.116211f,
0.6679688f,
0f
};
int xscale = 80;
int yscale = 28;
float ssr1 = 0.9f;
float ssr2 = 0.3f;
long what_2 = 33188160;
long what_3 = 33600216;
byte zeroes48a[] = new byte[48];
byte zeroes48b[] = new byte[48];
float sss1 = 1.1728859f;
float sss2 = 1.1728706f;
float sss3 = 1.1728821f;
float sss4 = 1.1729145f;*/
List<IggyCharOffset> charOffsets = new ArrayList<>();
List<IggyShape> glyphs = new ArrayList<>();
for (SHAPE s : fontTag.glyphShapeTable) {
glyphs.add(SwfShapeToIggyConvertor.convertShape(s));
}
List<Character> chars = new ArrayList<>();
for (int code : fontTag.codeTable) {
chars.add((char) code);
}
IggyCharIndices codePoints = new IggyCharIndices(chars);
List<Float> scales = new ArrayList<>();
for (int adv : fontTag.fontAdvanceTable) {
scales.add(normalizeLengths(adv));
}
IggyCharAdvances charScales = new IggyCharAdvances(scales);
List<Character> charA = new ArrayList<>();
List<Character> charB = new ArrayList<>();
List<Short> kernOffs = new ArrayList<>();
//IggyCharOffset
for (KERNINGRECORD rec : fontTag.fontKerningTable) {
charA.add((char) rec.fontKerningCode1);
charB.add((char) rec.fontKerningCode2);
kernOffs.add((short) rec.fontKerningAdjustment);
}
IggyCharKerning charKernings = new IggyCharKerning(charA, charB, kernOffs);
for (int i = 0; i < fontTag.getCharacterCount(); i++) {
charOffsets.add(new IggyCharOffset(1, 0, 80, 19)); //XSCALE, YSCALE???
}
iggyFont.setCharCount(fontTag.getCharacterCount());
iggyFont.setCharCount2(fontTag.getCharacterCount());
iggyFont.setAscent(fontTag.getAscent());
iggyFont.setDescent(fontTag.getDescent());
iggyFont.setLeading(fontTag.getLeading());
iggyFont.setName(fontTag.getFontName());
iggyFont.setCharOffsets(charOffsets);
iggyFont.setGlyphs(glyphs);
iggyFont.setCodePoints(codePoints);
iggyFont.setCharScales(charScales);
iggyFont.setCharKernings(charKernings);
}
public static IggyFont createIggyFont(DefineFont2Tag fontTag) {
byte zeroone[] = new byte[28];
zeroone[12] = 1;
long flags = 65795;
float unk_float[] = new float[]{
-0.6484375f,
-1.116211f,
1.116211f,
0.6679688f,
0f
};
int xscale = 80;
int yscale = 28;
float ssr1 = 0.9f;
float ssr2 = 0.3f;
long what_2 = 33188160;
long what_3 = 33600216;
byte zeroes48a[] = new byte[48];
byte zeroes48b[] = new byte[48];
float sss1 = 1.1728859f;
float sss2 = 1.1728706f;
float sss3 = 1.1728821f;
float sss4 = 1.1729145f;
List<IggyCharOffset> charOffsets = new ArrayList<>();
List<IggyShape> glyphs = new ArrayList<>();
List<Character> chars = new ArrayList<>();
for (int code : fontTag.codeTable) {
chars.add((char) code);
}
IggyCharIndices codePoints = new IggyCharIndices(chars);
List<Float> scales = new ArrayList<>();
for (int adv : fontTag.fontAdvanceTable) {
scales.add((float) adv);
}
IggyCharAdvances charScales = new IggyCharAdvances(scales);
List<Character> charA = new ArrayList<>();
List<Character> charB = new ArrayList<>();
List<Short> kernOffs = new ArrayList<>();
for (KERNINGRECORD rec : fontTag.fontKerningTable) {
charA.add((char) rec.fontKerningCode1);
charB.add((char) rec.fontKerningCode2);
kernOffs.add((short) rec.fontKerningAdjustment);
}
IggyCharKerning charKernings = new IggyCharKerning(charA, charB, kernOffs);
IggyFont iggyFont = new IggyFont(IggyFont.ID, 0, zeroone, fontTag.getCharacterCount(),
fontTag.getAscent(), fontTag.getDescent(), fontTag.getLeading(), flags,
fontTag.fontKerningTable.size(), unk_float, 0, what_2, 0, 1,
xscale, yscale, 0, ssr1, ssr2, fontTag.getCharacterCount(), 0, what_3, zeroes48a, zeroes48b,
sss1, 1, sss2, 1, sss3, 1, sss4, 1, fontTag.getFontName(),
charOffsets, glyphs, codePoints, charScales, charKernings);
return iggyFont;
}
}
package com.jpexs.decompiler.flash.iggy.conversion;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.iggy.IggyCharAdvances;
import com.jpexs.decompiler.flash.iggy.IggyCharIndices;
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
import com.jpexs.decompiler.flash.iggy.IggyFont;
import com.jpexs.decompiler.flash.iggy.IggyShape;
import com.jpexs.decompiler.flash.iggy.IggySwf;
import com.jpexs.decompiler.flash.iggy.IggyText;
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
import com.jpexs.decompiler.flash.types.SHAPE;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
*
* @author JPEXS
*/
public class SwfToIggyConvertor {
private static float normalizeLengths(int val) {
return (val / 1024f);
}
public static void updateIggy(IggySwf iggySwf, SWF swf) throws IOException {
List<DefineFont2Tag> fontTags = new ArrayList<>();
List<DefineEditTextTag> textTags = new ArrayList<>();
List<DoABC2Tag> abcTags = new ArrayList<>();
for (Tag t : swf.getTags()) {
if (t instanceof DefineFont2Tag) {
fontTags.add((DefineFont2Tag) t);
}
if (t instanceof DefineEditTextTag) {
textTags.add((DefineEditTextTag) t);
}
if (t instanceof DoABC2Tag) {
abcTags.add((DoABC2Tag) t);
}
}
if (abcTags.size() > 1) {
throw new IOException("Cannot save more than one ABC tag");
}
int fontCount = iggySwf.getFonts().size();
if (fontCount != fontTags.size()) {
throw new IOException("Font count is different from original iggy file");
}
for (int i = 0; i < fontCount; i++) {
IggyFont iggyFont = iggySwf.getFonts().get(i);
DefineFont2Tag fontTag = fontTags.get(i);
SwfToIggyConvertor.updateIggyFont(iggyFont, fontTag);
}
int textCount = iggySwf.getTexts().size();
if (textCount != textTags.size()) {
throw new IOException("Text count is different from original iggy file");
}
for (int i = 0; i < textCount; i++) {
IggyText iggyText = iggySwf.getTexts().get(i);
DefineEditTextTag textTag = textTags.get(i);
SwfToIggyConvertor.updateIggyText(iggyText, textTag);
}
if (!abcTags.isEmpty()) {
DoABC2Tag abcTag = abcTags.get(0);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte abcTagData[] = abcTag.getData();
byte declData[] = Arrays.copyOfRange(abcTagData, 4/*UI32 flags*/ + 1 /*empty string as name*/ + 3 /*versions, leaving one zero intact*/, abcTagData.length);
iggySwf.getDeclStrings().setData(declData);
}
}
public static void updateIggyText(IggyText iggyText, DefineEditTextTag textTag) {
iggyText.setInitialText(textTag.initialText);
}
public static void updateIggyFont(IggyFont iggyFont, DefineFont2Tag fontTag) {
/*byte zeroone[] = new byte[28];
zeroone[12] = 1;
long flags = 65795;
float unk_float[] = new float[]{
-0.6484375f,
-1.116211f,
1.116211f,
0.6679688f,
0f
};
int xscale = 80;
int yscale = 28;
float ssr1 = 0.9f;
float ssr2 = 0.3f;
long what_2 = 33188160;
long what_3 = 33600216;
byte zeroes48a[] = new byte[48];
byte zeroes48b[] = new byte[48];
float sss1 = 1.1728859f;
float sss2 = 1.1728706f;
float sss3 = 1.1728821f;
float sss4 = 1.1729145f;*/
List<IggyCharOffset> charOffsets = new ArrayList<>();
List<IggyShape> glyphs = new ArrayList<>();
for (SHAPE s : fontTag.glyphShapeTable) {
glyphs.add(SwfShapeToIggyConvertor.convertShape(s));
}
List<Character> chars = new ArrayList<>();
for (int code : fontTag.codeTable) {
chars.add((char) code);
}
IggyCharIndices codePoints = new IggyCharIndices(chars);
List<Float> scales = new ArrayList<>();
for (int adv : fontTag.fontAdvanceTable) {
scales.add(normalizeLengths(adv));
}
IggyCharAdvances charScales = new IggyCharAdvances(scales);
List<Character> charA = new ArrayList<>();
List<Character> charB = new ArrayList<>();
List<Short> kernOffs = new ArrayList<>();
//IggyCharOffset
for (KERNINGRECORD rec : fontTag.fontKerningTable) {
charA.add((char) rec.fontKerningCode1);
charB.add((char) rec.fontKerningCode2);
kernOffs.add((short) rec.fontKerningAdjustment);
}
IggyCharKerning charKernings = new IggyCharKerning(charA, charB, kernOffs);
for (int i = 0; i < fontTag.getCharacterCount(); i++) {
charOffsets.add(new IggyCharOffset(1, 0, 80, 19)); //XSCALE, YSCALE???
}
iggyFont.setCharCount(fontTag.getCharacterCount());
iggyFont.setCharCount2(fontTag.getCharacterCount());
iggyFont.setAscent(fontTag.getAscent());
iggyFont.setDescent(fontTag.getDescent());
iggyFont.setLeading(fontTag.getLeading());
iggyFont.setName(fontTag.getFontName());
iggyFont.setCharOffsets(charOffsets);
iggyFont.setGlyphs(glyphs);
iggyFont.setCodePoints(codePoints);
iggyFont.setCharScales(charScales);
iggyFont.setCharKernings(charKernings);
}
public static IggyFont createIggyFont(DefineFont2Tag fontTag) {
byte zeroone[] = new byte[28];
zeroone[12] = 1;
long flags = 65795;
float unk_float[] = new float[]{
-0.6484375f,
-1.116211f,
1.116211f,
0.6679688f,
0f
};
int xscale = 80;
int yscale = 28;
float ssr1 = 0.9f;
float ssr2 = 0.3f;
long what_2 = 33188160;
long what_3 = 33600216;
byte zeroes48a[] = new byte[48];
byte zeroes48b[] = new byte[48];
float sss1 = 1.1728859f;
float sss2 = 1.1728706f;
float sss3 = 1.1728821f;
float sss4 = 1.1729145f;
List<IggyCharOffset> charOffsets = new ArrayList<>();
List<IggyShape> glyphs = new ArrayList<>();
List<Character> chars = new ArrayList<>();
for (int code : fontTag.codeTable) {
chars.add((char) code);
}
IggyCharIndices codePoints = new IggyCharIndices(chars);
List<Float> scales = new ArrayList<>();
for (int adv : fontTag.fontAdvanceTable) {
scales.add((float) adv);
}
IggyCharAdvances charScales = new IggyCharAdvances(scales);
List<Character> charA = new ArrayList<>();
List<Character> charB = new ArrayList<>();
List<Short> kernOffs = new ArrayList<>();
for (KERNINGRECORD rec : fontTag.fontKerningTable) {
charA.add((char) rec.fontKerningCode1);
charB.add((char) rec.fontKerningCode2);
kernOffs.add((short) rec.fontKerningAdjustment);
}
IggyCharKerning charKernings = new IggyCharKerning(charA, charB, kernOffs);
IggyFont iggyFont = new IggyFont(IggyFont.ID, 0, zeroone, fontTag.getCharacterCount(),
fontTag.getAscent(), fontTag.getDescent(), fontTag.getLeading(), flags,
fontTag.fontKerningTable.size(), unk_float, 0, what_2, 0, 1,
xscale, yscale, 0, ssr1, ssr2, fontTag.getCharacterCount(), 0, what_3, zeroes48a, zeroes48b,
sss1, 1, sss2, 1, sss3, 1, sss4, 1, fontTag.getFontName(),
charOffsets, glyphs, codePoints, charScales, charKernings);
return iggyFont;
}
}

View File

@@ -1,188 +1,188 @@
/*
* Copyright (C) 2010-2016 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.treeitems;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFBundle;
import com.jpexs.decompiler.flash.SWFContainerItem;
import com.jpexs.decompiler.flash.SWFSourceInfo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
*
* @author JPEXS
*/
public class SWFList implements List<SWF>, SWFContainerItem {
public String name;
public SWFBundle bundle;
public SWFSourceInfo sourceInfo;
public List<SWF> swfs = new ArrayList<>();
public boolean isBundle() {
return bundle != null;
}
@Override
public SWF getSwf() {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public String toString() {
if (isBundle()) {
return name;
} else {
return swfs.get(0).getFileTitle();
}
}
@Override
public Iterator<SWF> iterator() {
return swfs.iterator();
}
@Override
public int size() {
return swfs.size();
}
@Override
public boolean isEmpty() {
return swfs.isEmpty();
}
@Override
public boolean contains(Object o) {
return swfs.contains(o);
}
@Override
public Object[] toArray() {
return swfs.toArray();
}
@Override
public <T> T[] toArray(T[] ts) {
return swfs.toArray(ts);
}
@Override
public boolean add(SWF e) {
return swfs.add(e);
}
@Override
public boolean remove(Object o) {
return swfs.remove(o);
}
@Override
public boolean containsAll(Collection<?> clctn) {
return swfs.containsAll(clctn);
}
@Override
public boolean addAll(Collection<? extends SWF> clctn) {
return swfs.addAll(clctn);
}
@Override
public boolean removeAll(Collection<?> clctn) {
return swfs.removeAll(clctn);
}
@Override
public boolean retainAll(Collection<?> clctn) {
return swfs.retainAll(clctn);
}
@Override
public void clear() {
swfs.clear();
}
@Override
public boolean addAll(int i, Collection<? extends SWF> clctn) {
return swfs.addAll(i, clctn);
}
@Override
public SWF get(int i) {
if (i < 0 || i >= swfs.size()) {
return null;
}
return swfs.get(i);
}
@Override
public SWF set(int i, SWF e) {
return swfs.set(i, e);
}
@Override
public void add(int i, SWF e) {
swfs.add(i, e);
}
@Override
public SWF remove(int i) {
return swfs.remove(i);
}
@Override
public int indexOf(Object o) {
return swfs.indexOf(0);
}
@Override
public int lastIndexOf(Object o) {
return swfs.lastIndexOf(o);
}
@Override
public ListIterator<SWF> listIterator() {
return swfs.listIterator();
}
@Override
public ListIterator<SWF> listIterator(int i) {
return swfs.listIterator(i);
}
@Override
public List<SWF> subList(int i, int i1) {
return swfs.subList(i, i1);
}
@Override
public boolean isModified() {
for (SWF s : swfs) {
if (s.isModified()) {
return true;
}
}
return false;
}
}
/*
* Copyright (C) 2010-2016 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.treeitems;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFBundle;
import com.jpexs.decompiler.flash.SWFContainerItem;
import com.jpexs.decompiler.flash.SWFSourceInfo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
*
* @author JPEXS
*/
public class SWFList implements List<SWF>, SWFContainerItem {
public String name;
public SWFBundle bundle;
public SWFSourceInfo sourceInfo;
public List<SWF> swfs = new ArrayList<>();
public boolean isBundle() {
return bundle != null;
}
@Override
public SWF getSwf() {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public String toString() {
if (isBundle()) {
return name;
} else {
return swfs.get(0).getFileTitle();
}
}
@Override
public Iterator<SWF> iterator() {
return swfs.iterator();
}
@Override
public int size() {
return swfs.size();
}
@Override
public boolean isEmpty() {
return swfs.isEmpty();
}
@Override
public boolean contains(Object o) {
return swfs.contains(o);
}
@Override
public Object[] toArray() {
return swfs.toArray();
}
@Override
public <T> T[] toArray(T[] ts) {
return swfs.toArray(ts);
}
@Override
public boolean add(SWF e) {
return swfs.add(e);
}
@Override
public boolean remove(Object o) {
return swfs.remove(o);
}
@Override
public boolean containsAll(Collection<?> clctn) {
return swfs.containsAll(clctn);
}
@Override
public boolean addAll(Collection<? extends SWF> clctn) {
return swfs.addAll(clctn);
}
@Override
public boolean removeAll(Collection<?> clctn) {
return swfs.removeAll(clctn);
}
@Override
public boolean retainAll(Collection<?> clctn) {
return swfs.retainAll(clctn);
}
@Override
public void clear() {
swfs.clear();
}
@Override
public boolean addAll(int i, Collection<? extends SWF> clctn) {
return swfs.addAll(i, clctn);
}
@Override
public SWF get(int i) {
if (i < 0 || i >= swfs.size()) {
return null;
}
return swfs.get(i);
}
@Override
public SWF set(int i, SWF e) {
return swfs.set(i, e);
}
@Override
public void add(int i, SWF e) {
swfs.add(i, e);
}
@Override
public SWF remove(int i) {
return swfs.remove(i);
}
@Override
public int indexOf(Object o) {
return swfs.indexOf(0);
}
@Override
public int lastIndexOf(Object o) {
return swfs.lastIndexOf(o);
}
@Override
public ListIterator<SWF> listIterator() {
return swfs.listIterator();
}
@Override
public ListIterator<SWF> listIterator(int i) {
return swfs.listIterator(i);
}
@Override
public List<SWF> subList(int i, int i1) {
return swfs.subList(i, i1);
}
@Override
public boolean isModified() {
for (SWF s : swfs) {
if (s.isModified()) {
return true;
}
}
return false;
}
}