diff --git a/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java b/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java
index 12459889c..06f0b3345 100644
--- a/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java
+++ b/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java
@@ -1281,7 +1281,7 @@ public class SWFInputStream extends InputStream {
case 2:
ret = new DefineShapeTag(swf, data, version, pos);
break;
- //case 3
+ //case 3: FreeCharacter
case 4:
ret = new PlaceObjectTag(swf, data, version, pos);
break;
@@ -1318,7 +1318,7 @@ public class SWFInputStream extends InputStream {
case 15:
ret = new StartSoundTag(swf, data, version, pos);
break;
- //case 16
+ //case 16:
case 17:
ret = new DefineButtonSoundTag(swf, data, version, pos);
break;
@@ -1343,7 +1343,7 @@ public class SWFInputStream extends InputStream {
case 24:
ret = new ProtectTag(swf, data, version, pos);
break;
- //case 25:
+ //case 25: PathsArePostscript
case 26:
ret = new PlaceObject2Tag(swf, data, version, pos);
break;
@@ -1351,9 +1351,9 @@ public class SWFInputStream extends InputStream {
case 28:
ret = new RemoveObject2Tag(swf, data, version, pos);
break;
- //case 29:
+ //case 29: SyncFrame
//case 30:
- //case 31:
+ //case 31: FreeAll
case 32:
ret = new DefineShape3Tag(swf, data, version, pos);
break;
@@ -1372,15 +1372,15 @@ public class SWFInputStream extends InputStream {
case 37:
ret = new DefineEditTextTag(swf, data, version, pos);
break;
- //case 38:
+ //case 38: DefineVideo
case 39:
ret = new DefineSpriteTag(swf, data, version, level, pos, paralel, skipUnusualTags);
break;
- //case 40:
+ //case 40: NameCharacter
case 41:
ret = new ProductInfoTag(swf, data, version, pos);
break;
- //case 42:
+ //case 42: DefineTextFormat
case 43:
ret = new FrameLabelTag(swf, data, version, pos);
break;
@@ -1391,11 +1391,15 @@ public class SWFInputStream extends InputStream {
case 46:
ret = new DefineMorphShapeTag(swf, data, version, pos);
break;
- //case 47:
+ //case 47: GenerateFrame
case 48:
ret = new DefineFont2Tag(swf, data, version, pos);
break;
- //case 49-55:
+ //case 49: GeneratorCommand
+ //case 50: DefineCommandObject
+ //case 51: CharacterSet
+ //case 52: ExternalFont
+ //case 53-55
case 56:
ret = new ExportAssetsTag(swf, data, version, pos);
break;
@@ -1489,6 +1493,13 @@ public class SWFInputStream extends InputStream {
case 91:
ret = new DefineFont4Tag(swf, data, version, pos);
break;
+ //case 92: certificate
+ case 93:
+ ret = new EnableTelemetryTag(swf, data, version, pos);
+ break;
+ case 94:
+ ret = new PlaceObject4Tag(swf, data, version, pos);
+ break;
default:
ret = new Tag(swf, tag.getId(), "Unknown", data, pos);
}
diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/EnableTelemetryTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/EnableTelemetryTag.java
new file mode 100644
index 000000000..6dd8e16e3
--- /dev/null
+++ b/trunk/src/com/jpexs/decompiler/flash/tags/EnableTelemetryTag.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010-2013 JPEXS
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.jpexs.decompiler.flash.tags;
+
+import com.jpexs.decompiler.flash.SWF;
+import com.jpexs.decompiler.flash.SWFInputStream;
+import com.jpexs.decompiler.flash.SWFOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Enable flash profiling information
+ *
+ * @author JPEXS
+ */
+public class EnableTelemetryTag extends Tag {
+
+ public static final int ID = 93;
+ public int reserved;
+ public byte passwordHash[];
+
+ /**
+ * Gets data bytes
+ *
+ * @param version SWF version
+ * @return Bytes of data
+ */
+ @Override
+ public byte[] getData(int version) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStream os = baos;
+ SWFOutputStream sos = new SWFOutputStream(os, version);
+ try {
+ sos.writeUB(16, reserved);
+ sos.write(passwordHash);
+ } catch (IOException e) {
+ }
+ return baos.toByteArray();
+ }
+
+ /**
+ * Constructor
+ *
+ * @param swf
+ * @param data Data bytes
+ * @param version SWF version
+ * @param pos
+ * @throws IOException
+ */
+ public EnableTelemetryTag(SWF swf, byte data[], int version, long pos) throws IOException {
+ super(swf, ID, "", data, pos);
+ SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
+ reserved = (int) sis.readUB(16);
+ passwordHash = sis.readBytes(32);
+ }
+}
diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java
index 97a4e8443..8d28d0900 100644
--- a/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java
+++ b/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java
@@ -274,6 +274,7 @@ public class PlaceObject3Tag extends CharacterIdTag implements Container, PlaceO
/**
* Constructor
*
+ * @param swf
* @param data Data bytes
* @param version SWF version
* @param pos
diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java
new file mode 100644
index 000000000..8e9358650
--- /dev/null
+++ b/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2010-2013 JPEXS
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.jpexs.decompiler.flash.tags;
+
+import com.jpexs.decompiler.flash.Configuration;
+import com.jpexs.decompiler.flash.EndOfStreamException;
+import com.jpexs.decompiler.flash.SWF;
+import com.jpexs.decompiler.flash.SWFInputStream;
+import com.jpexs.decompiler.flash.SWFOutputStream;
+import com.jpexs.decompiler.flash.abc.CopyOutputStream;
+import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
+import com.jpexs.decompiler.flash.tags.base.Container;
+import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
+import com.jpexs.decompiler.flash.types.CLIPACTIONS;
+import com.jpexs.decompiler.flash.types.CXFORM;
+import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
+import com.jpexs.decompiler.flash.types.MATRIX;
+import com.jpexs.decompiler.flash.types.RGBA;
+import com.jpexs.decompiler.flash.types.filters.FILTER;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Same as PlaceObject3Tag except additional AMF data
+ *
+ * @author JPEXS
+ */
+public class PlaceObject4Tag extends CharacterIdTag implements Container, PlaceObjectTypeTag {
+
+ /**
+ * @since SWF 5 has clip actions (sprite characters only)
+ */
+ public boolean placeFlagHasClipActions;
+ /**
+ * Has clip depth
+ */
+ public boolean placeFlagHasClipDepth;
+ /**
+ * Has name
+ */
+ public boolean placeFlagHasName;
+ /**
+ * Has ratio
+ */
+ public boolean placeFlagHasRatio;
+ /**
+ * Has color transform
+ */
+ public boolean placeFlagHasColorTransform;
+ /**
+ * Has matrix
+ */
+ public boolean placeFlagHasMatrix;
+ /**
+ * Places a character
+ */
+ public boolean placeFlagHasCharacter;
+ /**
+ * Defines a character to be moved
+ */
+ public boolean placeFlagMove;
+ /**
+ * Has class name or character ID of bitmap to place. If
+ * PlaceFlagHasClassName, use ClassName. If PlaceFlagHasCharacter, use
+ * CharacterId
+ */
+ public boolean placeFlagHasImage;
+ /**
+ * Has class name of object to place
+ */
+ public boolean placeFlagHasClassName;
+ /**
+ * Enables bitmap caching
+ */
+ public boolean placeFlagHasCacheAsBitmap;
+ /**
+ * Has blend mode
+ */
+ public boolean placeFlagHasBlendMode;
+ /**
+ * Has filter list
+ */
+ public boolean placeFlagHasFilterList;
+ /**
+ * Has opaque background. SWF 11 and higher.
+ */
+ public boolean placeFlagOpaqueBackground;
+ /**
+ * Has visibility flag. SWF 11 and higher.
+ */
+ public boolean placeFlagHasVisible;
+ /**
+ * Depth of character
+ */
+ public int depth;
+ /**
+ * If PlaceFlagHasClassName or (PlaceFlagHasImage and
+ * PlaceFlagHasCharacter), Name of the class to place
+ */
+ public String className;
+ /**
+ * If PlaceFlagHasCharacter, ID of character to place
+ */
+ public int characterId;
+ /**
+ * If PlaceFlagHasMatrix, Transform matrix data
+ */
+ public MATRIX matrix;
+ /**
+ * If PlaceFlagHasColorTransform, Color transform data
+ */
+ public CXFORMWITHALPHA colorTransform;
+ /**
+ * If PlaceFlagHasRatio, Ratio
+ */
+ public int ratio;
+ /**
+ * If PlaceFlagHasName, Name of character
+ */
+ public String name;
+ /**
+ * If PlaceFlagHasClipDepth, Clip depth
+ */
+ public int clipDepth;
+ /**
+ * If PlaceFlagHasFilterList, List of filters on this object
+ */
+ public List surfaceFilterList;
+ /**
+ * If PlaceFlagHasBlendMode, Blend mode
+ */
+ public int blendMode;
+ /**
+ * If PlaceFlagHasCacheAsBitmap, 0 = Bitmap cache disabled, 1-255 = Bitmap
+ * cache enabled
+ */
+ public int bitmapCache;
+ /**
+ * @since SWF 5 If PlaceFlagHasClipActions, Clip Actions Data
+ */
+ public CLIPACTIONS clipActions;
+ /**
+ * If PlaceFlagHasVisible, 0 = Place invisible, 1 = Place visible
+ */
+ public int visible;
+ /**
+ * If PlaceFlagHasVisible, Background color
+ */
+ public RGBA backgroundColor;
+ // FIXME bug found in ecoDrive.swf,
+ private boolean bitmapCacheBug;
+ private int reserved;
+ public static final int ID = 94;
+ public byte amfData[]; //TODO: Parse AMF data?
+
+ @Override
+ public List getFilters() {
+ if (placeFlagHasFilterList) {
+ return surfaceFilterList;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public int getClipDepth() {
+ if (placeFlagHasClipDepth) {
+ return clipDepth;
+ }
+ return -1;
+ }
+
+ /**
+ * Gets data bytes
+ *
+ * @param version SWF version
+ * @return Bytes of data
+ */
+ @Override
+ public byte[] getData(int version) {
+ if (Configuration.DISABLE_DANGEROUS) {
+ return super.getData(version);
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStream os = baos;
+ if (Configuration.DEBUG_COPY) {
+ os = new CopyOutputStream(os, new ByteArrayInputStream(super.data));
+ }
+ SWFOutputStream sos = new SWFOutputStream(os, version);
+ try {
+ sos.writeUB(1, placeFlagHasClipActions ? 1 : 0);
+ sos.writeUB(1, placeFlagHasClipDepth ? 1 : 0);
+ sos.writeUB(1, placeFlagHasName ? 1 : 0);
+ sos.writeUB(1, placeFlagHasRatio ? 1 : 0);
+ sos.writeUB(1, placeFlagHasColorTransform ? 1 : 0);
+ sos.writeUB(1, placeFlagHasMatrix ? 1 : 0);
+ sos.writeUB(1, placeFlagHasCharacter ? 1 : 0);
+ sos.writeUB(1, placeFlagMove ? 1 : 0);
+ sos.writeUB(1, reserved);
+ sos.writeUB(1, placeFlagOpaqueBackground ? 1 : 0); //SWF11
+ sos.writeUB(1, placeFlagHasVisible ? 1 : 0); //SWF11
+ sos.writeUB(1, placeFlagHasImage ? 1 : 0);
+ sos.writeUB(1, placeFlagHasClassName ? 1 : 0);
+ sos.writeUB(1, placeFlagHasCacheAsBitmap ? 1 : 0);
+ sos.writeUB(1, placeFlagHasBlendMode ? 1 : 0);
+ sos.writeUB(1, placeFlagHasFilterList ? 1 : 0);
+ sos.writeUI16(depth);
+ if (placeFlagHasClassName) {
+ sos.writeString(className);
+ }
+ if (placeFlagHasCharacter) {
+ sos.writeUI16(characterId);
+ }
+ if (placeFlagHasMatrix) {
+ sos.writeMatrix(matrix);
+ }
+ if (placeFlagHasColorTransform) {
+ sos.writeCXFORMWITHALPHA(colorTransform);
+ }
+ if (placeFlagHasRatio) {
+ sos.writeUI16(ratio);
+ }
+ if (placeFlagHasName) {
+ sos.writeString(name);
+ }
+ if (placeFlagHasClipDepth) {
+ sos.writeUI16(clipDepth);
+ }
+ if (placeFlagHasFilterList) {
+ sos.writeFILTERLIST(surfaceFilterList);
+ }
+ if (placeFlagHasBlendMode) {
+ sos.writeUI8(blendMode);
+ }
+ if (placeFlagHasCacheAsBitmap) {
+ if (!bitmapCacheBug) {
+ sos.writeUI8(bitmapCache);
+ }
+ }
+ if (placeFlagHasVisible) {
+ sos.writeUI8(visible);
+ }
+ if (placeFlagOpaqueBackground) {
+ sos.writeRGBA(backgroundColor);
+ }
+ if (placeFlagHasClipActions) {
+ sos.writeCLIPACTIONS(clipActions);
+ }
+ sos.close();
+ } catch (IOException ex) {
+ }
+ return baos.toByteArray();
+ }
+
+ /**
+ * Constructor
+ *
+ * @param swf
+ * @param data Data bytes
+ * @param version SWF version
+ * @param pos
+ * @throws IOException
+ */
+ public PlaceObject4Tag(SWF swf, byte data[], int version, long pos) throws IOException {
+ super(swf, ID, "PlaceObject4", data, pos);
+ SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
+ placeFlagHasClipActions = sis.readUB(1) == 1;
+ placeFlagHasClipDepth = sis.readUB(1) == 1;
+ placeFlagHasName = sis.readUB(1) == 1;
+ placeFlagHasRatio = sis.readUB(1) == 1;
+ placeFlagHasColorTransform = sis.readUB(1) == 1;
+ placeFlagHasMatrix = sis.readUB(1) == 1;
+ placeFlagHasCharacter = sis.readUB(1) == 1;
+ placeFlagMove = sis.readUB(1) == 1;
+ reserved = (int) sis.readUB(1);
+ placeFlagOpaqueBackground = sis.readUB(1) == 1; //SWF11
+ placeFlagHasVisible = sis.readUB(1) == 1; //SWF11
+ placeFlagHasImage = sis.readUB(1) == 1;
+ placeFlagHasClassName = sis.readUB(1) == 1;
+ placeFlagHasCacheAsBitmap = sis.readUB(1) == 1;
+ placeFlagHasBlendMode = sis.readUB(1) == 1;
+ placeFlagHasFilterList = sis.readUB(1) == 1;
+
+ depth = sis.readUI16();
+ if (placeFlagHasClassName) {
+ className = sis.readString();
+ }
+ if (placeFlagHasCharacter) {
+ characterId = sis.readUI16();
+ }
+ if (placeFlagHasMatrix) {
+ matrix = sis.readMatrix();
+ }
+ if (placeFlagHasColorTransform) {
+ colorTransform = sis.readCXFORMWITHALPHA();
+ }
+ if (placeFlagHasRatio) {
+ ratio = sis.readUI16();
+ }
+ if (placeFlagHasName) {
+ name = sis.readString();
+ }
+ if (placeFlagHasClipDepth) {
+ clipDepth = sis.readUI16();
+ }
+ if (placeFlagHasFilterList) {
+ surfaceFilterList = sis.readFILTERLIST();
+ }
+ if (placeFlagHasBlendMode) {
+ blendMode = sis.readUI8();
+ }
+ bitmapCacheBug = false;
+ if (placeFlagHasCacheAsBitmap) {
+ try {
+ bitmapCache = sis.readUI8();
+ } catch (EndOfStreamException eex) {
+ bitmapCacheBug = true;
+ bitmapCache = 1;
+ }
+ }
+
+ if (placeFlagHasVisible) {
+ visible = sis.readUI8();
+ }
+ if (placeFlagOpaqueBackground) {
+ backgroundColor = sis.readRGBA();
+ }
+
+ if (placeFlagHasClipActions) {
+ clipActions = sis.readCLIPACTIONS();
+ }
+ amfData = sis.readBytes(sis.available());
+ }
+
+ /**
+ * Returns all sub-items
+ *
+ * @return List of sub-items
+ */
+ @Override
+ public List