diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharKerning.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharKerning.java index 997999b76..e838c0ad6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharKerning.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharKerning.java @@ -13,6 +13,8 @@ import java.util.List; */ public class IggyCharKerning implements StructureInterface { + public static final int STRUCT_SIZE = 6; + private long kernCount; List charsA; List charsB; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharOffset.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharOffset.java index 74b197582..687ecaad1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharOffset.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharOffset.java @@ -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) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyDeclStrings.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyDeclStrings.java index a948e7b87..9d229b8a4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyDeclStrings.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyDeclStrings.java @@ -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); 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 de66dd8b0..f490db013 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 @@ -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 subFileEntries = new ArrayList<>(); private List subFileEntriesData = new ArrayList<>(); - private List headers = new ArrayList<>(); private List iggySwfs = new ArrayList<>(); - private List> indexTables = new ArrayList<>(); - private List> offsetTables = new ArrayList<>(); - private List 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 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 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 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 indexTable = new ArrayList<>(); - List 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)))); } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader64.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader64.java index 0da2c4e5a..a2d35c3ee 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader64.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader64.java @@ -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(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFont.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFont.java index c70b17c98..a75ef98e9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFont.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFont.java @@ -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() { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/FontBinInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontBinInfo.java similarity index 90% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/FontBinInfo.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontBinInfo.java index cd0da4d55..d11cde5fb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/FontBinInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontBinInfo.java @@ -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); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontTypeInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontTypeInfo.java index 38958d521..33ec71665 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontTypeInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontTypeInfo.java @@ -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) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyIndexBuilder.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyIndexBuilder.java deleted file mode 100644 index dace78461..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyIndexBuilder.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.jpexs.decompiler.flash.iggy; - -/** - * - * @author JPEXS - */ -public class IggyIndexBuilder { - - public void writeTable(int cnt, DataType type, boolean pad) { - - } -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySequence.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySequence.java index 1ef7e26f0..026af5b43 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySequence.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySequence.java @@ -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); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShape.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShape.java index 33c0ccfa3..ec0eb6ed1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShape.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShape.java @@ -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); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShapeNode.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShapeNode.java index 9507acd9e..04d9d4132 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShapeNode.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShapeNode.java @@ -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; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java index eedd9101f..8e63e8be9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java @@ -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 fonts; + List fonts = new ArrayList<>(); + private List font_data_addresses = new ArrayList<>(); + List add_fonts = new ArrayList<>(); + private List 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 texts = new ArrayList<>(); + private List text_data_addresses = new ArrayList<>(); + private List add_texts = new ArrayList<>(); + private List add_text_data_addresses = new ArrayList<>(); - private long font_data_addresses[]; - private long font_data_sizes[]; - private List text_addresses = new ArrayList<>(); - private List text_data_sizes = new ArrayList<>(); - private List text_data_bytes = new ArrayList<>(); private byte font_add_data[]; - private List font_add_off = new ArrayList<>(); - private List font_add_size = new ArrayList<>(); - private FontBinInfo font_bin_info[]; + private List 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 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 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); } 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 index 1ddd359a9..0896d379b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyText.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyText.java @@ -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() { 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 7acf46afb..18947a11d 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 @@ -102,12 +102,13 @@ public class IggyToSwfConvertor { fat.useNetwork = false; swf.addTag(fat); - Set fontIndices = file.getFontIds(swfIndex); + //Set fontIndices = file.getFontIds(swfIndex); + int fontCount = file.getFontCount(swfIndex); int currentCharId = 0; Map 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++; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/AbstractDataStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/AbstractDataStream.java index f99fc86a4..3f9367f09 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/AbstractDataStream.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/AbstractDataStream.java @@ -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); - } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/EmptyIndexing.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/EmptyIndexing.java deleted file mode 100644 index 6e868625e..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/EmptyIndexing.java +++ /dev/null @@ -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]; - } - -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IggyIndexBuilder.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IggyIndexBuilder.java new file mode 100644 index 000000000..c8e077f0e --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IggyIndexBuilder.java @@ -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 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; + } + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyIndexParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IggyIndexParser.java similarity index 68% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyIndexParser.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IggyIndexParser.java index b8277a0a1..0de06a2c7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyIndexParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IggyIndexParser.java @@ -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); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IndexingDataStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IndexingDataStream.java deleted file mode 100644 index 610ab8344..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IndexingDataStream.java +++ /dev/null @@ -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 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; - } - } -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IndexingDataStreamInterface.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IndexingDataStreamInterface.java deleted file mode 100644 index 0e6d250f3..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IndexingDataStreamInterface.java +++ /dev/null @@ -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(); -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/RandomAccessFileDataStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/RandomAccessFileDataStream.java index eb6a15a4c..4b0f613bd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/RandomAccessFileDataStream.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/RandomAccessFileDataStream.java @@ -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(); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/WriteDataStreamInterface.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/WriteDataStreamInterface.java index f22ace170..ba48899a4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/WriteDataStreamInterface.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/WriteDataStreamInterface.java @@ -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(); }