Fixed #2004 Freezing when a shape has nonimage character set as fill

This commit is contained in:
Jindra Petřík
2023-04-09 16:16:47 +02:00
parent bbde6c0d13
commit 9a23497c80
42 changed files with 86 additions and 60 deletions

View File

@@ -658,7 +658,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
int characterId = ((CharacterTag) tag).getCharacterId();
if (characterId != -1) {
Set<Integer> needed = new HashSet<>();
tag.getNeededCharacters(needed);
tag.getNeededCharacters(needed, this);
for (Integer needed1 : needed) {
Set<Integer> s = dep.get(needed1);
if (s == null) {
@@ -4382,7 +4382,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
CharacterTag cht = (CharacterTag) t;
if (cht.getCharacterId() != -1) {
Set<Integer> needed = new HashSet<>();
cht.getNeededCharacters(needed);
cht.getNeededCharacters(needed, this);
characterToNeeded.put(cht.getCharacterId(), needed);
}
}

View File

@@ -127,7 +127,7 @@ public class CSMTextSettingsTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(textID);
}
}

View File

@@ -100,7 +100,7 @@ public class DefineButtonCxformTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(buttonId);
}
}

View File

@@ -142,7 +142,7 @@ public class DefineButtonSoundTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
if (buttonSoundChar0 != 0) {
needed.add(buttonSoundChar0);
}

View File

@@ -944,7 +944,7 @@ public class DefineEditTextTag extends TextTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
if (hasFont) {
needed.add(fontId);
}

View File

@@ -119,7 +119,7 @@ public class DefineFontAlignZonesTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(fontID);
}
}

View File

@@ -187,7 +187,7 @@ public class DefineFontInfo2Tag extends FontInfoTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(fontID);
}
}

View File

@@ -188,7 +188,7 @@ public class DefineFontInfoTag extends FontInfoTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(fontID);
}
}

View File

@@ -97,7 +97,7 @@ public class DefineFontNameTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(fontId);
}
}

View File

@@ -217,7 +217,7 @@ public class DefineScalingGridTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(characterId);
}

View File

@@ -375,7 +375,7 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
for (Tag t : getTags()) {
if ((t instanceof CharacterIdTag) && !(t instanceof SoundStreamHeadTypeTag) && !(t instanceof DefineExternalStreamSound)) {
needed.add(((CharacterIdTag) t).getCharacterId());

View File

@@ -277,7 +277,7 @@ public class DoInitActionTag extends Tag implements CharacterIdTag, ASMSource {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(spriteId);
}
}

View File

@@ -151,7 +151,7 @@ public class ExportAssetsTag extends SymbolClassTypeTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.addAll(tags);
}
}

View File

@@ -85,7 +85,7 @@ public class FreeCharacterTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(characterId);
}
}

View File

@@ -94,7 +94,7 @@ public class NameCharacterTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(characterId);
}
}

View File

@@ -289,7 +289,7 @@ public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceCont
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
if (placeFlagHasCharacter) {
needed.add(characterId);
}

View File

@@ -476,7 +476,7 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
if (placeFlagHasCharacter) {
needed.add(characterId);
}

View File

@@ -497,7 +497,7 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
if (placeFlagHasCharacter) {
needed.add(characterId);
}

View File

@@ -143,7 +143,7 @@ public class PlaceObjectTag extends PlaceObjectTypeTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(characterId);
}

View File

@@ -108,7 +108,7 @@ public class RemoveObjectTag extends RemoveTag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(characterId);
}
}

View File

@@ -141,7 +141,7 @@ public class SymbolClassTag extends SymbolClassTypeTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
for (int t : tags) {
if (t != 0) { //main class
needed.add(t);

View File

@@ -608,7 +608,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
}
public Set<Integer> getMissingNeededCharacters(Set<Integer> needed) {
@@ -645,7 +645,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
public void getNeededCharactersDeep(Set<Integer> needed) {
Set<Integer> needed2 = new LinkedHashSet<>();
getNeededCharacters(needed2);
getNeededCharacters(needed2, swf);
List<Integer> needed3 = new ArrayList<>(needed2);
for (int i = 0; i < needed3.size(); i++) {
@@ -656,7 +656,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
if (swf.getCharacters().containsKey(characterId)) {
Set<Integer> needed4 = new LinkedHashSet<>();
CharacterTag character = swf.getCharacter(characterId);
character.getNeededCharacters(needed4);
character.getNeededCharacters(needed4, swf);
List<Integer> newItems = new ArrayList<>();
for(int n : needed4) {
int index = needed3.indexOf((Integer) n);

View File

@@ -99,7 +99,7 @@ public class VideoFrameTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
needed.add(streamID);
}
}

View File

@@ -66,7 +66,7 @@ public abstract class ButtonTag extends DrawableTag implements Timelined {
public abstract boolean trackAsMenu();
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
for (BUTTONRECORD r : getRecords()) {
needed.add(r.characterId);
}

View File

@@ -116,10 +116,10 @@ public abstract class MorphShapeTag extends DrawableTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
morphFillStyles.getNeededCharacters(needed);
startEdges.getNeededCharacters(needed);
endEdges.getNeededCharacters(needed);
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
morphFillStyles.getNeededCharacters(needed, swf);
startEdges.getNeededCharacters(needed, swf);
endEdges.getNeededCharacters(needed, swf);
}
@Override

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.SWF;
import java.util.Set;
/**
@@ -24,7 +25,7 @@ import java.util.Set;
*/
public interface NeedsCharacters {
public void getNeededCharacters(Set<Integer> needed);
public void getNeededCharacters(Set<Integer> needed, SWF swf);
public boolean replaceCharacter(int oldCharacterId, int newCharacterId);

View File

@@ -94,10 +94,10 @@ public abstract class ShapeTag extends DrawableTag implements LazyObject {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
SHAPEWITHSTYLE shapes = getShapes();
if (shapes != null) {
getShapes().getNeededCharacters(needed);
getShapes().getNeededCharacters(needed, swf);
}
}

View File

@@ -607,7 +607,7 @@ public abstract class StaticTextTag extends TextTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
for (TEXTRECORD tr : textRecords) {
if (tr.styleFlagsHasFont) {
needed.add(tr.fontId);

View File

@@ -16,8 +16,11 @@
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.DefineShape3Tag;
import com.jpexs.decompiler.flash.tags.DefineShape4Tag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.ConditionalType;
@@ -86,7 +89,7 @@ public class FILLSTYLE implements NeedsCharacters, FieldChangeObserver, Serializ
public MATRIX bitmapMatrix;
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
if ((fillStyleType == REPEATING_BITMAP)
|| (fillStyleType == CLIPPED_BITMAP)
|| (fillStyleType == NON_SMOOTHED_REPEATING_BITMAP)
@@ -94,7 +97,10 @@ public class FILLSTYLE implements NeedsCharacters, FieldChangeObserver, Serializ
if (bitmapId == 65535) { //In some cases, this special value is used, but is not used. Ignore it. (#1851)
return;
}
needed.add(bitmapId);
CharacterTag character = swf.getCharacter(bitmapId);
if (character instanceof ImageTag) {
needed.add(bitmapId);
}
}
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
import com.jpexs.decompiler.flash.types.annotations.SWFArray;
import java.io.Serializable;
@@ -31,9 +32,9 @@ public class FILLSTYLEARRAY implements NeedsCharacters, Serializable {
public FILLSTYLE[] fillStyles;
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
for (FILLSTYLE fs : fillStyles) {
fs.getNeededCharacters(needed);
fs.getNeededCharacters(needed, swf);
}
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.DefineShape3Tag;
import com.jpexs.decompiler.flash.tags.DefineShape4Tag;
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
@@ -37,7 +38,7 @@ public class LINESTYLE implements NeedsCharacters, Serializable, ILINESTYLE {
public RGB color;
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
}
@Override

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.EnumValue;
@@ -88,9 +89,9 @@ public class LINESTYLE2 implements NeedsCharacters, Serializable, ILINESTYLE {
public FILLSTYLE fillType;
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
if (hasFillFlag) {
fillType.getNeededCharacters(needed);
fillType.getNeededCharacters(needed, swf);
}
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.DefineShape2Tag;
import com.jpexs.decompiler.flash.tags.DefineShape3Tag;
import com.jpexs.decompiler.flash.tags.DefineShape4Tag;
@@ -41,15 +42,15 @@ public class LINESTYLEARRAY implements NeedsCharacters, Serializable {
public LINESTYLE2[] lineStyles2 = new LINESTYLE2[0];
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
if (lineStyles != null) {
for (ILINESTYLE ls : lineStyles) {
ls.getNeededCharacters(needed);
ls.getNeededCharacters(needed, swf);
}
}
if (lineStyles != null) {
for (ILINESTYLE ls : lineStyles2) {
ls.getNeededCharacters(needed);
ls.getNeededCharacters(needed, swf);
}
}
}

View File

@@ -16,6 +16,9 @@
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.EnumValue;
@@ -81,12 +84,18 @@ public class MORPHFILLSTYLE implements NeedsCharacters, Serializable {
public MATRIX endBitmapMatrix;
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
if ((fillStyleType == REPEATING_BITMAP)
|| (fillStyleType == CLIPPED_BITMAP)
|| (fillStyleType == NON_SMOOTHED_REPEATING_BITMAP)
|| (fillStyleType == NON_SMOOTHED_CLIPPED_BITMAP)) {
needed.add(bitmapId);
if (bitmapId == 65535) { //In some cases, this special value is used, but is not used. Ignore it. (#1851)
return;
}
CharacterTag character = swf.getCharacter(bitmapId);
if (character instanceof ImageTag) {
needed.add(bitmapId);
}
}
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
import java.io.Serializable;
import java.util.Set;
@@ -29,9 +30,9 @@ public class MORPHFILLSTYLEARRAY implements NeedsCharacters, Serializable {
public MORPHFILLSTYLE[] fillStyles;
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
for (MORPHFILLSTYLE fs : fillStyles) {
fs.getNeededCharacters(needed);
fs.getNeededCharacters(needed, swf);
}
}

View File

@@ -50,9 +50,9 @@ public class SHAPE implements NeedsCharacters, Serializable {
private Shape fastCachedOutline;
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
for (SHAPERECORD r : shapeRecords) {
r.getNeededCharacters(needed);
r.getNeededCharacters(needed, swf);
}
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
@@ -35,11 +36,11 @@ public class SHAPEWITHSTYLE extends SHAPE implements NeedsCharacters, Serializab
public LINESTYLEARRAY lineStyles;
@Override
public void getNeededCharacters(Set<Integer> needed) {
fillStyles.getNeededCharacters(needed);
lineStyles.getNeededCharacters(needed);
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
fillStyles.getNeededCharacters(needed, swf);
lineStyles.getNeededCharacters(needed, swf);
for (SHAPERECORD r : shapeRecords) {
r.getNeededCharacters(needed);
r.getNeededCharacters(needed, swf);
}
}

View File

@@ -62,7 +62,7 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
public abstract void calculateBits();
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
}
@Override

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.types.shaperecords;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
@@ -83,9 +84,9 @@ public final class StyleChangeRecord extends SHAPERECORD implements Cloneable {
public int numLineBits;
@Override
public void getNeededCharacters(Set<Integer> needed) {
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
if (stateNewStyles) {
fillStyles.getNeededCharacters(needed);
fillStyles.getNeededCharacters(needed, swf);
}
}

View File

@@ -1815,7 +1815,7 @@ public class XFLConverter {
for (Tag tag : swf.getTags()) {
if (tag instanceof ShapeTag) {
Set<Integer> needed = new HashSet<>();
tag.getNeededCharacters(needed);
tag.getNeededCharacters(needed, swf);
ShapeTag sht = (ShapeTag) tag;
if (needed.contains(imageTag.getCharacterId())) {
List<FILLSTYLE> fs = new ArrayList<>();