streams refactoring - separate package

This commit is contained in:
Jindra Petřík
2016-11-27 09:12:22 +01:00
parent d71416ea8e
commit d2bdf8eb94
26 changed files with 1895 additions and 1713 deletions

View File

@@ -1,5 +1,7 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

View File

@@ -1,5 +1,7 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.ArrayList;

View File

@@ -1,5 +1,7 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

View File

@@ -1,5 +1,7 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.logging.Logger;

View File

@@ -1,89 +1,92 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @author JPEXS
*/
public class IggyDataReader implements StructureInterface {
final static int NO_OFFSET = 1;
@IggyFieldType(value = DataType.widechar_t, count = 48)
String name;
Map<Integer, IggyFont> fonts;
Map<Integer, IggyText> texts;
Map<Integer, Integer> text2Font;
private IggyFlashHeader64 header;
private Map<Long, Long> sizesOfOffsets;
private List<Long> allOffsets;
public IggyDataReader(IggyFlashHeader64 header, AbstractDataStream stream, List<Long> offsets) throws IOException {
this.header = header;
sizesOfOffsets = new HashMap<>();
for (int i = 0; i < offsets.size() - 1; i++) {
sizesOfOffsets.put(offsets.get(i), offsets.get(i + 1) - offsets.get(i));
}
sizesOfOffsets.put(offsets.get(offsets.size() - 1), 0L); //Last offset has 0L length?
this.allOffsets = offsets;
readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
//here is offset[0]
StringBuilder nameBuilder = new StringBuilder();
do {
char c = (char) stream.readUI16();
if (c == '\0') {
break;
}
nameBuilder.append(c);
} while (true);
name = nameBuilder.toString();
//here is offset[1]
int pad8 = 8 - (int) (stream.position() % 8);
stream.seek(pad8, SeekMode.CUR);
//here is offset [2]
fonts = new HashMap<>();
int fontIndex = 0;
for (int i = 2; i < allOffsets.size(); i++) {
long offset = allOffsets.get(i);
stream.seek(offset, SeekMode.SET);
int type = stream.readUI16();
stream.seek(-2, SeekMode.CUR);
if (type == IggyFont.ID) {
IggyFont font = new IggyFont(stream);
fonts.put(fontIndex++, font);
}
if (type == IggyText.ID) {
//TODO: Texts - incomplete
}
}
}
public String getName() {
return name;
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[\r\n");
sb.append("name ").append(name).append("\r\n");
return sb.toString();
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @author JPEXS
*/
public class IggyDataReader implements StructureInterface {
final static int NO_OFFSET = 1;
@IggyFieldType(value = DataType.widechar_t, count = 48)
String name;
Map<Integer, IggyFont> fonts;
Map<Integer, IggyText> texts;
Map<Integer, Integer> text2Font;
private IggyFlashHeader64 header;
private Map<Long, Long> sizesOfOffsets;
private List<Long> allOffsets;
public IggyDataReader(IggyFlashHeader64 header, AbstractDataStream stream, List<Long> offsets) throws IOException {
this.header = header;
sizesOfOffsets = new HashMap<>();
for (int i = 0; i < offsets.size() - 1; i++) {
sizesOfOffsets.put(offsets.get(i), offsets.get(i + 1) - offsets.get(i));
}
sizesOfOffsets.put(offsets.get(offsets.size() - 1), 0L); //Last offset has 0L length?
this.allOffsets = offsets;
readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
//here is offset[0]
StringBuilder nameBuilder = new StringBuilder();
do {
char c = (char) stream.readUI16();
if (c == '\0') {
break;
}
nameBuilder.append(c);
} while (true);
name = nameBuilder.toString();
//here is offset[1]
int pad8 = 8 - (int) (stream.position() % 8);
stream.seek(pad8, SeekMode.CUR);
//here is offset [2]
fonts = new HashMap<>();
int fontIndex = 0;
for (int i = 2; i < allOffsets.size(); i++) {
long offset = allOffsets.get(i);
stream.seek(offset, SeekMode.SET);
int type = stream.readUI16();
stream.seek(-2, SeekMode.CUR);
if (type == IggyFont.ID) {
IggyFont font = new IggyFont(stream);
fonts.put(fontIndex++, font);
}
if (type == IggyText.ID) {
//TODO: Texts - incomplete
}
}
}
public String getName() {
return name;
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[\r\n");
sb.append("name ").append(name).append("\r\n");
return sb.toString();
}
}

View File

@@ -1,195 +1,196 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
/**
*
* @author JPEXS
*
* Based of works of somebody called eternity.
*
* All relative offsets are relative from that specific field position All
* relative offsets can get value "1" to indicate "nothing"
*/
public class IggyFlashHeader32 implements IggyFlashHeaderInterface {
@IggyFieldType(DataType.uint32_t)
long main_offset; // 0 Relative offset to first section (matches sizeof header)
@IggyFieldType(DataType.uint32_t)
long as3_section_offset; // 4 Relative offset to as3 file names table...
@IggyFieldType(DataType.uint32_t)
long unk_offset; // 8 relative offset to something
@IggyFieldType(DataType.uint32_t)
long unk_offset2; // 0xC relative offset to something
@IggyFieldType(DataType.uint32_t)
long unk_offset3; // 0x10 relative offset to something
@IggyFieldType(DataType.uint32_t)
long unk_offset4; // 0x14 relative offset to something
@IggyFieldType(DataType.uint32_t)
long xmin; //0x18 in pixels
@IggyFieldType(DataType.uint32_t)
long ymin; //0x0C in pixels
@IggyFieldType(DataType.uint32_t)
long xmax; // 0x20 in pixels
@IggyFieldType(DataType.uint32_t)
long ymax; // 0x24 in pixels
@IggyFieldType(DataType.uint32_t)
long unk_28; // probably number of blocks/objects after header
@IggyFieldType(DataType.uint32_t)
long unk_2C;
@IggyFieldType(DataType.uint32_t)
long unk_30;
@IggyFieldType(DataType.uint32_t)
long unk_34;
@IggyFieldType(DataType.uint32_t)
long unk_38;
@IggyFieldType(DataType.uint32_t)
long unk_3C;
@IggyFieldType(DataType.float_t)
float frameRate;
@IggyFieldType(DataType.uint32_t)
long unk_44;
@IggyFieldType(DataType.uint32_t)
long unk_48;
@IggyFieldType(DataType.uint32_t)
long unk_4C;
@IggyFieldType(DataType.uint32_t)
long names_offset; // 0x50 relative offset to the names/import section of the file
@IggyFieldType(DataType.uint32_t)
long unk_offset5; // 0x54 relative offset to something
@IggyFieldType(DataType.uint64_t)
long unk_58; // Maybe number of imports/names pointed by names_offset
@IggyFieldType(DataType.uint32_t)
long last_section_offset; // 0x60 relative offset, points to the small last section of the file
@IggyFieldType(DataType.uint32_t)
long unk_offset6; // 0x64 relative offset to something
@IggyFieldType(DataType.uint32_t)
long as3_code_offset; // 0x68 relative offset to as3 code (8 bytes header + abc blob)
@IggyFieldType(DataType.uint32_t)
long as3_names_offset; // 0x6C relative offset to as3 file names table (or classes names or whatever)
@IggyFieldType(DataType.uint32_t)
long unk_70;
@IggyFieldType(DataType.uint32_t)
long unk_74;
@IggyFieldType(DataType.uint32_t)
long unk_78; // Maybe number of classes / as3 names
@IggyFieldType(DataType.uint32_t)
long unk_7C;
// Offset 0x80 (outside header): there are *unk_28* relative offsets that point to flash objects.
// The flash objects are in a format different to swf but there is probably a way to convert between them.
// After the offsets, the bodies of objects pointed above, which apparently have a code like 0xFFXX to identify the type of object, followed by a (unique?) identifier
// for the object.
// A DefineEditText-like object can be easily spotted and apparently uses type code 0x06 (or 0xFF06) but as stated above,
// it is written in a different way.
public IggyFlashHeader32(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
main_offset = stream.readUI32();
as3_section_offset = stream.readUI32();
unk_offset = stream.readUI32();
unk_offset2 = stream.readUI32();
unk_offset3 = stream.readUI32();
unk_offset4 = stream.readUI32();
xmin = stream.readUI32();
ymin = stream.readUI32();
xmax = stream.readUI32();
ymax = stream.readUI32();
unk_28 = stream.readUI32();
unk_2C = stream.readUI32();
unk_30 = stream.readUI32();
unk_34 = stream.readUI32();
unk_38 = stream.readUI32();
unk_3C = stream.readUI32();
frameRate = stream.readFloat();
unk_44 = stream.readUI32();
unk_48 = stream.readUI32();
unk_4C = stream.readUI32();
unk_3C = stream.readUI32();
names_offset = stream.readUI32();
unk_offset5 = stream.readUI32();
unk_58 = stream.readUI64();
last_section_offset = stream.readUI32();
unk_offset6 = stream.readUI32();
as3_code_offset = stream.readUI32();
as3_names_offset = stream.readUI32();
unk_70 = stream.readUI32();
unk_74 = stream.readUI32();
unk_78 = stream.readUI32();
unk_7C = stream.readUI32();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[\r\n");
sb.append("main_offset ").append(main_offset).append("\r\n");
sb.append("as3_section_offset ").append(as3_section_offset).append("\r\n");
sb.append("unk_offset ").append(unk_offset).append("\r\n");
sb.append("unk_offset2 ").append(unk_offset2).append("\r\n");
sb.append("unk_offset3 ").append(unk_offset3).append("\r\n");
sb.append("unk_offset4 ").append(unk_offset4).append("\r\n");
sb.append("xmin ").append(xmin).append("\r\n");
sb.append("ymin ").append(ymin).append("\r\n");
sb.append("xmax ").append(xmax).append("\r\n");
sb.append("ymax ").append(ymax).append("\r\n");
sb.append("unk_28 ").append(unk_28).append("\r\n");
sb.append("unk_2C ").append(unk_2C).append("\r\n");
sb.append("unk_30 ").append(unk_30).append("\r\n");
sb.append("unk_34 ").append(unk_34).append("\r\n");
sb.append("unk_38 ").append(unk_38).append("\r\n");
sb.append("unk_3C ").append(unk_3C).append("\r\n");
sb.append("frameRate ").append(frameRate).append("\r\n");
sb.append("unk_44 ").append(unk_44).append("\r\n");
sb.append("unk_48 ").append(unk_48).append("\r\n");
sb.append("unk_4C ").append(unk_4C).append("\r\n");
sb.append("names_offset ").append(names_offset).append("\r\n");
sb.append("unk_offset5 ").append(unk_offset5).append("\r\n");
sb.append("unk_58 ").append(unk_58).append("\r\n");
sb.append("last_section_offset ").append(last_section_offset).append("\r\n");
sb.append("unk_offset6 ").append(unk_offset6).append("\r\n");
sb.append("as3_code_offset ").append(as3_code_offset).append("\r\n");
sb.append("as3_names_offset ").append(as3_names_offset).append("\r\n");
sb.append("unk_70 ").append(unk_70).append("\r\n");
sb.append("unk_74 ").append(unk_74).append("\r\n");
sb.append("unk_78 ").append(unk_78).append("\r\n");
sb.append("unk_7C ").append(unk_7C).append("\r\n");
sb.append("]");
return sb.toString();
}
@Override
public long getXMin() {
return xmin;
}
@Override
public long getYMin() {
return ymin;
}
@Override
public long getXMax() {
return xmax;
}
@Override
public long getYMax() {
return ymax;
}
@Override
public float getFrameRate() {
return frameRate;
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
/**
*
* @author JPEXS
*
* Based of works of somebody called eternity.
*
* All relative offsets are relative from that specific field position All
* relative offsets can get value "1" to indicate "nothing"
*/
public class IggyFlashHeader32 implements IggyFlashHeaderInterface {
@IggyFieldType(DataType.uint32_t)
long main_offset; // 0 Relative offset to first section (matches sizeof header)
@IggyFieldType(DataType.uint32_t)
long as3_section_offset; // 4 Relative offset to as3 file names table...
@IggyFieldType(DataType.uint32_t)
long unk_offset; // 8 relative offset to something
@IggyFieldType(DataType.uint32_t)
long unk_offset2; // 0xC relative offset to something
@IggyFieldType(DataType.uint32_t)
long unk_offset3; // 0x10 relative offset to something
@IggyFieldType(DataType.uint32_t)
long unk_offset4; // 0x14 relative offset to something
@IggyFieldType(DataType.uint32_t)
long xmin; //0x18 in pixels
@IggyFieldType(DataType.uint32_t)
long ymin; //0x0C in pixels
@IggyFieldType(DataType.uint32_t)
long xmax; // 0x20 in pixels
@IggyFieldType(DataType.uint32_t)
long ymax; // 0x24 in pixels
@IggyFieldType(DataType.uint32_t)
long unk_28; // probably number of blocks/objects after header
@IggyFieldType(DataType.uint32_t)
long unk_2C;
@IggyFieldType(DataType.uint32_t)
long unk_30;
@IggyFieldType(DataType.uint32_t)
long unk_34;
@IggyFieldType(DataType.uint32_t)
long unk_38;
@IggyFieldType(DataType.uint32_t)
long unk_3C;
@IggyFieldType(DataType.float_t)
float frameRate;
@IggyFieldType(DataType.uint32_t)
long unk_44;
@IggyFieldType(DataType.uint32_t)
long unk_48;
@IggyFieldType(DataType.uint32_t)
long unk_4C;
@IggyFieldType(DataType.uint32_t)
long names_offset; // 0x50 relative offset to the names/import section of the file
@IggyFieldType(DataType.uint32_t)
long unk_offset5; // 0x54 relative offset to something
@IggyFieldType(DataType.uint64_t)
long unk_58; // Maybe number of imports/names pointed by names_offset
@IggyFieldType(DataType.uint32_t)
long last_section_offset; // 0x60 relative offset, points to the small last section of the file
@IggyFieldType(DataType.uint32_t)
long unk_offset6; // 0x64 relative offset to something
@IggyFieldType(DataType.uint32_t)
long as3_code_offset; // 0x68 relative offset to as3 code (8 bytes header + abc blob)
@IggyFieldType(DataType.uint32_t)
long as3_names_offset; // 0x6C relative offset to as3 file names table (or classes names or whatever)
@IggyFieldType(DataType.uint32_t)
long unk_70;
@IggyFieldType(DataType.uint32_t)
long unk_74;
@IggyFieldType(DataType.uint32_t)
long unk_78; // Maybe number of classes / as3 names
@IggyFieldType(DataType.uint32_t)
long unk_7C;
// Offset 0x80 (outside header): there are *unk_28* relative offsets that point to flash objects.
// The flash objects are in a format different to swf but there is probably a way to convert between them.
// After the offsets, the bodies of objects pointed above, which apparently have a code like 0xFFXX to identify the type of object, followed by a (unique?) identifier
// for the object.
// A DefineEditText-like object can be easily spotted and apparently uses type code 0x06 (or 0xFF06) but as stated above,
// it is written in a different way.
public IggyFlashHeader32(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
main_offset = stream.readUI32();
as3_section_offset = stream.readUI32();
unk_offset = stream.readUI32();
unk_offset2 = stream.readUI32();
unk_offset3 = stream.readUI32();
unk_offset4 = stream.readUI32();
xmin = stream.readUI32();
ymin = stream.readUI32();
xmax = stream.readUI32();
ymax = stream.readUI32();
unk_28 = stream.readUI32();
unk_2C = stream.readUI32();
unk_30 = stream.readUI32();
unk_34 = stream.readUI32();
unk_38 = stream.readUI32();
unk_3C = stream.readUI32();
frameRate = stream.readFloat();
unk_44 = stream.readUI32();
unk_48 = stream.readUI32();
unk_4C = stream.readUI32();
unk_3C = stream.readUI32();
names_offset = stream.readUI32();
unk_offset5 = stream.readUI32();
unk_58 = stream.readUI64();
last_section_offset = stream.readUI32();
unk_offset6 = stream.readUI32();
as3_code_offset = stream.readUI32();
as3_names_offset = stream.readUI32();
unk_70 = stream.readUI32();
unk_74 = stream.readUI32();
unk_78 = stream.readUI32();
unk_7C = stream.readUI32();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[\r\n");
sb.append("main_offset ").append(main_offset).append("\r\n");
sb.append("as3_section_offset ").append(as3_section_offset).append("\r\n");
sb.append("unk_offset ").append(unk_offset).append("\r\n");
sb.append("unk_offset2 ").append(unk_offset2).append("\r\n");
sb.append("unk_offset3 ").append(unk_offset3).append("\r\n");
sb.append("unk_offset4 ").append(unk_offset4).append("\r\n");
sb.append("xmin ").append(xmin).append("\r\n");
sb.append("ymin ").append(ymin).append("\r\n");
sb.append("xmax ").append(xmax).append("\r\n");
sb.append("ymax ").append(ymax).append("\r\n");
sb.append("unk_28 ").append(unk_28).append("\r\n");
sb.append("unk_2C ").append(unk_2C).append("\r\n");
sb.append("unk_30 ").append(unk_30).append("\r\n");
sb.append("unk_34 ").append(unk_34).append("\r\n");
sb.append("unk_38 ").append(unk_38).append("\r\n");
sb.append("unk_3C ").append(unk_3C).append("\r\n");
sb.append("frameRate ").append(frameRate).append("\r\n");
sb.append("unk_44 ").append(unk_44).append("\r\n");
sb.append("unk_48 ").append(unk_48).append("\r\n");
sb.append("unk_4C ").append(unk_4C).append("\r\n");
sb.append("names_offset ").append(names_offset).append("\r\n");
sb.append("unk_offset5 ").append(unk_offset5).append("\r\n");
sb.append("unk_58 ").append(unk_58).append("\r\n");
sb.append("last_section_offset ").append(last_section_offset).append("\r\n");
sb.append("unk_offset6 ").append(unk_offset6).append("\r\n");
sb.append("as3_code_offset ").append(as3_code_offset).append("\r\n");
sb.append("as3_names_offset ").append(as3_names_offset).append("\r\n");
sb.append("unk_70 ").append(unk_70).append("\r\n");
sb.append("unk_74 ").append(unk_74).append("\r\n");
sb.append("unk_78 ").append(unk_78).append("\r\n");
sb.append("unk_7C ").append(unk_7C).append("\r\n");
sb.append("]");
return sb.toString();
}
@Override
public long getXMin() {
return xmin;
}
@Override
public long getYMin() {
return ymin;
}
@Override
public long getXMax() {
return xmax;
}
@Override
public long getYMax() {
return ymax;
}
@Override
public float getFrameRate() {
return frameRate;
}
}

View File

@@ -1,211 +1,212 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
/**
*
* @author Jindra
*
* Based of works of somebody called eternity.
*/
public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
@IggyFieldType(DataType.uint64_t)
long main_offset; // 0 Relative offset to first section (matches sizeof header);
@IggyFieldType(DataType.uint64_t)
long as3_section_offset; // 8 Relative offset to as3 file names table...
@IggyFieldType(DataType.uint64_t)
long unk_offset; // 0x10 relative offset to something
@IggyFieldType(DataType.uint64_t)
long unk_offset2; // 0x18 relative offset to something
@IggyFieldType(DataType.uint64_t)
long unk_offset3; // 0x20 relative offset to something
@IggyFieldType(DataType.uint64_t)
long unk_offset4; // 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)
long ymin; // 0x34 in pixels
@IggyFieldType(DataType.uint32_t)
long xmax; // 0x38 in pixels
@IggyFieldType(DataType.uint32_t)
long ymax; // 0x3C in pixels
@IggyFieldType(DataType.uint32_t)
long unk_40; // probably numer of blocks/objects after header
@IggyFieldType(DataType.uint32_t)
long unk_44;
@IggyFieldType(DataType.uint32_t)
long unk_48;
@IggyFieldType(DataType.uint32_t)
long unk_4C;
@IggyFieldType(DataType.uint32_t)
long unk_50;
@IggyFieldType(DataType.uint32_t)
long unk_54;
@IggyFieldType(DataType.float_t)
float frame_rate;
@IggyFieldType(DataType.uint32_t)
long unk_5C;
@IggyFieldType(DataType.uint64_t)
long fonts_offset;
@IggyFieldType(DataType.uint64_t)
long unk_68;
@IggyFieldType(DataType.uint64_t)
long names_offset; // 0x70 relative offset to the names/import section of the file - end of fonts
@IggyFieldType(DataType.uint64_t)
long unk_offset5; // 0x78 relative offset to something
@IggyFieldType(DataType.uint64_t)
long unk_80; // Maybe number of imports/names pointed by names_offset
@IggyFieldType(DataType.uint64_t)
long last_section_offset; // 0x88 relative offset, points to the small last section of the file
@IggyFieldType(DataType.uint64_t)
long unk_offset6; // 0x90 relative offset to something
@IggyFieldType(DataType.uint64_t)
long as3_code_offset; // 0x98 relative offset to as3 code (16 bytes header + abc blob)
@IggyFieldType(DataType.uint64_t)
long as3_names_offset; // 0xA0 relative offset to as3 file names table (or classes names or whatever)
@IggyFieldType(DataType.uint32_t)
long unk_A8;
@IggyFieldType(DataType.uint32_t) //font_main_off
long unk_AC; //font_main_size
@IggyFieldType(DataType.uint32_t) //font_info_off
long font_count; // Maybe number of classes / as3 names //font_info_size
@IggyFieldType(DataType.uint32_t)
long unk_B4; //zero (?)
// Offset 0xB8 (outside header): there are *unk_40* relative offsets that point to flash objects.
// The flash objects are in a format different to swf but there is probably a way to convert between them.
// After the offsets, the bodies of objects pointed above, which apparently have a code like 0xFFXX to identify the type of object, followed by a (unique?) identifier
// for the object.
// A DefineEditText-like object can be easily spotted and apparently uses type code 0x06 (or 0xFF06) but as stated above,
// it is written in a different way.
public IggyFlashHeader64(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
main_offset = stream.readUI64();
as3_section_offset = stream.readUI64();
unk_offset = stream.readUI64();
unk_offset2 = stream.readUI64();
unk_offset3 = stream.readUI64();
unk_offset4 = stream.readUI64();
xmin = stream.readUI32();
ymin = stream.readUI32();
xmax = stream.readUI32();
ymax = stream.readUI32();
unk_40 = stream.readUI32();
unk_44 = stream.readUI32();
unk_48 = stream.readUI32();
unk_4C = stream.readUI32();
unk_50 = stream.readUI32();
unk_54 = stream.readUI32();
frame_rate = stream.readFloat();
unk_5C = stream.readUI32();
fonts_offset = stream.readUI64();
unk_68 = stream.readUI64();
names_offset = stream.readUI64();
unk_offset5 = stream.readUI64();
unk_80 = stream.readUI64();
last_section_offset = stream.readUI64();
unk_offset6 = stream.readUI64();
as3_code_offset = stream.readUI64();
as3_names_offset = stream.readUI64();
unk_A8 = stream.readUI32();
unk_AC = stream.readUI32();
font_count = stream.readUI32();
unk_B4 = stream.readUI32();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[\r\n");
sb.append("main_offset ").append(main_offset).append("\r\n");
sb.append("as3_section_offset ").append(as3_section_offset);
sb.append(" global: ").append(main_offset + as3_section_offset);
sb.append("\r\n");
sb.append("unk_offset ").append(unk_offset);
if (unk_offset != 1) {
sb.append(" global: ").append(main_offset + unk_offset);
}
sb.append("\r\n");
sb.append("unk_offset2 ").append(unk_offset2);
if (unk_offset2 != 1) {
sb.append(" global: ").append(main_offset + unk_offset2);
}
sb.append("\r\n");
sb.append("unk_offset3 ").append(unk_offset3);
if (unk_offset3 != 1) {
sb.append(" global: ").append(main_offset + unk_offset3);
}
sb.append("\r\n");
sb.append("unk_offset4 ").append(unk_offset4);
if (unk_offset4 != 1) {
sb.append(" global: ").append(main_offset + unk_offset4);
}
sb.append("\r\n");
sb.append("xmin ").append(xmin).append("\r\n");
sb.append("ymin ").append(ymin).append("\r\n");
sb.append("xmax ").append(ymax).append("\r\n");
sb.append("ymax ").append(ymax).append("\r\n");
sb.append("unk_40 ").append(unk_40).append("\r\n");
sb.append("unk_44 ").append(unk_44).append("\r\n");
sb.append("unk_48 ").append(unk_48).append("\r\n");
sb.append("unk_4C ").append(unk_4C).append("\r\n");
sb.append("unk_50 ").append(unk_50).append("\r\n");
sb.append("unk_54 ").append(unk_54).append("\r\n");
sb.append("frame_rate ").append(frame_rate).append("\r\n");
sb.append("unk_5C ").append(unk_5C).append("\r\n");
sb.append("fonts_offset ").append(fonts_offset).append("\r\n");
sb.append("unk_68 ").append(unk_68).append("\r\n");
sb.append("names_offset ").append(names_offset).append("\r\n");
sb.append("unk_offset5 ").append(unk_offset5).append("\r\n");
sb.append("unk_80 ").append(unk_80).append("\r\n");
sb.append("last_section_offset ").append(last_section_offset).append("\r\n");
sb.append("unk_offset6 ").append(unk_offset6).append("\r\n");
sb.append("as3_code_offset ").append(as3_code_offset).append("\r\n");
sb.append("as3_names_offset ").append(as3_names_offset).append("\r\n");
sb.append("unk_A8 ").append(unk_A8).append("\r\n");
sb.append("unk_AC ").append(unk_AC).append("\r\n");
sb.append("font_count ").append(font_count).append("\r\n");
sb.append("unk_B4 ").append(unk_B4).append("\r\n");
sb.append("]");
return sb.toString();
}
@Override
public long getXMin() {
return xmin;
}
@Override
public long getYMin() {
return ymin;
}
@Override
public long getXMax() {
return xmax;
}
@Override
public long getYMax() {
return ymax;
}
@Override
public float getFrameRate() {
return frame_rate;
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
/**
*
* @author Jindra
*
* Based of works of somebody called eternity.
*/
public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
@IggyFieldType(DataType.uint64_t)
long main_offset; // 0 Relative offset to first section (matches sizeof header);
@IggyFieldType(DataType.uint64_t)
long as3_section_offset; // 8 Relative offset to as3 file names table...
@IggyFieldType(DataType.uint64_t)
long unk_offset; // 0x10 relative offset to something
@IggyFieldType(DataType.uint64_t)
long unk_offset2; // 0x18 relative offset to something
@IggyFieldType(DataType.uint64_t)
long unk_offset3; // 0x20 relative offset to something
@IggyFieldType(DataType.uint64_t)
long unk_offset4; // 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)
long ymin; // 0x34 in pixels
@IggyFieldType(DataType.uint32_t)
long xmax; // 0x38 in pixels
@IggyFieldType(DataType.uint32_t)
long ymax; // 0x3C in pixels
@IggyFieldType(DataType.uint32_t)
long unk_40; // probably numer of blocks/objects after header
@IggyFieldType(DataType.uint32_t)
long unk_44;
@IggyFieldType(DataType.uint32_t)
long unk_48;
@IggyFieldType(DataType.uint32_t)
long unk_4C;
@IggyFieldType(DataType.uint32_t)
long unk_50;
@IggyFieldType(DataType.uint32_t)
long unk_54;
@IggyFieldType(DataType.float_t)
float frame_rate;
@IggyFieldType(DataType.uint32_t)
long unk_5C;
@IggyFieldType(DataType.uint64_t)
long fonts_offset;
@IggyFieldType(DataType.uint64_t)
long unk_68;
@IggyFieldType(DataType.uint64_t)
long names_offset; // 0x70 relative offset to the names/import section of the file - end of fonts
@IggyFieldType(DataType.uint64_t)
long unk_offset5; // 0x78 relative offset to something
@IggyFieldType(DataType.uint64_t)
long unk_80; // Maybe number of imports/names pointed by names_offset
@IggyFieldType(DataType.uint64_t)
long last_section_offset; // 0x88 relative offset, points to the small last section of the file
@IggyFieldType(DataType.uint64_t)
long unk_offset6; // 0x90 relative offset to something
@IggyFieldType(DataType.uint64_t)
long as3_code_offset; // 0x98 relative offset to as3 code (16 bytes header + abc blob)
@IggyFieldType(DataType.uint64_t)
long as3_names_offset; // 0xA0 relative offset to as3 file names table (or classes names or whatever)
@IggyFieldType(DataType.uint32_t)
long unk_A8;
@IggyFieldType(DataType.uint32_t) //font_main_off
long unk_AC; //font_main_size
@IggyFieldType(DataType.uint32_t) //font_info_off
long font_count; // Maybe number of classes / as3 names //font_info_size
@IggyFieldType(DataType.uint32_t)
long unk_B4; //zero (?)
// Offset 0xB8 (outside header): there are *unk_40* relative offsets that point to flash objects.
// The flash objects are in a format different to swf but there is probably a way to convert between them.
// After the offsets, the bodies of objects pointed above, which apparently have a code like 0xFFXX to identify the type of object, followed by a (unique?) identifier
// for the object.
// A DefineEditText-like object can be easily spotted and apparently uses type code 0x06 (or 0xFF06) but as stated above,
// it is written in a different way.
public IggyFlashHeader64(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
main_offset = stream.readUI64();
as3_section_offset = stream.readUI64();
unk_offset = stream.readUI64();
unk_offset2 = stream.readUI64();
unk_offset3 = stream.readUI64();
unk_offset4 = stream.readUI64();
xmin = stream.readUI32();
ymin = stream.readUI32();
xmax = stream.readUI32();
ymax = stream.readUI32();
unk_40 = stream.readUI32();
unk_44 = stream.readUI32();
unk_48 = stream.readUI32();
unk_4C = stream.readUI32();
unk_50 = stream.readUI32();
unk_54 = stream.readUI32();
frame_rate = stream.readFloat();
unk_5C = stream.readUI32();
fonts_offset = stream.readUI64();
unk_68 = stream.readUI64();
names_offset = stream.readUI64();
unk_offset5 = stream.readUI64();
unk_80 = stream.readUI64();
last_section_offset = stream.readUI64();
unk_offset6 = stream.readUI64();
as3_code_offset = stream.readUI64();
as3_names_offset = stream.readUI64();
unk_A8 = stream.readUI32();
unk_AC = stream.readUI32();
font_count = stream.readUI32();
unk_B4 = stream.readUI32();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[\r\n");
sb.append("main_offset ").append(main_offset).append("\r\n");
sb.append("as3_section_offset ").append(as3_section_offset);
sb.append(" global: ").append(main_offset + as3_section_offset);
sb.append("\r\n");
sb.append("unk_offset ").append(unk_offset);
if (unk_offset != 1) {
sb.append(" global: ").append(main_offset + unk_offset);
}
sb.append("\r\n");
sb.append("unk_offset2 ").append(unk_offset2);
if (unk_offset2 != 1) {
sb.append(" global: ").append(main_offset + unk_offset2);
}
sb.append("\r\n");
sb.append("unk_offset3 ").append(unk_offset3);
if (unk_offset3 != 1) {
sb.append(" global: ").append(main_offset + unk_offset3);
}
sb.append("\r\n");
sb.append("unk_offset4 ").append(unk_offset4);
if (unk_offset4 != 1) {
sb.append(" global: ").append(main_offset + unk_offset4);
}
sb.append("\r\n");
sb.append("xmin ").append(xmin).append("\r\n");
sb.append("ymin ").append(ymin).append("\r\n");
sb.append("xmax ").append(ymax).append("\r\n");
sb.append("ymax ").append(ymax).append("\r\n");
sb.append("unk_40 ").append(unk_40).append("\r\n");
sb.append("unk_44 ").append(unk_44).append("\r\n");
sb.append("unk_48 ").append(unk_48).append("\r\n");
sb.append("unk_4C ").append(unk_4C).append("\r\n");
sb.append("unk_50 ").append(unk_50).append("\r\n");
sb.append("unk_54 ").append(unk_54).append("\r\n");
sb.append("frame_rate ").append(frame_rate).append("\r\n");
sb.append("unk_5C ").append(unk_5C).append("\r\n");
sb.append("fonts_offset ").append(fonts_offset).append("\r\n");
sb.append("unk_68 ").append(unk_68).append("\r\n");
sb.append("names_offset ").append(names_offset).append("\r\n");
sb.append("unk_offset5 ").append(unk_offset5).append("\r\n");
sb.append("unk_80 ").append(unk_80).append("\r\n");
sb.append("last_section_offset ").append(last_section_offset).append("\r\n");
sb.append("unk_offset6 ").append(unk_offset6).append("\r\n");
sb.append("as3_code_offset ").append(as3_code_offset).append("\r\n");
sb.append("as3_names_offset ").append(as3_names_offset).append("\r\n");
sb.append("unk_A8 ").append(unk_A8).append("\r\n");
sb.append("unk_AC ").append(unk_AC).append("\r\n");
sb.append("font_count ").append(font_count).append("\r\n");
sb.append("unk_B4 ").append(unk_B4).append("\r\n");
sb.append("]");
return sb.toString();
}
@Override
public long getXMin() {
return xmin;
}
@Override
public long getYMin() {
return ymin;
}
@Override
public long getXMax() {
return xmax;
}
@Override
public long getYMax() {
return ymax;
}
@Override
public float getFrameRate() {
return frame_rate;
}
}

View File

@@ -1,18 +1,20 @@
package com.jpexs.decompiler.flash.iggy;
/**
*
* @author JPEXS
*/
public interface IggyFlashHeaderInterface extends StructureInterface {
public long getXMin();
public long getYMin();
public long getXMax();
public long getYMax();
public float getFrameRate();
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
/**
*
* @author JPEXS
*/
public interface IggyFlashHeaderInterface extends StructureInterface {
public long getXMin();
public long getYMin();
public long getXMax();
public long getYMax();
public float getFrameRate();
}

View File

@@ -1,5 +1,8 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.iggy.streams.ByteArrayDataStream;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;

View File

@@ -1,5 +1,7 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;

View File

@@ -1,165 +1,167 @@
package com.jpexs.decompiler.flash.iggy;
import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;
/**
*
* @author Jindra
*/
public class IggyIndexParser {
private static Logger LOGGER = Logger.getLogger(IggyIndexParser.class.getName());
/*
Offsets:
1) name
2) UI16 - zero
3) tag list
4) ... tag data offsets
*/
/**
* Parser for index data. It creates table of indices and table of offsets
*
* @param indexStream Stream of index
* @param indexTableEntry Output index tabke
* @param offsets Output list of offsets
* @throws IOException on error
*/
public static void parseIndex(ByteArrayDataStream indexStream, List<Integer> indexTableEntry, List<Long> offsets) throws IOException {
int indexTableSize = indexStream.readUI8();
int[] indexTable = new int[indexTableSize];
for (int i = 0; i < indexTableSize; i++) {
int offset = indexStream.readUI8();
LOGGER.fine(String.format("index_table_entry: %02x\n", offset));
indexTable[i] = offset;
indexTableEntry.add(offset);
int num = indexStream.readUI8();
indexStream.seek(num * 2, SeekMode.CUR);
}
long offset = 0;
int code;
while ((code = indexStream.readUI8()) > -1) {
LOGGER.finer(String.format("Code = %x\n", code));
if (code < 0x80) // 0-0x7F
{
// code is directly an index to the index_table
if (code >= indexTableSize) {
LOGGER.severe(String.format("< 0x80: index is greater than index_table_size. %x > %x\n", code, indexTableSize));
return;
}
offset += indexTable[code];
} else if (code < 0xC0) // 0x80-BF
{
int index;
if ((index = indexStream.readUI8()) < 0) {
LOGGER.severe(String.format("< 0xC0: Cannot read index.\n"));
return;
}
if (index >= indexTableSize) {
LOGGER.severe(String.format("< 0xC0: index is greater than index_table_size. %x > %x\n", index, indexTableSize));
return;
}
int n = code - 0x7F;
offset += indexTable[index] * n;
} else if (code < 0xD0) // 0xC0-0xCF
{
offset += ((code * 2) - 0x17E);
} else if (code < 0xE0) // 0xD0-0xDF
{
// Code here depends on plattform[0], we are assuming it is 1, as we checked in load function
int i = code & 0xF;
int n8;
int n;
if ((n8 = indexStream.readUI8()) < 0) {
LOGGER.severe(String.format("< 0xE0: Cannot read n.\n"));
return;
}
n = n8 + 1;
if (indexStream.is64()) {
if (i <= 2) {
offset += 8 * n; // Ptr type
} else if (i <= 4) {
offset += 2 * n;
} else if (i == 5) {
offset += 4 * n;
} else if (i == 6) {
offset += 8 * n; // 64 bits type
} else {
LOGGER.severe(String.format("< 0xE0: Invalid value for i (%x %x)\n", i, code));
}
} else {
switch (i) {
case 2:
offset += 4 * n; // Ptr type
break;
case 4:
offset += 2 * n;
break;
case 5:
offset += 4 * n; // 32 bits type
break;
case 6:
offset += 8 * n;
break;
default:
LOGGER.severe(String.format("< 0xE0: invalid value for i (%x %x)\n", i, code));
}
}
} else if (code == 0xFC) {
indexStream.seek(1, SeekMode.CUR);
} else if (code == 0xFD) {
int n, m;
if ((n = indexStream.readUI8()) < 0) {
LOGGER.severe(String.format("0xFD: Cannot read n.\n"));
return;
}
if ((m = indexStream.readUI8()) < 0) {
LOGGER.severe(String.format("0xFD: Cannot read m.\n"));
return;
}
offset += n;
indexStream.seek(m * 2, SeekMode.CUR);
} else if (code == 0xFE) {
int n8;
int n;
if ((n8 = indexStream.readUI8()) < 0) {
LOGGER.severe(String.format("0xFE: Cannot read n.\n"));
return;
}
n = n8 + 1;
offset += n;
} else if (code == 0xFF) {
long n;
if ((n = indexStream.readUI32()) < 0) {
LOGGER.severe(String.format("0xFF: Cannot read n.\n"));
return;
}
offset += n;
} else {
LOGGER.warning(String.format("Unrecognized code: %x\n", code));
}
offsets.add(offset);
}
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;
/**
*
* @author Jindra
*/
public class IggyIndexParser {
private static Logger LOGGER = Logger.getLogger(IggyIndexParser.class.getName());
/*
Offsets:
1) name
2) UI16 - zero
3) tag list
4) ... tag data offsets
*/
/**
* Parser for index data. It creates table of indices and table of offsets
*
* @param indexStream Stream of index
* @param indexTableEntry Output index tabke
* @param offsets Output list of offsets
* @throws IOException on error
*/
public static void parseIndex(AbstractDataStream indexStream, List<Integer> indexTableEntry, List<Long> offsets) throws IOException {
int indexTableSize = indexStream.readUI8();
int[] indexTable = new int[indexTableSize];
for (int i = 0; i < indexTableSize; i++) {
int offset = indexStream.readUI8();
LOGGER.fine(String.format("index_table_entry: %02x\n", offset));
indexTable[i] = offset;
indexTableEntry.add(offset);
int num = indexStream.readUI8();
indexStream.seek(num * 2, SeekMode.CUR);
}
long offset = 0;
int code;
while ((code = indexStream.readUI8()) > -1) {
LOGGER.finer(String.format("Code = %x\n", code));
if (code < 0x80) // 0-0x7F
{
// code is directly an index to the index_table
if (code >= indexTableSize) {
LOGGER.severe(String.format("< 0x80: index is greater than index_table_size. %x > %x\n", code, indexTableSize));
return;
}
offset += indexTable[code];
} else if (code < 0xC0) // 0x80-BF
{
int index;
if ((index = indexStream.readUI8()) < 0) {
LOGGER.severe(String.format("< 0xC0: Cannot read index.\n"));
return;
}
if (index >= indexTableSize) {
LOGGER.severe(String.format("< 0xC0: index is greater than index_table_size. %x > %x\n", index, indexTableSize));
return;
}
int n = code - 0x7F;
offset += indexTable[index] * n;
} else if (code < 0xD0) // 0xC0-0xCF
{
offset += ((code * 2) - 0x17E);
} else if (code < 0xE0) // 0xD0-0xDF
{
// Code here depends on plattform[0], we are assuming it is 1, as we checked in load function
int i = code & 0xF;
int n8;
int n;
if ((n8 = indexStream.readUI8()) < 0) {
LOGGER.severe(String.format("< 0xE0: Cannot read n.\n"));
return;
}
n = n8 + 1;
if (indexStream.is64()) {
if (i <= 2) {
offset += 8 * n; // Ptr type
} else if (i <= 4) {
offset += 2 * n;
} else if (i == 5) {
offset += 4 * n;
} else if (i == 6) {
offset += 8 * n; // 64 bits type
} else {
LOGGER.severe(String.format("< 0xE0: Invalid value for i (%x %x)\n", i, code));
}
} else {
switch (i) {
case 2:
offset += 4 * n; // Ptr type
break;
case 4:
offset += 2 * n;
break;
case 5:
offset += 4 * n; // 32 bits type
break;
case 6:
offset += 8 * n;
break;
default:
LOGGER.severe(String.format("< 0xE0: invalid value for i (%x %x)\n", i, code));
}
}
} else if (code == 0xFC) {
indexStream.seek(1, SeekMode.CUR);
} else if (code == 0xFD) {
int n, m;
if ((n = indexStream.readUI8()) < 0) {
LOGGER.severe(String.format("0xFD: Cannot read n.\n"));
return;
}
if ((m = indexStream.readUI8()) < 0) {
LOGGER.severe(String.format("0xFD: Cannot read m.\n"));
return;
}
offset += n;
indexStream.seek(m * 2, SeekMode.CUR);
} else if (code == 0xFE) {
int n8;
int n;
if ((n8 = indexStream.readUI8()) < 0) {
LOGGER.severe(String.format("0xFE: Cannot read n.\n"));
return;
}
n = n8 + 1;
offset += n;
} else if (code == 0xFF) {
long n;
if ((n = indexStream.readUI32()) < 0) {
LOGGER.severe(String.format("0xFF: Cannot read n.\n"));
return;
}
offset += n;
} else {
LOGGER.warning(String.format("Unrecognized code: %x\n", code));
}
offsets.add(offset);
}
}
}

View File

@@ -1,5 +1,8 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.ArrayList;

View File

@@ -1,5 +1,7 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.logging.Level;

View File

@@ -1,5 +1,7 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import java.io.IOException;

View File

@@ -1,5 +1,7 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
/**
*
* @author JPEXS

View File

@@ -1,194 +1,196 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class IggyText implements StructureInterface {
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
@IggyArrayFieldType(value = DataType.widechar_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(AbstractDataStream stream) throws IOException {
this.readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream 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();
//flags
enum_hex = s.readUI16();
int en = enum_hex;
//guessing - it could be like DefineEditText?...
hasText = ((en >> 0) & 1) == 1;
wordWrap = ((en >> 1) & 1) == 1;
multiline = ((en >> 2) & 1) == 1;
password = ((en >> 3) & 1) == 1;
readOnly = ((en >> 4) & 1) == 1;
hasTextColor = ((en >> 5) & 1) == 1;
hasMaxLength = ((en >> 6) & 1) == 1;
hasFont = ((en >> 7) & 1) == 1;
hasFontClass = ((en >> 8) & 1) == 1;
autosize = ((en >> 9) & 1) == 1;
hasLayout = ((en >> 10) & 1) == 1;
noSelect = ((en >> 11) & 1) == 1;
border = ((en >> 12) & 1) == 1;
wasStatic = ((en >> 13) & 1) == 1;
html = ((en >> 14) & 1) == 1;
useOutlines = ((en >> 15) & 1) == 1;
//if hasFont?
fontIndex = s.readUI16(); //fontId
//if hasFontClass - readString?
//if hasFont || hasFontClass - readFontHeight?
//if hasTextColor....?
zero = s.readUI32();
one = s.readUI64(); //01CB FF33 3333
some = s.readBytes(32); // [6] => 40, [24] => 8
StringBuilder textBuilder = new StringBuilder();
do {
char c = (char) s.readUI16();
if (c == '\0') {
break;
}
textBuilder.append(c);
} while (true);
initialText = textBuilder.toString();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
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;
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class IggyText implements StructureInterface {
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
@IggyArrayFieldType(value = DataType.widechar_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(AbstractDataStream stream) throws IOException {
this.readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream 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();
//flags
enum_hex = s.readUI16();
int en = enum_hex;
//guessing - it could be like DefineEditText?...
hasText = ((en >> 0) & 1) == 1;
wordWrap = ((en >> 1) & 1) == 1;
multiline = ((en >> 2) & 1) == 1;
password = ((en >> 3) & 1) == 1;
readOnly = ((en >> 4) & 1) == 1;
hasTextColor = ((en >> 5) & 1) == 1;
hasMaxLength = ((en >> 6) & 1) == 1;
hasFont = ((en >> 7) & 1) == 1;
hasFontClass = ((en >> 8) & 1) == 1;
autosize = ((en >> 9) & 1) == 1;
hasLayout = ((en >> 10) & 1) == 1;
noSelect = ((en >> 11) & 1) == 1;
border = ((en >> 12) & 1) == 1;
wasStatic = ((en >> 13) & 1) == 1;
html = ((en >> 14) & 1) == 1;
useOutlines = ((en >> 15) & 1) == 1;
//if hasFont?
fontIndex = s.readUI16(); //fontId
//if hasFontClass - readString?
//if hasFont || hasFontClass - readFontHeight?
//if hasTextColor....?
zero = s.readUI32();
one = s.readUI64(); //01CB FF33 3333
some = s.readBytes(32); // [6] => 40, [24] => 8
StringBuilder textBuilder = new StringBuilder();
do {
char c = (char) s.readUI16();
if (c == '\0') {
break;
}
textBuilder.append(c);
} while (true);
initialText = textBuilder.toString();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
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;
}
}

View File

@@ -1,5 +1,6 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import java.io.IOException;
/**

View File

@@ -1,4 +1,4 @@
package com.jpexs.decompiler.flash.iggy;
package com.jpexs.decompiler.flash.iggy.streams;
import java.io.EOFException;
import java.io.IOException;
@@ -7,20 +7,24 @@ import java.io.IOException;
*
* @author JPEXS
*/
public abstract class AbstractDataStream {
public abstract class AbstractDataStream implements DataStreamInterface {
/**
* Available bytes
*
* @return null if unknown, long value otherwise
*/
@Override
public abstract Long available();
@Override
public abstract long position();
@Override
public abstract boolean is64();
protected long readUI64() throws IOException {
@Override
public long readUI64() throws IOException {
try {
return (readUI32() + (readUI32() << 32)) & 0xffffffffffffffffL;
} catch (EOFException ex) {
@@ -28,7 +32,8 @@ public abstract class AbstractDataStream {
}
}
protected boolean writeUI64(long val) throws IOException {
@Override
public boolean writeUI64(long val) throws IOException {
write((int) (val & 0xff));
write((int) ((val >> 8) & 0xff));
write((int) ((val >> 16) & 0xff));
@@ -41,7 +46,8 @@ public abstract class AbstractDataStream {
return true;
}
protected long readUI32() throws IOException {
@Override
public long readUI32() throws IOException {
try {
return (readUI8() + (readUI8() << 8) + (readUI8() << 16) + (readUI8() << 24));
} catch (EOFException ex) {
@@ -49,7 +55,8 @@ public abstract class AbstractDataStream {
}
}
protected boolean writeUI32(long val) throws IOException {
@Override
public boolean writeUI32(long val) throws IOException {
write((int) (val & 0xff));
write((int) ((val >> 8) & 0xff));
write((int) ((val >> 16) & 0xff));
@@ -57,7 +64,8 @@ public abstract class AbstractDataStream {
return true;
}
protected int readUI16() throws IOException {
@Override
public int readUI16() throws IOException {
try {
return (readUI8() + (readUI8() << 8)) & 0xffff;
} catch (EOFException ex) {
@@ -65,13 +73,15 @@ public abstract class AbstractDataStream {
}
}
protected boolean writeUI16(int val) throws IOException {
@Override
public boolean writeUI16(int val) throws IOException {
write(val & 0xff);
write((val >> 8) & 0xff);
return true;
}
protected int readUI8() throws IOException {
@Override
public int readUI8() throws IOException {
try {
return read() & 0xff;
} catch (EOFException ex) {
@@ -79,20 +89,24 @@ public abstract class AbstractDataStream {
}
}
protected boolean writeUI8(int val) throws IOException {
@Override
public boolean writeUI8(int val) throws IOException {
write(val);
return true;
}
protected float readFloat() throws IOException {
@Override
public float readFloat() throws IOException {
return Float.intBitsToFloat((int) readUI32());
}
protected boolean writeFloat(float val) throws IOException {
@Override
public boolean writeFloat(float val) throws IOException {
return writeUI32(Float.floatToIntBits(val));
}
protected byte[] readBytes(int numBytes) throws IOException {
@Override
public byte[] readBytes(int numBytes) throws IOException {
byte[] ret = new byte[numBytes];
for (int i = 0; i < numBytes; i++) {
ret[i] = (byte) read();
@@ -100,17 +114,27 @@ public abstract class AbstractDataStream {
return ret;
}
protected void writeBytes(byte[] data) throws IOException {
@Override
public void writeBytes(byte[] data) throws IOException {
for (int i = 0; i < data.length; i++) {
write(data[i] & 0xff);
}
}
protected abstract int read() throws IOException;
@Override
public abstract int read() throws IOException;
protected abstract void seek(long pos, SeekMode mode) throws IOException;
@Override
public abstract void seek(long pos, SeekMode mode) throws IOException;
protected void write(int val) throws IOException {
@Override
public void write(int val) throws IOException {
//nothing
}
@Override
public void close() {
//nothing
}
}

View File

@@ -1,85 +1,90 @@
package com.jpexs.decompiler.flash.iggy;
import java.io.EOFException;
import java.io.IOException;
import java.util.Arrays;
/**
*
* @author JPEXS
*/
public class ByteArrayDataStream extends AbstractDataStream {
private byte[] data;
private long pos;
private boolean use64bit;
public ByteArrayDataStream(int initialSize, boolean use64bit) {
this(new byte[initialSize], use64bit);
}
@Override
public long position() {
return pos;
}
public ByteArrayDataStream(byte data[], boolean use64bit) {
this.data = data;
pos = 0;
this.use64bit = use64bit;
}
@Override
public boolean is64() {
return use64bit;
}
@Override
protected int read() throws IOException {
if (pos >= data.length) {
throw new EOFException("End of stream reached");
}
int ret = data[(int) pos] & 0xff;
pos++;
return ret;
}
public void resize(int newsize) {
data = Arrays.copyOf(data, newsize);
if (pos > data.length) {
pos = data.length;
}
}
@Override
protected void write(int val) throws IOException {
if (pos >= data.length) {
throw new EOFException("End of stream reached");
}
data[(int) pos] = (byte) val;
pos++;
}
@Override
protected void seek(long pos, SeekMode mode) throws IOException {
long newpos = pos;
if (mode == SeekMode.CUR) {
newpos = this.pos + pos;
} else if (mode == SeekMode.END) {
newpos = data.length - pos;
}
if (newpos > data.length) {
throw new ArrayIndexOutOfBoundsException("Position outside bounds accessed: " + pos + ". Size: " + data.length);
} else if (newpos < 0) {
throw new ArrayIndexOutOfBoundsException("Negative position accessed: " + pos);
} else {
this.pos = (int) newpos;
}
}
@Override
public Long available() {
return (long) (data.length - pos);
}
}
package com.jpexs.decompiler.flash.iggy.streams;
import java.io.EOFException;
import java.io.IOException;
import java.util.Arrays;
/**
*
* @author JPEXS
*/
public class ByteArrayDataStream extends AbstractDataStream {
private byte[] data;
private long pos;
private boolean use64bit;
public ByteArrayDataStream(int initialSize, boolean use64bit) {
this(new byte[initialSize], use64bit);
}
@Override
public long position() {
return pos;
}
public ByteArrayDataStream(byte data[], boolean use64bit) {
this.data = data;
pos = 0;
this.use64bit = use64bit;
}
@Override
public boolean is64() {
return use64bit;
}
@Override
public int read() throws IOException {
if (pos >= data.length) {
throw new EOFException("End of stream reached");
}
int ret = data[(int) pos] & 0xff;
pos++;
return ret;
}
public void resize(int newsize) {
data = Arrays.copyOf(data, newsize);
if (pos > data.length) {
pos = data.length;
}
}
@Override
public void write(int val) throws IOException {
if (pos >= data.length) {
throw new EOFException("End of stream reached");
}
data[(int) pos] = (byte) val;
pos++;
}
@Override
public void seek(long pos, SeekMode mode) throws IOException {
long newpos = pos;
if (mode == SeekMode.CUR) {
newpos = this.pos + pos;
} else if (mode == SeekMode.END) {
newpos = data.length - pos;
}
if (newpos > data.length) {
throw new ArrayIndexOutOfBoundsException("Position outside bounds accessed: " + pos + ". Size: " + data.length);
} else if (newpos < 0) {
throw new ArrayIndexOutOfBoundsException("Negative position accessed: " + pos);
} else {
this.pos = (int) newpos;
}
}
@Override
public Long available() {
return (long) (data.length - pos);
}
@Override
public void close() {
//nothing
}
}

View File

@@ -0,0 +1,9 @@
package com.jpexs.decompiler.flash.iggy.streams;
/**
*
* @author JPEXS
*/
public interface DataStreamInterface extends ReadDataStreamInterface, WriteDataStreamInterface {
}

View File

@@ -0,0 +1,88 @@
package com.jpexs.decompiler.flash.iggy.streams;
import java.io.EOFException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
*
* @author JPEXS
*/
public class RandomAccessFileDataStream extends AbstractDataStream {
private RandomAccessFile raf;
private boolean is64;
public RandomAccessFileDataStream(File file) throws FileNotFoundException {
this(new RandomAccessFile(file, "rw"));
}
public RandomAccessFileDataStream(RandomAccessFile rafile) {
this.raf = rafile;
}
@Override
public Long available() {
try {
return raf.length() - raf.getFilePointer();
} catch (IOException ex) {
return null;
}
}
@Override
public long position() {
try {
return raf.getFilePointer();
} catch (IOException ex) {
return -1;
}
}
public void set64(boolean is64) {
this.is64 = is64;
}
@Override
public boolean is64() {
return is64;
}
@Override
public int read() throws IOException {
int val = raf.read();
if (val == -1) {
throw new EOFException();
}
return val;
}
@Override
public void seek(long pos, SeekMode mode) throws IOException {
long newpos = pos;
if (mode == SeekMode.CUR) {
newpos = raf.getFilePointer() + pos;
} else if (mode == SeekMode.END) {
newpos = raf.length() - pos;
}
if (newpos > raf.length()) {
throw new ArrayIndexOutOfBoundsException("Position outside bounds accessed: " + pos + ". Size: " + raf.length());
} else if (newpos < 0) {
throw new ArrayIndexOutOfBoundsException("Negative position accessed: " + pos);
} else {
raf.seek(newpos);
}
}
@Override
public void close() {
try {
raf.close();
} catch (IOException ex) {
//ignore
}
}
}

View File

@@ -0,0 +1,40 @@
package com.jpexs.decompiler.flash.iggy.streams;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public interface ReadDataStreamInterface extends AutoCloseable {
/**
* Available bytes
*
* @return null if unknown, long value otherwise
*/
public Long available();
public long position();
public boolean is64();
public long readUI64() throws IOException;
public long readUI32() throws IOException;
public int readUI16() throws IOException;
public int readUI8() throws IOException;
public int read() throws IOException;
public byte[] readBytes(int numBytes) throws IOException;
public float readFloat() throws IOException;
public void seek(long pos, SeekMode mode) throws IOException;
@Override
public void close();
}

View File

@@ -1,9 +1,9 @@
package com.jpexs.decompiler.flash.iggy;
/**
*
* @author Jindra
*/
public enum SeekMode {
SET, CUR, END
}
package com.jpexs.decompiler.flash.iggy.streams;
/**
*
* @author Jindra
*/
public enum SeekMode {
SET, CUR, END
}

View File

@@ -1,15 +1,16 @@
package com.jpexs.decompiler.flash.iggy;
import java.io.IOException;
import java.util.List;
/**
*
* @author JPEXS
*/
public interface StructureInterface {
public void readFromDataStream(AbstractDataStream stream) throws IOException;
public void writeToDataStream(AbstractDataStream stream) throws IOException;
}
package com.jpexs.decompiler.flash.iggy.streams;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import java.io.IOException;
import java.util.List;
/**
*
* @author JPEXS
*/
public interface StructureInterface {
public void readFromDataStream(AbstractDataStream stream) throws IOException;
public void writeToDataStream(AbstractDataStream stream) throws IOException;
}

View File

@@ -0,0 +1,40 @@
package com.jpexs.decompiler.flash.iggy.streams;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public interface WriteDataStreamInterface extends AutoCloseable {
/**
* Available bytes
*
* @return null if unknown, long value otherwise
*/
public Long available();
public long position();
public boolean is64();
public boolean writeUI64(long val) throws IOException;
public boolean writeUI32(long val) throws IOException;
public boolean writeUI16(int val) throws IOException;
public boolean writeUI8(int val) throws IOException;
public void write(int val) throws IOException;
public void writeBytes(byte[] data) throws IOException;
public boolean writeFloat(float val) throws IOException;
public void seek(long pos, SeekMode mode) throws IOException;
@Override
public void close();
}