Iggy - generating Index finished

Other various Iggy fixes
This commit is contained in:
Jindra Petřík
2016-12-03 21:59:42 +01:00
parent 72af4e6e93
commit 5bb0d8ac83
23 changed files with 792 additions and 641 deletions

View File

@@ -13,6 +13,8 @@ import java.util.List;
*/
public class IggyCharKerning implements StructureInterface {
public static final int STRUCT_SIZE = 6;
private long kernCount;
List<Character> charsA;
List<Character> charsB;

View File

@@ -13,6 +13,8 @@ import java.util.logging.Logger;
*/
public class IggyCharOffset implements StructureInterface {
public static final int STRUCT_SIZE = 32;
private static Logger LOGGER = Logger.getLogger(IggyCharOffset.class.getName());
@IggyFieldType(DataType.uint64_t)

View File

@@ -2,6 +2,7 @@ package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
@@ -51,10 +52,14 @@ public class IggyDeclStrings implements StructureInterface {
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
IggyIndexBuilder ib = s.getIndexing();
s.writeUI64(one);
s.writeUI32(size);
s.writeBytes(xxx);
ib.writeLengthSkipTwice(8 + 4 + 3, 0);
ib.writeLengthUI32(size);
s.writeBytes(data);
ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE);
s.writeBytes(padd);
s.writeUI64(one);
s.writeUI64(zero);

View File

@@ -1,13 +1,13 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexParser;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.RandomAccessFileDataStream;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.DataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.IndexingDataStream;
import com.jpexs.decompiler.flash.iggy.streams.IndexingDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.TemporaryDataStream;
import com.jpexs.helpers.Helper;
import java.io.File;
@@ -17,6 +17,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -38,11 +39,7 @@ public class IggyFile implements StructureInterface {
private List<IggySubFileEntry> subFileEntries = new ArrayList<>();
private List<byte[]> subFileEntriesData = new ArrayList<>();
private List<IggyFlashHeaderInterface> headers = new ArrayList<>();
private List<IggySwf> iggySwfs = new ArrayList<>();
private List<List<Integer>> indexTables = new ArrayList<>();
private List<List<Long>> offsetTables = new ArrayList<>();
private List<DataStreamInterface> indexDataStreams = new ArrayList<>();
public static final int FIRST_TAG_POSITION = 3;
@@ -50,7 +47,7 @@ public class IggyFile implements StructureInterface {
IggySwf iggySwf = iggySwfs.get(targetSwfIndex);
iggySwf.replaceFontTag(fontIndex, newFont);
IndexingDataStreamInterface indexStream = new IndexingDataStream();
IggyIndexBuilder indexStream = new IggyIndexBuilder();
DataStreamInterface flashStream = new TemporaryDataStream();
flashStream.setIndexing(indexStream);
iggySwf.writeToDataStream(flashStream);
@@ -85,34 +82,12 @@ public class IggyFile implements StructureInterface {
}
}
private boolean setSwfItemLength(int swfIndex, int itemindex, long newLength) {
DataStreamInterface stream = indexDataStreams.get(swfIndex);
List<Long> offsetTable = offsetTables.get(swfIndex);
long offset = offsetTable.get(itemindex);
long nextOffset = itemindex == offsetTable.size() - 1 ? stream.totalSize() : offsetTable.get(itemindex + 1);
long currentSize = nextOffset - offset;
try {
byte indexData[] = stream.getAllBytes();
setItemLength(offset, header.is64(), indexData, newLength);
indexDataStreams.set(swfIndex, new TemporaryDataStream(indexData)); //TODO: optimize!
long lengthDelta = newLength - currentSize;
for (int i = itemindex + 1; i < offsetTable.size(); i++) {
offsetTable.set(i, offsetTable.get(i) + lengthDelta);
}
return true;
} catch (IOException ex) {
return false;
}
}
public IggySwf getSwf(int swfIndex) {
return iggySwfs.get(swfIndex);
}
public Set<Integer> getFontIds(int swfIndex) {
return iggySwfs.get(swfIndex).fonts.keySet();
public int getFontCount(int swfIndex) {
return iggySwfs.get(swfIndex).fonts.size();
}
public IggyFont getFont(int swfIndex, int fontId) {
@@ -221,13 +196,15 @@ public class IggyFile implements StructureInterface {
IggyFile iggyFile = new IggyFile(inFile);
extractIggyFile(inFile, extractDirOrig);
IggySwf iswf = iggyFile.getSwf(0);
IggyFont ifont = iswf.fonts.get(0);
iggyFile.replaceFontTag(0, 0, ifont);
iggyFile.replaceSwf(0, iswf);
//IggyFont ifont = iswf.fonts.get(0);
//iggyFile.replaceFontTag(0, 0, ifont);
outFile.delete();
try (RandomAccessFileDataStream outputStream = new RandomAccessFileDataStream(outFile)) {
iggyFile.writeToDataStream(outputStream);
}
extractIggyFile(outFile, extractDirNew);
System.exit(0);
}
private static void copyStream(InputStream is, OutputStream os) {
@@ -669,27 +646,42 @@ public class IggyFile implements StructureInterface {
}
//WIP
public boolean replaceSwf(int targetSwfIndex, IggySwf iggySwf) {
return false; //Not working yet - need to make IggySWF.writeToDataStream work
public boolean replaceSwf(int targetSwfIndex, IggySwf iggySwf) throws IOException {
/*if (targetSwfIndex < 0 || targetSwfIndex >= getSwfCount()) {
if (targetSwfIndex < 0 || targetSwfIndex >= getSwfCount()) {
throw new ArrayIndexOutOfBoundsException("No such SWF file index");
}
byte replacementData[];
byte replacementIndexData[];
IggyIndexBuilder ib = new IggyIndexBuilder();
try (DataStreamInterface stream = new TemporaryDataStream()) {
headers.get(targetSwfIndex).writeToDataStream(stream);
stream.setIndexing(ib);
iggySwf.writeToDataStream(stream);
replacementData = stream.getAllBytes();
replacementIndexData = ib.getIndexBytes();
} catch (IOException ex) {
Logger.getLogger(IggyFile.class.getName()).log(Level.SEVERE, "Error during updating SWF", ex);
return false;
}
IggyIndexParser.parseIndex(true, new TemporaryDataStream(replacementIndexData), new ArrayList<>(), new ArrayList<>());
int swfIndex = 0;
long offsetsChange = 0;
for (int i = 0; i < subFileEntries.size(); i++) {
IggySubFileEntry entry = subFileEntries.get(i);
entry.offset += offsetsChange;
if (entry.type == IggySubFileEntry.TYPE_INDEX) {
if (swfIndex == targetSwfIndex) {
long oldSize = entry.size;
long newSize = replacementIndexData.length;
offsetsChange = offsetsChange + (newSize - oldSize);
entry.size = newSize;
entry.size2 = newSize;
subFileEntriesData.set(i, replacementIndexData);
}
swfIndex++;
}
if (entry.type == IggySubFileEntry.TYPE_FLASH) {
if (swfIndex == targetSwfIndex) {
long oldSize = entry.size;
@@ -698,29 +690,19 @@ public class IggyFile implements StructureInterface {
entry.size = newSize;
entry.size2 = newSize;
//entries after this one will have modified offsets
subFileEntriesData.set(i, replacementData);
}
swfIndex++;
}
}
subFileEntriesData.set(targetSwfIndex, replacementData);
return true;*/
return true;
}
private void parseEntries() throws IOException {
List<DataStreamInterface> flashDataStreams = new ArrayList<>();
for (int i = 0; i < subFileEntries.size(); i++) {
IggySubFileEntry entry = subFileEntries.get(i);
DataStreamInterface dataStream = new TemporaryDataStream(getEntryData(i));
if (entry.type == IggySubFileEntry.TYPE_INDEX) {
List<Integer> indexTable = new ArrayList<>();
List<Long> offsets = new ArrayList<>();
IggyIndexParser.parseIndex(header.is64(), dataStream, indexTable, offsets);
indexDataStreams.add(dataStream);
indexTables.add(indexTable);
offsetTables.add(offsets);
} else if (entry.type == IggySubFileEntry.TYPE_FLASH) {
iggySwfs.add(new IggySwf(dataStream));
if (entry.type == IggySubFileEntry.TYPE_FLASH) {
iggySwfs.add(new IggySwf(new TemporaryDataStream(getEntryData(i))));
}
}
}

View File

@@ -51,16 +51,10 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
float frame_rate;
@IggyFieldType(DataType.uint32_t)
long unk_5C;
@IggyFieldType(DataType.uint32_t)
long additional_import1;
@IggyFieldType(DataType.uint32_t)
long zero1;
//local
private int imported = 0;
@IggyFieldType(DataType.uint64_t)
long unk_guid; // same for some fonts (eng + chinese)
long imported_guid;
@IggyFieldType(DataType.uint64_t)
long my_guid; // same for some fonts (eng + chinese)
@IggyFieldType(DataType.uint64_t)
long off_names; // 0x70 relative offset to the names/import section of the file - end of fonts
@IggyFieldType(DataType.uint64_t)
@@ -127,8 +121,8 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
}
}
public boolean isImported() {
return imported == 1;
public long getImported_guid() {
return imported_guid;
}
public long getBaseAddress() {
@@ -212,12 +206,8 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
unk_54 = stream.readUI32();
frame_rate = stream.readFloat();
unk_5C = stream.readUI32();
additional_import1 = stream.readUI32();
if (additional_import1 > 0) {
imported = 1;
}
zero1 = stream.readUI32();
unk_guid = stream.readUI64();
imported_guid = stream.readUI64();
my_guid = stream.readUI64();
off_names = stream.readUI64();
names_address = off_names == 1 ? 0 : off_names + stream.position() - 8;
@@ -270,9 +260,8 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
stream.writeUI32(unk_54);
stream.writeFloat(frame_rate);
stream.writeUI32(unk_5C);
stream.writeUI32(additional_import1);
stream.writeUI32(zero1);
stream.writeUI64(unk_guid);
stream.writeUI64(imported_guid);
stream.writeUI64(my_guid);
off_names = names_address == 0 ? 1 : names_address - stream.position();
stream.writeUI64(off_names);
off_unk78 = unk78_address == 0 ? 1 : unk78_address - stream.position();

View File

@@ -7,6 +7,7 @@ import com.jpexs.decompiler.flash.iggy.streams.TemporaryDataStream;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.DataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -217,6 +218,8 @@ public class IggyFont extends IggyTag {
start_of_kern = s.readUI64();
long abs_start_of_kern = makeAbsOffset(s, start_of_kern);
zero_padd = s.readUI64();
//--------------------------------------
what_2 = s.readUI64();
zero_padd_2 = s.readUI64();
start_of_name = s.readUI64();
@@ -244,6 +247,7 @@ public class IggyFont extends IggyTag {
}
subName = subNameBuilder.toString();
zeroes48a = s.readBytes(48);
sss1 = s.readFloat();
one_padd2 = s.readUI32();
sss2 = s.readFloat();
@@ -295,6 +299,8 @@ public class IggyFont extends IggyTag {
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
IggyIndexBuilder ib = s.getIndexing();
ib.writeConstLength(IggyIndexBuilder.CONST_GENERAL_FONT_INFO_SIZE);
s.writeUI16(type);
s.writeUI16(fontId);
s.writeBytes(zeroone);
@@ -316,6 +322,7 @@ public class IggyFont extends IggyTag {
s.writeUI64(start_of_kern);
long abs_start_of_kern = makeAbsOffset(s, start_of_kern);
s.writeUI64(zero_padd);
ib.writeConstLength(IggyIndexBuilder.CONST_GENERAL_FONT_INFO2_SIZE);
s.writeUI64(what_2);
s.writeUI64(zero_padd_2);
s.writeUI64(start_of_name);
@@ -355,6 +362,9 @@ public class IggyFont extends IggyTag {
//align to 8 bytes boundary
int len = name.length() * 2 + 2;
ib.write16bitArray(name.length() + 1);
ib.pad8bytes();
int pad8 = 8 - (len % 8);
if (pad8 < 8) {
for (int i = 0; i < pad8; i++) {
@@ -366,7 +376,8 @@ public class IggyFont extends IggyTag {
s.writeUI64(0); //pad zero
if (abs_start_of_char_struct != 0) {
s.seek(abs_start_of_char_struct, SeekMode.SET);
long baseOfsAddr = s.position();
ib.writeConstLengthArray(IggyIndexBuilder.CONST_CHAR_OFFSET_SIZE, charOffsets.size());
//offsets of shapes
for (IggyCharOffset ofs : charOffsets) {
ofs.writeToDataStream(s);
@@ -384,21 +395,30 @@ public class IggyFont extends IggyTag {
for (char c : codePoints.chars) {
s.writeUI16(c);
}
s.writeUI32(0);
ib.write16bitArray(codePoints.chars.size());
ib.pad8bytes();
s.pad8bytes();
}
if (abs_start_of_scale != 0) {
s.seek(abs_start_of_scale, SeekMode.SET);
charScales.writeToDataStream(s);
ib.write32bitArray(charScales.advances.size());
ib.pad8bytes();
s.pad8bytes();
}
if (abs_start_of_kern != 0) {
s.seek(abs_start_of_kern, SeekMode.SET);
ib.writeConstLengthArray(IggyIndexBuilder.CONST_KERNING_RECORD_SIZE, kern_count);
charKernings.writeToDataStream(s);
ib.pad8bytes();
s.pad8bytes();
}
if ((s.position() - abs_start_of_char_index) % 8 != 0) {
/*if ((s.position() - abs_start_of_char_index) % 8 != 0) {
byte padd[] = new byte[(int) (((s.position() - abs_start_of_char_index) / 8 + 1) * 8 - (s.position() - abs_start_of_char_index))];
s.writeBytes(padd);
}
ib.writePaddingTo8(s.position());*/
}
public int getType() {

View File

@@ -10,7 +10,9 @@ import java.io.IOException;
*
* @author JPEXS
*/
public class FontBinInfo implements StructureInterface {
public class IggyFontBinInfo implements StructureInterface {
public static final int STRUCT_SIZE = 96;
@IggyFieldType(DataType.uint64_t)
long size_of_this_info = 96;
@@ -35,7 +37,7 @@ public class FontBinInfo implements StructureInterface {
@IggyFieldType(value = DataType.uint8_t, count = 40)
byte pad[];
public FontBinInfo(ReadDataStreamInterface s) throws IOException {
public IggyFontBinInfo(ReadDataStreamInterface s) throws IOException {
readFromDataStream(s);
}

View File

@@ -13,6 +13,7 @@ import java.io.IOException;
*/
public class IggyFontTypeInfo implements StructureInterface {
public static final int STRUCT_SIZE = 24;
@IggyFieldType(DataType.uint64_t)
long zero;
@IggyFieldType(DataType.uint64_t)

View File

@@ -1,12 +0,0 @@
package com.jpexs.decompiler.flash.iggy;
/**
*
* @author JPEXS
*/
public class IggyIndexBuilder {
public void writeTable(int cnt, DataType type, boolean pad) {
}
}

View File

@@ -1,7 +1,9 @@
package com.jpexs.decompiler.flash.iggy;
import static com.jpexs.decompiler.flash.iggy.IggyFontBinInfo.STRUCT_SIZE;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
@@ -13,6 +15,8 @@ import java.io.IOException;
*/
public class IggySequence implements StructureInterface {
public static final int STRUCT_SIZE = 16;
@IggyArrayFieldType(value = DataType.uint64_t, count = 2)
public long onepadd[];
@@ -25,9 +29,6 @@ public class IggySequence implements StructureInterface {
@IggyFieldType(DataType.wchar_t)
public String sequence_name;
@IggyArrayFieldType(DataType.uint8_t)
byte pad[];
@IggyFieldType(DataType.uint64_t)
public long zero2;
@@ -43,33 +44,28 @@ public class IggySequence implements StructureInterface {
for (int i = 0; i < onepadd.length; i++) {
onepadd[i] = s.readUI64();
}
//sequence start
local_seq_offset = s.readUI64();
zero = s.readUI64();
StringBuilder sequence_name_builder = new StringBuilder();
for (int i = 0; i < local_seq_offset; i++) {
sequence_name_builder.append((char) s.readUI16());
}
sequence_name = sequence_name_builder.toString();
int pad8 = 8 - (int) (s.position() % 8);
if (pad8 < 8) {
pad = s.readBytes(pad8);
} else {
pad = new byte[0];
}
sequence_name = s.readWChar();
s.pad8bytes();
zero2 = s.readUI64(); //zero2
}
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
IggyIndexBuilder ib = s.getIndexing();
ib.writeLengthSkipTwice(16, 0);
for (int i = 0; i < onepadd.length; i++) {
s.writeUI64(onepadd[i]);
}
ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE);
s.writeUI64(local_seq_offset);
s.writeUI64(zero);
for (int i = 0; i < sequence_name.length(); i++) {
s.writeUI16(sequence_name.charAt(i));
}
s.writeBytes(pad);
ib.write16bitArray(sequence_name.length() + 1);
s.writeWChar(sequence_name);
s.pad8bytes();
ib.pad8bytes();
s.writeUI64(zero2);
}
}

View File

@@ -1,9 +1,12 @@
package com.jpexs.decompiler.flash.iggy;
import static com.jpexs.decompiler.flash.iggy.IggyCharOffset.STRUCT_SIZE;
import static com.jpexs.decompiler.flash.iggy.IggyShapeNode.STRUCT_SIZE;
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 com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.IOException;
@@ -17,6 +20,8 @@ import java.util.logging.Logger;
*/
public class IggyShape implements StructureInterface {
public static final int STRUCT_SIZE = 64;
private static Logger LOGGER = Logger.getLogger(IggyShape.class.getName());
@IggyFieldType(DataType.float_t)
@@ -106,6 +111,7 @@ public class IggyShape implements StructureInterface {
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
s.getIndexing().writeConstLength(IggyIndexBuilder.CONST_SHAPE_SIZE);
s.writeFloat(minx);
s.writeFloat(miny);
s.writeFloat(maxx);
@@ -118,6 +124,8 @@ public class IggyShape implements StructureInterface {
s.writeUI32(one4);
s.writeUI32(two1);
s.getIndexing().writeConstLengthArray(IggyIndexBuilder.CONST_SHAPE_NODE_SIZE, nodes.size());
for (IggyShapeNode node : nodes) {
node.writeToDataStream(s);
}

View File

@@ -1,5 +1,6 @@
package com.jpexs.decompiler.flash.iggy;
import static com.jpexs.decompiler.flash.iggy.IggyShape.STRUCT_SIZE;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
@@ -15,6 +16,8 @@ import java.util.logging.Logger;
*/
public class IggyShapeNode implements StructureInterface {
public static final int STRUCT_SIZE = 24;
private static Logger LOGGER = Logger.getLogger(IggyShapeNode.class.getName());
public static int NODE_TYPE_MOVE = 1;

View File

@@ -6,6 +6,7 @@ import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.DataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.TemporaryDataStream;
import com.jpexs.helpers.Helper;
import java.io.FileOutputStream;
@@ -26,7 +27,10 @@ public class IggySwf implements StructureInterface {
@IggyFieldType(value = DataType.wchar_t, count = 48)
String name;
Map<Integer, IggyFont> fonts;
List<IggyFont> fonts = new ArrayList<>();
private List<Long> font_data_addresses = new ArrayList<>();
List<IggyFont> add_fonts = new ArrayList<>();
private List<Long> add_font_data_addresses = new ArrayList<>();
private IggyFlashHeader64 hdr;
@@ -35,27 +39,27 @@ public class IggySwf implements StructureInterface {
public IggySwf(ReadDataStreamInterface stream) throws IOException {
readFromDataStream(stream);
}
private List<IggyText> texts = new ArrayList<>();
private List<Long> text_data_addresses = new ArrayList<>();
private List<IggyText> add_texts = new ArrayList<>();
private List<Long> add_text_data_addresses = new ArrayList<>();
private long font_data_addresses[];
private long font_data_sizes[];
private List<Long> text_addresses = new ArrayList<>();
private List<Long> text_data_sizes = new ArrayList<>();
private List<byte[]> text_data_bytes = new ArrayList<>();
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[];
private List<Long> font_additional_size = new ArrayList<>();
private IggyFontBinInfo font_bin_info[];
private IggySequence sequence;
private IggyFontTypeInfo type_info[];
private String type_info_name[];
private IggyDeclStrings decl_strings;
private long ofs_additional;
private long additional_address;
public IggyFlashHeader64 getHdr() {
return hdr;
}
public void replaceFontTag(int fontIndex, IggyFont newFont) throws IOException {
long newLen;
/*long newLen;
byte newData[];
try (WriteDataStreamInterface stream = new TemporaryDataStream()) {
newFont.writeToDataStream(stream);
@@ -66,7 +70,7 @@ public class IggySwf implements StructureInterface {
//FIXME
Helper.writeFile("d:\\Dropbox\\jpexs-laptop\\iggi\\extraxtdir_new\\font" + fontIndex + ".bin", newData);
/* long oldLen = font_data_sizes[fontIndex];
long oldLen = font_data_sizes[fontIndex];
long diff = newLen - oldLen;
if (diff != 0) {
font_data_sizes[fontIndex] = newLen;
@@ -103,9 +107,71 @@ public class IggySwf implements StructureInterface {
s.seek(hdr.getBaseAddress(), SeekMode.SET);
s.readUI64(); //pad 1
font_data_addresses = new long[(int) hdr.font_count];
font_data_sizes = new long[(int) hdr.font_count];
List<Long> itemsAddresses = new ArrayList<>();
while (true) {
long offset = s.readUI64();
if (offset == 1) {
break;
}
itemsAddresses.add(offset + s.position() - 8);
}
if (hdr.getImported_guid() != 0) {
ofs_additional = s.readUI64();
additional_address = ofs_additional == 1 ? 0 : ofs_additional + s.position() - 8;
}
for (Long addr : itemsAddresses) {
s.seek(addr, SeekMode.SET);
int kind = s.readUI8();
s.seek(-1, SeekMode.CUR);
switch (kind) {
case 22 /*FONT*/:
IggyFont font = new IggyFont(s);
font_data_addresses.add(addr);
fonts.add(font);
break;
case 6 /*TEXT*/:
IggyText text = new IggyText(s);
text_data_addresses.add(addr);
texts.add(text);
break;
default:
throw new RuntimeException("Unknown item kind: " + kind);
}
}
if (additional_address != 0) {
s.seek(additional_address, SeekMode.SET);
List<Long> additionalItemsAddresses = new ArrayList<>();
while (true) {
long offset = s.readUI64();
if (offset == 1) {
break;
}
additionalItemsAddresses.add(offset + s.position() - 8);
}
for (Long addr : additionalItemsAddresses) {
s.seek(addr, SeekMode.SET);
int kind = s.readUI8();
s.seek(-1, SeekMode.CUR);
switch (kind) {
case 22 /*FONT*/:
IggyFont font = new IggyFont(s);
add_font_data_addresses.add(addr);
add_fonts.add(font);
break;
case 6 /*TEXT*/:
IggyText text = new IggyText(s);
add_text_data_addresses.add(addr);
add_texts.add(text);
break;
default:
throw new RuntimeException("Unknown imported item kind: " + kind);
}
}
}
/*
for (int i = 0; i < hdr.font_count; i++) {
long offset = s.readUI64();
font_data_addresses[i] = offset + s.position() - 8;
@@ -135,56 +201,70 @@ public class IggySwf implements StructureInterface {
}
s.readUI64(); //1
if (hdr.isImported()) { // tohle muze narusit iggy order, ale oni to pak stejne pocitaji dle infa
long additionalOffset = s.readUI64();
font_add_off.add(additionalOffset + s.position() - 8);
font_add_size.add(hdr.getFontEndAddress() - font_add_off.get(0));
if (s.readUI8(font_add_off.get(0)) != 22) { //22 = Text
for (int i = 0; i < text_addresses.size(); i++) {
if (s.readUI8(text_addresses.get(i)) == 22) { //TEXT
if (hdr.getImported_guid() != 0) {
ofs_additional = s.readUI64();
additional_address = ofs_additional + s.position() - 8;
font_additional_addresses.add(additional_address);
font_additional_size.add(hdr.getFontEndAddress() - font_additional_addresses.get(0));
if (s.readUI8(font_additional_addresses.get(0)) != 22) { //additional is not text
// font je hozen mezi infa...
for (int i = 0; i < text_addresses.size(); i++) { //walk all already read texts
if (s.readUI8(text_addresses.get(i)) == 22) { //check if it's text
long pomoff;
long pomsize;
pomoff = text_addresses.get(i);
pomsize = text_data_sizes.get(i);
text_addresses.set(i, font_add_off.get(0));
text_data_sizes.set(i, font_add_size.get(0));
font_add_off.set(0, pomoff);
font_add_size.set(0, pomsize);
text_addresses.set(i, font_additional_addresses.get(0));
text_data_sizes.set(i, font_additional_size.get(0));
font_additional_addresses.set(0, pomoff);
font_additional_size.set(0, pomsize);
}
}
}
}
}*/
/* if (s.readUI8(s.position()) == 22) { //22 = Text
byte[] textHdr = s.readBytes(IggyText.STRUCT_SIZE);
String textStr = s.readWChar();
s.pad8bytes();
}*/
//here is offset [3] - 744
fonts = new HashMap<>();
/* fonts = new ArrayList<>();
for (int i = 0; i < hdr.font_count; i++) {
s.seek(font_data_addresses[i], SeekMode.SET);
byte font_data[] = s.readBytes((int) font_data_sizes[i]);
//FIXME
Helper.writeFile("d:\\Dropbox\\jpexs-laptop\\iggi\\extraxtdir_orig\\font" + i + ".bin", font_data);
//Helper.writeFile("d:\\Dropbox\\jpexs-laptop\\iggi\\extraxtdir_orig\\font" + i + ".bin", font_data);
s.seek(-font_data_sizes[i], SeekMode.CUR);
IggyFont font = new IggyFont(s);
fonts.put(i, font);
fonts.add(font);
}
for (int i = 0; i < text_addresses.size(); i++) {
for (int i = 0;
i < text_addresses.size();
i++) {
s.seek(text_addresses.get(i), SeekMode.SET);
byte text_data[] = s.readBytes((int) (long) text_data_sizes.get(i));
text_data_bytes.add(text_data);
texts.add(new IggyText(s));
//byte text_data[] = s.readBytes((int) (long) text_data_sizes.get(i));
//text_data_bytes.add(text_data);
}
if (hdr.isImported()) {
s.seek(font_add_off.get(0), SeekMode.SET);
font_add_data = s.readBytes((int) (long) font_add_size.get(0));
}
if (hdr.getImported_guid()
!= 0) {
s.seek(font_additional_addresses.get(0), SeekMode.SET);
font_add_data = s.readBytes((int) (long) font_additional_size.get(0));
}*/
s.seek(hdr.getFontEndAddress(), SeekMode.SET);
//here is offset [4] - 856 ?
font_bin_info = new FontBinInfo[(int) hdr.font_count];
font_bin_info = new IggyFontBinInfo[(int) hdr.font_count];
for (int i = 0; i < hdr.font_count; i++) {
font_bin_info[i] = new FontBinInfo(s);
font_bin_info[i] = new IggyFontBinInfo(s);
}
s.seek(hdr.getSequenceStartAddress1(), SeekMode.SET);
sequence = new IggySequence(s);
s.seek(hdr.getTypeFontsAddress(), SeekMode.SET);
type_info = new IggyFontTypeInfo[(int) hdr.font_count];
type_info_name = new String[(int) hdr.font_count];
@@ -208,52 +288,72 @@ public class IggySwf implements StructureInterface {
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
IggyIndexBuilder ib = s.getIndexing();
hdr.writeToDataStream(s);
s.getIndexing().writeIndexUI8SkipTwice8(184, 25);
ib.writeLengthSkipTwice(184, 0);
s.writeWChar(name);
s.pad8bytes();
s.writeUI64(1);
for (int i = 0; i < font_data_addresses.length; i++) {
long offset = font_data_addresses[i] - s.position();
ib.write16bitArray(name.length() + 1);
ib.writeTwoPaddingBytes();
ib.write64bitPointerArray(64);
for (int i = 0; i < font_data_addresses.size(); i++) {
long offset = font_data_addresses.get(i) - s.position();
s.writeUI64(offset);
}
for (int i = 0; i < text_addresses.size(); i++) {
long offset = text_addresses.get(i) - s.position();
for (int i = 0; i < text_data_addresses.size(); i++) {
long offset = text_data_addresses.get(i) - s.position();
s.writeUI64(offset);
}
if (hdr.font_count > 0) {
while (s.position() < font_data_addresses[0]) {
s.writeUI64(1);
}
}
for (int i = 0; i < hdr.font_count; i++) {
s.seek(font_data_addresses[i], SeekMode.SET);
fonts.get(i).writeToDataStream(s);
}
for (int i = 0; i < text_data_bytes.size(); i++) {
s.seek(text_addresses.get(i), SeekMode.SET);
s.writeBytes(text_data_bytes.get(i));
s.writeUI64(1);
if (additional_address != 0) {
long ofs_additional = additional_address - s.position();
s.writeUI64(ofs_additional);
}
if (hdr.isImported()) {
s.seek(font_add_off.get(0), SeekMode.SET);
s.writeBytes(font_add_data);
while (s.position() < font_data_addresses.get(0)) {
s.writeUI64(1);
}
for (int i = 0; i < fonts.size(); i++) {
s.seek(font_data_addresses.get(i), SeekMode.SET);
fonts.get(i).writeToDataStream(s);
}
for (int i = 0; i < texts.size(); i++) {
s.seek(text_data_addresses.get(i), SeekMode.SET);
texts.get(i).writeToDataStream(s);
}
if (hdr.getImported_guid() != 0) {
for (int i = 0; i < add_fonts.size(); i++) {
s.seek(add_font_data_addresses.get(i), SeekMode.SET);
fonts.get(i).writeToDataStream(s);
}
for (int i = 0; i < add_texts.size(); i++) {
s.seek(add_text_data_addresses.get(i), SeekMode.SET);
texts.get(i).writeToDataStream(s);
}
}
s.seek(hdr.getFontEndAddress(), SeekMode.SET);
ib.writeConstLengthArray(IggyIndexBuilder.CONST_BIN_INFO_SIZE, hdr.font_count);
for (int i = 0; i < hdr.font_count; i++) {
font_bin_info[i].writeToDataStream(s);
}
s.seek(hdr.getSequenceStartAddress1(), SeekMode.SET);
sequence.writeToDataStream(s);
ib.writeConstLengthArray(IggyIndexBuilder.CONST_TYPE_INFO_SIZE, hdr.font_count);
s.seek(hdr.getTypeFontsAddress(), SeekMode.SET);
for (int i = 0; i < hdr.font_count; i++) {
type_info[i].writeToDataStream(s);
}
for (int i = 0; i < hdr.font_count; i++) {
ib.write16bitArray(type_info_name[i].length() + 1);
type_info[i].writeFontInfo(type_info_name[i], s);
}
s.pad8bytes();
ib.pad8bytes();
s.seek(hdr.getDeclStringsAddress(), SeekMode.SET);
decl_strings.writeToDataStream(s);
}

View File

@@ -3,7 +3,9 @@ package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.IOException;
@@ -13,6 +15,8 @@ import java.io.IOException;
*/
public class IggyText implements StructureInterface {
public static final int STRUCT_SIZE = 104;
public static final int ID = 0xFF06;
@IggyFieldType(DataType.uint16_t)
@@ -58,6 +62,8 @@ public class IggyText implements StructureInterface {
long one;
@IggyArrayFieldType(value = DataType.uint8_t, count = 32)
byte[] some; // same for different fonts
long ofs_name;
@IggyArrayFieldType(value = DataType.wchar_t)
String initialText; //till end of info file?
@@ -95,51 +101,42 @@ public class IggyText implements StructureInterface {
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();
ofs_name = s.readUI64();
long name_address = ofs_name + s.position() - 8;
s.seek(name_address, SeekMode.SET);
initialText = s.readWChar();
s.pad8bytes();
}
@Override
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
s.getIndexing().writeConstLength(IggyIndexBuilder.CONST_IMPORTED_DATA_SIZE);
s.writeUI16(type);
s.writeUI16(textIndex);
s.writeBytes(zeroone);
s.writeFloat(par1);
s.writeFloat(par2);
s.writeFloat(par3);
s.writeFloat(par4);
s.writeUI16(enum_hex);
s.writeUI16(fontIndex);
s.writeUI32(zero);
s.writeUI64(one);
s.writeBytes(some);
s.writeUI64(ofs_name);
long name_address = ofs_name + s.position() - 8;
s.seek(name_address, SeekMode.SET);
s.writeWChar(initialText);
s.pad8bytes();
s.getIndexing().write16bitArray(initialText.length() + 1);
s.getIndexing().pad8bytes();
}
public int getType() {

View File

@@ -102,12 +102,13 @@ public class IggyToSwfConvertor {
fat.useNetwork = false;
swf.addTag(fat);
Set<Integer> fontIndices = file.getFontIds(swfIndex);
//Set<Integer> fontIndices = file.getFontIds(swfIndex);
int fontCount = file.getFontCount(swfIndex);
int currentCharId = 0;
Map<Integer, Integer> fontIndex2CharId = new HashMap<>();
for (int fontIndex : fontIndices) {
for (int fontIndex = 0; fontIndex < fontCount; fontIndex++) {
IggyFont iggyFont = file.getFont(swfIndex, fontIndex);
DefineFont2Tag fontTag = new DefineFont2Tag(swf);
currentCharId++;

View File

@@ -199,11 +199,22 @@ public abstract class AbstractDataStream implements DataStreamInterface {
@Override
public void pad8bytes() throws IOException {
int pad8 = 8 - (int) (position() % 8);
if (pad8 < 8) {
for (int i = 0; i < pad8; i++) {
int pad8 = (int) (position() % 8);
switch (pad8) {
case 1:
write(0);
case 2:
write(0);
case 3:
write(0);
case 4:
write(0);
case 5:
write(0);
case 6:
write(0);
case 7:
write(0);
}
}
}

View File

@@ -1,84 +0,0 @@
package com.jpexs.decompiler.flash.iggy.streams;
/**
*
* @author JPEXS
*/
public class EmptyIndexing implements IndexingDataStreamInterface {
@Override
public void writeIndexToTable(int val0to255) {
}
@Override
public long writeIndexFromTable(int tableIndex0to127) {
return 0;
}
@Override
public long writeIndex40(int num1to40, int countUI8) {
return 0;
}
@Override
public long writeIndexMultiply2(int num0to15) {
return 0;
}
@Override
public long writeIndexPtr(boolean is64, long cnt) {
return 0;
}
@Override
public long writeIndex16bit(long cnt) {
return 0;
}
@Override
public long writeIndex32bit(long cnt) {
return 0;
}
@Override
public long writeIndex64bit(long cnt) {
return 0;
}
@Override
public long writeIndexSkip1() {
return 0;
}
@Override
public long writeIndexUI8SkipTwice8(int ofs, int skipTwice) {
return 0;
}
@Override
public long writeIndexUI8Positive(int val) {
return 0;
}
@Override
public long writeIndexUI32(long offset) {
return 0;
}
@Override
public long writeIndex(int code, boolean is64, long val, long val2) {
return 0;
}
@Override
public byte[] getIndexTableBytes() {
return new byte[0];
}
@Override
public byte[] getIndexBytes() {
return new byte[0];
}
}

View File

@@ -0,0 +1,430 @@
package com.jpexs.decompiler.flash.iggy.streams;
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
import com.jpexs.decompiler.flash.iggy.IggyFontBinInfo;
import com.jpexs.decompiler.flash.iggy.IggyFontTypeInfo;
import com.jpexs.decompiler.flash.iggy.IggySequence;
import com.jpexs.decompiler.flash.iggy.IggyShape;
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class IggyIndexBuilder {
private static Logger LOGGER = Logger.getLogger(IggyIndexBuilder.class.getName());
/*static PrintWriter pw;
static {
try {
pw = new PrintWriter("d:\\Dropbox\\jpexs-laptop\\iggi\\extraxtdir_new\\index.txt");
} catch (FileNotFoundException ex) {
Logger.getLogger(IggyIndexParser.class.getName()).log(Level.SEVERE, null, ex);
}
LOGGER.setLevel(Level.ALL);
LOGGER.addHandler(new Handler() {
@Override
public void publish(LogRecord record) {
pw.println("" + record.getMessage());
}
@Override
public void flush() {
pw.flush();
}
@Override
public void close() throws SecurityException {
pw.close();
}
});
}*/
private static final int CODE_FC_SKIP1 = 0xFC;
private static final int CODE_FD_OFS8_SKIP_TWICE8 = 0xFD;
private static final int CODE_FE_OFS8_POSITIVE = 0xFE;
private static final int CODE_FF_OFS32 = 0xFF;
private List<Integer> constTable = new ArrayList<>();
private WriteDataStreamInterface indexStream;
private static final int CONST_VAL_SHAPE_NODE_SIZE = IggyShapeNode.STRUCT_SIZE;
private static final int CONST_VAL_KERNING_RECORD_SIZE = IggyCharKerning.STRUCT_SIZE;
private static final int CONST_VAL_CHAR_OFFSET_SIZE = IggyCharOffset.STRUCT_SIZE;
private static final int CONST_VAL_BIN_INFO_SIZE = IggyFontBinInfo.STRUCT_SIZE;
private static final int CONST_VAL_TYPE_INFO_SIZE = IggyFontTypeInfo.STRUCT_SIZE;
private static final int CONST_VAL_SHAPE_SIZE = IggyShape.STRUCT_SIZE;
private static final int CONST_VAL_GENERAL_FONT_INFO_SIZE = 112;
private static final int CONST_VAL_GENERAL_FONT_INFO2_SIZE = 240;
private static final int CONST_VAL_IMPORTED_DATA_SIZE = 104;
private static final int CONST_VAL_SEQUENCE_SIZE = IggySequence.STRUCT_SIZE;
public static final int[] DEFAULT_CONST_TABLE = new int[]{
CONST_VAL_SHAPE_NODE_SIZE,
CONST_VAL_KERNING_RECORD_SIZE,
CONST_VAL_CHAR_OFFSET_SIZE,
CONST_VAL_BIN_INFO_SIZE,
CONST_VAL_TYPE_INFO_SIZE,
CONST_VAL_SHAPE_SIZE,
CONST_VAL_GENERAL_FONT_INFO_SIZE,
CONST_VAL_GENERAL_FONT_INFO2_SIZE,
CONST_VAL_IMPORTED_DATA_SIZE,
CONST_VAL_SEQUENCE_SIZE
};
public static final int CONST_SHAPE_NODE_SIZE = 0;
public static final int CONST_KERNING_RECORD_SIZE = 1;
public static final int CONST_CHAR_OFFSET_SIZE = 2;
public static final int CONST_BIN_INFO_SIZE = 3;
public static final int CONST_TYPE_INFO_SIZE = 4;
public static final int CONST_SHAPE_SIZE = 5;
public static final int CONST_GENERAL_FONT_INFO_SIZE = 6;
public static final int CONST_GENERAL_FONT_INFO2_SIZE = 7;
public static final int CONST_IMPORTED_DATA_SIZE = 8;
public static final int CONST_SEQUENCE_SIZE = 9;
//If these skipped numbers matter, this is sample
final byte[] STATIC_HDR = new byte[]{(byte) 0x0A, (byte) 0x18, (byte) 0x07, (byte) 0x00, (byte) 0x05, (byte) 0x04, (byte) 0x05, (byte) 0x08, (byte) 0x05, (byte) 0x0C, (byte) 0x05, (byte) 0x12, (byte) 0x04, (byte) 0x14, (byte) 0x04, (byte) 0x16,
(byte) 0x04, (byte) 0x06, (byte) 0x03, (byte) 0x00, (byte) 0x04, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x04, (byte) 0x20, (byte) 0x03, (byte) 0x08, (byte) 0x04, (byte) 0x10, (byte) 0x08, (byte) 0x18,
(byte) 0x02, (byte) 0x60, (byte) 0x0D, (byte) 0x00, (byte) 0x02, (byte) 0x09, (byte) 0x03, (byte) 0x0C, (byte) 0x05, (byte) 0x10, (byte) 0x05, (byte) 0x14, (byte) 0x05, (byte) 0x18, (byte) 0x05, (byte) 0x1C,
(byte) 0x05, (byte) 0x20, (byte) 0x05, (byte) 0x24, (byte) 0x05, (byte) 0x28, (byte) 0x04, (byte) 0x30, (byte) 0x02, (byte) 0x38, (byte) 0x04, (byte) 0x3A, (byte) 0x04, (byte) 0x18, (byte) 0x02, (byte) 0x08,
(byte) 0x02, (byte) 0x10, (byte) 0x05, (byte) 0x40, (byte) 0x09, (byte) 0x00, (byte) 0x05, (byte) 0x04, (byte) 0x05, (byte) 0x08, (byte) 0x05, (byte) 0x0C, (byte) 0x05, (byte) 0x10, (byte) 0x02, (byte) 0x18,
(byte) 0x05, (byte) 0x20, (byte) 0x02, (byte) 0x28, (byte) 0x02, (byte) 0x30, (byte) 0x02, (byte) 0x70, (byte) 0x12, (byte) 0x01, (byte) 0x0C, (byte) 0x02, (byte) 0x04, (byte) 0x08, (byte) 0x05, (byte) 0x10,
(byte) 0x02, (byte) 0x20, (byte) 0x04, (byte) 0x22, (byte) 0x04, (byte) 0x24, (byte) 0x04, (byte) 0x26, (byte) 0x04, (byte) 0x2B, (byte) 0x03, (byte) 0x30, (byte) 0x02, (byte) 0x38, (byte) 0x02, (byte) 0x40,
(byte) 0x02, (byte) 0x48, (byte) 0x05, (byte) 0x4C, (byte) 0x05, (byte) 0x50, (byte) 0x05, (byte) 0x54, (byte) 0x05, (byte) 0x58, (byte) 0x05, (byte) 0x60, (byte) 0x02, (byte) 0xF0, (byte) 0x01, (byte) 0x10,
(byte) 0x02, (byte) 0x68, (byte) 0x12, (byte) 0x01, (byte) 0x0C, (byte) 0x02, (byte) 0x04, (byte) 0x08, (byte) 0x05, (byte) 0x10, (byte) 0x02, (byte) 0x20, (byte) 0x05, (byte) 0x24, (byte) 0x05, (byte) 0x28,
(byte) 0x05, (byte) 0x2C, (byte) 0x05, (byte) 0x30, (byte) 0x04, (byte) 0x32, (byte) 0x04, (byte) 0x38, (byte) 0x02, (byte) 0x44, (byte) 0x04, (byte) 0x46, (byte) 0x04, (byte) 0x48, (byte) 0x04, (byte) 0x4A,
(byte) 0x04, (byte) 0x4C, (byte) 0x04, (byte) 0x4E, (byte) 0x04, (byte) 0x60, (byte) 0x02, (byte) 0x10, (byte) 0x02, (byte) 0x00, (byte) 0x02, (byte) 0x08, (byte) 0x05};
private long position = 0;
public IggyIndexBuilder() throws IOException {
indexStream = new TemporaryDataStream();
for (int i = 0; i < DEFAULT_CONST_TABLE.length; i++) {
constTable.add(DEFAULT_CONST_TABLE[i]);
}
}
private byte[] getIndexTableBytes() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(constTable.size());
for (int i = 0; i < constTable.size(); i++) {
baos.write(constTable.get(i));
baos.write(0);
}
return baos.toByteArray();
}
public byte[] getIndexBytes() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(getIndexTableBytes());
baos.write(indexStream.getAllBytes());
} catch (IOException ex) {
//should not happen
}
return baos.toByteArray();
}
public long writeConstLength(int constIndex) {
return writeIndex(constIndex, false, 0, 0);
}
private long writeConstLengthArrayUpTo64(int constIndex, int cntUpTo64) {
if (cntUpTo64 == 1) {
return writeIndex(constIndex, false, 0, 0);
}
return writeIndex(0x80 + cntUpTo64 - 1, false, constIndex, 0);
}
/*private int indexOfConst(int val) {
int index = constTable.indexOf(val);
if (index > -1) {
return index;
}
constTable.add(val);
return constTable.size() - 1;
}*/
public long writeConstLengthArray(int constIndex, long cnt) {
long ret = 0;
long rem = cnt;
while (true) {
if (rem <= 64) {
ret += writeConstLengthArrayUpTo64(constIndex, (int) rem);
break;
} else {
rem -= 64;
ret += writeConstLengthArrayUpTo64(constIndex, 64);
}
}
return ret;
}
public long pad8bytes() {
int pad8 = (int) (position % 8);
switch (pad8) {
case 2:
writePaddingBytes(2); //+6
break;
case 4:
writePaddingBytes(1); //+4
break;
case 6:
writePaddingBytes(0); // +2
break;
}
return 0;
}
public long writeTwoPaddingBytes() {
return writePaddingBytes(0);
}
public long writePadding16bit() {
return writePaddingBytes(0);
}
public long writePadding32bit() {
return writePaddingBytes(1);
}
public long writePadding64bit() {
return writePaddingBytes(2);
}
public long writePaddingBytes(int twoPlusHowManyTwoBytes) {
return writeIndex(0xC0 + twoPlusHowManyTwoBytes, false, 0, 0);
}
public long writePointerArray(boolean is64, long cnt) {
return writeIndex(0xD0 + 0x2, is64, cnt - 1, 0);
}
public long write64bitPointerArray(long cnt) {
return writeIndex(0xD0 + 0x2, true, cnt - 1, 0);
}
public long write32bitPointerArray(long cnt) {
return writeIndex(0xD0 + 0x2, false, cnt - 1, 0);
}
public long write16bitArray(long cnt) {
return writeIndex(0xD0 + 0x4, false, cnt - 1, 0);
}
public long write32bitArray(long cnt) {
return writeIndex(0xD0 + 0x5, false, cnt - 1, 0);
}
public long write64bitArray(long cnt) {
return writeIndex(0xD0 + 0x6, false, cnt - 1, 0);
}
public long skipOneInIndex() {
return writeIndex(CODE_FC_SKIP1, false, 0, 0);
}
public long writeLengthSkipTwice(int lenUI8, int skipTwice) {
return writeIndex(CODE_FD_OFS8_SKIP_TWICE8, false, lenUI8, skipTwice);
}
public long writeLengthBytePositive(int valUI8) {
return writeIndex(CODE_FE_OFS8_POSITIVE, false, valUI8, 0);
}
public long writeLengthUI32(long offset) {
return writeIndex(CODE_FF_OFS32, false, offset, 0);
}
private long writeIndex(int code, boolean is64, long val, long skipNum) {
try {
LOGGER.finest(String.format("index offset: %d, %04X", STATIC_HDR.length + indexStream.position(), STATIC_HDR.length + indexStream.position()));
LOGGER.finer(String.format("Code = 0x%02X", code));
indexStream.writeUI8(code);
if (code < 0x80) // 0-0x7F
{
LOGGER.finest("0-0x7F: code is directly an index to the index_table");
// code is directly an index to the index_table
if (code >= constTable.size()) {
LOGGER.severe(String.format("< 0x80: index is greater than index_table_size. %x > %x", code, constTable.size()));
return 0;
}
LOGGER.finest(String.format("LENGTH = indexTable[%d] = %d", code, constTable.get(code)));
long ret = constTable.get(code);
position += ret;
return ret;
} else if (code < 0xC0) // 0x80-BF
{
LOGGER.finest("0x80-BF: table[0..255]*(code-0x7F)");
int index;
indexStream.writeUI8((int) val);
if ((index = (int) val) < 0) {
LOGGER.severe(String.format("< 0xC0: Cannot read index."));
return 0;
}
if (index >= constTable.size()) {
LOGGER.severe(String.format("< 0xC0: index is greater than index_table_size. %x > %x", index, constTable.size()));
return 0;
}
int n = code - 0x7F;
LOGGER.finest(String.format("index = %d, n = code - 0x7F = %d", index, n));
LOGGER.finest(String.format("LENGTH = indexTable[index] * n = indexTable[%d] * %d = %d", index, n, constTable.get(index) * n));
long ret = constTable.get(index) * n;
position += ret;
return ret;
} else if (code < 0xD0) // 0xC0-0xCF
{
LOGGER.finest("0xC0-CF: code*2-0x17E");
long ret = ((code * 2) - 0x17E);
position += ret;
return ret;
} else if (code < 0xE0) // 0xD0-0xDF
{
LOGGER.finest("0xD0-0xDF: platform based");
// 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;
indexStream.writeUI8((int) val);
if ((n8 = (int) val) < 0) {
LOGGER.severe(String.format("< 0xE0: Cannot read n."));
return 0;
}
n = n8 + 1;
LOGGER.finest(String.format("i=%X", i));
LOGGER.finest(String.format("n=%d", n));
if (is64) {
if (i <= 2) {
LOGGER.finest(String.format("offset += %d", 8 * n));
position += 8 * n;
return 8 * n; // Ptr type
} else if (i <= 4) {
LOGGER.finest(String.format("offset += %d", 2 * n));
position += 2 * n;
return 2 * n;
} else if (i == 5) {
LOGGER.finest(String.format("offset += %d", 4 * n));
position += 4 * n;
return 4 * n;
} else if (i == 6) {
LOGGER.finest(String.format("offset += %d", 8 * n));
position += 8 * n;
return 8 * n; // 64 bits type
} else {
LOGGER.severe(String.format("< 0xE0: Invalid value for i (%x %x)", i, code));
return 0;
}
} else {
switch (i) {
case 2:
LOGGER.finest(String.format("offset += %d", 4 * n));
position += 4 * n;
return 4 * n; // Ptr type;
case 4:
LOGGER.finest(String.format("offset += %d", 2 * n));
position += 2 * n;
return 2 * n;
case 5:
LOGGER.finest(String.format("offset += %d", 4 * n));
position += 4 * n;
return 4 * n; // 32 bits type
case 6:
LOGGER.finest(String.format("offset += %d", 8 * n));
position += 8 * n;
return 8 * n;
default:
LOGGER.severe(String.format("< 0xE0: invalid value for i (%x %x)", i, code));
return 0;
}
}
} else if (code == CODE_FC_SKIP1) {
LOGGER.finest(String.format("0xFC: skip 1 "));
//indexStream.seek(1, SeekMode.CUR);
return 1; //seek 1
} else if (code == CODE_FD_OFS8_SKIP_TWICE8) {
LOGGER.finest(String.format("0xFD: 0..255, skip 2 * 0..255 "));
int n, m;
indexStream.writeUI8((int) val);
if ((n = (int) val) < 0) {
LOGGER.severe(String.format("0xFD: Cannot read n."));
return 0;
}
indexStream.writeUI8((int) skipNum);
if ((m = (int) skipNum) < 0) {
LOGGER.severe(String.format("0xFD: Cannot read m."));
return 0;
}
long offset = n;
position += n;
LOGGER.finest(String.format("offset += %d", n));
long skip = m * 2;
LOGGER.finest(String.format("skip %d", m * 2));
return offset + skip;
} else if (code == CODE_FE_OFS8_POSITIVE) {
LOGGER.finest(String.format("0xFD: 0..255 + 1 "));
int n8;
int n;
indexStream.writeUI8((int) val);
if ((n8 = (int) val) < 0) {
LOGGER.severe(String.format("0xFE: Cannot read n."));
return 0;
}
n = n8 + 1;
position += n;
LOGGER.finest(String.format("offset += %d", n));
return n;
} else if (code == CODE_FF_OFS32) {
LOGGER.finest(String.format("0xFF: 32bit "));
long n;
indexStream.writeUI32(val);
if ((n = val) < 0) {
LOGGER.severe(String.format("0xFF: Cannot read n."));
return 0;
}
LOGGER.finest(String.format("offset += %d", n));
position += n;
return n;
} else {
LOGGER.warning(String.format("Unrecognized code: %x", code));
return 0;
}
} catch (IOException ex) {
return 0;
}
}
}

View File

@@ -1,10 +1,8 @@
package com.jpexs.decompiler.flash.iggy;
package com.jpexs.decompiler.flash.iggy.streams;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
@@ -14,30 +12,40 @@ import java.util.logging.Logger;
/**
*
* @author Jindra
* @author JPEXS
*/
public class IggyIndexParser {
private static Logger LOGGER = Logger.getLogger(IggyIndexParser.class.getName());
/*
static PrintWriter pw;
static {
try {
pw = new PrintWriter("d:\\Dropbox\\jpexs-laptop\\iggi\\extraxtdir_new\\index.txt");
} catch (FileNotFoundException ex) {
Logger.getLogger(IggyIndexParser.class.getName()).log(Level.SEVERE, null, ex);
}
LOGGER.setLevel(Level.ALL);
LOGGER.addHandler(new Handler() {
@Override
public void publish(LogRecord record) {
System.out.println("" + record.getMessage());
pw.println("" + record.getMessage());
}
@Override
public void flush() {
pw.flush();
}
@Override
public void close() throws SecurityException {
pw.close();
}
});
}
*/
/**
* Parser for index data. It creates table of indices and table of offsets
*
@@ -51,7 +59,7 @@ public class IggyIndexParser {
int[] indexTable = new int[indexTableSize];
for (int i = 0; i < indexTableSize; i++) {
int offset = indexStream.readUI8();
LOGGER.fine(String.format("index_table_entry: %02x", offset));
LOGGER.fine(String.format("index_table_entry: %d", offset));
indexTable[i] = offset;
indexTableEntry.add(offset);
int num = indexStream.readUI8();
@@ -61,8 +69,12 @@ public class IggyIndexParser {
long offset = 0;
int code;
String tabs = "\t\t\t\t";
LOGGER.finer(String.format("-- OFFSET: 0" + tabs));
while ((code = indexStream.readUI8()) > -1) {
LOGGER.finer(String.format("Code = %x", code));
LOGGER.finer(String.format("Code = 0x%02X", code));
if (code < 0x80) // 0-0x7F
{
@@ -74,7 +86,7 @@ public class IggyIndexParser {
}
offset += indexTable[code];
LOGGER.finest(String.format("ofset += %d", indexTable[code]));
LOGGER.finest(String.format("LENGTH = indexTable[%d] = %d", code, indexTable[code]));
} else if (code < 0xC0) // 0x80-BF
{
@@ -92,11 +104,14 @@ public class IggyIndexParser {
}
int n = code - 0x7F;
LOGGER.finest(String.format("index = %d, n = code - 0x7F = %d", index, n));
LOGGER.finest(String.format("LENGTH = indexTable[index] * n = indexTable[%d] * %d = %d", index, n, indexTable[index] * n));
offset += indexTable[index] * n;
} else if (code < 0xD0) // 0xC0-0xCF
{
LOGGER.finest("0xC0-CF: code*2-0x17E");
offset += ((code * 2) - 0x17E);
LOGGER.finest(String.format("LENGTH = (code * 2) - 0x17E = (0x%02X * 2) - 0x17E = %d", code, ((code * 2) - 0x17E)));
} else if (code < 0xE0) // 0xD0-0xDF
{
LOGGER.finest("0xD0-0xDF: platform based");
@@ -119,16 +134,16 @@ public class IggyIndexParser {
if (is64) {
if (i <= 2) {
offset += 8 * n; // Ptr type
LOGGER.finest(String.format("offset += %d", 8 * n));
LOGGER.finest(String.format("LENGTH = 8 * n = 8 * %d = %d", n, 8 * n));
} else if (i <= 4) {
offset += 2 * n;
LOGGER.finest(String.format("offset += %d", 2 * n));
LOGGER.finest(String.format("LENGTH = 2 * n = 2 * %d = %d", n, 2 * n));
} else if (i == 5) {
offset += 4 * n;
LOGGER.finest(String.format("offset += %d", 4 * n));
LOGGER.finest(String.format("LENGTH = 4 * n = 4 * %d = %d", n, 4 * n));
} else if (i == 6) {
offset += 8 * n; // 64 bits type
LOGGER.finest(String.format("offset += %d", 8 * n));
LOGGER.finest(String.format("LENGTH = 8 * n = 8 * %d = %d", n, 8 * n));
} else {
LOGGER.severe(String.format("< 0xE0: Invalid value for i (%x %x)", i, code));
}
@@ -136,26 +151,26 @@ public class IggyIndexParser {
switch (i) {
case 2:
offset += 4 * n; // Ptr type
LOGGER.finest(String.format("offset += %d", 4 * n));
LOGGER.finest(String.format("LENGTH = 4 * n = 4 * %d = %d", n, 4 * n));
break;
case 4:
offset += 2 * n;
LOGGER.finest(String.format("offset += %d", 2 * n));
LOGGER.finest(String.format("LENGTH = 2 * n = 2 * %d = %d", n, 2 * n));
break;
case 5:
offset += 4 * n; // 32 bits type
LOGGER.finest(String.format("offset += %d", 4 * n));
LOGGER.finest(String.format("LENGTH = 4 * n = 4 * %d = %d", n, 4 * n));
break;
case 6:
offset += 8 * n;
LOGGER.finest(String.format("offset += %d", 8 * n));
LOGGER.finest(String.format("LENGTH = 8 * n = 8 * %d = %d", n, 8 * n));
break;
default:
LOGGER.severe(String.format("< 0xE0: invalid value for i (%x %x)", i, code));
}
}
} else if (code == 0xFC) {
LOGGER.finest(String.format("0xFC: skip 1 "));
LOGGER.finest(String.format("0xFC: SKIP 1 "));
indexStream.seek(1, SeekMode.CUR);
} else if (code == 0xFD) {
LOGGER.finest(String.format("0xFD: 0..255, skip 2 * 0..255 "));
@@ -165,16 +180,18 @@ public class IggyIndexParser {
LOGGER.severe(String.format("0xFD: Cannot read n."));
return;
}
LOGGER.finest(String.format("n = %d", n));
if ((m = indexStream.readUI8()) < 0) {
LOGGER.severe(String.format("0xFD: Cannot read m."));
return;
}
LOGGER.finest(String.format("m = %d", m));
offset += n;
LOGGER.finest(String.format("offset += %d", n));
LOGGER.finest(String.format("LENGTH = n = %d", n));
indexStream.seek(m * 2, SeekMode.CUR);
LOGGER.finest(String.format("skip %d", m * 2));
LOGGER.finest(String.format("SKIP m * 2 = skip %d * 2 = %d", m, m * 2));
} else if (code == 0xFE) {
LOGGER.finest(String.format("0xFD: 0..255 + 1 "));
int n8;
@@ -184,10 +201,11 @@ public class IggyIndexParser {
LOGGER.severe(String.format("0xFE: Cannot read n."));
return;
}
LOGGER.finest(String.format("n8 = %d", n8));
n = n8 + 1;
offset += n;
LOGGER.finest(String.format("offset += %d", n));
LOGGER.finest(String.format("LENGTH = n8 + 1 = %d + 1 = %d", n8, n));
} else if (code == 0xFF) {
LOGGER.finest(String.format("0xFF: 32bit "));
long n;
@@ -198,12 +216,12 @@ public class IggyIndexParser {
}
offset += n;
LOGGER.finest(String.format("offset += %d", n));
LOGGER.finest(String.format("LENGTH = n = %d", n));
} else {
LOGGER.warning(String.format("Unrecognized code: %x", code));
}
LOGGER.finer(String.format("OFFSET: %d", offset));
LOGGER.finer(String.format("-- OFFSET: %d" + tabs, offset));
offsets.add(offset);
}

View File

@@ -1,272 +0,0 @@
package com.jpexs.decompiler.flash.iggy.streams;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class IndexingDataStream implements IndexingDataStreamInterface {
public static final int CODE_FC_SKIP1 = 0xFC;
public static final int CODE_FD_OFS8_SKIP_TWICE8 = 0xFD;
public static final int CODE_FE_OFS8_POSITIVE = 0xFE;
public static final int CODE_FF_OFS32 = 0xFF;
private static Logger LOGGER = Logger.getLogger(IndexingDataStream.class.getName());
private List<Integer> indexTable;
private WriteDataStreamInterface indexStream;
public IndexingDataStream() throws IOException {
indexStream = new TemporaryDataStream();
indexTable = new ArrayList<>();
}
@Override
public byte[] getIndexTableBytes() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(indexTable.size());
for (int i = 0; i < indexTable.size(); i++) {
baos.write(indexTable.get(i));
if (i == indexTable.size() - 1) {
int pad8 = (indexTable.size() * 2) % 8;
baos.write(pad8 / 2); //pad to 8 bytes(?)
} else {
baos.write(0); //how many bytes to skip
}
}
return baos.toByteArray();
}
public byte[] getIndexBytes() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(getIndexTableBytes());
baos.write(indexStream.getAllBytes());
} catch (IOException ex) {
//should not happen
}
return baos.toByteArray();
}
@Override
public void writeIndexToTable(int val0to255) {
indexTable.add(val0to255);
}
@Override
public long writeIndexFromTable(int tableIndex0to127) {
return writeIndex(tableIndex0to127, false, 0, 0);
}
@Override
public long writeIndex40(int num1to40, int countUI8) {
return writeIndex(0x80 + num1to40, false, countUI8, 0);
}
@Override
public long writeIndexMultiply2(int num0to15) {
return writeIndex(0xC0 + num0to15, false, 0, 0);
}
@Override
public long writeIndexPtr(boolean is64, long cnt) {
return writeIndex(0xD0 + 0x2, false, cnt - 1, 0);
}
@Override
public long writeIndex16bit(long cnt) {
return writeIndex(0xD0 + 0x4, false, cnt - 1, 0);
}
@Override
public long writeIndex32bit(long cnt) {
return writeIndex(0xD0 + 0x5, false, cnt - 1, 0);
}
@Override
public long writeIndex64bit(long cnt) {
return writeIndex(0xD0 + 0x6, false, cnt - 1, 0);
}
@Override
public long writeIndexSkip1() {
return writeIndex(CODE_FC_SKIP1, false, 0, 0);
}
@Override
public long writeIndexUI8SkipTwice8(int ofs, int skipTwice) {
return writeIndex(CODE_FD_OFS8_SKIP_TWICE8, false, ofs, skipTwice);
}
@Override
public long writeIndexUI8Positive(int val) {
return writeIndex(CODE_FE_OFS8_POSITIVE, false, val, 0);
}
@Override
public long writeIndexUI32(long offset) {
return writeIndex(CODE_FF_OFS32, false, offset, 0);
}
@Override
public long writeIndex(int code, boolean is64, long val, long skipNum) {
try {
indexStream.writeUI8(code);
if (code < 0x80) // 0-0x7F
{
LOGGER.finest("0-0x7F: code is directly an index to the index_table");
// code is directly an index to the index_table
if (code >= indexTable.size()) {
LOGGER.severe(String.format("< 0x80: index is greater than index_table_size. %x > %x", code, indexTable.size()));
return 0;
}
LOGGER.finest(String.format("ofset += %d", indexTable.get(code)));
return indexTable.get(code);
} else if (code < 0xC0) // 0x80-BF
{
LOGGER.finest("0x80-BF: table[0..255]*(code-0x7F)");
int index;
indexStream.writeUI8((int) val);
if ((index = (int) val) < 0) {
LOGGER.severe(String.format("< 0xC0: Cannot read index."));
return 0;
}
if (index >= indexTable.size()) {
LOGGER.severe(String.format("< 0xC0: index is greater than index_table_size. %x > %x", index, indexTable.size()));
return 0;
}
int n = code - 0x7F;
return indexTable.get(index) * n;
} else if (code < 0xD0) // 0xC0-0xCF
{
LOGGER.finest("0xC0-CF: code*2-0x17E");
return ((code * 2) - 0x17E);
} else if (code < 0xE0) // 0xD0-0xDF
{
LOGGER.finest("0xD0-0xDF: platform based");
// 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;
indexStream.writeUI8((int) val);
if ((n8 = (int) val) < 0) {
LOGGER.severe(String.format("< 0xE0: Cannot read n."));
return 0;
}
n = n8 + 1;
LOGGER.finest(String.format("i=%X", i));
LOGGER.finest(String.format("n=%d", n));
if (is64) {
if (i <= 2) {
LOGGER.finest(String.format("offset += %d", 8 * n));
return 8 * n; // Ptr type
} else if (i <= 4) {
LOGGER.finest(String.format("offset += %d", 2 * n));
return 2 * n;
} else if (i == 5) {
LOGGER.finest(String.format("offset += %d", 4 * n));
return 4 * n;
} else if (i == 6) {
LOGGER.finest(String.format("offset += %d", 8 * n));
return 8 * n; // 64 bits type
} else {
LOGGER.severe(String.format("< 0xE0: Invalid value for i (%x %x)", i, code));
return 0;
}
} else {
switch (i) {
case 2:
LOGGER.finest(String.format("offset += %d", 4 * n));
return 4 * n; // Ptr type;
case 4:
LOGGER.finest(String.format("offset += %d", 2 * n));
return 2 * n;
case 5:
LOGGER.finest(String.format("offset += %d", 4 * n));
return 4 * n; // 32 bits type
case 6:
LOGGER.finest(String.format("offset += %d", 8 * n));
return 8 * n;
default:
LOGGER.severe(String.format("< 0xE0: invalid value for i (%x %x)", i, code));
return 0;
}
}
} else if (code == CODE_FC_SKIP1) {
LOGGER.finest(String.format("0xFC: skip 1 "));
//indexStream.seek(1, SeekMode.CUR);
return 1; //seek 1
} else if (code == CODE_FD_OFS8_SKIP_TWICE8) {
LOGGER.finest(String.format("0xFD: 0..255, skip 2 * 0..255 "));
int n, m;
indexStream.writeUI8((int) val);
if ((n = (int) val) < 0) {
LOGGER.severe(String.format("0xFD: Cannot read n."));
return 0;
}
indexStream.writeUI8((int) skipNum);
if ((m = (int) skipNum) < 0) {
LOGGER.severe(String.format("0xFD: Cannot read m."));
return 0;
}
long offset = n;
LOGGER.finest(String.format("offset += %d", n));
long skip = m * 2;
LOGGER.finest(String.format("skip %d", m * 2));
return offset + skip;
} else if (code == CODE_FE_OFS8_POSITIVE) {
LOGGER.finest(String.format("0xFD: 0..255 + 1 "));
int n8;
int n;
indexStream.writeUI8((int) val);
if ((n8 = (int) val) < 0) {
LOGGER.severe(String.format("0xFE: Cannot read n."));
return 0;
}
n = n8 + 1;
LOGGER.finest(String.format("offset += %d", n));
return n;
} else if (code == CODE_FF_OFS32) {
LOGGER.finest(String.format("0xFF: 32bit "));
long n;
indexStream.writeUI32(val);
if ((n = val) < 0) {
LOGGER.severe(String.format("0xFF: Cannot read n."));
return 0;
}
LOGGER.finest(String.format("offset += %d", n));
return n;
} else {
LOGGER.warning(String.format("Unrecognized code: %x", code));
return 0;
}
} catch (IOException ex) {
return 0;
}
}
}

View File

@@ -1,38 +0,0 @@
package com.jpexs.decompiler.flash.iggy.streams;
/**
*
* @author JPEXS
*/
public interface IndexingDataStreamInterface {
public void writeIndexToTable(int val0to255);
public long writeIndexFromTable(int tableIndex0to127);
public long writeIndex40(int num1to40, int countUI8);
public long writeIndexMultiply2(int num0to15);
public long writeIndexPtr(boolean is64, long cnt);
public long writeIndex16bit(long cnt);
public long writeIndex32bit(long cnt);
public long writeIndex64bit(long cnt);
public long writeIndexSkip1();
public long writeIndexUI8SkipTwice8(int ofs, int skipTwice);
public long writeIndexUI8Positive(int val);
public long writeIndexUI32(long offset);
public long writeIndex(int code, boolean is64, long val, long val2);
public byte[] getIndexTableBytes();
public byte[] getIndexBytes();
}

View File

@@ -16,24 +16,19 @@ public class RandomAccessFileDataStream extends AbstractDataStream {
private File file;
private RandomAccessFile raf;
private IndexingDataStreamInterface indexing;
private IggyIndexBuilder indexing;
protected File getFile() {
return file;
}
@Override
public void setIndexing(IndexingDataStreamInterface indexing) {
public void setIndexing(IggyIndexBuilder indexing) {
this.indexing = indexing;
}
public RandomAccessFileDataStream(File file) throws FileNotFoundException {
this(file, new EmptyIndexing());
}
public RandomAccessFileDataStream(File file, IndexingDataStreamInterface indexing) throws FileNotFoundException {
this.file = file;
this.indexing = indexing;
raf = new RandomAccessFile(file, "rw");
}
@@ -116,22 +111,17 @@ public class RandomAccessFileDataStream extends AbstractDataStream {
}
@Override
public IndexingDataStreamInterface getIndexing() {
public IggyIndexBuilder getIndexing() {
return indexing;
}
@Override
public boolean writeWChar(String name) throws IOException {
indexing.writeIndex16bit(name.length() + 1);
return super.writeWChar(name);
}
@Override
public void pad8bytes() throws IOException {
int pad8 = 8 - (int) (position() % 8);
if (pad8 < 8) {
indexing.writeIndexMultiply2(pad8 / 2);
}
super.pad8bytes();
}

View File

@@ -46,7 +46,7 @@ public interface WriteDataStreamInterface extends AutoCloseable {
@Override
public void close();
public void setIndexing(IndexingDataStreamInterface indexing);
public void setIndexing(IggyIndexBuilder indexing);
public IndexingDataStreamInterface getIndexing();
public IggyIndexBuilder getIndexing();
}