diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFile.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFile.java index 4b248ef66..5704ed74d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFile.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFile.java @@ -112,475 +112,6 @@ public class IggyFile implements StructureInterface { } } - private static void processFile(File f) { - if (f.isDirectory()) { - System.out.println("Processing directory " + f + ":"); - File iggyFiles[] = f.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.endsWith(".iggy"); - } - }); - for (File sf : iggyFiles) { - processFile(sf); - } - return; - } - System.out.print("Processing file " + f + "..."); - try { - File dir = f.getParentFile(); - File extractDir = new File(dir, "extracted_" + (f.getName()).replace(".iggy", "")); - extractDir.mkdir(); - extractIggyFile(f, extractDir); - System.out.println("OK"); - } catch (Exception ex) { - System.err.println("FAIL"); - System.exit(1); - } - } - - public static void main(String[] args) throws IOException { - /* - String indexFileName = "d:\\Dropbox\\jpexs-laptop\\iggi\\extraxtdir_orig\\index4_type0.bin"; - IggyIndexParser.parseIndex(true, new TemporaryDataStream(Helper.readFile(indexFileName)), new ArrayList<>(), new ArrayList<>()); - - System.exit(0);*/ - String inFileName = "d:\\Dropbox\\jpexs-laptop\\iggi\\lib_loc_english_font.iggy"; - String outFileName = "d:\\Dropbox\\jpexs-laptop\\iggi\\lib_loc_english_font2.iggy"; - - File extractDirOrig = new File("d:\\Dropbox\\jpexs-laptop\\iggi\\extraxtdir_orig"); - File extractDirNew = new File("d:\\Dropbox\\jpexs-laptop\\iggi\\extraxtdir_new"); - - if (!extractDirOrig.exists()) { - extractDirOrig.mkdir(); - } - if (!extractDirNew.exists()) { - extractDirNew.mkdir(); - } - - File inFile = new File(inFileName); - File outFile = new File(outFileName); - IggyFile iggyFile = new IggyFile(inFile); - extractIggyFile(inFile, extractDirOrig); - iggyFile.updateFlashEntry(); - 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) { - try { - final int bufSize = 4096; - byte[] buf = new byte[bufSize]; - int cnt; - while ((cnt = is.read(buf)) > 0) { - os.write(buf, 0, cnt); - } - } catch (IOException ex) { - // ignore - } - } - - private static boolean updateIndex(long item_offset /*uint32_t*/, boolean is_64, byte index_bytes[], long item_size_change /*int32_t*/) throws IOException { - TemporaryDataStream stream = new TemporaryDataStream(index_bytes); - - /* - index_table: - n = UI8 - for i=0..n-1 - table[i] = UI8 - cnt = UI8 - cnt * UI16 - - */ - int index_table_size = stream.readUI8(); - int index_table[] = new int[index_table_size]; - - for (int i = 0; i < index_table_size; i++) { - index_table[i] = stream.readUI8(); - int num = stream.readUI8(); - stream.seek(num * 2, SeekMode.CUR); - //num * UI16 - } - - int state = 0; - long offset = 0;//uint32_t - int code; //uint8_t - - while ((code = stream.readUI8()) >= 0) { - if (state == 1) { - if (code != 0xFD) { - LOGGER.log(Level.WARNING, "We were expecting code 0xFD in state 1."); - return false; - } - } else if (state == 2) { - if (code != 0xFF) { - LOGGER.log(Level.WARNING, "We were expecting code 0xFF in state 2."); - return false; - } - } - - if (code < 0x80) // 0-0x7F - { - // code is directly an index to the index_table - if (code >= index_table_size) { - LOGGER.log(Level.WARNING, String.format("< 0x80: index is greater than index_table_size. %x > %x", code, index_table_size)); - return false; - } - - offset += index_table[code]; - } else if (code < 0xC0) // 0x80-BF - { - int index; //uint8_t - - if ((index = stream.readUI8()) < 0) { - LOGGER.log(Level.WARNING, "< 0xC0: Cannot read index."); - return false; - } - - if (index >= index_table_size) { - LOGGER.log(Level.WARNING, String.format("< 0xC0: index is greater than index_table_size. %x > %x", index, index_table_size)); - return false; - } - - 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; //uint8_t - int n8; //uint8_t - int n; - - if ((n8 = stream.readUI8()) < 0) { - LOGGER.log(Level.WARNING, "< 0xE0: Cannot read n."); - return false; - } - - 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 { - LOGGER.log(Level.WARNING, String.format("< 0xE0: Invalid value for i (%x %x)", 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.log(Level.WARNING, String.format("< 0xE0: invalid value for i (%x %x)", i, code)); - } - } - } else if (code == 0xFC) { - stream.seek(1, SeekMode.CUR); - } else if (code == 0xFD) { - int n, m; //uint8_t - - if ((n = stream.readUI8()) < 0) { - LOGGER.log(Level.WARNING, "0xFD: Cannot read n."); - return false; - } - - if (state == 1) { - if (is_64) { - if (n != 0xF) { - LOGGER.log(Level.WARNING, String.format("We were expecting an offset of 0xF in state 1.")); - return false; - } - } else if (n != 0xB) { - LOGGER.log(Level.WARNING, "We were expecting an offset of 0xB in state 1."); - return false; - } - - state = 2; - } - - if ((m = stream.readUI8()) < 0) { - LOGGER.log(Level.WARNING, "0xFD: Cannot read m."); - return false; - } - - offset += n; - stream.seek(m * 2, SeekMode.CUR); - } else if (code == 0xFE) { - int n8; //uint8_t - int n; - - if ((n8 = stream.readUI8()) < 0) { - LOGGER.log(Level.WARNING, "0xFE: Cannot read n."); - return false; - } - - n = n8 + 1; - offset += n; - } else if (code == 0xFF) { - long n; //uint32_t - - if ((n = stream.readUI32()) < 0) { - LOGGER.log(Level.WARNING, "0xFF: Cannot read n."); - return false; - } - - if (state == 2) { - n += item_size_change; - stream.seek(-4, SeekMode.CUR); - return stream.writeUI32(n); - } - - offset += n; - } else { - LOGGER.log(Level.WARNING, String.format("Unrecognized code: %x", code)); - } - - if (state == 0 && offset == item_offset) { - state = 1; - } - } - return false; - } - - /** - * Gets length of an item. - * - * @param item_offset - * @param is_64 - * @param index_bytes - * @return null when item not exists, item length otherwise - * @throws IOException - */ - private static Long getItemLength(long item_offset /*uint32_t*/, boolean is_64, byte index_bytes[]) throws IOException { - return itemLength(item_offset, is_64, index_bytes, null); - } - - /** - * Sets new length of an item. - * - * @param item_offset - * @param is_64 - * @param index_bytes - * @param newLength - * @return null when item not exists, old item length otherwise - * @throws IOException - */ - private static Long setItemLength(long item_offset /*uint32_t*/, boolean is_64, byte index_bytes[], long newLength) throws IOException { - return itemLength(item_offset, is_64, index_bytes, newLength); - } - - /** - * Sets/Gets length of an item - * - * @param item_offset - * @param is_64 - * @param index_bytes - * @param newValue New value to set. If null then no change. - * @return null when item does not exists, old item length otherwise - * @throws IOException - */ - private static Long itemLength(long item_offset /*uint32_t*/, boolean is_64, byte index_bytes[], Long newValue) throws IOException { - TemporaryDataStream stream = new TemporaryDataStream(index_bytes); - - /* - index_table: - n = UI8 - for i=0..n-1 - table[i] = UI8 - cnt = UI8 - cnt * UI16 - - */ - int index_table_size = stream.readUI8(); - int index_table[] = new int[index_table_size]; - - for (int i = 0; i < index_table_size; i++) { - index_table[i] = stream.readUI8(); - int num = stream.readUI8(); - stream.seek(num * 2, SeekMode.CUR); - //num * UI16 - } - - int state = 0; - long offset = 0;//uint32_t - int code; //uint8_t - - while ((code = stream.readUI8()) >= 0) { - if (state == 1) { - if (code != 0xFD) { - LOGGER.log(Level.WARNING, "We were expecting code 0xFD in state 1."); - return null; - } - } else if (state == 2) { - if (code != 0xFF) { - LOGGER.log(Level.WARNING, "We were expecting code 0xFF in state 2."); - return null; - } - } - - if (code < 0x80) // 0-0x7F - { - // code is directly an index to the index_table - if (code >= index_table_size) { - LOGGER.log(Level.WARNING, String.format("< 0x80: index is greater than index_table_size. %x > %x", code, index_table_size)); - return null; - } - - offset += index_table[code]; - } else if (code < 0xC0) // 0x80-BF - { - int index; //uint8_t - - if ((index = stream.readUI8()) < 0) { - LOGGER.log(Level.WARNING, "< 0xC0: Cannot read index."); - return null; - } - - if (index >= index_table_size) { - LOGGER.log(Level.WARNING, String.format("< 0xC0: index is greater than index_table_size. %x > %x", index, index_table_size)); - return null; - } - - 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; //uint8_t - int n8; //uint8_t - int n; - - if ((n8 = stream.readUI8()) < 0) { - LOGGER.log(Level.WARNING, "< 0xE0: Cannot read n."); - return null; - } - - 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 { - LOGGER.log(Level.WARNING, String.format("< 0xE0: Invalid value for i (%x %x)", 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.log(Level.WARNING, String.format("< 0xE0: invalid value for i (%x %x)", i, code)); - } - } - } else if (code == 0xFC) { - stream.seek(1, SeekMode.CUR); - } else if (code == 0xFD) { - int n, m; //uint8_t - - if ((n = stream.readUI8()) < 0) { - LOGGER.log(Level.WARNING, "0xFD: Cannot read n."); - return null; - } - - if (state == 1) { - if (is_64) { - if (n != 0xF) { - LOGGER.log(Level.WARNING, String.format("We were expecting an offset of 0xF in state 1.")); - return null; - } - } else if (n != 0xB) { - LOGGER.log(Level.WARNING, "We were expecting an offset of 0xB in state 1."); - return null; - } - - state = 2; - } - - if ((m = stream.readUI8()) < 0) { - LOGGER.log(Level.WARNING, "0xFD: Cannot read m."); - return null; - } - - offset += n; - stream.seek(m * 2, SeekMode.CUR); - } else if (code == 0xFE) { - int n8; //uint8_t - int n; - - if ((n8 = stream.readUI8()) < 0) { - LOGGER.log(Level.WARNING, "0xFE: Cannot read n."); - return null; - } - - n = n8 + 1; - offset += n; - } else if (code == 0xFF) { - long n; //uint32_t - - if ((n = stream.readUI32()) < 0) { - LOGGER.log(Level.WARNING, "0xFF: Cannot read n."); - return null; - } - - if (state == 2) { - if (newValue != null) { - stream.seek(-4, SeekMode.CUR); - stream.writeUI32(newValue); - } - return n; - } - - offset += n; - } else { - LOGGER.log(Level.WARNING, String.format("Unrecognized code: %x", code)); - } - - if (state == 0 && offset == item_offset) { - state = 1; - } - } - return null; - } - public String getSwfName() { return iggySwf.getName(); } @@ -703,16 +234,33 @@ public class IggyFile implements StructureInterface { for (int i = 0; i < subFileEntries.size(); i++) { IggySubFileEntry entry = subFileEntries.get(i); + if (entry.type != IggySubFileEntry.TYPE_FLASH || entry.type != IggySubFileEntry.TYPE_INDEX) { + continue; + } entry.offset = currentOffset; currentOffset += entry.size; entry.writeToDataStream(stream); } for (int i = 0; i < subFileEntries.size(); i++) { + IggySubFileEntry entry = subFileEntries.get(i); + if (entry.type != IggySubFileEntry.TYPE_FLASH || entry.type != IggySubFileEntry.TYPE_INDEX) { + continue; + } + byte[] entryData = subFileEntriesData.get(i); stream.writeBytes(entryData); } + for (int i = 0; i < subFileEntries.size(); i++) { + IggySubFileEntry entry = subFileEntries.get(i); + if (entry.type != IggySubFileEntry.TYPE_FLASH || entry.type != IggySubFileEntry.TYPE_INDEX) { + subFileEntries.remove(i); + subFileEntriesData.remove(i); + i--; + } + } + } }