diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/DataType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/DataType.java index e3fd968cd..245b64957 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/DataType.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/DataType.java @@ -1,9 +1,9 @@ -package com.jpexs.decompiler.flash.iggy; - -/** - * @author JPEXS - */ -public enum DataType { - ubits, uint8_t, uint16_t, uint32_t, uint64_t, float_t, unknown, - widechar_t //or maybe just "string"? It has two bytes per character and is null terminated -} +package com.jpexs.decompiler.flash.iggy; + +/** + * @author JPEXS + */ +public enum DataType { + ubits, uint8_t, uint16_t, uint32_t, uint64_t, float_t, unknown, int64_t, + widechar_t //or maybe just "string"? It has two bytes per character and is null terminated +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/FontBinInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/FontBinInfo.java new file mode 100644 index 000000000..cd0da4d55 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/FontBinInfo.java @@ -0,0 +1,81 @@ +package com.jpexs.decompiler.flash.iggy; + +import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType; +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 FontBinInfo implements StructureInterface { + + @IggyFieldType(DataType.uint64_t) + long size_of_this_info = 96; + @IggyFieldType(value = DataType.uint16_t, count = 4) + int font_specific[]; + @IggyFieldType(DataType.float_t) + float normX; + @IggyFieldType(DataType.float_t) + float zero; + @IggyFieldType(DataType.float_t) + float zero2; + @IggyFieldType(DataType.float_t) + float normY; + @IggyFieldType(DataType.float_t) + float minSize; + @IggyFieldType(DataType.float_t) + float maxSize; + @IggyFieldType(DataType.uint64_t) + long order_in_iggy_file; + @IggyFieldType(DataType.int64_t) + long address_back; //relative + @IggyFieldType(value = DataType.uint8_t, count = 40) + byte pad[]; + + public FontBinInfo(ReadDataStreamInterface s) throws IOException { + readFromDataStream(s); + } + + @Override + public void readFromDataStream(ReadDataStreamInterface s) throws IOException { + size_of_this_info = s.readUI64(); + if (size_of_this_info != 96) { + throw new IOException(String.format("Wrong iggy font format (bininfo)!")); + } + font_specific = new int[4]; + for (int i = 0; i < font_specific.length; i++) { + font_specific[i] = s.readUI16(); + } + normX = s.readFloat(); + zero = s.readFloat(); + zero2 = s.readFloat(); + normY = s.readFloat(); + minSize = s.readFloat(); + maxSize = s.readFloat(); + order_in_iggy_file = s.readUI64(); + address_back = s.readSI64(); +//if(address_back + s.position() - 8 != text_offsets[i]) Printf("Wrong iggy font format (bininfo-offsetback) (%u)!\n",i); + pad = s.readBytes(40); + } + + @Override + public void writeToDataStream(WriteDataStreamInterface s) throws IOException { + s.writeUI64(size_of_this_info); + for (int i = 0; i < font_specific.length; i++) { + s.writeUI16(font_specific[i]); + } + s.writeFloat(normX); + s.writeFloat(zero); + s.writeFloat(zero2); + s.writeFloat(normY); + s.writeFloat(minSize); + s.writeFloat(maxSize); + s.writeUI64(order_in_iggy_file); + s.writeSI64(address_back); + s.writeBytes(pad); + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader64.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader64.java index 4c296d361..0da2c4e5a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader64.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader64.java @@ -16,17 +16,17 @@ import java.lang.reflect.Field; public class IggyFlashHeader64 implements IggyFlashHeaderInterface { @IggyFieldType(DataType.uint64_t) - long off_start; // 0 Relative offset to first section (matches sizeof header); + long off_base; // 0 Relative offset to first section (matches sizeof header); @IggyFieldType(DataType.uint64_t) - long off_seq_end; // 8 Relative offset to as3 file names table... + long off_sequence_end; // 8 Relative offset to as3 file names table... @IggyFieldType(DataType.uint64_t) long off_font_end; // 0x10 relative offset to something @IggyFieldType(DataType.uint64_t) - long off_seq_start1; // 0x18 relative offset to something + long off_sequence_start1; // 0x18 relative offset to something @IggyFieldType(DataType.uint64_t) - long pad_to_match; // 0x20 relative offset to something + long off_sequence_start2; // 0x20 relative offset to something @IggyFieldType(DataType.uint64_t) - long off_seq_start2; // 0x28 names_offset; 0x50 relative pointer to the names/import section of the file + long off_sequence_start3; // 0x28 names_offset; 0x50 relative pointer to the names/import section of the file @IggyFieldType(DataType.uint32_t) long xmin; // 0x30 in pixels @IggyFieldType(DataType.uint32_t) @@ -66,7 +66,7 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface { @IggyFieldType(DataType.uint64_t) long off_unk78; // 0x78 relative offset to something @IggyFieldType(DataType.uint64_t) - long off_unk80; + long unk80; @IggyFieldType(DataType.uint64_t) long off_last_section; @IggyFieldType(DataType.uint64_t) @@ -97,9 +97,9 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface { private long font_end_address; private long sequence_start_address1; private long sequence_start_address2; + private long sequence_start_address3; private long names_address; private long unk78_address; - private long unk80_address; private long last_section_address; private long flash_filename_address; private long decl_strings_address; @@ -152,7 +152,7 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface { } public long getSequenceStartAddress2() { - return sequence_start_address2; + return sequence_start_address3; } public long getNamesAddress() { @@ -163,10 +163,6 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface { return unk78_address; } - public long getUnk80Address() { - return unk80_address; - } - public long getLastSectionAddress() { return last_section_address; } @@ -185,28 +181,30 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface { @Override public void readFromDataStream(ReadDataStreamInterface stream) throws IOException { - /* 0:*/ off_start = stream.readUI64(); - base_address = off_start + stream.position() - 8; - /* 8:*/ off_seq_end = stream.readUI64(); - sequence_end_address = off_seq_end + stream.position() - 8; - /* 10:*/ off_font_end = stream.readUI64(); - font_end_address = off_font_end + stream.position() - 8; - /* 18:*/ off_seq_start1 = stream.readUI64(); //to 1 padd occurence (2 times) - sequence_start_address1 = off_seq_start1 + stream.position() - 8; - pad_to_match = stream.readUI64(); - if (pad_to_match != 1) { - throw new IOException("Wrong iggy file - no pad to match 1"); - } - off_seq_start2 = stream.readUI64(); - if (off_seq_start1 != off_seq_start2) { - throw new IOException("Wrong iggy font format (sequence_start)!\n"); - } - sequence_start_address2 = off_seq_start2 + stream.position() - 8; + off_base = stream.readUI64(); + base_address = off_base == 1 ? 0 : off_base + stream.position() - 8; + + off_sequence_end = stream.readUI64(); + sequence_end_address = off_sequence_end == 1 ? 0 : off_sequence_end + stream.position() - 8; + + off_font_end = stream.readUI64(); + font_end_address = off_font_end == 1 ? 0 : off_font_end + stream.position() - 8; + + off_sequence_start1 = stream.readUI64(); + sequence_start_address1 = off_sequence_start1 == 1 ? 0 : off_sequence_start1 + stream.position() - 8; + + off_sequence_start2 = stream.readUI64(); + sequence_start_address2 = off_sequence_start2 == 1 ? 0 : off_sequence_start2 + stream.position() - 8; + + off_sequence_start3 = stream.readUI64(); + sequence_start_address3 = off_sequence_start3 == 1 ? 0 : off_sequence_start3 + stream.position() - 8; + xmin = stream.readUI32(); ymin = stream.readUI32(); xmax = stream.readUI32(); ymax = stream.readUI32(); - unk_40 = stream.readUI32(); + + unk_40 = stream.readUI32(); // probably number of blocks/objects after header unk_44 = stream.readUI32(); unk_48 = stream.readUI32(); unk_4C = stream.readUI32(); @@ -222,19 +220,24 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface { unk_guid = stream.readUI64(); off_names = stream.readUI64(); - names_address = off_names + stream.position() - 8; + names_address = off_names == 1 ? 0 : off_names + stream.position() - 8; + off_unk78 = stream.readUI64(); - unk78_address = off_unk78 + stream.position() - 8; - off_unk80 = stream.readUI64(); - unk80_address = off_unk80 + stream.position() - 8; + unk78_address = off_unk78 == 1 ? 0 : off_unk78 + stream.position() - 8; + + unk80 = stream.readUI64(); //Maybe number of imports/names pointed by names_offset + off_last_section = stream.readUI64(); - last_section_address = off_last_section + stream.position() - 8; + last_section_address = off_last_section == 1 ? 0 : off_last_section + stream.position() - 8; + off_flash_filename = stream.readUI64(); - flash_filename_address = off_flash_filename + stream.position() - 8; - off_decl_strings = stream.readUI64(); - decl_strings_address = off_decl_strings + stream.position() - 8; - off_type_of_fonts = stream.readUI64(); - type_fonts_address = off_type_of_fonts + stream.position() - 8; + flash_filename_address = off_flash_filename == 1 ? 0 : off_flash_filename + stream.position() - 8; + + off_decl_strings = stream.readUI64(); //relative offset to as3 code (16 bytes header + abc blob) + decl_strings_address = off_decl_strings == 1 ? 0 : off_decl_strings + stream.position() - 8; + + off_type_of_fonts = stream.readUI64(); //relative offset to as3 file names table (or classes names or whatever) + type_fonts_address = off_type_of_fonts == 1 ? 0 : off_type_of_fonts + stream.position() - 8; flags = stream.readUI64(); font_count = stream.readUI32(); @@ -243,17 +246,18 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface { @Override public void writeToDataStream(WriteDataStreamInterface stream) throws IOException { - off_start = base_address - stream.position(); - stream.writeUI64(off_start); - off_seq_end = sequence_end_address - stream.position(); - stream.writeUI64(off_seq_end); - off_font_end = font_end_address - stream.position(); + off_base = base_address == 0 ? 1 : base_address - stream.position(); + stream.writeUI64(off_base); + off_sequence_end = sequence_end_address == 0 ? 1 : sequence_end_address - stream.position(); + stream.writeUI64(off_sequence_end); + off_font_end = font_end_address == 0 ? 1 : font_end_address - stream.position(); stream.writeUI64(off_font_end); - off_seq_start1 = sequence_start_address1 - stream.position(); - stream.writeUI64(off_seq_start1); - stream.writeUI64(pad_to_match); - off_seq_start2 = sequence_start_address2 - stream.position(); - stream.writeUI64(off_seq_start2); + off_sequence_start1 = sequence_start_address1 == 0 ? 1 : sequence_start_address1 - stream.position(); + stream.writeUI64(off_sequence_start1); + off_sequence_start2 = sequence_start_address2 == 0 ? 1 : sequence_start_address2 - stream.position(); + stream.writeUI64(off_sequence_start2); + off_sequence_start3 = sequence_start_address3 == 0 ? 1 : sequence_start_address3 - stream.position(); + stream.writeUI64(off_sequence_start3); stream.writeUI32(xmin); stream.writeUI32(ymin); stream.writeUI32(xmax); @@ -269,19 +273,18 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface { stream.writeUI32(additional_import1); stream.writeUI32(zero1); stream.writeUI64(unk_guid); - off_names = names_address - stream.position(); + off_names = names_address == 0 ? 1 : names_address - stream.position(); stream.writeUI64(off_names); - off_unk78 = unk78_address - stream.position(); + off_unk78 = unk78_address == 0 ? 1 : unk78_address - stream.position(); stream.writeUI64(off_unk78); - off_unk80 = unk80_address - stream.position(); - stream.writeUI64(off_unk80); - off_last_section = last_section_address - stream.position(); + stream.writeUI64(unk80); + off_last_section = last_section_address == 0 ? 1 : last_section_address - stream.position(); stream.writeUI64(off_last_section); - off_flash_filename = flash_filename_address - stream.position(); + off_flash_filename = flash_filename_address == 0 ? 1 : flash_filename_address - stream.position(); stream.writeUI64(off_flash_filename); - off_decl_strings = decl_strings_address - stream.position(); + off_decl_strings = decl_strings_address == 0 ? 1 : decl_strings_address - stream.position(); stream.writeUI64(off_decl_strings); - off_type_of_fonts = type_fonts_address - stream.position(); + off_type_of_fonts = type_fonts_address == 0 ? 1 : type_fonts_address - stream.position(); stream.writeUI64(off_type_of_fonts); stream.writeUI64(flags); stream.writeUI32(font_count); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java index a8596d460..920f578d6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java @@ -44,6 +44,7 @@ public class IggySwf implements StructureInterface { private byte font_add_data[]; private List font_add_off = new ArrayList<>(); private List font_add_size = new ArrayList<>(); + private FontBinInfo font_bin_info[]; public IggyFlashHeader64 getHdr() { return hdr; @@ -171,11 +172,16 @@ public class IggySwf implements StructureInterface { font_add_data = s.readBytes((int) (long) font_add_size.get(0)); } s.seek(hdr.getFontEndAddress(), SeekMode.SET); + font_bin_info = new FontBinInfo[(int) hdr.font_count]; + for (int i = 0; i < hdr.font_count; i++) { + font_bin_info[i] = new FontBinInfo(s); + } + s.seek(hdr.getSequenceStartAddress1(), SeekMode.SET); - WriteDataStreamInterface outs = new TemporaryDataStream(); + //TODO: sequence,typeoffonts,declstrings,binarydata + /*WriteDataStreamInterface outs = new TemporaryDataStream(); writeToDataStream(outs); - Helper.writeFile("d:\\Dropbox\\jpexs-laptop\\iggi\\parts\\swf_out.bin", outs.getAllBytes()); - + Helper.writeFile("d:\\Dropbox\\jpexs-laptop\\iggi\\parts\\swf_out.bin", outs.getAllBytes());*/ } public String getName() { @@ -225,6 +231,11 @@ public class IggySwf implements StructureInterface { s.seek(font_add_off.get(0), SeekMode.SET); s.writeBytes(font_add_data); } + s.seek(hdr.getFontEndAddress(), SeekMode.SET); + for (int i = 0; i < hdr.font_count; i++) { + font_bin_info[i].writeToDataStream(s); + } + //TODO: sequence,typeoffonts,declstrings,binarydata } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/AbstractDataStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/AbstractDataStream.java index fd22b1c73..88f057208 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/AbstractDataStream.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/AbstractDataStream.java @@ -22,11 +22,17 @@ public abstract class AbstractDataStream implements DataStreamInterface { @Override public long readUI64() throws IOException { - try { - return (readUI32() + (readUI32() << 32)) & 0xffffffffffffffffL; - } catch (EOFException ex) { - return -1; - } + long lsb = readUI32(); + long msb = readUI32(); + long result = msb << 32 | lsb; + return result & 0xffffffffffffffffL; + } + + @Override + public long readSI64() throws IOException { + long lsb = readUI32(); + long msb = readUI32(); + return msb << 32 | lsb; } @Override @@ -43,10 +49,24 @@ public abstract class AbstractDataStream implements DataStreamInterface { return true; } + @Override + public boolean writeSI64(long val) throws IOException { + write((int) (val & 0xff)); + write((int) ((val >> 8) & 0xff)); + write((int) ((val >> 16) & 0xff)); + write((int) ((val >> 24) & 0xff)); + + write((int) ((val >> 32) & 0xff)); + write((int) ((val >> 40) & 0xff)); + write((int) ((val >> 48) & 0xff)); + write((int) ((val >> 56) & 0xff)); + return true; + } + @Override public long readUI32() throws IOException { try { - return (readUI8() + (readUI8() << 8) + (readUI8() << 16) + (readUI8() << 24)); + return (readUI8() | (readUI8() << 8) | (readUI8() << 16) | (readUI8() << 24)); } catch (EOFException ex) { return -1; } @@ -64,7 +84,7 @@ public abstract class AbstractDataStream implements DataStreamInterface { @Override public int readUI16() throws IOException { try { - return (readUI8() + (readUI8() << 8)) & 0xffff; + return (readUI8() | (readUI8() << 8)) & 0xffff; } catch (EOFException ex) { return -1; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/ReadDataStreamInterface.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/ReadDataStreamInterface.java index 7bd57a76c..1364ce5da 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/ReadDataStreamInterface.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/ReadDataStreamInterface.java @@ -21,6 +21,8 @@ public interface ReadDataStreamInterface extends AutoCloseable { public long readUI64() throws IOException; + public long readSI64() throws IOException; + public long readUI32() throws IOException; public int readUI16() throws IOException; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/WriteDataStreamInterface.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/WriteDataStreamInterface.java index 1e087fd1b..01d48d282 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/WriteDataStreamInterface.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/WriteDataStreamInterface.java @@ -21,6 +21,8 @@ public interface WriteDataStreamInterface extends AutoCloseable { public boolean writeUI64(long val) throws IOException; + public boolean writeSI64(long val) throws IOException; + public boolean writeUI32(long val) throws IOException; public boolean writeUI16(int val) throws IOException;