signed 64 bit read/write, font bin info read/save

This commit is contained in:
Jindra Petřík
2016-11-30 18:49:32 +01:00
parent 48177bb534
commit 94d12bfe4c
7 changed files with 196 additions and 77 deletions

View File

@@ -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
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -44,6 +44,7 @@ public class IggySwf implements StructureInterface {
private byte font_add_data[];
private List<Long> font_add_off = new ArrayList<>();
private List<Long> 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

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;