new SWF tags - EnableTelemetry, PlaceObject4

This commit is contained in:
Jindra Petk
2013-08-08 20:14:49 +02:00
parent 29d038b474
commit 4945a37833
4 changed files with 606 additions and 10 deletions

View File

@@ -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);
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -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

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<FILTER> 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<FILTER> 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<Object> getSubItems() {
List<Object> ret = new ArrayList<>();
if (placeFlagHasClipActions) {
ret.addAll(clipActions.clipActionRecords);
}
return ret;
}
/**
* Returns number of sub-items
*
* @return Number of sub-items
*/
@Override
public int getItemCount() {
if (!placeFlagHasClipActions) {
return 0;
}
return clipActions.clipActionRecords.size();
}
@Override
public Set<Integer> getNeededCharacters() {
Set<Integer> ret = new HashSet<>();
if (placeFlagHasCharacter) {
ret.add(characterId);
}
return ret;
}
@Override
public int getCharacterId() {
if (placeFlagHasCharacter) {
return characterId;
} else {
return -1;
}
}
@Override
public int getDepth() {
return depth;
}
@Override
public MATRIX getMatrix() {
if (placeFlagHasMatrix) {
return matrix;
} else {
return null;
}
}
@Override
public String getInstanceName() {
if (placeFlagHasName) {
return name;
}
return null;
}
@Override
public CXFORM getColorTransform() {
return null;
}
@Override
public CXFORMWITHALPHA getColorTransformWithAlpha() {
if (placeFlagHasColorTransform) {
return colorTransform;
} else {
return null;
}
}
@Override
public int getBlendMode() {
return blendMode;
}
@Override
public String getClassName() {
if (placeFlagHasClassName) {
return className;
}
return null;
}
@Override
public boolean cacheAsBitmap() {
return placeFlagHasCacheAsBitmap;
}
@Override
public boolean isVisible() {
if (placeFlagHasVisible) {
return visible == 1;
}
return true;
}
@Override
public RGBA getBackgroundColor() {
if (placeFlagOpaqueBackground) {
return backgroundColor;
}
return null;
}
@Override
public boolean flagMove() {
return placeFlagMove;
}
@Override
public int getRatio() {
if (!placeFlagHasRatio) {
return -1;
}
return ratio;
}
@Override
public void setInstanceName(String name) {
placeFlagHasName = true;
this.name = name;
}
@Override
public void setClassName(String className) {
placeFlagHasClassName = true;
this.className = className;
}
@Override
public String toString() {
if (name != null) {
return super.toString() + " (" + name + ")";
} else {
return super.toString();
}
}
@Override
public CLIPACTIONS getClipActions() {
if (placeFlagHasClipActions) {
return clipActions;
} else {
return null;
}
}
}