From 22695b985b8ef312c234e9ee42e3c091cdc82e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Mon, 12 Dec 2016 12:14:11 +0100 Subject: [PATCH] Iggy - reading and writing ABC --- .../flash/iggy/IggyDeclStrings.java | 26 +++++++++++----- .../jpexs/decompiler/flash/iggy/IggySwf.java | 4 +++ .../iggy/conversion/IggyToSwfConvertor.java | 30 ++++++++++++++++++- .../iggy/conversion/SwfToIggyConvertor.java | 18 +++++++++++ 4 files changed, 70 insertions(+), 8 deletions(-) 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 c9c21b2c8..587df7dc7 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 @@ -16,8 +16,8 @@ public class IggyDeclStrings implements StructureInterface { @IggyFieldType(DataType.uint64_t) long one; - @IggyFieldType(DataType.uint32_t) - long size; + //@IggyFieldType(DataType.uint32_t) + //long size; @IggyArrayFieldType(value = DataType.uint8_t, count = 3) byte xxx[]; @IggyArrayFieldType(value = DataType.uint8_t, countField = "size") @@ -28,6 +28,14 @@ public class IggyDeclStrings implements StructureInterface { @IggyFieldType(DataType.uint64_t) long zero; + public byte[] getData() { + return data; + } + + public void setData(byte[] data) { + this.data = data; + } + public IggyDeclStrings(ReadDataStreamInterface stream) throws IOException { readFromDataStream(stream); } @@ -35,7 +43,7 @@ public class IggyDeclStrings implements StructureInterface { @Override public void readFromDataStream(ReadDataStreamInterface s) throws IOException { one = s.readUI64(); - size = s.readUI32(); + long size = s.readUI32(); xxx = s.readBytes(3); data = s.readBytes((int) size); if ((15 + size) % 8 != 0) { @@ -54,13 +62,17 @@ public class IggyDeclStrings implements StructureInterface { public void writeToDataStream(WriteDataStreamInterface s) throws IOException { IggyIndexBuilder ib = s.getIndexing(); s.writeUI64(one); - s.writeUI32(size); - s.writeBytes(xxx); + s.writeUI32(data.length); ib.writeLengthCustom(15, new int[]{0x00, 0x08}, new int[]{2, 5}); - ib.writeLengthUI32(size); + s.writeBytes(xxx); s.writeBytes(data); - ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE); + ib.writeLengthUI32(data.length); + if ((15 + data.length) % 8 != 0) { + byte[] padd = new byte[((int) (((15 + data.length) / 8 + 1) * 8 - 15 - data.length))]; + s.writeBytes(padd); + } s.writeBytes(padd); + ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE); s.writeUI64(one); s.writeUI64(zero); } 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 03734b25d..e5907428c 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 @@ -332,4 +332,8 @@ public class IggySwf implements StructureInterface { return sb.toString(); } + public IggyDeclStrings getDeclStrings() { + return decl_strings; + } + } 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 f8bd1674d..658c0dd29 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 @@ -2,17 +2,20 @@ package com.jpexs.decompiler.flash.iggy.conversion; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFCompression; +import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.iggy.IggyShape; import com.jpexs.decompiler.flash.iggy.IggyCharKerning; import com.jpexs.decompiler.flash.iggy.IggyShapeNode; import com.jpexs.decompiler.flash.iggy.IggyCharOffset; import com.jpexs.decompiler.flash.iggy.IggyCharAdvances; +import com.jpexs.decompiler.flash.iggy.IggyDeclStrings; import com.jpexs.decompiler.flash.iggy.IggyFile; import com.jpexs.decompiler.flash.iggy.IggyFont; import com.jpexs.decompiler.flash.iggy.IggySwf; import com.jpexs.decompiler.flash.iggy.IggyText; import com.jpexs.decompiler.flash.tags.DefineEditTextTag; import com.jpexs.decompiler.flash.tags.DefineFont2Tag; +import com.jpexs.decompiler.flash.tags.DoABC2Tag; import com.jpexs.decompiler.flash.tags.EndTag; import com.jpexs.decompiler.flash.tags.FileAttributesTag; import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; @@ -26,7 +29,9 @@ import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord; import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord; import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; +import com.jpexs.helpers.ByteArrayRange; import java.awt.Color; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -36,6 +41,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; /** * @@ -88,7 +95,7 @@ public class IggyToSwfConvertor { swf.version = 10; //FIXME FileAttributesTag fat = new FileAttributesTag(swf); - fat.actionScript3 = false; + fat.actionScript3 = true; fat.hasMetadata = false; fat.useNetwork = false; swf.addTag(fat); @@ -196,6 +203,27 @@ public class IggyToSwfConvertor { swf.addTag(textTag); } + IggyDeclStrings declStrings = iggySwf.getDeclStrings(); + if (declStrings != null) { + byte[] abcData = declStrings.getData(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + baos.write(new byte[]{1, 0, 0, 0, 0, 0x10, 0, 0x2E}); + baos.write(abcData); + } catch (IOException ex) { + //should not happen + } + byte[] fullAbcTagData = baos.toByteArray(); + try { + DoABC2Tag nabc = new DoABC2Tag(new SWFInputStream(swf, fullAbcTagData), new ByteArrayRange(fullAbcTagData)); + nabc.setModified(true); + swf.addTag(nabc); + } catch (IOException ex) { + //ignore + } + + } + swf.addTag( new EndTag(swf)); swf.setModified( diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfToIggyConvertor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfToIggyConvertor.java index 331516073..fb04a79fa 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfToIggyConvertor.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfToIggyConvertor.java @@ -1,6 +1,7 @@ package com.jpexs.decompiler.flash.iggy.conversion; import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.iggy.IggyCharAdvances; import com.jpexs.decompiler.flash.iggy.IggyCharIndices; import com.jpexs.decompiler.flash.iggy.IggyCharKerning; @@ -11,11 +12,14 @@ import com.jpexs.decompiler.flash.iggy.IggySwf; import com.jpexs.decompiler.flash.iggy.IggyText; import com.jpexs.decompiler.flash.tags.DefineEditTextTag; import com.jpexs.decompiler.flash.tags.DefineFont2Tag; +import com.jpexs.decompiler.flash.tags.DoABC2Tag; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.types.KERNINGRECORD; import com.jpexs.decompiler.flash.types.SHAPE; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -31,6 +35,7 @@ public class SwfToIggyConvertor { public static void updateIggy(IggySwf iggySwf, SWF swf) throws IOException { List fontTags = new ArrayList<>(); List textTags = new ArrayList<>(); + List abcTags = new ArrayList<>(); for (Tag t : swf.getTags()) { if (t instanceof DefineFont2Tag) { @@ -39,6 +44,12 @@ public class SwfToIggyConvertor { if (t instanceof DefineEditTextTag) { textTags.add((DefineEditTextTag) t); } + if (t instanceof DoABC2Tag) { + abcTags.add((DoABC2Tag) t); + } + } + if (abcTags.size() > 1) { + throw new IOException("Cannot save more than one ABC tag"); } int fontCount = iggySwf.getFonts().size(); if (fontCount != fontTags.size()) { @@ -59,6 +70,13 @@ public class SwfToIggyConvertor { DefineEditTextTag textTag = textTags.get(i); SwfToIggyConvertor.updateIggyText(iggyText, textTag); } + if (!abcTags.isEmpty()) { + DoABC2Tag abcTag = abcTags.get(0); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte abcTagData[] = abcTag.getData(); + byte declData[] = Arrays.copyOfRange(abcTagData, 4/*UI32 flags*/ + 1 /*empty string as name*/ + 3 /*versions, leaving one zero intact*/, abcTagData.length); + iggySwf.getDeclStrings().setData(declData); + } } public static void updateIggyText(IggyText iggyText, DefineEditTextTag textTag) {