Program: 61457
Project: 61457
Buggy source:
private static void convertLibrary(SWF swf,Map<Integer,String> characterVariables,Map<Integer,String> characterClasses,List<Integer> nonLibraryShapes,String backgroundColor,ReadOnlyTagList tags,HashMap<Integer,CharacterTag> characters,HashMap<String,byte[]> files,HashMap<String,byte[]> datfiles,FLAVersion flaVersion,StringBuilder ret){
  List<String> media=new ArrayList<>();
  List<String> symbols=new ArrayList<>();
  for (  int ch : characters.keySet()) {
    CharacterTag symbol=characters.get(ch);
    if ((symbol instanceof ShapeTag) && nonLibraryShapes.contains(symbol.getCharacterId())) {
      continue;
    }
    if ((symbol instanceof ShapeTag) || (symbol instanceof DefineSpriteTag) || (symbol instanceof ButtonTag)) {
      StringBuilder symbolStr=new StringBuilder();
      symbolStr.append("String_Node_Str").append(symbol.getCharacterId()).append("String_Node_Str").append(getTimestamp(swf)).append("String_Node_Str");
      if (symbol instanceof ShapeTag) {
        symbolStr.append("String_Node_Str");
      }
 else       if (symbol instanceof ButtonTag) {
        symbolStr.append("String_Node_Str");
        if (((ButtonTag)symbol).trackAsMenu()) {
          symbolStr.append("String_Node_Str");
        }
      }
      boolean linkageExportForAS=false;
      if (characterClasses.containsKey(symbol.getCharacterId())) {
        linkageExportForAS=true;
        symbolStr.append("String_Node_Str").append(Helper.escapeHTML(characterClasses.get(symbol.getCharacterId()))).append("String_Node_Str");
      }
      if (characterVariables.containsKey(symbol.getCharacterId())) {
        linkageExportForAS=true;
        symbolStr.append("String_Node_Str").append(Helper.escapeHTML(characterVariables.get(symbol.getCharacterId()))).append("String_Node_Str");
      }
      if (linkageExportForAS) {
        symbolStr.append("String_Node_Str");
      }
      symbolStr.append("String_Node_Str");
      symbolStr.append("String_Node_Str");
      String itemIcon=null;
      if (symbol instanceof ButtonTag) {
        itemIcon="String_Node_Str";
        symbolStr.append("String_Node_Str").append(symbol.getCharacterId()).append("String_Node_Str");
        symbolStr.append("String_Node_Str");
        ButtonTag button=(ButtonTag)symbol;
        List<BUTTONRECORD> records=button.getRecords();
        int maxDepth=0;
        for (        BUTTONRECORD rec : records) {
          if (rec.placeDepth > maxDepth) {
            maxDepth=rec.placeDepth;
          }
        }
        for (int i=maxDepth; i >= 1; i--) {
          symbolStr.append("String_Node_Str").append(maxDepth - i + 1).append("String_Node_Str");
          if (i == 1) {
            symbolStr.append("String_Node_Str");
          }
          symbolStr.append("String_Node_Str").append(randomOutlineColor()).append("String_Node_Str");
          symbolStr.append("String_Node_Str");
          int lastFrame=0;
          loopframes:           for (int frame=1; frame <= 4; frame++) {
            for (            BUTTONRECORD rec : records) {
              if (rec.placeDepth == i) {
                boolean ok=false;
switch (frame) {
case 1:
                  ok=rec.buttonStateUp;
                break;
case 2:
              ok=rec.buttonStateOver;
            break;
case 3:
          ok=rec.buttonStateDown;
        break;
case 4:
      ok=rec.buttonStateHitTest;
    break;
}
if (!ok) {
  continue;
}
CXFORMWITHALPHA colorTransformAlpha=null;
int blendMode=0;
List<FILTER> filters=new ArrayList<>();
if (button instanceof DefineButton2Tag) {
  colorTransformAlpha=rec.colorTransform;
  if (rec.buttonHasBlendMode) {
    blendMode=rec.blendMode;
  }
  if (rec.buttonHasFilterList) {
    filters=rec.filterList;
  }
}
CharacterTag character=characters.get(rec.characterId);
MATRIX matrix=rec.placeMatrix;
String recCharStr;
int characterId=character.getCharacterId();
if ((character instanceof ShapeTag) && (nonLibraryShapes.contains(characterId))) {
  ShapeTag shape=(ShapeTag)character;
  recCharStr=convertShape(characters,matrix,shape.getShapeNum(),shape.getShapes().shapeRecords,shape.getShapes().fillStyles,shape.getShapes().lineStyles,false,false);
}
 else if (character instanceof TextTag) {
  recCharStr=convertText(null,(TextTag)character,matrix,filters,null);
}
 else if (character instanceof DefineVideoStreamTag) {
  recCharStr=convertVideoInstance(null,matrix,(DefineVideoStreamTag)character,null);
}
 else {
  recCharStr=convertSymbolInstance(null,matrix,colorTransformAlpha,false,blendMode,filters,true,null,null,characters.get(rec.characterId),characters,tags,flaVersion);
}
int duration=frame - lastFrame;
lastFrame=frame;
if (duration > 0) {
  if (duration > 1) {
    symbolStr.append("String_Node_Str");
    symbolStr.append((frame - duration));
    symbolStr.append("String_Node_Str");
    symbolStr.append("String_Node_Str").append(duration - 1).append("String_Node_Str");
    symbolStr.append("String_Node_Str").append(KEY_MODE_NORMAL).append("String_Node_Str");
    symbolStr.append("String_Node_Str");
    symbolStr.append("String_Node_Str");
    symbolStr.append("String_Node_Str");
  }
  symbolStr.append("String_Node_Str");
  symbolStr.append((frame - 1));
  symbolStr.append("String_Node_Str");
  symbolStr.append("String_Node_Str").append(KEY_MODE_NORMAL).append("String_Node_Str");
  symbolStr.append("String_Node_Str");
  symbolStr.append(recCharStr);
  symbolStr.append("String_Node_Str");
  symbolStr.append("String_Node_Str");
}
}
}
}
symbolStr.append("String_Node_Str");
symbolStr.append("String_Node_Str");
}
symbolStr.append("String_Node_Str");
symbolStr.append("String_Node_Str");
}
 else if (symbol instanceof DefineSpriteTag) {
DefineSpriteTag sprite=(DefineSpriteTag)symbol;
if (sprite.getTags().isEmpty()) {
continue;
}
symbolStr.append(convertTimeline(sprite.spriteId,nonLibraryShapes,backgroundColor,tags,sprite.getTags(),characters,"String_Node_Str" + symbol.getCharacterId(),flaVersion,files));
}
 else if (symbol instanceof ShapeTag) {
itemIcon="String_Node_Str";
ShapeTag shape=(ShapeTag)symbol;
symbolStr.append("String_Node_Str").append(symbol.getCharacterId()).append("String_Node_Str");
symbolStr.append("String_Node_Str");
SHAPEWITHSTYLE shapeWithStyle=shape.getShapes();
if (shapeWithStyle != null) {
symbolStr.append(convertShape(characters,null,shape.getShapeNum(),shapeWithStyle.shapeRecords,shapeWithStyle.fillStyles,shapeWithStyle.lineStyles,false,true));
}
symbolStr.append("String_Node_Str");
symbolStr.append("String_Node_Str");
}
symbolStr.append("String_Node_Str");
symbolStr.append("String_Node_Str");
String symbolStr2=prettyFormatXML(symbolStr.toString());
String symbolFile="String_Node_Str" + symbol.getCharacterId() + "String_Node_Str";
files.put(symbolFile,Utf8Helper.getBytes(symbolStr2));
String symbLinkStr="String_Node_Str";
symbLinkStr+="String_Node_Str" + symbolFile + "String_Node_Str";
if (itemIcon != null) {
symbLinkStr+="String_Node_Str" + itemIcon + "String_Node_Str";
}
symbLinkStr+="String_Node_Str";
if (flaVersion.ordinal() >= FLAVersion.CS5_5.ordinal()) {
symbLinkStr+="String_Node_Str" + getTimestamp(swf) + "String_Node_Str";
}
symbLinkStr+="String_Node_Str";
symbols.add(symbLinkStr);
}
 else if (symbol instanceof ImageTag) {
ImageTag imageTag=(ImageTag)symbol;
boolean allowSmoothing=false;
looptags: for (Tag tag : swf.getTags()) {
if (tag instanceof ShapeTag) {
Set<Integer> needed=new HashSet<>();
tag.getNeededCharacters(needed);
ShapeTag sht=(ShapeTag)tag;
if (needed.contains(imageTag.getCharacterId())) {
List<FILLSTYLE> fs=new ArrayList<>();
SHAPEWITHSTYLE s=sht.getShapes();
for (FILLSTYLE f : s.fillStyles.fillStyles) {
fs.add(f);
}
for (SHAPERECORD r : s.shapeRecords) {
if (r instanceof StyleChangeRecord) {
StyleChangeRecord scr=(StyleChangeRecord)r;
if (scr.stateNewStyles) {
  for (  FILLSTYLE f : scr.fillStyles.fillStyles) {
    fs.add(f);
  }
}
}
}
for (FILLSTYLE f : fs) {
if (Arrays.asList(FILLSTYLE.REPEATING_BITMAP,FILLSTYLE.CLIPPED_BITMAP,FILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP,FILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP).contains(f.fillStyleType) && f.bitmapId == imageTag.getCharacterId()) {
allowSmoothing=f.fillStyleType == FILLSTYLE.CLIPPED_BITMAP || f.fillStyleType == FILLSTYLE.REPEATING_BITMAP;
break looptags;
}
}
}
}
}
byte imageBytes[]=Helper.readStream(imageTag.getImageData());
SerializableImage image=imageTag.getImage(false);
ImageFormat format=imageTag.getImageFormat();
String symbolFile="String_Node_Str" + symbol.getCharacterId() + imageTag.getImageFormat().getExtension();
files.put(symbolFile,imageBytes);
String mediaLinkStr="String_Node_Str" + symbolFile + "String_Node_Str"+ getTimestamp(swf)+ "String_Node_Str"+ imageBytes.length+ "String_Node_Str";
if (allowSmoothing) {
mediaLinkStr+="String_Node_Str";
}
switch (format) {
case PNG:
case GIF:
mediaLinkStr+="String_Node_Str";
break;
case JPEG:
mediaLinkStr+="String_Node_Str";
break;
}
if (characterClasses.containsKey(symbol.getCharacterId())) {
mediaLinkStr+="String_Node_Str" + characterClasses.get(symbol.getCharacterId()) + "String_Node_Str";
}
mediaLinkStr+="String_Node_Str" + symbolFile + "String_Node_Str"+ (media.size() + 1)+ "String_Node_Str"+ getTimestamp(swf)+ "String_Node_Str"+ image.getWidth()+ "String_Node_Str"+ image.getHeight()+ "String_Node_Str";
media.add(mediaLinkStr);
}
 else if ((symbol instanceof SoundStreamHeadTypeTag) || (symbol instanceof DefineSoundTag)) {
int soundFormat=0;
int soundRate=0;
boolean soundType=false;
boolean soundSize=false;
long soundSampleCount=0;
byte[] soundData=SWFInputStream.BYTE_ARRAY_EMPTY;
int[] rateMap={5,11,22,44};
String exportFormat="String_Node_Str";
if (symbol instanceof SoundStreamHeadTypeTag) {
SoundStreamHeadTypeTag sstream=(SoundStreamHeadTypeTag)symbol;
soundFormat=sstream.getSoundFormatId();
soundRate=sstream.getSoundRate();
soundType=sstream.getSoundType();
soundSize=sstream.getSoundSize();
soundSampleCount=sstream.getSoundSampleCount();
boolean found=false;
for (Tag t : tags) {
if (found && (t instanceof SoundStreamBlockTag)) {
SoundStreamBlockTag bl=(SoundStreamBlockTag)t;
soundData=bl.streamSoundData.getRangeData();
break;
}
if (t == symbol) {
found=true;
}
}
}
 else if (symbol instanceof DefineSoundTag) {
DefineSoundTag sound=(DefineSoundTag)symbol;
soundFormat=sound.soundFormat;
soundRate=sound.soundRate;
soundType=sound.soundType;
soundData=sound.soundData.getRangeData();
soundSize=sound.soundSize;
soundSampleCount=sound.soundSampleCount;
}
int format=0;
int bits=0;
if ((soundFormat == SoundFormat.FORMAT_ADPCM) || (soundFormat == SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN) || (soundFormat == SoundFormat.FORMAT_UNCOMPRESSED_NATIVE_ENDIAN)) {
exportFormat="String_Node_Str";
if (soundType) {
format+=1;
}
switch (soundRate) {
case 0:
format+=2;
break;
case 1:
format+=6;
break;
case 2:
format+=10;
break;
case 3:
format+=14;
break;
}
}
if (soundFormat == SoundFormat.FORMAT_SPEEX) {
bits=18;
}
if (soundFormat == SoundFormat.FORMAT_ADPCM) {
exportFormat="String_Node_Str";
try {
SWFInputStream sis=new SWFInputStream(swf,soundData);
int adpcmCodeSize=(int)sis.readUB(2,"String_Node_Str");
bits=2 + adpcmCodeSize;
}
 catch (IOException ex) {
logger.log(Level.SEVERE,null,ex);
}
}
if (soundFormat == SoundFormat.FORMAT_MP3) {
exportFormat="String_Node_Str";
if (!soundType) {
format+=1;
}
format+=4;
try {
MP3SOUNDDATA s=new MP3SOUNDDATA(new SWFInputStream(swf,soundData),false);
MP3FRAME frame=s.frames.get(0);
int bitRate=frame.getBitRate();
switch (bitRate) {
case 8:
bits=6;
break;
case 16:
bits=7;
break;
case 20:
bits=8;
break;
case 24:
bits=9;
break;
case 32:
bits=10;
break;
case 48:
bits=11;
break;
case 56:
bits=12;
break;
case 64:
bits=13;
break;
case 80:
bits=14;
break;
case 112:
bits=15;
break;
case 128:
bits=16;
break;
case 160:
bits=17;
break;
}
}
 catch (IOException|ArrayIndexOutOfBoundsException ex) {
logger.log(Level.SEVERE,null,ex);
}
}
SoundTag st=(SoundTag)symbol;
SoundFormat fmt=st.getSoundFormat();
byte[] data=SWFInputStream.BYTE_ARRAY_EMPTY;
try {
data=new SoundExporter().exportSound(st,SoundExportMode.MP3_WAV);
}
 catch (IOException ex) {
logger.log(Level.SEVERE,null,ex);
}
String symbolFile="String_Node_Str" + symbol.getCharacterId() + "String_Node_Str"+ exportFormat;
files.put(symbolFile,data);
String mediaLinkStr="String_Node_Str" + symbolFile + "String_Node_Str"+ getTimestamp(swf)+ "String_Node_Str"+ data.length+ "String_Node_Str";
mediaLinkStr+="String_Node_Str" + symbolFile + "String_Node_Str";
mediaLinkStr+="String_Node_Str";
mediaLinkStr+=rateMap[soundRate] + "String_Node_Str";
mediaLinkStr+="String_Node_Str" + (soundSize ? "String_Node_Str" : "String_Node_Str");
mediaLinkStr+="String_Node_Str" + (soundType ? "String_Node_Str" : "String_Node_Str");
mediaLinkStr+="String_Node_Str";
mediaLinkStr+="String_Node_Str" + format + "String_Node_Str"+ bits+ "String_Node_Str"+ soundSampleCount+ "String_Node_Str";
boolean linkageExportForAS=false;
if (characterClasses.containsKey(symbol.getCharacterId())) {
linkageExportForAS=true;
mediaLinkStr+="String_Node_Str" + characterClasses.get(symbol.getCharacterId()) + "String_Node_Str";
}
if (characterVariables.containsKey(symbol.getCharacterId())) {
linkageExportForAS=true;
mediaLinkStr+="String_Node_Str" + Helper.escapeHTML(characterVariables.get(symbol.getCharacterId())) + "String_Node_Str";
}
if (linkageExportForAS) {
mediaLinkStr+="String_Node_Str";
}
mediaLinkStr+="String_Node_Str";
media.add(mediaLinkStr);
}
 else if (symbol instanceof DefineVideoStreamTag) {
DefineVideoStreamTag video=(DefineVideoStreamTag)symbol;
String videoType="String_Node_Str";
switch (video.codecID) {
case 2:
videoType="String_Node_Str";
break;
case 3:
videoType="String_Node_Str";
break;
case 4:
videoType="String_Node_Str";
break;
case 5:
videoType="String_Node_Str";
break;
}
byte[] data=SWFInputStream.BYTE_ARRAY_EMPTY;
try {
data=new MovieExporter().exportMovie(video,MovieExportMode.FLV);
}
 catch (IOException ex) {
logger.log(Level.SEVERE,null,ex);
}
String symbolFile="String_Node_Str" + symbol.getCharacterId() + "String_Node_Str"+ "String_Node_Str";
String mediaLinkStr="String_Node_Str";
if (data.length == 0) {
long ts=getTimestamp(swf);
String datFileName="String_Node_Str" + (datfiles.size() + 1) + "String_Node_Str"+ ts+ "String_Node_Str";
mediaLinkStr="String_Node_Str" + symbolFile + "String_Node_Str"+ symbolFile+ "String_Node_Str"+ ts+ "String_Node_Str"+ datFileName+ "String_Node_Str";
datfiles.put(datFileName,new byte[]{(byte)0x03,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0xA0,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x78,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x59,(byte)0x40,(byte)0x18,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0xFF,(byte)0xFE,(byte)0xFF,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00});
}
 else {
files.put(symbolFile,data);
mediaLinkStr="String_Node_Str" + symbolFile + "String_Node_Str"+ getTimestamp(swf)+ "String_Node_Str"+ data.length+ "String_Node_Str";
mediaLinkStr+="String_Node_Str" + symbolFile + "String_Node_Str";
mediaLinkStr+="String_Node_Str" + videoType + "String_Node_Str";
mediaLinkStr+="String_Node_Str" + (int)swf.frameRate + "String_Node_Str";
mediaLinkStr+="String_Node_Str" + video.width + "String_Node_Str";
mediaLinkStr+="String_Node_Str" + video.height + "String_Node_Str";
double len=(double)video.numFrames / swf.frameRate;
mediaLinkStr+="String_Node_Str" + len + "String_Node_Str";
boolean linkageExportForAS=false;
if (characterClasses.containsKey(symbol.getCharacterId())) {
linkageExportForAS=true;
mediaLinkStr+="String_Node_Str" + characterClasses.get(symbol.getCharacterId()) + "String_Node_Str";
}
if (characterVariables.containsKey(symbol.getCharacterId())) {
linkageExportForAS=true;
mediaLinkStr+="String_Node_Str" + Helper.escapeHTML(characterVariables.get(symbol.getCharacterId())) + "String_Node_Str";
}
if (linkageExportForAS) {
mediaLinkStr+="String_Node_Str";
}
mediaLinkStr+="String_Node_Str";
}
media.add(mediaLinkStr);
}
}
if (!media.isEmpty()) {
ret.append("String_Node_Str");
for (String m : media) {
ret.append(m);
}
ret.append("String_Node_Str");
}
if (!symbols.isEmpty()) {
ret.append("String_Node_Str");
for (String s : symbols) {
ret.append(s);
}
ret.append("String_Node_Str");
}
}

Fixed version (ground truth):
private void convertLibrary(SWF swf,Map<Integer,String> characterVariables,Map<Integer,String> characterClasses,List<Integer> nonLibraryShapes,String backgroundColor,ReadOnlyTagList tags,HashMap<Integer,CharacterTag> characters,HashMap<String,byte[]> files,HashMap<String,byte[]> datfiles,FLAVersion flaVersion,StringBuilder ret){
  List<String> media=new ArrayList<>();
  List<String> symbols=new ArrayList<>();
  for (  int ch : characters.keySet()) {
    CharacterTag symbol=characters.get(ch);
    if ((symbol instanceof ShapeTag) && nonLibraryShapes.contains(symbol.getCharacterId())) {
      continue;
    }
    if ((symbol instanceof ShapeTag) || (symbol instanceof DefineSpriteTag) || (symbol instanceof ButtonTag)) {
      StringBuilder symbolStr=new StringBuilder();
      symbolStr.append("String_Node_Str").append(symbol.getCharacterId()).append("String_Node_Str").append(getTimestamp(swf)).append("String_Node_Str");
      if (symbol instanceof ShapeTag) {
        symbolStr.append("String_Node_Str");
      }
 else       if (symbol instanceof ButtonTag) {
        symbolStr.append("String_Node_Str");
        if (((ButtonTag)symbol).trackAsMenu()) {
          symbolStr.append("String_Node_Str");
        }
      }
      boolean linkageExportForAS=false;
      if (characterClasses.containsKey(symbol.getCharacterId())) {
        linkageExportForAS=true;
        symbolStr.append("String_Node_Str").append(Helper.escapeHTML(characterClasses.get(symbol.getCharacterId()))).append("String_Node_Str");
      }
      if (characterVariables.containsKey(symbol.getCharacterId())) {
        linkageExportForAS=true;
        symbolStr.append("String_Node_Str").append(Helper.escapeHTML(characterVariables.get(symbol.getCharacterId()))).append("String_Node_Str");
      }
      if (linkageExportForAS) {
        symbolStr.append("String_Node_Str");
      }
      symbolStr.append("String_Node_Str");
      symbolStr.append("String_Node_Str");
      String itemIcon=null;
      if (symbol instanceof ButtonTag) {
        itemIcon="String_Node_Str";
        symbolStr.append("String_Node_Str").append(symbol.getCharacterId()).append("String_Node_Str");
        symbolStr.append("String_Node_Str");
        ButtonTag button=(ButtonTag)symbol;
        List<BUTTONRECORD> records=button.getRecords();
        int maxDepth=0;
        for (        BUTTONRECORD rec : records) {
          if (rec.placeDepth > maxDepth) {
            maxDepth=rec.placeDepth;
          }
        }
        for (int i=maxDepth; i >= 1; i--) {
          symbolStr.append("String_Node_Str").append(maxDepth - i + 1).append("String_Node_Str");
          if (i == 1) {
            symbolStr.append("String_Node_Str");
          }
          symbolStr.append("String_Node_Str").append(randomOutlineColor()).append("String_Node_Str");
          symbolStr.append("String_Node_Str");
          int lastFrame=0;
          loopframes:           for (int frame=1; frame <= 4; frame++) {
            for (            BUTTONRECORD rec : records) {
              if (rec.placeDepth == i) {
                boolean ok=false;
switch (frame) {
case 1:
                  ok=rec.buttonStateUp;
                break;
case 2:
              ok=rec.buttonStateOver;
            break;
case 3:
          ok=rec.buttonStateDown;
        break;
case 4:
      ok=rec.buttonStateHitTest;
    break;
}
if (!ok) {
  continue;
}
CXFORMWITHALPHA colorTransformAlpha=null;
int blendMode=0;
List<FILTER> filters=new ArrayList<>();
if (button instanceof DefineButton2Tag) {
  colorTransformAlpha=rec.colorTransform;
  if (rec.buttonHasBlendMode) {
    blendMode=rec.blendMode;
  }
  if (rec.buttonHasFilterList) {
    filters=rec.filterList;
  }
}
CharacterTag character=characters.get(rec.characterId);
MATRIX matrix=rec.placeMatrix;
String recCharStr;
int characterId=character.getCharacterId();
if ((character instanceof ShapeTag) && (nonLibraryShapes.contains(characterId))) {
  ShapeTag shape=(ShapeTag)character;
  recCharStr=convertShape(characters,matrix,shape.getShapeNum(),shape.getShapes().shapeRecords,shape.getShapes().fillStyles,shape.getShapes().lineStyles,false,false);
}
 else if (character instanceof TextTag) {
  recCharStr=convertText(null,(TextTag)character,matrix,filters,null);
}
 else if (character instanceof DefineVideoStreamTag) {
  recCharStr=convertVideoInstance(null,matrix,(DefineVideoStreamTag)character,null);
}
 else {
  recCharStr=convertSymbolInstance(null,matrix,colorTransformAlpha,false,blendMode,filters,true,null,null,characters.get(rec.characterId),characters,tags,flaVersion);
}
int duration=frame - lastFrame;
lastFrame=frame;
if (duration > 0) {
  if (duration > 1) {
    symbolStr.append("String_Node_Str");
    symbolStr.append((frame - duration));
    symbolStr.append("String_Node_Str");
    symbolStr.append("String_Node_Str").append(duration - 1).append("String_Node_Str");
    symbolStr.append("String_Node_Str").append(KEY_MODE_NORMAL).append("String_Node_Str");
    symbolStr.append("String_Node_Str");
    symbolStr.append("String_Node_Str");
    symbolStr.append("String_Node_Str");
  }
  symbolStr.append("String_Node_Str");
  symbolStr.append((frame - 1));
  symbolStr.append("String_Node_Str");
  symbolStr.append("String_Node_Str").append(KEY_MODE_NORMAL).append("String_Node_Str");
  symbolStr.append("String_Node_Str");
  symbolStr.append(recCharStr);
  symbolStr.append("String_Node_Str");
  symbolStr.append("String_Node_Str");
}
}
}
}
symbolStr.append("String_Node_Str");
symbolStr.append("String_Node_Str");
}
symbolStr.append("String_Node_Str");
symbolStr.append("String_Node_Str");
}
 else if (symbol instanceof DefineSpriteTag) {
DefineSpriteTag sprite=(DefineSpriteTag)symbol;
if (sprite.getTags().isEmpty()) {
continue;
}
symbolStr.append(convertTimeline(sprite.spriteId,nonLibraryShapes,backgroundColor,tags,sprite.getTags(),characters,"String_Node_Str" + symbol.getCharacterId(),flaVersion,files));
}
 else if (symbol instanceof ShapeTag) {
itemIcon="String_Node_Str";
ShapeTag shape=(ShapeTag)symbol;
symbolStr.append("String_Node_Str").append(symbol.getCharacterId()).append("String_Node_Str");
symbolStr.append("String_Node_Str");
SHAPEWITHSTYLE shapeWithStyle=shape.getShapes();
if (shapeWithStyle != null) {
symbolStr.append(convertShape(characters,null,shape.getShapeNum(),shapeWithStyle.shapeRecords,shapeWithStyle.fillStyles,shapeWithStyle.lineStyles,false,true));
}
symbolStr.append("String_Node_Str");
symbolStr.append("String_Node_Str");
}
symbolStr.append("String_Node_Str");
symbolStr.append("String_Node_Str");
String symbolStr2=prettyFormatXML(symbolStr.toString());
String symbolFile="String_Node_Str" + symbol.getCharacterId() + "String_Node_Str";
files.put(symbolFile,Utf8Helper.getBytes(symbolStr2));
String symbLinkStr="String_Node_Str";
symbLinkStr+="String_Node_Str" + symbolFile + "String_Node_Str";
if (itemIcon != null) {
symbLinkStr+="String_Node_Str" + itemIcon + "String_Node_Str";
}
symbLinkStr+="String_Node_Str";
if (flaVersion.ordinal() >= FLAVersion.CS5_5.ordinal()) {
symbLinkStr+="String_Node_Str" + getTimestamp(swf) + "String_Node_Str";
}
symbLinkStr+="String_Node_Str";
symbols.add(symbLinkStr);
}
 else if (symbol instanceof ImageTag) {
ImageTag imageTag=(ImageTag)symbol;
boolean allowSmoothing=false;
looptags: for (Tag tag : swf.getTags()) {
if (tag instanceof ShapeTag) {
Set<Integer> needed=new HashSet<>();
tag.getNeededCharacters(needed);
ShapeTag sht=(ShapeTag)tag;
if (needed.contains(imageTag.getCharacterId())) {
List<FILLSTYLE> fs=new ArrayList<>();
SHAPEWITHSTYLE s=sht.getShapes();
for (FILLSTYLE f : s.fillStyles.fillStyles) {
fs.add(f);
}
for (SHAPERECORD r : s.shapeRecords) {
if (r instanceof StyleChangeRecord) {
StyleChangeRecord scr=(StyleChangeRecord)r;
if (scr.stateNewStyles) {
  for (  FILLSTYLE f : scr.fillStyles.fillStyles) {
    fs.add(f);
  }
}
}
}
for (FILLSTYLE f : fs) {
if (Arrays.asList(FILLSTYLE.REPEATING_BITMAP,FILLSTYLE.CLIPPED_BITMAP,FILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP,FILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP).contains(f.fillStyleType) && f.bitmapId == imageTag.getCharacterId()) {
allowSmoothing=f.fillStyleType == FILLSTYLE.CLIPPED_BITMAP || f.fillStyleType == FILLSTYLE.REPEATING_BITMAP;
break looptags;
}
}
}
}
}
byte imageBytes[]=Helper.readStream(imageTag.getImageData());
SerializableImage image=imageTag.getImage(false);
ImageFormat format=imageTag.getImageFormat();
String symbolFile="String_Node_Str" + symbol.getCharacterId() + imageTag.getImageFormat().getExtension();
files.put(symbolFile,imageBytes);
String mediaLinkStr="String_Node_Str" + symbolFile + "String_Node_Str"+ getTimestamp(swf)+ "String_Node_Str"+ imageBytes.length+ "String_Node_Str";
if (allowSmoothing) {
mediaLinkStr+="String_Node_Str";
}
switch (format) {
case PNG:
case GIF:
mediaLinkStr+="String_Node_Str";
break;
case JPEG:
mediaLinkStr+="String_Node_Str";
break;
}
if (characterClasses.containsKey(symbol.getCharacterId())) {
mediaLinkStr+="String_Node_Str" + characterClasses.get(symbol.getCharacterId()) + "String_Node_Str";
}
mediaLinkStr+="String_Node_Str" + symbolFile + "String_Node_Str"+ (media.size() + 1)+ "String_Node_Str"+ getTimestamp(swf)+ "String_Node_Str"+ image.getWidth()+ "String_Node_Str"+ image.getHeight()+ "String_Node_Str";
media.add(mediaLinkStr);
}
 else if ((symbol instanceof SoundStreamHeadTypeTag) || (symbol instanceof DefineSoundTag)) {
int soundFormat=0;
int soundRate=0;
boolean soundType=false;
boolean soundSize=false;
long soundSampleCount=0;
byte[] soundData=SWFInputStream.BYTE_ARRAY_EMPTY;
int[] rateMap={5,11,22,44};
String exportFormat="String_Node_Str";
if (symbol instanceof SoundStreamHeadTypeTag) {
SoundStreamHeadTypeTag sstream=(SoundStreamHeadTypeTag)symbol;
soundFormat=sstream.getSoundFormatId();
soundRate=sstream.getSoundRate();
soundType=sstream.getSoundType();
soundSize=sstream.getSoundSize();
soundSampleCount=sstream.getSoundSampleCount();
boolean found=false;
for (Tag t : tags) {
if (found && (t instanceof SoundStreamBlockTag)) {
SoundStreamBlockTag bl=(SoundStreamBlockTag)t;
soundData=bl.streamSoundData.getRangeData();
break;
}
if (t == symbol) {
found=true;
}
}
}
 else if (symbol instanceof DefineSoundTag) {
DefineSoundTag sound=(DefineSoundTag)symbol;
soundFormat=sound.soundFormat;
soundRate=sound.soundRate;
soundType=sound.soundType;
soundData=sound.soundData.getRangeData();
soundSize=sound.soundSize;
soundSampleCount=sound.soundSampleCount;
}
int format=0;
int bits=0;
if ((soundFormat == SoundFormat.FORMAT_ADPCM) || (soundFormat == SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN) || (soundFormat == SoundFormat.FORMAT_UNCOMPRESSED_NATIVE_ENDIAN)) {
exportFormat="String_Node_Str";
if (soundType) {
format+=1;
}
switch (soundRate) {
case 0:
format+=2;
break;
case 1:
format+=6;
break;
case 2:
format+=10;
break;
case 3:
format+=14;
break;
}
}
if (soundFormat == SoundFormat.FORMAT_SPEEX) {
bits=18;
}
if (soundFormat == SoundFormat.FORMAT_ADPCM) {
exportFormat="String_Node_Str";
try {
SWFInputStream sis=new SWFInputStream(swf,soundData);
int adpcmCodeSize=(int)sis.readUB(2,"String_Node_Str");
bits=2 + adpcmCodeSize;
}
 catch (IOException ex) {
logger.log(Level.SEVERE,null,ex);
}
}
if (soundFormat == SoundFormat.FORMAT_MP3) {
exportFormat="String_Node_Str";
if (!soundType) {
format+=1;
}
format+=4;
try {
MP3SOUNDDATA s=new MP3SOUNDDATA(new SWFInputStream(swf,soundData),false);
MP3FRAME frame=s.frames.get(0);
int bitRate=frame.getBitRate();
switch (bitRate) {
case 8:
bits=6;
break;
case 16:
bits=7;
break;
case 20:
bits=8;
break;
case 24:
bits=9;
break;
case 32:
bits=10;
break;
case 48:
bits=11;
break;
case 56:
bits=12;
break;
case 64:
bits=13;
break;
case 80:
bits=14;
break;
case 112:
bits=15;
break;
case 128:
bits=16;
break;
case 160:
bits=17;
break;
}
}
 catch (IOException|ArrayIndexOutOfBoundsException ex) {
logger.log(Level.SEVERE,null,ex);
}
}
SoundTag st=(SoundTag)symbol;
SoundFormat fmt=st.getSoundFormat();
byte[] data=SWFInputStream.BYTE_ARRAY_EMPTY;
try {
data=new SoundExporter().exportSound(st,SoundExportMode.MP3_WAV);
}
 catch (IOException ex) {
logger.log(Level.SEVERE,null,ex);
}
String symbolFile="String_Node_Str" + symbol.getCharacterId() + "String_Node_Str"+ exportFormat;
files.put(symbolFile,data);
String mediaLinkStr="String_Node_Str" + symbolFile + "String_Node_Str"+ getTimestamp(swf)+ "String_Node_Str"+ data.length+ "String_Node_Str";
mediaLinkStr+="String_Node_Str" + symbolFile + "String_Node_Str";
mediaLinkStr+="String_Node_Str";
mediaLinkStr+=rateMap[soundRate] + "String_Node_Str";
mediaLinkStr+="String_Node_Str" + (soundSize ? "String_Node_Str" : "String_Node_Str");
mediaLinkStr+="String_Node_Str" + (soundType ? "String_Node_Str" : "String_Node_Str");
mediaLinkStr+="String_Node_Str";
mediaLinkStr+="String_Node_Str" + format + "String_Node_Str"+ bits+ "String_Node_Str"+ soundSampleCount+ "String_Node_Str";
boolean linkageExportForAS=false;
if (characterClasses.containsKey(symbol.getCharacterId())) {
linkageExportForAS=true;
mediaLinkStr+="String_Node_Str" + characterClasses.get(symbol.getCharacterId()) + "String_Node_Str";
}
if (characterVariables.containsKey(symbol.getCharacterId())) {
linkageExportForAS=true;
mediaLinkStr+="String_Node_Str" + Helper.escapeHTML(characterVariables.get(symbol.getCharacterId())) + "String_Node_Str";
}
if (linkageExportForAS) {
mediaLinkStr+="String_Node_Str";
}
mediaLinkStr+="String_Node_Str";
media.add(mediaLinkStr);
}
 else if (symbol instanceof DefineVideoStreamTag) {
DefineVideoStreamTag video=(DefineVideoStreamTag)symbol;
String videoType="String_Node_Str";
switch (video.codecID) {
case 2:
videoType="String_Node_Str";
break;
case 3:
videoType="String_Node_Str";
break;
case 4:
videoType="String_Node_Str";
break;
case 5:
videoType="String_Node_Str";
break;
}
byte[] data=SWFInputStream.BYTE_ARRAY_EMPTY;
try {
data=new MovieExporter().exportMovie(video,MovieExportMode.FLV);
}
 catch (IOException ex) {
logger.log(Level.SEVERE,null,ex);
}
String symbolFile="String_Node_Str" + symbol.getCharacterId() + "String_Node_Str"+ "String_Node_Str";
String mediaLinkStr="String_Node_Str";
if (data.length == 0) {
long ts=getTimestamp(swf);
String datFileName="String_Node_Str" + (datfiles.size() + 1) + "String_Node_Str"+ ts+ "String_Node_Str";
mediaLinkStr="String_Node_Str" + symbolFile + "String_Node_Str"+ symbolFile+ "String_Node_Str"+ ts+ "String_Node_Str"+ datFileName+ "String_Node_Str";
datfiles.put(datFileName,new byte[]{(byte)0x03,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0xA0,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x78,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x59,(byte)0x40,(byte)0x18,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0xFF,(byte)0xFE,(byte)0xFF,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00});
}
 else {
files.put(symbolFile,data);
mediaLinkStr="String_Node_Str" + symbolFile + "String_Node_Str"+ getTimestamp(swf)+ "String_Node_Str"+ data.length+ "String_Node_Str";
mediaLinkStr+="String_Node_Str" + symbolFile + "String_Node_Str";
mediaLinkStr+="String_Node_Str" + videoType + "String_Node_Str";
mediaLinkStr+="String_Node_Str" + (int)swf.frameRate + "String_Node_Str";
mediaLinkStr+="String_Node_Str" + video.width + "String_Node_Str";
mediaLinkStr+="String_Node_Str" + video.height + "String_Node_Str";
double len=(double)video.numFrames / swf.frameRate;
mediaLinkStr+="String_Node_Str" + len + "String_Node_Str";
boolean linkageExportForAS=false;
if (characterClasses.containsKey(symbol.getCharacterId())) {
linkageExportForAS=true;
mediaLinkStr+="String_Node_Str" + characterClasses.get(symbol.getCharacterId()) + "String_Node_Str";
}
if (characterVariables.containsKey(symbol.getCharacterId())) {
linkageExportForAS=true;
mediaLinkStr+="String_Node_Str" + Helper.escapeHTML(characterVariables.get(symbol.getCharacterId())) + "String_Node_Str";
}
if (linkageExportForAS) {
mediaLinkStr+="String_Node_Str";
}
mediaLinkStr+="String_Node_Str";
}
media.add(mediaLinkStr);
}
}
if (!media.isEmpty()) {
ret.append("String_Node_Str");
for (String m : media) {
ret.append(m);
}
ret.append("String_Node_Str");
}
if (!symbols.isEmpty()) {
ret.append("String_Node_Str");
for (String s : symbols) {
ret.append(s);
}
ret.append("String_Node_Str");
}
}