From 6df722eda99e88ea351c524ba19be69ec67c59e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Fri, 25 Nov 2016 10:59:45 +0100 Subject: [PATCH] Distinguish texts and fonts. --- .../decompiler/flash/iggy/IggyDataReader.java | 76 +++++----- .../jpexs/decompiler/flash/iggy/IggyFile.java | 22 ++- .../iggy/{IggyFontData.java => IggyFont.java} | 13 +- .../decompiler/flash/iggy/IggyFontInfo.java | 23 --- .../jpexs/decompiler/flash/iggy/IggyText.java | 142 ++++++++++++++++++ .../iggy/conversion/IggyToSwfConvertor.java | 16 +- 6 files changed, 212 insertions(+), 80 deletions(-) rename libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/{IggyFontData.java => IggyFont.java} (86%) delete mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontInfo.java create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyText.java diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyDataReader.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyDataReader.java index 725b64fbd..cb4d3c7bc 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyDataReader.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyDataReader.java @@ -19,8 +19,9 @@ public class IggyDataReader implements StructureInterface { @IggyFieldType(value = DataType.widechar_t, count = 48) String name; - List fontDatas; - List fontInfos; + Map fonts; + Map texts; + Map text2Font; private IggyFlashHeader64 header; private Map sizesOfOffsets; @@ -52,50 +53,55 @@ public class IggyDataReader implements StructureInterface { stream.readUI64(); //pad 1 - long[] font_main_offsets = new long[(int) header.font_count]; + long[] fontOffsets = new long[(int) header.font_count]; for (int i = 0; i < header.font_count; i++) { - font_main_offsets[i] = stream.position() + stream.readUI64(); + fontOffsets[i] = stream.position() + stream.readUI64(); } - long[] font_info_offsets = new long[(int) header.font_count]; - for (int i = 0; i < header.font_count; i++) { - long pos = stream.position(); - long offset = stream.readUI64(); - font_info_offsets[i] = offset == NO_OFFSET ? NO_OFFSET : pos + offset; + List textOffsets = new ArrayList<>(); + + while (true) { + long val = stream.readUI64(); + if (val == 1) { + break; + } + textOffsets.add(stream.position() + val); } - long pad_len = 840 - stream.position(); - stream.seek(pad_len, SeekMode.CUR); - /*List fontMainStreams = new ArrayList<>(); + //long pad_len = 840 - stream.position(); + stream.seek(840, SeekMode.SET); - for (int i = 0; i < header.font_count; i++) { - long fontMainOffset = font_main_offsets[i]; - //long fontMainSize = sizesOfOffsets.get(font_main_offsets[i]); - //stream.seek(fontMainOffset, SeekMode.SET); - //byte[] fontMainData = stream.readBytes((int) fontMainSize); - //fontMainStreams.add(new ByteArrayDataStream(fontMainData, stream.is64())); - }*/ - List fontInfoStreams = new ArrayList<>(); + Long lastOffset = null; + texts = new HashMap<>(); + text2Font = new HashMap<>(); + long textDataSizes[] = new long[(int) header.font_count]; - for (int i = 0; i < header.font_count; i++) { - long fontInfoOffset = font_info_offsets[i]; - if (fontInfoOffset == NO_OFFSET) { - fontInfoStreams.add(null); + long offsetAfterTexts = header.as3_section_offset; + + for (int i = 0; i < textOffsets.size(); i++) { + long textOffset = textOffsets.get(i); + if (lastOffset == null) { + lastOffset = textOffset; } else { - long fontInfoSize = sizesOfOffsets.get(font_info_offsets[i]); - - stream.seek(fontInfoOffset, SeekMode.SET); - byte[] fontInfoData = stream.readBytes((int) fontInfoSize); - - fontInfoStreams.add(new ByteArrayDataStream(fontInfoData, stream.is64())); + textDataSizes[i - 1] = textOffset - lastOffset; } } + if (lastOffset != null) { + textDataSizes[(int) header.font_count - 1] = offsetAfterTexts - lastOffset; + } - fontDatas = new ArrayList<>(); - fontInfos = new ArrayList<>(); + for (int i = 0; i < textOffsets.size(); i++) { + long textOffset = textOffsets.get(i); + stream.seek(textOffset, SeekMode.SET); + byte[] textData = stream.readBytes((int) textDataSizes[i]); + IggyText text = new IggyText(new ByteArrayDataStream(textData, stream.is64())); + text2Font.put(text.textId, text.fontId); + texts.put(text.textId, text); + } + fonts = new HashMap<>(); for (int i = 0; i < header.font_count; i++) { - stream.seek(font_main_offsets[i], SeekMode.SET); - IggyFontData part = new IggyFontData(stream); - fontDatas.add(part); + stream.seek(fontOffsets[i], SeekMode.SET); + IggyFont font = new IggyFont(stream); + fonts.put(font.fontId, font); } } 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 7eebdf523..8a05befac 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 @@ -12,6 +12,7 @@ import java.io.OutputStream; import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -33,16 +34,20 @@ public class IggyFile extends AbstractDataStream implements AutoCloseable { private List headers = new ArrayList<>(); private List flashDataReaders = new ArrayList<>(); - public int getFontCount(int swfIndex) { - return flashDataReaders.get(swfIndex).fontDatas.size(); + public Set getFontIds(int swfIndex) { + return flashDataReaders.get(swfIndex).fonts.keySet(); } - public IggyFontData getFontData(int swfIndex, int fontIndex) { - return flashDataReaders.get(swfIndex).fontDatas.get(fontIndex); + public IggyFont getFont(int swfIndex, int fontId) { + return flashDataReaders.get(swfIndex).fonts.get(fontId); } - public IggyFontInfo getFontInfo(int swfIndex, int fontIndex) { - return null; //FIXME!!! //flashDataReaders.get(swfIndex).fontInfos.get(fontIndex); + public IggyText getText(int swfIndex, int textId) { + return flashDataReaders.get(swfIndex).texts.get(textId); + } + + public Set getTextIds(int swfIndex) { + return flashDataReaders.get(swfIndex).texts.keySet(); } @Override @@ -61,8 +66,7 @@ public class IggyFile extends AbstractDataStream implements AutoCloseable { subFileEntries.add(new IggySubFileEntry(this)); } - //TODO: use these two for something - List> indexTables = new ArrayList<>(); + List> indexTables = new ArrayList<>(); //TODO: use this two for something ?? List> offsetTables = new ArrayList<>(); List flashDataStreams = new ArrayList<>(); @@ -156,6 +160,7 @@ public class IggyFile extends AbstractDataStream implements AutoCloseable { }; } + @Override protected int read() throws IOException { int val = raf.read(); if (val == -1) { @@ -217,6 +222,7 @@ public class IggyFile extends AbstractDataStream implements AutoCloseable { } public static void main(String[] args) throws IOException { + System.out.println("Iggy file splitter"); if (args.length == 0) { System.err.println("No file specified"); System.exit(1); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFont.java similarity index 86% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontData.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFont.java index 36b91ab78..c695f8d21 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFont.java @@ -12,12 +12,12 @@ import org.omg.CORBA.StructMemberHelper; * * @author JPEXS */ -public class IggyFontData implements StructureInterface { +public class IggyFont implements StructureInterface { @IggyFieldType(DataType.uint16_t) int type; //stejny pro rozdilne fonty @IggyFieldType(DataType.uint16_t) - int order_in_iggy_file; + int fontId; @IggyArrayFieldType(value = DataType.uint8_t, count = 28) byte[] zeroone; // stejny pro rozdilne fonty @IggyFieldType(DataType.uint16_t) @@ -83,7 +83,6 @@ public class IggyFontData implements StructureInterface { @IggyFieldType(DataType.uint32_t) long one_padd5; - //FSeek(start_name); @IggyFieldType(value = DataType.widechar_t, count = 16) String name; @@ -95,9 +94,9 @@ public class IggyFontData implements StructureInterface { byte[] padTo4byteBoundary; - public IggyFontData(int type, int order_in_iggy_file, byte[] zeroone, int char_count2, int[] what_1, long flags, long start_of_char_struct, long start_of_char_index, long start_of_scale, long kern_count, float[] unk_float, long start_of_kern, long zero_padd, long what_2, long zero_padd_2, long start_of_name, long one_padd, int xscale, int yscale, long zero_padd_3, float ssr1, float ssr2, long char_count, long zero_padd_4, long what_3, byte[] zeroes, float sss1, long one_padd2, float sss2, long one_padd3, float sss3, long one_padd4, float sss4, long one_padd5, String name, List charOffsets, List chars, IggyCharIndices charIndices, IggyCharScales charScales, IggyCharKerning charKernings, byte[] padTo4byteBoundary) { + public IggyFont(int type, int order_in_iggy_file, byte[] zeroone, int char_count2, int[] what_1, long flags, long start_of_char_struct, long start_of_char_index, long start_of_scale, long kern_count, float[] unk_float, long start_of_kern, long zero_padd, long what_2, long zero_padd_2, long start_of_name, long one_padd, int xscale, int yscale, long zero_padd_3, float ssr1, float ssr2, long char_count, long zero_padd_4, long what_3, byte[] zeroes, float sss1, long one_padd2, float sss2, long one_padd3, float sss3, long one_padd4, float sss4, long one_padd5, String name, List charOffsets, List chars, IggyCharIndices charIndices, IggyCharScales charScales, IggyCharKerning charKernings, byte[] padTo4byteBoundary) { this.type = type; - this.order_in_iggy_file = order_in_iggy_file; + this.fontId = order_in_iggy_file; this.zeroone = zeroone; this.char_count2 = char_count2; this.what_1 = what_1; @@ -139,7 +138,7 @@ public class IggyFontData implements StructureInterface { this.padTo4byteBoundary = padTo4byteBoundary; } - public IggyFontData(AbstractDataStream stream) throws IOException { + public IggyFont(AbstractDataStream stream) throws IOException { readFromDataStream(stream); } @@ -155,7 +154,7 @@ public class IggyFontData implements StructureInterface { public void readFromDataStream(AbstractDataStream stream) throws IOException { ByteArrayDataStream s = new ByteArrayDataStream(stream.readBytes((int) (long) stream.available()), stream.is64()); type = s.readUI16(); - order_in_iggy_file = s.readUI16(); + fontId = s.readUI16(); zeroone = s.readBytes(28); char_count2 = s.readUI16(); what_1 = new int[3]; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontInfo.java deleted file mode 100644 index bdbe2511f..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontInfo.java +++ /dev/null @@ -1,23 +0,0 @@ -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 IggyFontInfo implements StructureInterface { - - @Override - public void readFromDataStream(AbstractDataStream stream) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void writeToDataStream(AbstractDataStream stream) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); - } - -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyText.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyText.java new file mode 100644 index 000000000..d94ae096d --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyText.java @@ -0,0 +1,142 @@ +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 { + + @IggyFieldType(DataType.uint16_t) + int type; // Tag type + @IggyFieldType(DataType.uint16_t) + int textId; + @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; + @IggyFieldType(DataType.uint16_t) + int fontId; + @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.textId = 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.fontId = 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(); + textId = s.readUI16(); + zeroone = s.readBytes(28); + par1 = s.readFloat(); + par2 = s.readFloat(); + par3 = s.readFloat(); + par4 = s.readFloat(); + enum_hex = s.readUI16(); + fontId = s.readUI16(); + zero = s.readUI32(); + one = s.readUI64(); + some = s.readBytes(32); + 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 getOrder_in_iggy_file() { + return textId; + } + + 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 getFor_which_font_order_in_iggyfile() { + return fontId; + } + + public long getZero() { + return zero; + } + + public long getOne() { + return one; + } + + public byte[] getSome() { + return some; + } + + public String getIntitalText() { + return initialText; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyToSwfConvertor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyToSwfConvertor.java index 1ca592841..74c3eddfb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyToSwfConvertor.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyToSwfConvertor.java @@ -4,8 +4,8 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFCompression; import com.jpexs.decompiler.flash.iggy.IggyChar; import com.jpexs.decompiler.flash.iggy.IggyFile; -import com.jpexs.decompiler.flash.iggy.IggyFontData; -import com.jpexs.decompiler.flash.iggy.IggyFontInfo; +import com.jpexs.decompiler.flash.iggy.IggyFont; +import com.jpexs.decompiler.flash.iggy.IggyText; import com.jpexs.decompiler.flash.tags.DefineFont2Tag; import com.jpexs.decompiler.flash.tags.EndTag; import com.jpexs.decompiler.flash.tags.FileAttributesTag; @@ -16,6 +16,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Set; /** * @@ -75,12 +76,13 @@ public class IggyToSwfConvertor { fat.useNetwork = false; swf.addTag(fat); - int fontCount = file.getFontCount(swfIndex); - for (int fontIndex = 0; fontIndex < fontCount; fontIndex++) { - IggyFontData iggyFontData = file.getFontData(swfIndex, fontIndex); - IggyFontInfo fontInfo = file.getFontInfo(swfIndex, fontIndex); //TODO! + Set fontKeys = file.getFontIds(swfIndex); + + for (int fontKey : fontKeys) { + IggyFont iggyFontData = file.getFont(swfIndex, fontKey); + IggyText fontInfo = file.getText(swfIndex, fontKey); DefineFont2Tag fontTag = new DefineFont2Tag(swf); - fontTag.fontID = fontIndex + 1; + fontTag.fontID = fontKey + 1; fontTag.codeTable = new ArrayList<>(); fontTag.fontName = iggyFontData.getName(); fontTag.glyphShapeTable = new ArrayList<>();