Added GFX - DefineExternalImage2 - IdType field recognition

This commit is contained in:
Jindra Petřík
2024-07-30 06:39:43 +02:00
parent a20f94c619
commit 4c2a2e5374
11 changed files with 79 additions and 28 deletions

View File

@@ -26,6 +26,7 @@ All notable changes to this project will be documented in this file.
available through context menu on ABC, ABCContainers, SWFs and in the ABC Explorer,
`-abcclean` command on CLI
- GFX - better fileformat detection
- GFX - DefineExternalImage2 - IdType field recognition
### Fixed
- Debugger - getting children of top level variables

View File

@@ -52,7 +52,10 @@ public abstract class CharacterTag extends Tag implements CharacterIdTag {
@Override
public Map<String, String> getNameProperties() {
Map<String, String> ret = super.getNameProperties();
ret.put("chid", "" + getCharacterId());
int chid = getCharacterId();
if (chid > -1) {
ret.put("chid", "" + chid);
}
if (exportName != null) {
ret.put ("exp", Helper.escapePCodeString(exportName));
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.tags.gfx;
import com.jpexs.decompiler.flash.tags.gfx.enums.FileFormatType;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.gfx.TgaSupport;
import com.jpexs.decompiler.flash.tags.base.ImageTag;

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.tags.gfx;
import com.jpexs.decompiler.flash.tags.gfx.enums.FileFormatType;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;

View File

@@ -16,13 +16,13 @@
*/
package com.jpexs.decompiler.flash.tags.gfx;
import com.jpexs.decompiler.flash.tags.gfx.enums.IdType;
import com.jpexs.decompiler.flash.tags.gfx.enums.FileFormatType;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.gfx.TgaSupport;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.TagInfo;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
import com.jpexs.helpers.ByteArrayRange;
@@ -33,13 +33,8 @@ import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Objects;
import javax.imageio.ImageIO;
import net.npe.dds.DDSReader;
/**
*
@@ -53,16 +48,7 @@ public class DefineExternalImage2 extends AbstractGfxImageTag {
public int imageID;
public static final int UNKNOWN_IS_STANDALONE = 0;
public static final int UNKNOWN_HAS_SUBIMAGES = 9;
/**
* Special unknown field. This seems to have value of 9 when it has
* DefineSubImages and in this case, imageId is not treated as a
* characterId. If it has value of 0, this tag is threated as standalone
* external image - standard character.
*/
public int unknownID;
public int idType;
public int bitmapFormat;
@@ -91,7 +77,7 @@ public class DefineExternalImage2 extends AbstractGfxImageTag {
@Override
public void getData(SWFOutputStream sos) throws IOException {
sos.writeUI16(imageID);
sos.writeUI16(unknownID);
sos.writeUI16(idType);
sos.writeUI16(bitmapFormat);
sos.writeUI16(targetWidth);
sos.writeUI16(targetHeight);
@@ -112,7 +98,7 @@ public class DefineExternalImage2 extends AbstractGfxImageTag {
public DefineExternalImage2(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, NAME, data);
readData(sis, data, 0, false, false, false);
characterID = unknownID == 0 ? imageID : - 1;
characterID = idType == IdType.IDTYPE_NONE ? imageID : - 1;
}
public DefineExternalImage2(SWF swf) {
@@ -121,7 +107,7 @@ public class DefineExternalImage2 extends AbstractGfxImageTag {
fileName = "";
targetWidth = 1;
targetHeight = 1;
unknownID = UNKNOWN_HAS_SUBIMAGES;
idType = IdType.IDTYPE_NONE;
bitmapFormat = FileFormatType.FILE_DDS;
characterID = -1;
createFailedImage();
@@ -130,7 +116,7 @@ public class DefineExternalImage2 extends AbstractGfxImageTag {
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
imageID = sis.readUI16("imageID");
unknownID = sis.readUI16("unknownID");
idType = sis.readUI16("idType");
bitmapFormat = sis.readUI16("bitmapFormat");
targetWidth = sis.readUI16("targetWidth");
targetHeight = sis.readUI16("targetHeight");
@@ -226,7 +212,7 @@ public class DefineExternalImage2 extends AbstractGfxImageTag {
@Override
public String getUniqueId() {
if (unknownID == 0) {
if (idType == IdType.IDTYPE_NONE) {
return super.getUniqueId();
}
return "i" + imageID;
@@ -250,8 +236,9 @@ public class DefineExternalImage2 extends AbstractGfxImageTag {
}
tagInfo.addInfo("general", "bitmapFormat", bitmapFormatStr);
if (unknownID != 0) {
if (idType != IdType.IDTYPE_NONE) {
tagInfo.addInfo("general", "imageId", imageID);
}
tagInfo.addInfo("general", "idType", IdType.idTypeToString(idType) + " (" + idType + ")");
}
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.tags.gfx;
import com.jpexs.decompiler.flash.tags.gfx.enums.FileFormatType;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;

View File

@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.gfx;
package com.jpexs.decompiler.flash.tags.gfx.enums;
import java.lang.reflect.Field;

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2010-2023 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.gfx.enums;
import java.lang.reflect.Field;
/**
*
* @author JPEXS
*/
public class IdType {
private static final int IDTYPE_BIT_SWF = 0; // Id comes from SWF File.
private static final int IDTYPE_BIT_STATIC = 1; // Id assigned uniquely during loading.
private static final int IDTYPE_BIT_EXPORT = 2; // Id assigned uniquely during export.
public static final int IDTYPE_NONE = 0;
public static final int IDTYPE_INTERNALCONSTANT = 0 | IDTYPE_BIT_STATIC;
public static final int IDTYPE_GRADIENTIMAGE = 4 | IDTYPE_BIT_STATIC;
public static final int IDTYPE_DYNFONTIMAGE = 8 | IDTYPE_BIT_STATIC;
public static final int IDTYPE_FONTIMAGE = 4 | IDTYPE_BIT_EXPORT;
public static String idTypeToString(int idType) {
try {
for (Field f : IdType.class.getDeclaredFields()) {
if (f.getName().startsWith("IDTYPE_BIT_")) {
continue;
}
if (f.getInt(IdType.class) == idType) {
return f.getName().substring(7); //strip "IDTYPE_" prefix
}
}
} catch (IllegalAccessException iae) {
return "UNKNOWN";
}
return "UNKNOWN";
}
}

View File

@@ -188,6 +188,7 @@ import com.jpexs.decompiler.flash.tags.base.UnsupportedSamplingRateException;
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalImage2;
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalStreamSound;
import com.jpexs.decompiler.flash.tags.gfx.DefineSubImage;
import com.jpexs.decompiler.flash.tags.gfx.enums.IdType;
import com.jpexs.decompiler.flash.tags.text.TextParseException;
import com.jpexs.decompiler.flash.timeline.AS3Package;
import com.jpexs.decompiler.flash.timeline.DepthState;
@@ -6133,7 +6134,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
ImageTag imageTagCopy = (ImageTag) imageTag.cloneTag();
imageTagCopy.setSwf(swf);
int imageCharId = imageTag.getCharacterId();
if ((imageTag instanceof DefineExternalImage2) && (((DefineExternalImage2) imageTag).unknownID > 0)) {
if ((imageTag instanceof DefineExternalImage2) && (((DefineExternalImage2) imageTag).idType != IdType.IDTYPE_NONE)) {
imageCharId = swf.getNextCharacterId();
imageTagCopy.characterID = imageCharId;
}

View File

@@ -1267,4 +1267,6 @@ contextmenu.cleanAbc = Clean ABC - remove unused items
warning.cleanAbc = This action will remove items from ABC which have zero usages - they are not referenced form any script.\r\n\
Some kinds of obfuscated SWFs could be damaged this way.\r\n\
Use it at your own risk. Do you want to continue?
Use it at your own risk. Do you want to continue?
tagInfo.idType = Type of the id

View File

@@ -1242,4 +1242,6 @@ contextmenu.cleanAbc = Vy\u010distit ABC - odebrat nepou\u017e\u00edvan\u00e9 po
warning.cleanAbc = Tato akce odstran\u00ed z ABC polo\u017eky, kter\u00e9 maj\u00ed nula pou\u017eit\u00ed - nen\u00ed na n\u011b odkazov\u00e1no z \u017e\u00e1dn\u00e9ho skriptu.\r\n\
N\u011bkter\u00e9 druhy obfuskovan\u00fdch SWF to m\u016f\u017ee po\u0161kodit.\r\n\
Pou\u017e\u00edvejte ji na vlastn\u00ed riziko. Chcete pokra\u010dovat?
Pou\u017e\u00edvejte ji na vlastn\u00ed riziko. Chcete pokra\u010dovat?
tagInfo.idType = Typ id