From d84557d5b0409384c352dee8dc2e29d0cb910867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Tue, 22 Nov 2016 21:36:56 +0100 Subject: [PATCH] parsing index (WIP) --- .../decompiler/flash/iggy/IggyExtractor.java | 166 +++++++++++++++++- .../flash/iggy/IggyFlashHeader32.java | 3 +- 2 files changed, 165 insertions(+), 4 deletions(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyExtractor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyExtractor.java index 4b39b6127..b4f417aee 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyExtractor.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyExtractor.java @@ -30,6 +30,12 @@ public class IggyExtractor extends AbstractDataStream implements AutoCloseable { private IggyHeader header; private List subFileEntries = new ArrayList<>(); + List> indexTables = new ArrayList<>(); + List> offsetTables = new ArrayList<>(); + + IggyFlashHeader64 fh64 = null; + IggyFlashHeader32 fh32 = null; + public IggyExtractor(File file) throws IOException { raf = new RandomAccessFile(file, "r"); header = new IggyHeader(this); @@ -49,12 +55,18 @@ public class IggyExtractor extends AbstractDataStream implements AutoCloseable { } } - IggyFlashHeader64 fh64 = null; - IggyFlashHeader32 fh32 = null; + for (byte[] index_data : indexDatas) { + List indexTableEntry = new ArrayList<>(); + List offsets = new ArrayList<>(); + parseIndex(is64(), index_data, indexTableEntry, offsets); + indexTables.add(indexTableEntry); + offsetTables.add(offsets); + } for (ByteArrayDataStream fs : flashStreams) { if (is64()) { fh64 = new IggyFlashHeader64(fs); + System.out.println("" + fh64); } else { fh32 = new IggyFlashHeader32(fs); } @@ -636,6 +648,156 @@ public class IggyExtractor extends AbstractDataStream implements AutoCloseable { return null; } + /** + * + * @param is_64 + * @param index_bytes + * @param indexTableEntry + * @param offsets + * @throws IOException + */ + private static void parseIndex(boolean is_64, byte index_bytes[], List indexTableEntry, List offsets) throws IOException { + ByteArrayDataStream stream = new ByteArrayDataStream(index_bytes); + + int index_table_size = stream.readUI8(); + int[] index_table = new int[index_table_size]; + + for (int i = 0; i < index_table_size; i++) { + int offset = stream.readUI8(); + //System.err.printf("index_table_entry: %02x\n", offset); + index_table[i] = offset; + indexTableEntry.add(offset); + int num = stream.readUI8(); + stream.seek(num * 2, SeekMode.CUR); + } + + long offset = 0; + int code; + + while ((code = stream.readUI8()) > -1) { + //DPRINTF("Code = %x\n", code); + + if (code < 0x80) // 0-0x7F + { + // code is directly an index to the index_table + if (code >= index_table_size) { + System.err.printf("< 0x80: index is greater than index_table_size. %x > %x\n", code, index_table_size); + return; + } + + offset += index_table[code]; + } else if (code < 0xC0) // 0x80-BF + { + int index; + + if ((index = stream.readUI8()) < 0) { + System.err.printf("< 0xC0: Cannot read index.\n"); + return; + } + + if (index >= index_table_size) { + System.err.printf("< 0xC0: index is greater than index_table_size. %x > %x\n", index, index_table_size); + return; + } + + int n = code - 0x7F; + offset += index_table[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 = stream.readUI8()) < 0) { + System.err.printf("< 0xE0: Cannot read n.\n"); + return; + } + + n = n8 + 1; + + if (is_64) { + 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 { + System.err.printf("< 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: + System.err.printf("< 0xE0: invalid value for i (%x %x)\n", i, code); + } + } + } else if (code == 0xFC) { + stream.seek(1, SeekMode.CUR); + } else if (code == 0xFD) { + int n, m; + + if ((n = stream.readUI8()) < 0) { + System.err.printf("0xFD: Cannot read n.\n"); + return; + } + + if ((m = stream.readUI8()) < 0) { + System.err.printf("0xFD: Cannot read m.\n"); + return; + } + + offset += n; + stream.seek(m * 2, SeekMode.CUR); + } else if (code == 0xFE) { + int n8; + int n; + + if ((n8 = stream.readUI8()) < 0) { + System.err.printf("0xFE: Cannot read n.\n"); + return; + } + + n = n8 + 1; + offset += n; + } else if (code == 0xFF) { + long n; + + if ((n = stream.readUI32()) < 0) { + System.err.printf("0xFF: Cannot read n.\n"); + return; + } + + offset += n; + } else { + System.err.printf("Unrecognized code: %x\n", code); + } + + offsets.add(offset); + } + } + @Override public Long available() { try { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader32.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader32.java index da2b5f87b..df0231654 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader32.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader32.java @@ -1,6 +1,5 @@ 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.tags.Tag; import com.jpexs.decompiler.flash.tags.TagTypeInfo; @@ -41,7 +40,7 @@ public class IggyFlashHeader32 implements StructureInterface { @IggyFieldType(DataType.uint32_t) long ymax; // 0x24 in pixels @IggyFieldType(DataType.uint32_t) - long unk_28; // probably numer of blocks/objects after header + long unk_28; // probably number of blocks/objects after header @IggyFieldType(DataType.uint32_t) long unk_2C; @IggyFieldType(DataType.uint32_t)